Пример #1
0
        public void Setup()
        {
            this.native = new NATIVE_INDEXLIST()
            {
                tableid             = (IntPtr)0x1000,
                cRecord             = 100,
                columnidindexname   = 0,
                columnidgrbitIndex  = 1,
                columnidcKey        = 2,
                columnidcEntry      = 3,
                columnidcPage       = 4,
                columnidcColumn     = 5,
                columnidiColumn     = 6,
                columnidcolumnid    = 7,
                columnidcoltyp      = 8,
                columnidCountry     = 9,
                columnidLangid      = 10,
                columnidCp          = 11,
                columnidCollate     = 12,
                columnidgrbitColumn = 13,
                columnidcolumnname  = 14,
                columnidLCMapFlags  = 15,
            };

            this.converted = new JET_INDEXLIST();
            this.converted.SetFromNativeIndexlist(this.native);
        }
Пример #2
0
        public void JetIndexlistToString()
        {
            var value = new JET_INDEXLIST {
                cRecord = 3, tableid = new JET_TABLEID {
                    Value = (IntPtr)0x1a
                }
            };

            Assert.AreEqual("JET_INDEXLIST(0x1a,3 records)", value.ToString());
        }
Пример #3
0
        public void Setup()
        {
#pragma warning disable 618 // It's OK to use Deprecated values in our tests.
            this.native = new NATIVE_INDEXLIST()
            {
                tableid            = (IntPtr)0x1000,
                cRecord            = 100,
                columnidindexname  = 0,
                columnidgrbitIndex = 1,
                columnidcKey       = 2,
                columnidcEntry     = 3,
                columnidcPage      = 4,
                columnidcColumn    = 5,
                columnidiColumn    = 6,
                columnidcolumnid   = 7,
                columnidcoltyp     = 8,

// Suppressing error that columnidCountry is deprecated.
#pragma warning disable 618
                columnidCountry = 9,
#pragma warning restore 618
                columnidLangid = 10,
                columnidCp     = 11,

// Suppressing error that columnidCollate is deprecated.
#pragma warning disable 618
                columnidCollate = 12,
#pragma warning restore 618
                columnidgrbitColumn = 13,
                columnidcolumnname  = 14,
                columnidLCMapFlags  = 15,
            };
#pragma warning restore 618

            this.converted = new JET_INDEXLIST();
            this.converted.SetFromNativeIndexlist(this.native);
        }
Пример #4
0
        /// <summary>
        /// Creates an <see cref="IndexDefinition"/> object from the specified <paramref name="indexList"/>.
        /// </summary>
        /// <param name="database">The database.</param>
        /// <param name="tableName">Name of the table.</param>
        /// <param name="indexList">The index list.</param>
        /// <returns>An <see cref="IndexDefinition"/> object represting the specified index.</returns>
        internal static IndexDefinition Load(IsamDatabase database, string tableName, JET_INDEXLIST indexList)
        {
            lock (database.IsamSession)
            {
                JET_SESID sesid = database.IsamSession.Sesid;
                using (IsamTransaction trx = new IsamTransaction(database.IsamSession))
                {
                    // load info for the index
                    IndexDefinition indexDefinition = new IndexDefinition();

                    indexDefinition.name = Api.RetrieveColumnAsString(
                        sesid,
                        indexList.tableid,
                        indexList.columnidindexname);

                    CreateIndexGrbit grbitIndex = (CreateIndexGrbit)Api.RetrieveColumnAsUInt32(sesid, indexList.tableid, indexList.columnidgrbitIndex);
                    indexDefinition.flags = IndexFlagsFromGrbits(grbitIndex);

                    Api.JetGetIndexInfo(
                        sesid,
                        database.Dbid,
                        tableName,
                        indexDefinition.name,
                        out indexDefinition.density,
                        JET_IdxInfo.SpaceAlloc);
                    int lcid;
                    Api.JetGetIndexInfo(
                        database.IsamSession.Sesid,
                        database.Dbid,
                        tableName,
                        indexDefinition.name,
                        out lcid,
                        JET_IdxInfo.LCID);
                    indexDefinition.cultureInfo = new CultureInfo(lcid);

                    indexDefinition.compareOptions =
                        Conversions.CompareOptionsFromLCMapFlags(
                            Api.RetrieveColumnAsUInt32(
                                database.IsamSession.Sesid,
                                indexList.tableid,
                                indexList.columnidLCMapFlags).GetValueOrDefault());

                    // CONSIDER:  move this workaround into Isam.Interop
                    try
                    {
                        ushort maxKeyLength;
                        Api.JetGetIndexInfo(
                            database.IsamSession.Sesid,
                            database.Dbid,
                            tableName,
                            indexDefinition.name,
                            out maxKeyLength,
                            JET_IdxInfo.KeyMost);
                        indexDefinition.maxKeyLength = maxKeyLength;
                    }
                    catch (EsentInvalidParameterException)
                    {
                        indexDefinition.maxKeyLength = 255;
                    }
                    catch (EsentColumnNotFoundException)
                    {
                        indexDefinition.maxKeyLength = 255;
                    }

                    // load info for each key column in the index
                    int currentColumn      = 0;
                    int totalNumberColumns = Api.RetrieveColumnAsInt32(sesid, indexList.tableid, indexList.columnidcColumn).GetValueOrDefault();

                    indexDefinition.keyColumnCollection = new KeyColumnCollection();
                    do
                    {
                        // load info for this key column
                        IndexKeyGrbit grbitColumn = (IndexKeyGrbit)Api.RetrieveColumnAsUInt32(sesid, indexList.tableid, indexList.columnidgrbitColumn);
                        bool          isAscending = (grbitColumn & IndexKeyGrbit.Descending) == 0;
                        string        columnName  = Api.RetrieveColumnAsString(
                            sesid,
                            indexList.tableid,
                            indexList.columnidcolumnname);
                        JET_COLUMNBASE columnbase;
                        Api.JetGetColumnInfo(sesid, database.Dbid, tableName, columnName, out columnbase);

                        indexDefinition.keyColumnCollection.Add(new KeyColumn(new Columnid(columnbase), isAscending));

                        // move onto the next key column definition, unless it is
                        // the last key column
                        if (currentColumn != totalNumberColumns - 1)
                        {
                            Api.TryMoveNext(sesid, indexList.tableid);
                        }
                    }while (++currentColumn < totalNumberColumns);

                    indexDefinition.keyColumnCollection.ReadOnly = true;

                    // Vista: There is currently no efficient means to retrieve the
                    // conditional columns for an index from JET.  so, we are
                    // going to reach into the catalog and fetch them directly.
                    //
                    // FUTURE: Windows 7 introduced Windows7IdxInfo.CreateIndex and Windows7IdxInfo.CreateIndex2 (and
                    // Win8 has Windows8IdxInfo.CreateIndex3). Consider retrieving the conditional columns with that
                    // API and converting the results. But that does not solve the problem for Vista.
                    indexDefinition.conditionalColumnCollection = new ConditionalColumnCollection();
                    JET_TABLEID tableidCatalog;
                    Api.JetOpenTable(
                        database.IsamSession.Sesid,
                        database.Dbid,
                        "MSysObjects",
                        null,
                        0,
                        OpenTableGrbit.ReadOnly,
                        out tableidCatalog);

                    Api.JetSetCurrentIndex(sesid, tableidCatalog, "RootObjects");

                    Api.MakeKey(sesid, tableidCatalog, true, MakeKeyGrbit.NewKey);
                    Api.MakeKey(sesid, tableidCatalog, tableName, Encoding.ASCII, MakeKeyGrbit.None);
                    Api.JetSeek(sesid, tableidCatalog, SeekGrbit.SeekEQ);

                    JET_COLUMNID columnidTemp = Api.GetTableColumnid(sesid, tableidCatalog, "ObjidTable");
                    int          objidTable   = Api.RetrieveColumnAsInt32(sesid, tableidCatalog, columnidTemp).GetValueOrDefault();

                    Api.JetSetCurrentIndex(sesid, tableidCatalog, "Name");
                    Api.MakeKey(sesid, tableidCatalog, objidTable, MakeKeyGrbit.NewKey);
                    Api.MakeKey(sesid, tableidCatalog, (short)3, MakeKeyGrbit.None);
                    Api.MakeKey(sesid, tableidCatalog, indexDefinition.name, Encoding.ASCII, MakeKeyGrbit.None);
                    Api.JetSeek(sesid, tableidCatalog, SeekGrbit.SeekEQ);

                    columnidTemp = Api.GetTableColumnid(sesid, tableidCatalog, "Flags");
                    int indexFlagsBytes = Api.RetrieveColumnAsInt32(sesid, tableidCatalog, columnidTemp).GetValueOrDefault();

                    columnidTemp = Api.GetTableColumnid(sesid, tableidCatalog, "ConditionalColumns");
                    byte[] conditionalColumnsBytes = Api.RetrieveColumn(sesid, tableidCatalog, columnidTemp);

                    for (int ib = 0; conditionalColumnsBytes != null && ib < conditionalColumnsBytes.Length; ib += 4)
                    {
                        uint           colid;
                        bool           mustBeNull;
                        JET_COLUMNBASE columnBase;

                        // fIDXExtendedColumns
                        if ((indexFlagsBytes & 0xffff0000) == 0x00010000)
                        {
                            // fIDXSEGTemplateColumn
                            if ((conditionalColumnsBytes[ib + 0] & 0x80) != 0)
                            {
                                // fCOLUMNIDTemplate
                                colid = 0x80000000 | (uint)(conditionalColumnsBytes[ib + 3] << 8) | (uint)conditionalColumnsBytes[ib + 2];
                            }
                            else
                            {
                                colid = (uint)(conditionalColumnsBytes[ib + 3] << 8) | (uint)conditionalColumnsBytes[ib + 2];
                            }

                            // fIDXSEGMustBeNull
                            if ((conditionalColumnsBytes[ib + 0] & 0x20) != 0)
                            {
                                mustBeNull = true;
                            }
                            else
                            {
                                mustBeNull = false;
                            }
                        }
                        else
                        {
                            // do not load conditional columns from an unknown format
                            continue;
                        }

                        JET_COLUMNID castedColid = JET_COLUMNID.CreateColumnidFromNativeValue(unchecked ((int)colid));
                        VistaApi.JetGetColumnInfo(
                            database.IsamSession.Sesid,
                            database.Dbid,
                            tableName,
                            castedColid,
                            out columnBase);

                        indexDefinition.conditionalColumnCollection.Add(new ConditionalColumn(new Columnid(columnBase), mustBeNull));
                    }

                    indexDefinition.conditionalColumnCollection.ReadOnly = true;

                    indexDefinition.ReadOnly = true;

                    return(indexDefinition);
                }
            }
        }