public void GetIndexInformationOneIndexWithStats() { string indexname = "nonuniqueindex"; string indexdef = "+ascii\0\0"; CreateIndexGrbit grbit = CreateIndexGrbit.None; Api.JetBeginTransaction(this.sesid); Api.JetCreateIndex(this.sesid, this.tableid, indexname, grbit, indexdef, indexdef.Length, 100); // Insert 9 records with 3 of each key value for (int i = 0; i < 3; ++i) { this.InsertRecordWithString("ascii", "foo", Encoding.ASCII); this.InsertRecordWithString("ascii", "bar", Encoding.ASCII); this.InsertRecordWithString("ascii", "baz", Encoding.ASCII); } Api.JetComputeStats(this.sesid, this.tableid); IEnumerable <IndexInfo> indexes = Api.GetTableIndexes(this.sesid, this.tableid); // There should be only one index IndexInfo info = indexes.Single(); Assert.AreEqual(indexname, info.Name); // The index has 3 unique keys, 9 entries and everything should fit on one page. Assert.AreEqual(3, info.Keys); Assert.AreEqual(9, info.Entries); Assert.AreEqual(1, info.Pages); Api.JetRollback(this.sesid, RollbackTransactionGrbit.None); }
public void GetIndexInformationOneIndexMultipleSegments() { string indexname = "multisegmentindex"; string indexdef = "+ascii\0-boolean\0\0"; CreateIndexGrbit grbit = CreateIndexGrbit.IndexUnique; Api.JetBeginTransaction(this.sesid); Api.JetCreateIndex(this.sesid, this.tableid, indexname, grbit, indexdef, indexdef.Length, 100); IEnumerable <IndexInfo> indexes = Api.GetTableIndexes(this.sesid, this.tableid); // There should be only one index IndexInfo info = indexes.Single(); Assert.AreEqual(indexname, info.Name); Assert.AreEqual(grbit, info.Grbit); Assert.AreEqual(2, info.IndexSegments.Length); Assert.AreEqual("ascii", info.IndexSegments[0].ColumnName, true); Assert.IsTrue(info.IndexSegments[0].IsAscending); Assert.AreEqual(JET_coltyp.LongText, info.IndexSegments[0].Coltyp); Assert.IsTrue(info.IndexSegments[0].IsASCII); Assert.AreEqual("boolean", info.IndexSegments[1].ColumnName, true); Assert.IsFalse(info.IndexSegments[1].IsAscending); Assert.AreEqual(JET_coltyp.Bit, info.IndexSegments[1].Coltyp); Api.JetRollback(this.sesid, RollbackTransactionGrbit.None); }
public void GetIndexInformationOneIndex() { string indexname = "myindex"; string indexdef = "+ascii\0\0"; CreateIndexGrbit grbit = CreateIndexGrbit.IndexUnique; Api.JetBeginTransaction(this.sesid); Api.JetCreateIndex(this.sesid, this.tableid, indexname, grbit, indexdef, indexdef.Length, 100); IEnumerable <IndexInfo> indexes = Api.GetTableIndexes(this.sesid, this.tableid); // There should be only one index IndexInfo info = indexes.Single(); Assert.AreEqual(indexname, info.Name); Assert.AreEqual(grbit, info.Grbit); // The index has no stats Assert.AreEqual(0, info.Keys); Assert.AreEqual(0, info.Entries); Assert.AreEqual(0, info.Pages); Assert.AreEqual(1, info.IndexSegments.Count); Assert.AreEqual("ascii", info.IndexSegments[0].ColumnName, true); Assert.IsTrue(info.IndexSegments[0].IsAscending); Assert.AreEqual(JET_coltyp.LongText, info.IndexSegments[0].Coltyp); Assert.IsTrue(info.IndexSegments[0].IsASCII); Api.JetRollback(this.sesid, RollbackTransactionGrbit.None); }
/// <summary> /// Retrieves the <see cref="CreateIndexGrbit"/> options from an <see cref="IndexDefinition"/> object. /// </summary> /// <param name="indexDefinition">The index definition.</param> /// <returns>The <see cref="CreateIndexGrbit"/> options.</returns> internal static CreateIndexGrbit GrbitFromIndexDefinition(IndexDefinition indexDefinition) { CreateIndexGrbit grbit = CreateIndexGrbit.None; // We always provide unicode normalization configuration, // but ManagedEsent will set the grbit automatically. // grbit = grbit | VistaGrbits.IndexUnicode; // We always provide a max key length, but ManagedEsent will // set the grbit automatically. // grbit = grbit | VistaGrbits.IndexKeyMost; // we always do cross product indexing of multi-values grbit = grbit | VistaGrbits.IndexCrossProduct; if ((indexDefinition.Flags & IndexFlags.Unique) != 0) { grbit = grbit | CreateIndexGrbit.IndexUnique; } if ((indexDefinition.Flags & IndexFlags.Primary) != 0) { grbit = grbit | CreateIndexGrbit.IndexPrimary; } if ((indexDefinition.Flags & IndexFlags.DisallowNull) != 0) { grbit = grbit | CreateIndexGrbit.IndexDisallowNull; } if ((indexDefinition.Flags & IndexFlags.IgnoreNull) != 0) { grbit = grbit | CreateIndexGrbit.IndexIgnoreNull; } if ((indexDefinition.Flags & IndexFlags.IgnoreAnyNull) != 0) { grbit = grbit | CreateIndexGrbit.IndexIgnoreAnyNull; } if ((indexDefinition.Flags & IndexFlags.SortNullsHigh) != 0) { grbit = grbit | CreateIndexGrbit.IndexSortNullsHigh; } if ((indexDefinition.Flags & IndexFlags.DisallowTruncation) != 0) { grbit = grbit | VistaGrbits.IndexDisallowTruncation; } // AllowTruncation is an Isam-only flag, and we require it. if ((indexDefinition.Flags & IndexFlags.AllowTruncation) == 0) { grbit = grbit | VistaGrbits.IndexDisallowTruncation; } return(grbit); }
/// <summary>Declare the index, specifying the flags as well.</summary> /// <param name="_strName">The name of the index.</param> /// <param name="_strKey">Double null-terminated string of null-delimited tokens.</param> /// <param name="_flags">Options for JetCreateIndex.</param> /// <remarks>Each token within the _strKey is of the form "<direction-specifier><column-name>", /// where direction-specification is either "+" or "-". /// For example, a _strKey of "+abc\0-def\0+ghi\0\0" will index over the three columns /// "abc" (in ascending order), "def" (in descending order), and "ghi" (in ascending order).</remarks> /// <seealso cref="JET_INDEXCREATE" /> public EseIndexAttribute(string _strName, string _strKey, CreateIndexGrbit _flags) { strName = _strName; strKey = _strKey; #if WINDOWS_UWP // Workaround for that nasty .NET Native bug that eats trailing nulls in my attributes. strKey = strKey.TrimEnd('\0') + "\0\0"; #endif flags = _flags; }
public void TestTableIndexesFromTableNameEnumerable() { string indexname = "myindex"; string indexdef = "+ascii\0\0"; CreateIndexGrbit grbit = CreateIndexGrbit.IndexUnique; Api.JetBeginTransaction(this.sesid); Api.JetCreateIndex(this.sesid, this.tableid, indexname, grbit, indexdef, indexdef.Length, 100); EnumerableTests.TestEnumerable(Api.GetTableIndexes(this.sesid, this.dbid, this.table)); Api.JetRollback(this.sesid, RollbackTransactionGrbit.None); }
internal IndexInfo( string name, CultureInfo cultureInfo, CompareOptions compareOptions, IndexSegment[] indexSegments, CreateIndexGrbit grbit) { this.Name = name; this.CultureInfo = cultureInfo; this.CompareOptions = compareOptions; this.IndexSegments = indexSegments; this.Grbit = grbit; }
/// <summary> /// Initializes a new instance of the IndexInfo class. /// </summary> /// <param name="name">Name of the index.</param> /// <param name="cultureInfo">CultureInfo for string sorting.</param> /// <param name="compareOptions">String comparison options.</param> /// <param name="indexSegments">Array of index segment descriptions.</param> /// <param name="grbit">Index options.</param> internal IndexInfo( string name, CultureInfo cultureInfo, CompareOptions compareOptions, IndexSegment[] indexSegments, CreateIndexGrbit grbit) { this.Name = name; this.CultureInfo = cultureInfo; this.CompareOptions = compareOptions; this.IndexSegments = indexSegments; this.Grbit = grbit; }
internal static bool areEqual(CreateIndexGrbit grDatabase, CreateIndexGrbit grDeclaration) { // For some reason, indices sometimes have IndexUnique bit even when it was not requested while creation. // So we ignore that bit when validating. grDatabase &= ~CreateIndexGrbit.IndexUnique; grDeclaration &= ~CreateIndexGrbit.IndexUnique; // The DB engine normalizes JET_bitIndexIgnore*Null bits if (grDeclaration.HasFlag(CreateIndexGrbit.IndexIgnoreAnyNull)) { grDeclaration |= CreateIndexGrbit.IndexIgnoreFirstNull; grDeclaration |= CreateIndexGrbit.IndexIgnoreNull; } return(grDatabase == grDeclaration); }
/// <summary> /// Converts the <see cref="CreateIndexGrbit"/> enumeration to <see cref="IndexFlags"/>. /// </summary> /// <param name="grbitIndex">Index of the grbit.</param> /// <returns>The <see cref="IndexFlags"/> equivalent to <paramref name="grbitIndex"/>.</returns> private static IndexFlags IndexFlagsFromGrbits(CreateIndexGrbit grbitIndex) { IndexFlags flags = IndexFlags.None; if ((grbitIndex & CreateIndexGrbit.IndexUnique) != 0) { flags = flags | IndexFlags.Unique; } if ((grbitIndex & CreateIndexGrbit.IndexPrimary) != 0) { flags = flags | IndexFlags.Primary; } if ((grbitIndex & CreateIndexGrbit.IndexDisallowNull) != 0) { flags = flags | IndexFlags.DisallowNull; } if ((grbitIndex & CreateIndexGrbit.IndexIgnoreNull) != 0) { flags = flags | IndexFlags.IgnoreNull; } if ((grbitIndex & CreateIndexGrbit.IndexIgnoreAnyNull) != 0) { flags = flags | IndexFlags.IgnoreAnyNull; } if ((grbitIndex & CreateIndexGrbit.IndexSortNullsHigh) != 0) { flags = flags | IndexFlags.SortNullsHigh; } if ((grbitIndex & VistaGrbits.IndexDisallowTruncation) != 0) { flags = flags | IndexFlags.DisallowTruncation; } else { flags = flags | IndexFlags.AllowTruncation; } return(flags); }
/// <summary> /// Initializes a new instance of the IndexInfo class. /// </summary> /// <param name="name">Name of the index.</param> /// <param name="cultureInfo">CultureInfo for string sorting.</param> /// <param name="compareOptions">String comparison options.</param> /// <param name="indexSegments">Array of index segment descriptions.</param> /// <param name="grbit">Index options.</param> /// <param name="keys">Number of unique keys in the index.</param> /// <param name="entries">Number of entries in the index.</param> /// <param name="pages">Number of pages in the index.</param> internal IndexInfo( string name, CultureInfo cultureInfo, CompareOptions compareOptions, IndexSegment[] indexSegments, CreateIndexGrbit grbit, int keys, int entries, int pages) { this.name = name; this.cultureInfo = cultureInfo; this.compareOptions = compareOptions; this.indexSegments = new ReadOnlyCollection <IndexSegment>(indexSegments); this.grbit = grbit; this.keys = keys; this.entries = entries; this.pages = pages; }
/// <summary> /// Initializes a new instance of the IndexInfo class. /// </summary> /// <param name="name">Name of the index.</param> /// <param name="cultureInfo">CultureInfo for string sorting.</param> /// <param name="compareOptions">String comparison options.</param> /// <param name="indexSegments">Array of index segment descriptions.</param> /// <param name="grbit">Index options.</param> /// <param name="keys">Number of unique keys in the index.</param> /// <param name="entries">Number of entries in the index.</param> /// <param name="pages">Number of pages in the index.</param> internal IndexInfo( string name, CultureInfo cultureInfo, CompareOptions compareOptions, IndexSegment[] indexSegments, CreateIndexGrbit grbit, int keys, int entries, int pages) { this.name = name; this.cultureInfo = cultureInfo; this.compareOptions = compareOptions; this.indexSegments = Array.AsReadOnly(indexSegments); this.grbit = grbit; this.keys = keys; this.entries = entries; this.pages = pages; }
public void GetIndexInformationOneIndexWithStats() { string indexname = "nonuniqueindex"; string indexdef = "+ascii\0\0"; CreateIndexGrbit grbit = CreateIndexGrbit.None; Api.JetBeginTransaction(this.sesid); Api.JetCreateIndex(this.sesid, this.tableid, indexname, grbit, indexdef, indexdef.Length, 100); // Insert 9 records with 3 of each key value for (int i = 0; i < 3; ++i) { this.InsertRecordWithString("ascii", "foo", LibraryHelpers.EncodingASCII); this.InsertRecordWithString("ascii", "bar", LibraryHelpers.EncodingASCII); this.InsertRecordWithString("ascii", "baz", LibraryHelpers.EncodingASCII); } #if !MANAGEDESENT_ON_WSA // Not exposed in MSDK Api.JetComputeStats(this.sesid, this.tableid); #endif IEnumerable <IndexInfo> indexes = Api.GetTableIndexes(this.sesid, this.tableid); // There should be only one index IndexInfo info = indexes.Single(); Assert.AreEqual(indexname, info.Name); #if !MANAGEDESENT_ON_WSA // Not exposed in MSDK // These tests rely on JetComputeStats(), which isn't present in Windows Store Apps. // The index has 3 unique keys, 9 entries and everything should fit on one page. Assert.AreEqual(3, info.Keys); Assert.AreEqual(9, info.Entries); Assert.AreEqual(1, info.Pages); #endif Api.JetRollback(this.sesid, RollbackTransactionGrbit.None); }
/// <summary> /// Converts the <see cref="CreateIndexGrbit"/> enumeration to <see cref="IndexFlags"/>. /// </summary> /// <param name="grbitIndex">Index of the grbit.</param> /// <returns>The <see cref="IndexFlags"/> equivalent to <paramref name="grbitIndex"/>.</returns> private static IndexFlags IndexFlagsFromGrbits(CreateIndexGrbit grbitIndex) { IndexFlags flags = IndexFlags.None; if ((grbitIndex & CreateIndexGrbit.IndexUnique) != 0) { flags = flags | IndexFlags.Unique; } if ((grbitIndex & CreateIndexGrbit.IndexPrimary) != 0) { flags = flags | IndexFlags.Primary; } if ((grbitIndex & CreateIndexGrbit.IndexDisallowNull) != 0) { flags = flags | IndexFlags.DisallowNull; } if ((grbitIndex & CreateIndexGrbit.IndexIgnoreNull) != 0) { flags = flags | IndexFlags.IgnoreNull; } if ((grbitIndex & CreateIndexGrbit.IndexIgnoreAnyNull) != 0) { flags = flags | IndexFlags.IgnoreAnyNull; } if ((grbitIndex & CreateIndexGrbit.IndexSortNullsHigh) != 0) { flags = flags | IndexFlags.SortNullsHigh; } if ((grbitIndex & VistaGrbits.IndexDisallowTruncation) != 0) { flags = flags | IndexFlags.DisallowTruncation; } else { flags = flags | IndexFlags.AllowTruncation; } return flags; }
/// <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); } } }
private static void CompareIndexCreateWithOutput( JET_INDEXCREATE orig, JET_INDEXCREATE actual) { Assert.AreEqual(orig.szIndexName, actual.szIndexName); Assert.AreEqual(orig.cConditionalColumn, actual.cConditionalColumn); Assert.AreEqual(orig.cbKey, actual.cbKey); Assert.AreEqual(orig.szKey, actual.szKey); if (orig.cbKeyMost == 0) { Assert.AreEqual(255, actual.cbKeyMost); } else { Assert.AreEqual(orig.cbKeyMost, actual.cbKeyMost); } if (orig.cbVarSegMac == 0) { Assert.AreEqual(255, actual.cbVarSegMac); } else { Assert.AreEqual(orig.cbVarSegMac, actual.cbVarSegMac); } if (orig.ulDensity == 0) { Assert.AreEqual(100, actual.ulDensity); } else { Assert.AreEqual(orig.ulDensity, actual.ulDensity); } // Clear the bits that might get set: CreateIndexGrbit originalGrbit = orig.grbit; CreateIndexGrbit actualGrbit = actual.grbit & ~(CreateIndexGrbit.IndexUnique | VistaGrbits.IndexUnicode); if (originalGrbit.HasFlag(CreateIndexGrbit.IndexIgnoreAnyNull)) { originalGrbit &= ~(CreateIndexGrbit.IndexIgnoreAnyNull | CreateIndexGrbit.IndexIgnoreFirstNull | CreateIndexGrbit.IndexIgnoreNull); actualGrbit &= ~(CreateIndexGrbit.IndexIgnoreAnyNull | CreateIndexGrbit.IndexIgnoreFirstNull | CreateIndexGrbit.IndexIgnoreNull); } Assert.AreEqual(originalGrbit, actualGrbit); if (orig.pSpaceHints == null) { JET_SPACEHINTS defaultSpaceHints = new JET_SPACEHINTS() { ulInitialDensity = 100, // Or is it actual.ulDensity ? }; Assert.IsTrue(defaultSpaceHints.ContentEquals(actual.pSpaceHints)); } else { Assert.IsTrue(orig.pSpaceHints.ContentEquals(actual.pSpaceHints)); } if (orig.pidxUnicode == null) { JET_UNICODEINDEX defaultUnicodeIndex = new JET_UNICODEINDEX() { dwMapFlags = 0x30401, szLocaleName = "en-us", }; Assert.IsTrue(defaultUnicodeIndex.ContentEquals(actual.pidxUnicode)); } }
/// <summary> /// Creates an index over data in an ESE database. An index can be used to locate /// specific data quickly. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The table to create the index on.</param> /// <param name="indexName"> /// Pointer to a null-terminated string that specifies the name of the index to create. /// </param> /// <param name="grbit">Index creation options.</param> /// <param name="keyDescription"> /// Pointer to a double null-terminated string of null-delimited tokens. /// </param> /// <param name="keyDescriptionLength"> /// The length, in characters, of szKey including the two terminating nulls. /// </param> /// <param name="density">Initial B+ tree density.</param> public static void JetCreateIndex( JET_SESID sesid, JET_TABLEID tableid, string indexName, CreateIndexGrbit grbit, string keyDescription, int keyDescriptionLength, int density) { Api.Check(Impl.JetCreateIndex(sesid, tableid, indexName, grbit, keyDescription, keyDescriptionLength, density)); }