/// <summary> /// Seek for a key and make sure we land on the expected record. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The table to seek on.</param> /// <param name="key">The key to seek for.</param> /// <param name="seekOption">The seek option.</param> /// <param name="columnid">The columnid of the data to retrieve.</param> /// <param name="expected">The expected data.</param> private static void VerifySeekFindRecord( JET_SESID sesid, JET_TABLEID tableid, int key, SeekGrbit seekOption, JET_COLUMNID columnid, int expected) { Console.WriteLine("\t\tSeek for {0} with {1}, expecting {2}", key, seekOption, expected); Api.MakeKey(sesid, tableid, key, MakeKeyGrbit.NewKey); Api.JetSeek(sesid, tableid, seekOption); int actual = Api.RetrieveColumnAsInt32(sesid, tableid, columnid).Value; BasicClass.Assert(expected == actual, String.Format("Expected {0}, got {1}. Seek is broken", expected, actual)); }
/// <summary> /// Efficiently positions a cursor to an index entry that matches the search /// criteria specified by the search key in that cursor and the specified /// inequality. A search key must have been previously constructed using JetMakeKey. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to position.</param> /// <param name="grbit">Seek option.</param> /// <returns>True if a record matching the criteria was found.</returns> public static bool TrySeek(JET_SESID sesid, JET_TABLEID tableid, SeekGrbit grbit) { var err = (JET_err)Impl.JetSeek(sesid, tableid, grbit); if (JET_err.RecordNotFound == err) { return(false); } Api.Check((int)err); Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error"); return(true); }
/// <summary> /// Create an index range on the cursor, controlling which records will be enumerated. /// After this call the cursor will be positioned on range.Max and can be enumerated /// backwards to range.Min with TryMovePrevious. /// </summary> /// <param name="range">The range to set.</param> /// <returns>False if the range is empty.</returns> public bool SetReverseIndexRange(KeyRange <TKey> range) { if (range.IsEmpty) { return(false); } if (null != range.Max) { // The possibilities we have here are: // 1. Key = 'k', exclusive: seek for < 'k' // 2. Key = 'k', inclusive: seek for <= 'k' // 3. Key = 'k', prefix: make a prefix key and seek LE if (range.Max.IsPrefix) { this.MakePrefixKey(range.Max.Value); } else { this.MakeKey(range.Max.Value); } SeekGrbit grbit = range.Max.IsInclusive ? SeekGrbit.SeekLE : SeekGrbit.SeekLT; if (!Api.TrySeek(this.sesid, this.dataTable, grbit)) { return(false); } } else { Api.MoveAfterLast(this.sesid, this.dataTable); if (!Api.TryMovePrevious(this.sesid, this.dataTable)) { return(false); } } if (null != range.Min) { this.MakeKey(range.Min.Value); SetIndexRangeGrbit grbit = range.Min.IsInclusive ? SetIndexRangeGrbit.RangeInclusive : SetIndexRangeGrbit.None; return(Api.TrySetIndexRange(this.sesid, this.dataTable, grbit)); } return(true); }
/// <summary> /// Create an index range on the cursor, controlling which records will be enumerated. /// </summary> /// <param name="range">The range to set.</param> /// <returns>False if the range is empty.</returns> public bool SetIndexRange(KeyRange <TKey> range) { if (range.IsEmpty) { return(false); } if (null != range.Min) { this.MakeKey(range.Min.Value); SeekGrbit grbit = range.Min.IsInclusive ? SeekGrbit.SeekGE : SeekGrbit.SeekGT; if (!Api.TrySeek(this.sesid, this.dataTable, grbit)) { return(false); } } else { Api.MoveBeforeFirst(this.sesid, this.dataTable); if (!Api.TryMoveNext(this.sesid, this.dataTable)) { return(false); } } if (null != range.Max) { if (range.Max.IsPrefix) { this.MakePrefixKey(range.Max.Value); } else { this.MakeKey(range.Max.Value); } SetIndexRangeGrbit grbit = SetIndexRangeGrbit.RangeUpperLimit | (range.Max.IsInclusive ? SetIndexRangeGrbit.RangeInclusive : SetIndexRangeGrbit.None); return(Api.TrySetIndexRange(this.sesid, this.dataTable, grbit)); } return(true); }
/// <summary> /// Seek for a record after making a key. /// </summary> /// <param name="grbit">Seek option.</param> public virtual void Seek(SeekGrbit grbit) { Api.JetSeek(this.session, this.table, grbit); }
/// <summary> /// Efficiently positions a cursor to an index entry that matches the search /// criteria specified by the search key in that cursor and the specified /// inequality. A search key must have been previously constructed using JetMakeKey. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to position.</param> /// <param name="grbit">Seek option.</param> /// <returns>True if a record matching the criteria was found.</returns> public static bool TrySeek(JET_SESID sesid, JET_TABLEID tableid, SeekGrbit grbit) { var err = (JET_err)Impl.JetSeek(sesid, tableid, grbit); if (JET_err.RecordNotFound == err) { return false; } Api.Check((int)err); Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error"); return true; }
/// <summary> /// Efficiently positions a cursor to an index entry that matches the search /// criteria specified by the search key in that cursor and the specified /// inequality. A search key must have been previously constructed using /// <see cref="JetMakeKey(JET_SESID,JET_TABLEID,byte[],int,MakeKeyGrbit)"/>. /// Also see <seealso cref="TrySeek"/>. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to position.</param> /// <param name="grbit">Seek options.</param> /// <returns>An ESENT warning.</returns> public static JET_wrn JetSeek(JET_SESID sesid, JET_TABLEID tableid, SeekGrbit grbit) { return Api.Check(Impl.JetSeek(sesid, tableid, grbit)); }
/// <summary> /// Seeks to record clustered. /// </summary> /// <param name="tableId">The table id.</param> /// <param name="key">The key to seek.</param> /// <param name="seekGrbit">The seek grbit.</param> private void SeekToRecordClustered(JET_TABLEID tableId, int key, SeekGrbit seekGrbit) { this.MakeKeyClustered(tableId, key); Api.JetSeek(this.sesId, tableId, seekGrbit); }
/// <summary> /// Restricts the records that are visible to the cursor to a range of /// the current index delineated by the specified keys. /// </summary> /// <param name="keyStart">The partial or full key used to set the start of the records to find on the current index</param> /// <param name="criteriaStart">Indicates if the starting key is inclusive or exclusive</param> /// <param name="keyEnd">The partial or full key used to set the end of the records to find on the current index</param> /// <param name="criteriaEnd">Indicates if the ending key is inclusive or exclusive</param> /// <remarks> /// The restriction will remain in effect until explicitly reset or /// until implicitly reset by other methods as noted. /// <para> /// Any previously defined restriction will be cleared. /// </para> /// <para> /// The cursor will be positioned before the first record in the new /// restriction. /// </para> /// </remarks> public void FindRecordsBetween(Key keyStart, BoundCriteria criteriaStart, Key keyEnd, BoundCriteria criteriaEnd) { lock (this.isamSession) { this.CheckDisposed(); this.OnNavigation(); // clear our index range this.FindAllRecords(); // setup the effective index range to be bounded by the specified keys this.keyStart = this.MakeKey(keyStart, false); this.grbitSeekStart = criteriaStart == BoundCriteria.Inclusive ? SeekGrbit.SeekGE : SeekGrbit.SeekGT; this.grbitRangeStart = criteriaStart == BoundCriteria.Inclusive ? SetIndexRangeGrbit.RangeInclusive : SetIndexRangeGrbit.None; this.keyEnd = this.MakeKey(keyEnd, true); this.grbitSeekEnd = criteriaEnd == BoundCriteria.Inclusive ? SeekGrbit.SeekLE : SeekGrbit.SeekLT; this.grbitRangeEnd = (criteriaEnd == BoundCriteria.Inclusive ? SetIndexRangeGrbit.RangeInclusive : SetIndexRangeGrbit.None) | SetIndexRangeGrbit.RangeUpperLimit; // move before first on the new index range this.MoveBeforeFirst(); } }
/// <summary> /// Seek for a key and make sure we don't find a record. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The table to seek on.</param> /// <param name="key">The key to seek for.</param> /// <param name="seekOption">The seek option.</param> private static void VerifySeekFails(JET_SESID sesid, JET_TABLEID tableid, int key, SeekGrbit seekOption) { Console.WriteLine("\t\tSeek for {0} with {1}, expecting failure", key, seekOption); Api.MakeKey(sesid, tableid, key, MakeKeyGrbit.NewKey); bool result = Api.TrySeek(sesid, tableid, seekOption); BasicClass.Assert(!result, "Found the record. Expected not found."); }
/// <summary> /// Efficiently positions a cursor to an index entry that matches the search /// criteria specified by the search key in that cursor and the specified /// inequality. A search key must have been previously constructed using JetMakeKey. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to position.</param> /// <param name="grbit">Seek option.</param> /// <returns>True if a record matching the criteria was found.</returns> public static bool TrySeek(JET_SESID sesid, JET_TABLEID tableid, SeekGrbit grbit) { var err = (JET_err)Impl.JetSeek(sesid, tableid, grbit); if (err >= JET_err.Success) { return true; } else if (JET_err.RecordNotFound == err) { return false; } Api.Check((int)err); throw new Exception("Unreachable code"); }