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); }
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()); }
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); }
/// <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); } } }