/// <summary> /// Retrieves the bookmark for the record that is associated with the index entry /// at the current position of a cursor. This bookmark can then be used to /// reposition that cursor back to the same record using JetGotoBookmark. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to retrieve the bookmark from.</param> /// <returns>The bookmark of the record.</returns> public static byte[] GetBookmark(JET_SESID sesid, JET_TABLEID tableid) { byte[] buffer = Caches.BookmarkCache.Allocate(); int bookmarkSize; Api.JetGetBookmark(sesid, tableid, buffer, buffer.Length, out bookmarkSize); byte[] bookmark = MemoryCache.Duplicate(buffer, bookmarkSize); Caches.BookmarkCache.Free(ref buffer); return(bookmark); }
/// <summary> /// Retrieves the key for the index entry at the current position of a cursor. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to retrieve the key from.</param> /// <param name="grbit">Retrieve key options.</param> /// <returns>The retrieved key.</returns> public static byte[] RetrieveKey(JET_SESID sesid, JET_TABLEID tableid, RetrieveKeyGrbit grbit) { byte[] buffer = Caches.BookmarkCache.Allocate(); int keySize; Api.JetRetrieveKey(sesid, tableid, buffer, buffer.Length, out keySize, grbit); byte[] key = MemoryCache.Duplicate(buffer, keySize); Caches.BookmarkCache.Free(ref buffer); return(key); }
/// <summary> /// Retrieves a single column value from the current record. The record is that /// record associated with the index entry at the current position of the cursor. /// Alternatively, this function can retrieve a column from a record being created /// in the cursor copy buffer. This function can also retrieve column data from an /// index entry that references the current record. In addition to retrieving the /// actual column value, JetRetrieveColumn can also be used to retrieve the size /// of a column, before retrieving the column data itself so that application /// buffers can be sized appropriately. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to retrieve the column from.</param> /// <param name="columnid">The columnid to retrieve.</param> /// <param name="grbit">Retrieve column options.</param> /// <param name="retinfo"> /// If pretinfo is give as NULL then the function behaves as though an itagSequence /// of 1 and an ibLongValue of 0 (zero) were given. This causes column retrieval to /// retrieve the first value of a multi-valued column, and to retrieve long data at /// offset 0 (zero). /// </param> /// <returns>The data retrieved from the column. Null if the column is null.</returns> public static byte[] RetrieveColumn( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit, JET_RETINFO retinfo) { // We expect most column values retrieved this way to be small (retrieving a 1GB LV as one // chunk is a bit extreme!). Allocate a cached buffer and use that, allocating a larger one // if needed. byte[] cache = Caches.ColumnCache.Allocate(); byte[] data = cache; int dataSize; JET_wrn wrn = JetRetrieveColumn( sesid, tableid, columnid, data, data.Length, out dataSize, grbit, retinfo); if (JET_wrn.ColumnNull == wrn) { // null column data = null; } else if (JET_wrn.Success == wrn) { data = MemoryCache.Duplicate(data, dataSize); } else { // there is more data to retrieve Debug.Assert(JET_wrn.BufferTruncated == wrn, "Unexpected warning", wrn.ToString()); data = new byte[dataSize]; wrn = JetRetrieveColumn( sesid, tableid, columnid, data, data.Length, out dataSize, grbit, retinfo); if (JET_wrn.Success != wrn) { string error = String.Format( CultureInfo.CurrentCulture, "Column size changed from {0} to {1}. The record was probably updated by another thread.", data.Length, dataSize); Trace.TraceError(error); throw new InvalidOperationException(error); } } Caches.ColumnCache.Free(ref cache); return(data); }