/// <summary> /// Constructs a search key that may then be used by <see cref="JetSeek"/> /// and <see cref="JetSetIndexRange"/>. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to create the key on.</param> /// <param name="data">Column data for the current key column of the current index.</param> /// <param name="encoding">The encoding used to convert the string.</param> /// <param name="grbit">Key options.</param> public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, string data, Encoding encoding, MakeKeyGrbit grbit) { CheckEncodingIsValid(encoding); if (null == data) { Api.JetMakeKey(sesid, tableid, null, 0, grbit); } else if (0 == data.Length) { Api.JetMakeKey(sesid, tableid, null, 0, grbit | MakeKeyGrbit.KeyDataZeroLength); } else if (Encoding.Unicode == encoding) { // Optimization for Unicode strings unsafe { fixed (char* buffer = data) { Api.JetMakeKey(sesid, tableid, (IntPtr) buffer, data.Length * sizeof(char), grbit); } } } else { byte[] bytes = encoding.GetBytes(data); Api.JetMakeKey(sesid, tableid, bytes, bytes.Length, grbit); } }
private static void CreateDocumentsTable(Session session, JET_TABLEID tableid) { JET_COLUMNID columnid; var guidColumn = new JET_COLUMNDEF { cbMax = 255, coltyp = JET_coltyp.Text, cp = JET_CP.Unicode, grbit = ColumndefGrbit.ColumnTagged }; Api.JetAddColumn(session, tableid, "id", guidColumn, null, 0, out columnid); var collectionColumn = new JET_COLUMNDEF { cbMax = 1000, coltyp = JET_coltyp.Text, cp = JET_CP.Unicode, grbit = ColumndefGrbit.ColumnTagged }; Api.JetAddColumn(session, tableid, "collection_name", collectionColumn, null, 0, out columnid); const string colectionIndexDef = "+collection_name\0\0"; Api.JetCreateIndex(session, tableid, "by_collection_name", CreateIndexGrbit.None, colectionIndexDef, colectionIndexDef.Length, 100); var textColumn = new JET_COLUMNDEF { coltyp = JET_coltyp.LongText, grbit = ColumndefGrbit.ColumnTagged }; Api.JetAddColumn(session, tableid, "data", textColumn, null, 0, out columnid); const string idIndexDef = "+id\0\0"; Api.JetCreateIndex(session, tableid, "by_id", CreateIndexGrbit.IndexPrimary, idIndexDef, idIndexDef.Length, 100); }
/// <summary> /// The JetSetColumn function modifies a single column value in a modified record to be inserted or to /// update the current record. It can overwrite an existing value, add a new value to a sequence of /// values in a multi-valued column, remove a value from a sequence of values in a multi-valued column, /// or update all or part of a long value (a column of type <see cref="JET_coltyp.LongText"/> /// or <see cref="JET_coltyp.LongBinary"/>). /// </summary> /// <remarks> /// This is an internal-only version of the API that takes a data buffer and an offset into the buffer. /// </remarks> /// <param name="sesid">The session which is performing the update.</param> /// <param name="tableid">The cursor to update. An update should be prepared.</param> /// <param name="columnid">The columnid to set.</param> /// <param name="data">The data to set.</param> /// <param name="dataSize">The size of data to set.</param> /// <param name="dataOffset">The offset in the data buffer to set data from.</param> /// <param name="grbit">SetColumn options.</param> /// <param name="setinfo">Used to specify itag or long-value offset.</param> /// <returns>A warning value.</returns> public static JET_wrn JetSetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data, int dataSize, int dataOffset, SetColumnGrbit grbit, JET_SETINFO setinfo) { if (dataOffset < 0 || (null != data && 0 != dataSize && dataOffset >= data.Length) || (null == data && dataOffset != 0)) { throw new ArgumentOutOfRangeException( "dataOffset", dataOffset, "must be inside the data buffer"); } if (null != data && dataSize > checked(data.Length - dataOffset) && (SetColumnGrbit.SizeLV != (grbit & SetColumnGrbit.SizeLV))) { throw new ArgumentOutOfRangeException( "dataSize", dataSize, "cannot be greater than the length of the data (unless the SizeLV option is used)"); } unsafe { fixed (byte* pointer = data) { return Api.JetSetColumn(sesid, tableid, columnid, new IntPtr(pointer + dataOffset), dataSize, grbit, setinfo); } } }
/// <summary> /// Initializes a new instance of the <see cref="ColumnAccessor" /> class. /// </summary> /// <param name="cursor">The cursor.</param> /// <param name="isamSession">The session.</param> /// <param name="tableid">The tableid.</param> /// <param name="grbit">The grbit.</param> internal ColumnAccessor(Cursor cursor, IsamSession isamSession, JET_TABLEID tableid, RetrieveColumnGrbit grbit) { this.cursor = cursor; this.isamSession = isamSession; this.tableid = tableid; this.grbit = grbit; }
/// <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> /// <remarks> /// This is an internal method that takes a buffer offset as well as size. /// </remarks> /// <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="data">The data buffer to be retrieved into.</param> /// <param name="dataSize">The size of the data buffer.</param> /// <param name="dataOffset">Offset into the data buffer to read data into.</param> /// <param name="actualDataSize">Returns the actual size of the data buffer.</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>An ESENT warning code.</returns> public static JET_wrn JetRetrieveColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data, int dataSize, int dataOffset, out int actualDataSize, RetrieveColumnGrbit grbit, JET_RETINFO retinfo) { if (dataOffset < 0 || (null != data && 0 != dataSize && dataOffset >= data.Length) || (null == data && dataOffset != 0)) { throw new ArgumentOutOfRangeException( "dataOffset", dataOffset, "must be inside the data buffer"); } if ((null == data && dataSize > 0) || (null != data && dataSize > data.Length)) { throw new ArgumentOutOfRangeException( "dataSize", dataSize, "cannot be greater than the length of the data"); } unsafe { fixed (byte* pointer = data) { return Api.JetRetrieveColumn( sesid, tableid, columnid, new IntPtr(pointer + dataOffset), dataSize, out actualDataSize, grbit, retinfo); } } }
public void ConvertObjectlistFromNative() { var tableid = new JET_TABLEID { Value = (IntPtr)0x1000 }; var col1 = new JET_COLUMNID { Value = 1 }; var col2 = new JET_COLUMNID { Value = 2 }; var col3 = new JET_COLUMNID { Value = 3 }; var col4 = new JET_COLUMNID { Value = 4 }; var col5 = new JET_COLUMNID { Value = 5 }; var col6 = new JET_COLUMNID { Value = 6 }; var native = new NATIVE_OBJECTLIST() { tableid = tableid.Value, cRecord = 100, columnidobjectname = col1.Value, columnidobjtyp = col2.Value, columnidgrbit = col3.Value, columnidflags = col4.Value, columnidcRecord = col5.Value, columnidcPage = col6.Value, }; var objectlist = new JET_OBJECTLIST(); objectlist.SetFromNativeObjectlist(native); Assert.AreEqual(tableid, objectlist.tableid); Assert.AreEqual(100, objectlist.cRecord); Assert.AreEqual(col1, objectlist.columnidobjectname); Assert.AreEqual(col2, objectlist.columnidobjtyp); Assert.AreEqual(col3, objectlist.columnidgrbit); Assert.AreEqual(col4, objectlist.columnidflags); Assert.AreEqual(col5, objectlist.columnidcRecord); Assert.AreEqual(col6, objectlist.columnidcPage); }
public bool Add(JET_SESID session, JET_TABLEID table, int level) { byte[] buffer; int actualBookmarkSize; var largeBuffer = IndexReaderBuffers.Buffers.TakeBuffer(bookmarkMost); try { Api.JetGetBookmark(session, table, largeBuffer, largeBuffer.Length, out actualBookmarkSize); buffer = new byte[actualBookmarkSize]; Buffer.BlockCopy(largeBuffer, 0, buffer, 0, actualBookmarkSize); } finally { IndexReaderBuffers.Buffers.ReturnBuffer(largeBuffer); } var res = itemsToDelete.TryAdd(new Key(buffer, actualBookmarkSize)); if (res) { itemsToDeletePerViewAndLevel.DecrementPerLevelCounters(level); } return res; }
protected override void DoCreateTable(Session session, JET_TABLEID tableid) { JET_COLUMNID columnid; Api.JetAddColumn(session, tableid, "FileId", new JET_COLUMNDEF() { coltyp = JET_coltyp.Text, cp = JET_CP.Unicode, cbMax = 255, grbit = ColumndefGrbit.ColumnNotNULL }, null, 0, out columnid); Api.JetAddColumn(session, tableid, "Size", new JET_COLUMNDEF() { coltyp = Windows10Coltyp.UnsignedLongLong, grbit = ColumndefGrbit.ColumnNotNULL }, null, 0, out columnid); Api.JetAddColumn(session, tableid, "DTicks", new JET_COLUMNDEF() { coltyp = VistaColtyp.LongLong, grbit = ColumndefGrbit.ColumnNotNULL }, null, 0, out columnid); Api.JetAddColumn(session, tableid, "OTicks", new JET_COLUMNDEF() { coltyp = VistaColtyp.LongLong, grbit = ColumndefGrbit.ColumnNotNULL }, null, 0, out columnid); var indexDef = "+FileId\0\0"; Api.JetCreateIndex(session, tableid, PrimaryIndexName, CreateIndexGrbit.IndexPrimary, indexDef, indexDef.Length, 100); }
public void Setup() { JET_TABLEID tableidTemp = new JET_TABLEID() { Value = (IntPtr)456, }; this.managed = new JET_TABLECREATE() { szTableName = "table7", szTemplateTableName = "parentTable", ulPages = 7, ulDensity = 62, rgcolumncreate = null, cColumns = 0, rgindexcreate = null, cIndexes = 0, szCallback = "module!FunkyFunction", cbtyp = JET_cbtyp.AfterReplace, grbit = CreateTableColumnIndexGrbit.FixedDDL, pSeqSpacehints = null, pLVSpacehints = null, cbSeparateLV = 0x999, tableid = tableidTemp, cCreated = 2, }; this.native = this.managed.GetNativeTableCreate2(); }
/// <summary> /// Constructs a search key that may then be used by <see cref="JetSeek"/> /// and <see cref="JetSetIndexRange"/>. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to create the key on.</param> /// <param name="data">Column data for the current key column of the current index.</param> /// <param name="encoding">The encoding used to convert the string.</param> /// <param name="grbit">Key options.</param> public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, string data, Encoding encoding, MakeKeyGrbit grbit) { CheckEncodingIsValid(encoding); if (null == data) { Api.JetMakeKey(sesid, tableid, null, 0, grbit); } else if (0 == data.Length) { Api.JetMakeKey(sesid, tableid, null, 0, grbit | MakeKeyGrbit.KeyDataZeroLength); } else if (Encoding.Unicode == encoding) { // Optimization for Unicode strings unsafe { fixed (char* buffer = data) { Api.JetMakeKey(sesid, tableid, new IntPtr(buffer), checked(data.Length * sizeof(char)), grbit); } } } else { #if MANAGEDESENT_ON_WSA // Encoding.GetBytes(char*, int, byte*, int) overload is missing in new Windows UI. // So we can't use the ColumnCache. We'll just use a different GetBytes() overload. byte[] buffer = encoding.GetBytes(data); Api.JetMakeKey(sesid, tableid, buffer, buffer.Length, grbit); #else // Convert the string using a cached column buffer. The column buffer is far larger // than the maximum key size, so any data truncation here won't matter. byte[] buffer = null; try { buffer = Caches.ColumnCache.Allocate(); int dataSize; unsafe { fixed (char* chars = data) fixed (byte* bytes = buffer) { dataSize = encoding.GetBytes(chars, data.Length, bytes, buffer.Length); } } JetMakeKey(sesid, tableid, buffer, dataSize, grbit); } finally { if (buffer != null) { Caches.ColumnCache.Free(ref buffer); } } #endif } }
/// <summary> /// Creates indexes over data in an ESE database. /// </summary> /// <remarks> /// When creating multiple indexes (i.e. with numIndexCreates /// greater than 1) this method MUST be called /// outside of any transactions and with exclusive access to the /// table. The JET_TABLEID returned by "Api.JetCreateTable" /// will have exlusive access or the table can be opened for /// exclusive access by passing <see cref="OpenTableGrbit.DenyRead"/> /// to <see cref="Api.JetOpenTable"/>. /// </remarks> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The table to create the index on.</param> /// <param name="indexcreates">Array of objects describing the indexes to be created.</param> /// <param name="numIndexCreates">Number of index description objects.</param> public static void JetCreateIndex4( JET_SESID sesid, JET_TABLEID tableid, JET_INDEXCREATE[] indexcreates, int numIndexCreates) { Api.Check(Api.Impl.JetCreateIndex4(sesid, tableid, indexcreates, numIndexCreates)); }
/// <summary> /// Retrieves information about a table column. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The table containing the column.</param> /// <param name="columnid">The columnid of the column.</param> /// <param name="columnbase">Filled in with information about the column.</param> public static void JetGetTableColumnInfo( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, out JET_COLUMNBASE columnbase) { Api.Check(Api.Impl.JetGetTableColumnInfo(sesid, tableid, columnid, out columnbase)); }
public static void JetGetTableIndexInfo( JET_SESID sesid, JET_TABLEID tableid, string indexname, out JET_INDEXLIST indexlist) { Api.JetGetTableIndexInfo(sesid, tableid, indexname, out indexlist, JET_IdxInfo.List); }
/// <summary> /// Initializes a new instance of the ColumnStream class. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to use.</param> /// <param name="columnid">The columnid of the column to set/retrieve data from.</param> public ColumnStream(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid) { this.sesid = sesid; this.tableid = tableid; this.columnid = columnid; this.ibLongValue = 0; this.Itag = 1; }
public EsentDb(string dbname) { this.dbname = dbname; instance = OpenInstance(dbname); session = CreateSession(instance); dbid = CreateDatabase(dbname, instance, session); table = CreateTable(session, dbid, "store", new Tuple<string, JET_coltyp>[] { Tuple.Create("key", JET_coltyp.Long), Tuple.Create("data", JET_coltyp.LongText) }); }
void ISchemaPart.ApplyToTable(Session session, JET_TABLEID table) { if (Api.GetTableColumns(session, table).All(ci => ci.Name != Name)) { var factory = EsentHelper.GetColumnFactory(Member); JET_COLUMNID columnid; Api.JetAddColumn(session, table, Name, factory(), null, 0, out columnid); } }
/// <summary> /// Initializes a new instance of the <see cref="TempTableHandle"/> class. /// </summary> /// <param name="name">The name.</param> /// <param name="sesid">The sesid.</param> /// <param name="tableid">The tableid.</param> /// <param name="inInsertMode">if set to <c>true</c> [in insert mode].</param> internal TempTableHandle(string name, JET_SESID sesid, JET_TABLEID tableid, bool inInsertMode) { this.guid = Guid.NewGuid(); this.name = name; this.sesid = sesid; this.tableid = tableid; this.inInsertMode = inInsertMode; this.cursorCount = 0; }
/// <summary> /// Create a NATIVE_INDEXRANGE from a cursor. /// </summary> /// <param name="tableid">The cursor containing the index range.</param> /// <returns>A new NATIVE_INDEXRANGE on the cursor.</returns> public static NATIVE_INDEXRANGE MakeIndexRangeFromTableid(JET_TABLEID tableid) { var s = new NATIVE_INDEXRANGE { tableid = tableid.Value, grbit = (uint) IndexRangeGrbit.RecordInIndex, }; s.cbStruct = (uint)Marshal.SizeOf(s); return s; }
void ISchemaPart.ApplyToTable(Session session, JET_TABLEID table) { if (!Api.GetTableColumns(session, table).Any(ci => ci.Name == Name)) { JET_COLUMNID columnid; Api.JetAddColumn(session, table, Name, new JET_COLUMNDEF {coltyp = JET_coltyp.Long, grbit = ColumndefGrbit.ColumnVersion}, null, 0, out columnid); } }
public void Setup() { this.directory = SetupHelper.CreateRandomDirectory(); this.instance = SetupHelper.CreateNewInstance(this.directory); // turn off logging so initialization is faster Api.JetSetSystemParameter(this.instance, JET_SESID.Nil, JET_param.Recovery, 0, "off"); Api.JetInit(ref this.instance); Api.JetBeginSession(this.instance, out this.sesid, String.Empty, String.Empty); this.tableid = JET_TABLEID.Nil; }
/// <summary> /// Initializes a new instance of the ColumnStream class. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to use.</param> /// <param name="columnid">The columnid of the column to set/retrieve data from.</param> public ColumnStream(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid) { // In some cases we rely on Int32 arithmetic overflow checking to catch // errors, which assumes that a long-value can store Int32.MaxValue bytes. Debug.Assert(MaxLongValueSize == Int32.MaxValue, "Expected maximum long value size to be Int32.MaxValue"); this.sesid = sesid; this.tableid = tableid; this.columnid = columnid; this.Itag = 1; }
/// <summary> /// If the records with the specified keys are not in the buffer cache /// then start asynchronous reads to bring the records into the database /// buffer cache. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The table to issue the prereads against.</param> /// <param name="keys"> /// The keys to preread. The keys must be sorted. /// </param> /// <param name="keyLengths">The lengths of the keys to preread.</param> /// <param name="keyCount"> /// The maximum number of keys to preread. /// </param> /// <param name="keysPreread"> /// Returns the number of keys to actually preread. /// </param> /// <param name="grbit"> /// Preread options. Used to specify the direction of the preread. /// </param> public static void JetPrereadKeys( JET_SESID sesid, JET_TABLEID tableid, byte[][] keys, int[] keyLengths, int keyCount, out int keysPreread, PrereadKeysGrbit grbit) { JetPrereadKeys(sesid, tableid, keys, keyLengths, 0, keyCount, out keysPreread, grbit); }
/// <summary> /// Modifies a single column value in a modified record to be inserted or to /// update the current record. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to update. An update should be prepared.</param> /// <param name="columnid">The columnid to set.</param> /// <param name="data">The data to set.</param> /// <param name="encoding">The encoding used to convert the string.</param> /// <param name="grbit">SetColumn options.</param> public static void SetColumn( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, string data, Encoding encoding, SetColumnGrbit grbit) { CheckEncodingIsValid(encoding); if (null == data) { JetSetColumn(sesid, tableid, columnid, null, 0, grbit, null); } else if (0 == data.Length) { JetSetColumn(sesid, tableid, columnid, null, 0, grbit | SetColumnGrbit.ZeroLength, null); } else if (Encoding.Unicode == encoding) { // Optimization for setting Unicode strings. unsafe { fixed (char* buffer = data) { JetSetColumn( sesid, tableid, columnid, new IntPtr(buffer), checked(data.Length * sizeof(char)), grbit, null); } } } else if (encoding.GetMaxByteCount(data.Length) <= Caches.ColumnCache.BufferSize) { // The encoding output will fix in a cached buffer. Get one to avoid // more memory allocations. byte[] buffer = Caches.ColumnCache.Allocate(); unsafe { fixed (char* chars = data) fixed (byte* bytes = buffer) { int dataSize = encoding.GetBytes(chars, data.Length, bytes, buffer.Length); JetSetColumn(sesid, tableid, columnid, new IntPtr(bytes), dataSize, grbit, null); } } Caches.ColumnCache.Free(ref buffer); } else { byte[] bytes = encoding.GetBytes(data); JetSetColumn(sesid, tableid, columnid, bytes, bytes.Length, grbit, null); } }
/// <summary> /// Removes an index range created with <see cref="JetSetIndexRange"/> or /// <see cref="TrySetIndexRange"/>. If no index range is present this /// method does nothing. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to remove the index range on.</param> public static void ResetIndexRange(JET_SESID sesid, JET_TABLEID tableid) { var err = (JET_err)Impl.JetSetIndexRange(sesid, tableid, SetIndexRangeGrbit.RangeRemove); if (JET_err.InvalidOperation == err) { // this error is expected if there isn't currently an index range return; } Api.Check((int)err); return; }
/// <summary> /// Add a column to the table. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The table to add the column to.</param> /// <param name="name">The name of the column.</param> /// <param name="coltyp">The type of the column.</param> /// <param name="cp">The codepage to use.</param> private void AddColumn(JET_SESID sesid, JET_TABLEID tableid, string name, JET_coltyp coltyp, JET_CP cp) { JET_COLUMNID ignored; Api.JetAddColumn( sesid, tableid, name, new JET_COLUMNDEF() { coltyp = coltyp, cp = cp }, null, 0, out ignored); }
/// <summary> /// If the records with the specified keys are not in the buffer cache /// then start asynchronous reads to bring the records into the database /// buffer cache. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The table to issue the prereads against.</param> /// <param name="keys"> /// The keys to preread. The keys must be sorted. /// </param> /// <param name="keyLengths">The lengths of the keys to preread.</param> /// <param name="keyIndex"> /// The index of the first key in the keys array to read. /// </param> /// <param name="keyCount"> /// The maximum number of keys to preread. /// </param> /// <param name="keysPreread"> /// Returns the number of keys to actually preread. /// </param> /// <param name="grbit"> /// Preread options. Used to specify the direction of the preread. /// </param> public static void JetPrereadKeys( JET_SESID sesid, JET_TABLEID tableid, byte[][] keys, int[] keyLengths, int keyIndex, int keyCount, out int keysPreread, PrereadKeysGrbit grbit) { Api.Check(Api.Impl.JetPrereadKeys(sesid, tableid, keys, keyLengths, keyIndex, keyCount, out keysPreread, grbit)); }
void ISchemaPart.ApplyToTable(Session session, JET_TABLEID table) { var indexDef = IndexHelper.BuildIndexDefinition(Name); if (Api.GetTableColumns(session, table).All(ci => ci.Name != Name)) { JET_COLUMNID columnid; var factory = EsentHelper.GetColumnFactory(Member); Api.JetAddColumn(session, table, Name, factory(), null, 0, out columnid); Api.JetCreateIndex(session, table, Name + "_index", CreateIndexGrbit.IndexPrimary, indexDef, indexDef.Length, _density); } }
/// <summary> /// Explicitly reserve the ability to update a row, write lock, or to explicitly prevent a row from /// being updated by any other session, read lock. Normally, row write locks are acquired implicitly as a /// result of updating rows. Read locks are usually not required because of record versioning. However, /// in some cases a transaction may desire to explicitly lock a row to enforce serialization, or to ensure /// that a subsequent operation will succeed. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to use. A lock will be acquired on the current record.</param> /// <param name="grbit">Lock options, use this to specify which type of lock to obtain.</param> /// <returns> /// True if the lock was obtained, false otherwise. An exception is thrown if an unexpected /// error is encountered. /// </returns> public static bool TryGetLock(JET_SESID sesid, JET_TABLEID tableid, GetLockGrbit grbit) { var err = (JET_err)Impl.JetGetLock(sesid, tableid, grbit); if (JET_err.WriteConflict == 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> /// Initializes a new instance of the Update class. This automatically /// begins an update. The update will be cancelled if /// not explicitly saved. /// </summary> /// <param name="sesid">The session to start the transaction for.</param> /// <param name="tableid">The tableid to prepare the update for.</param> /// <param name="prep">The type of update.</param> public Update(JET_SESID sesid, JET_TABLEID tableid, JET_prep prep) { if (JET_prep.Cancel == prep) { throw new ArgumentException("Cannot create an Update for JET_prep.Cancel", "prep"); } this.sesid = sesid; this.tableid = tableid; Api.JetPrepareUpdate(this.sesid, this.tableid, prep); this.ResourceWasAllocated(); }
/// <summary> /// Try to move to the last record in the table. If the table is empty this /// returns false, if a different error is encountered an exception is thrown. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to position.</param> /// <returns>True if the move was successful.</returns> public static bool TryMoveLast(JET_SESID sesid, JET_TABLEID tableid) { var err = (JET_err)Impl.JetMove(sesid, tableid, (int)JET_Move.Last, MoveGrbit.None); if (JET_err.NoCurrentRecord == err) { return false; } Api.Check((int)err); Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error"); return true; }
public IEnumerable <RevaleeTask> ListAllTasks() { if (_EseInstance == null) { throw new InvalidOperationException("Storage provider has not been opened."); } EseConnection connection = this._ConnectionPool.OpenConnection(); try { using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.DenyWrite | OpenTableGrbit.Preread | OpenTableGrbit.ReadOnly | OpenTableGrbit.Sequential)) { IDictionary <string, JET_COLUMNID> columnIds = connection.GetSchema(_TableNameCallbacks); if (Api.TryMoveFirst(connection, table)) { JET_SESID jetSession = connection; JET_TABLEID jetTable = table; JET_COLUMNID jetColumnCallbackId = columnIds[_ColumnNameCallbackId]; JET_COLUMNID jetColumnCreatedTime = columnIds[_ColumnNameCreatedTime]; JET_COLUMNID jetColumnCallbackTime = columnIds[_ColumnNameCallbackTime]; JET_COLUMNID jetColumnCallbackUrl = columnIds[_ColumnNameCallbackUrl]; JET_COLUMNID jetColumnAttemptsRemaining = columnIds[_ColumnNameAttemptsRemaining]; JET_COLUMNID jetColumnAuthorizationCipher = columnIds[_ColumnNameAuthorizationCipher]; do { Guid? callbackId = Api.RetrieveColumnAsGuid(jetSession, jetTable, jetColumnCallbackId); DateTime?createdTime = Api.RetrieveColumnAsDateTime(jetSession, jetTable, jetColumnCreatedTime); DateTime?callbackTime = Api.RetrieveColumnAsDateTime(jetSession, jetTable, jetColumnCallbackTime); string callbackUrl = Api.RetrieveColumnAsString(jetSession, jetTable, jetColumnCallbackUrl); int? attemptsRemainingColumn = Api.RetrieveColumnAsInt32(jetSession, jetTable, jetColumnAttemptsRemaining); string authorizationCipher = Api.RetrieveColumnAsString(jetSession, jetTable, jetColumnAuthorizationCipher); Uri callbackUri = null; if (callbackTime.HasValue && Uri.TryCreate(callbackUrl, UriKind.Absolute, out callbackUri) && createdTime.HasValue && callbackId.HasValue && attemptsRemainingColumn.HasValue) { RevaleeTask revivedTask = RevaleeTask.Revive( DateTime.SpecifyKind(callbackTime.Value, DateTimeKind.Utc), callbackUri, DateTime.SpecifyKind(createdTime.Value, DateTimeKind.Utc), callbackId.Value, attemptsRemainingColumn.Value, string.IsNullOrEmpty(authorizationCipher) ? null : authorizationCipher); yield return(revivedTask); } } while (Api.TryMoveNext(jetSession, jetTable)); } } } finally { _ConnectionPool.CloseConnection(connection); } yield break; }
private List <ColSpec> GetTableDef(JET_TABLEID table) { var columns = new List <ColumnInfo>(Esent.GetTableColumns(m_sesid, table)); var tableDef = new List <ColSpec>(); foreach (var column in columns) { var colspec = new ColSpec(); colspec.Name = column.Name; colspec.ColumnId = column.Columnid; colspec.Retriever = null; switch (column.Coltyp) { case JET_coltyp.Text: case JET_coltyp.LongText: colspec.Type = typeof(string); break; case JET_coltyp.Long: colspec.Type = typeof(int?); break; case JET_coltyp.Short: colspec.Type = typeof(short?); break; case JET_coltyp.UnsignedByte: colspec.Type = typeof(byte?); break; case JET_coltyp.Bit: colspec.Type = typeof(bool?); break; case JET_coltyp.DateTime: colspec.Type = typeof(DateTime?); break; case JET_coltyp.IEEEDouble: colspec.Type = typeof(double?); break; case JET_coltyp.IEEESingle: colspec.Type = typeof(float?); break; case JET_coltyp.Binary: case JET_coltyp.LongBinary: colspec.Retriever = (s, t, c) => { byte[] value = Esent.RetrieveColumn(s, t, c); if (value != null) { return(Convert.ToBase64String(value)); } else { return(value); } }; colspec.Type = typeof(string); break; case VistaColtyp.UnsignedLong: colspec.Type = typeof(UInt32?); break; case VistaColtyp.LongLong: colspec.Type = typeof(Int64?); break; case VistaColtyp.GUID: colspec.Type = typeof(Guid?); break; case VistaColtyp.UnsignedShort: colspec.Type = typeof(UInt16?); break; default: colspec.Retriever = (s, t, c) => "ERROR: unhandled type " + Enum.GetName(typeof(JET_coltyp), column.Coltyp) + "(" + (int)column.Coltyp + ")"; colspec.Type = typeof(string); break; } if (colspec.Retriever == null) { colspec.Retriever = ColumnRetrievers.ForType(colspec.Type); } tableDef.Add(colspec); } return(tableDef); }
/// <summary> /// Set a string. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The table to set the value in.</param> /// <param name="columnid">The column to set.</param> /// <param name="value">The value to set.</param> private static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, string value) { Api.SetColumn(sesid, tableid, columnid, value, Encoding.Unicode, SetColumnGrbit.IntrinsicLV); }
/// <summary> /// Set a date time. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The table to set the value in.</param> /// <param name="columnid">The column to set.</param> /// <param name="value">The value to set.</param> private static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, DateTime value) { Api.SetColumn(sesid, tableid, columnid, value.Ticks); }
public IEnumerable <RevaleeTask> ListTasksDueBetween(DateTime startTime, DateTime endTime) { if (_EseInstance == null) { throw new InvalidOperationException("Storage provider has not been opened."); } DateTime rangeStartTime = NormalizeDateTime(startTime); DateTime rangeEndTime = NormalizeDateTime(endTime); // Inclusive Upper Limit does not work properly for the CLR DateTime type. // Add the smallest amount of time that the Esent engine will detect to include the ending range inclusively. rangeEndTime = rangeEndTime.AddMilliseconds(1.0); EseConnection connection = this._ConnectionPool.OpenConnection(); try { using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.DenyWrite | OpenTableGrbit.Preread | OpenTableGrbit.ReadOnly | OpenTableGrbit.Sequential)) { IDictionary <string, JET_COLUMNID> columnIds = connection.GetSchema(_TableNameCallbacks); Api.JetSetCurrentIndex(connection, table, "due"); Api.MakeKey(connection, table, rangeStartTime, MakeKeyGrbit.NewKey); if (Api.TrySeek(connection, table, SeekGrbit.SeekGE)) { Api.MakeKey(connection, table, rangeEndTime, MakeKeyGrbit.NewKey); if (Api.TrySetIndexRange(connection, table, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit)) { JET_SESID jetSession = connection; JET_TABLEID jetTable = table; JET_COLUMNID jetColumnCallbackId = columnIds[_ColumnNameCallbackId]; JET_COLUMNID jetColumnCreatedTime = columnIds[_ColumnNameCreatedTime]; JET_COLUMNID jetColumnCallbackTime = columnIds[_ColumnNameCallbackTime]; JET_COLUMNID jetColumnCallbackUrl = columnIds[_ColumnNameCallbackUrl]; JET_COLUMNID jetColumnAttemptsRemaining = columnIds[_ColumnNameAttemptsRemaining]; JET_COLUMNID jetColumnAuthorizationCipher = columnIds[_ColumnNameAuthorizationCipher]; do { Guid? callbackId = Api.RetrieveColumnAsGuid(jetSession, jetTable, jetColumnCallbackId); DateTime?createdTime = Api.RetrieveColumnAsDateTime(jetSession, jetTable, jetColumnCreatedTime); DateTime?callbackTime = Api.RetrieveColumnAsDateTime(jetSession, jetTable, jetColumnCallbackTime); string callbackUrl = Api.RetrieveColumnAsString(jetSession, jetTable, jetColumnCallbackUrl); int? attemptsRemainingColumn = Api.RetrieveColumnAsInt32(jetSession, jetTable, jetColumnAttemptsRemaining); string authorizationCipher = Api.RetrieveColumnAsString(jetSession, jetTable, jetColumnAuthorizationCipher); Uri callbackUri = null; if (callbackTime.HasValue && Uri.TryCreate(callbackUrl, UriKind.Absolute, out callbackUri) && createdTime.HasValue && callbackId.HasValue && attemptsRemainingColumn.HasValue) { RevaleeTask revivedTask = RevaleeTask.Revive( DateTime.SpecifyKind(callbackTime.Value, DateTimeKind.Utc), callbackUri, DateTime.SpecifyKind(createdTime.Value, DateTimeKind.Utc), callbackId.Value, attemptsRemainingColumn.Value, string.IsNullOrEmpty(authorizationCipher) ? null : authorizationCipher); yield return(revivedTask); } } while (Api.TryMoveNext(jetSession, jetTable)); } } } } finally { _ConnectionPool.CloseConnection(connection); } yield break; }