public void VerifyUpdateFromNativeRetrievecolumnSetsCbactual() { var setcolumn = new JET_RETRIEVECOLUMN(); var native = new NATIVE_RETRIEVECOLUMN { cbActual = 0x100 }; setcolumn.UpdateFromNativeRetrievecolumn(native); Assert.AreEqual(0x100, setcolumn.cbActual); }
public void VerifyCheckThrowsExceptionWhenPvDataIsNull() { var setcolumn = new JET_RETRIEVECOLUMN { cbData = 1, }; setcolumn.CheckDataSize(); }
public void VerifyCheckThrowsExceptionWhenCbDataIsTooLong() { var setcolumn = new JET_RETRIEVECOLUMN { cbData = 100, pvData = new byte[9], }; setcolumn.CheckDataSize(); }
public void VerifyCheckThrowsExceptionWhenCbDataIsNegative() { var setcolumn = new JET_RETRIEVECOLUMN { cbData = -1, pvData = new byte[1], }; setcolumn.CheckDataSize(); }
public void VerifyCheckThrowsExceptionWhenIbCbDataIsTooLong() { var setcolumn = new JET_RETRIEVECOLUMN { ibData = 8, cbData = 3, pvData = new byte[10], }; setcolumn.CheckDataSize(); }
public void Setup() { this.managed = new JET_RETRIEVECOLUMN { cbData = 1, columnid = new JET_COLUMNID { Value = 2 }, grbit = RetrieveColumnGrbit.RetrieveCopy, ibLongValue = 3, itagSequence = 4, }; this.native = this.managed.GetNativeRetrievecolumn(); }
public void HowDoIDealWithMultivalues() { JET_SESID sesid = this.testSession; JET_DBID dbid = this.testDbid; JET_TABLEID tableid; JET_COLUMNDEF columndef = new JET_COLUMNDEF(); JET_COLUMNID tagColumn; Api.JetCreateTable(sesid, dbid, "table", 0, 100, out tableid); // Create the column. Any column can be multivalued. Using // ColumndefGrbit controls how the column is indexed. columndef.coltyp = JET_coltyp.LongText; columndef.cp = JET_CP.Unicode; columndef.grbit = ColumndefGrbit.ColumnMultiValued; Api.JetAddColumn(sesid, tableid, "tags", columndef, null, 0, out tagColumn); // Create the index. There will be one entry in the index for each // instance of the multivalued column. const string IndexKey = "+tags\0\0"; Api.JetCreateIndex(sesid, tableid, "tagsindex", CreateIndexGrbit.None, IndexKey, IndexKey.Length, 100); Api.JetBeginTransaction(sesid); // Now insert a record. An ESENT column can have multiple instances (multivalues) // inside the same record. Each multivalue is identified by an itag, the first itag // in a sequence is 1. Api.JetPrepareUpdate(sesid, tableid, JET_prep.Insert); // With no JET_SETINFO specified, itag 1 will be set. byte[] data = Encoding.Unicode.GetBytes("foo"); Api.JetSetColumn(sesid, tableid, tagColumn, data, data.Length, SetColumnGrbit.None, null); // Set a column with a setinfo. The itagSequence in the setinfo will be 0, which // means the value will be added to the collection of values, i.e. the column will // have two instances, "foo" and "bar". JET_SETINFO setinfo = new JET_SETINFO(); data = Encoding.Unicode.GetBytes("bar"); Api.JetSetColumn(sesid, tableid, tagColumn, data, data.Length, SetColumnGrbit.None, setinfo); // Add a third instance, explicitly setting the itagSequence data = Encoding.Unicode.GetBytes("baz"); setinfo.itagSequence = 4; Api.JetSetColumn(sesid, tableid, tagColumn, data, data.Length, SetColumnGrbit.None, setinfo); // Add a duplicate value, checking for uniqueness data = Encoding.Unicode.GetBytes("foo"); setinfo.itagSequence = 0; try { Api.JetSetColumn(sesid, tableid, tagColumn, data, data.Length, SetColumnGrbit.UniqueMultiValues, setinfo); Assert.Fail("Expected an EsentErrorException"); } catch (EsentErrorException ex) { Assert.AreEqual(JET_err.MultiValuedDuplicate, ex.Error); } Api.JetUpdate(sesid, tableid); // Find the record. We can seek for any column instance. Api.JetSetCurrentIndex(sesid, tableid, "tagsindex"); Api.MakeKey(sesid, tableid, "bar", Encoding.Unicode, MakeKeyGrbit.NewKey); Assert.IsTrue(Api.TrySeek(sesid, tableid, SeekGrbit.SeekEQ)); // Retrieve the number of column instances. This can be done with JetRetrieveColumns by setting // itagSequence to 0. JET_RETRIEVECOLUMN retrievecolumn = new JET_RETRIEVECOLUMN(); retrievecolumn.columnid = tagColumn; retrievecolumn.itagSequence = 0; Api.JetRetrieveColumns(sesid, tableid, new[] { retrievecolumn }, 1); Console.WriteLine("{0}", retrievecolumn.itagSequence); Assert.AreEqual(3, retrievecolumn.itagSequence); // Retrieve all the columns for (int itag = 1; itag <= retrievecolumn.itagSequence; ++itag) { JET_RETINFO retinfo = new JET_RETINFO { itagSequence = itag }; string s = Encoding.Unicode.GetString(Api.RetrieveColumn(sesid, tableid, tagColumn, RetrieveColumnGrbit.None, retinfo)); Console.WriteLine("{0}: {1}", itag, s); } // Update the record Api.JetPrepareUpdate(sesid, tableid, JET_prep.Replace); // With no JET_SETINFO specified, itag 1 will be set, overwriting the existing value. data = Encoding.Unicode.GetBytes("qux"); Api.JetSetColumn(sesid, tableid, tagColumn, data, data.Length, SetColumnGrbit.None, null); // Set an instance to null to delete it. setinfo.itagSequence = 2; Api.JetSetColumn(sesid, tableid, tagColumn, null, 0, SetColumnGrbit.None, setinfo); // Removing itag 2 moved the other itags down (i.e. itag 3 became itag 2). // Overwrite itag 2. data = Encoding.Unicode.GetBytes("xyzzy"); setinfo.itagSequence = 2; Api.JetSetColumn(sesid, tableid, tagColumn, data, data.Length, SetColumnGrbit.None, setinfo); // Now add a new instance by setting itag 0. This instance will go at the end. data = Encoding.Unicode.GetBytes("flob"); setinfo.itagSequence = 0; Api.JetSetColumn(sesid, tableid, tagColumn, data, data.Length, SetColumnGrbit.None, setinfo); Api.JetUpdate(sesid, tableid); // Retrieve the number of column instances again. retrievecolumn.itagSequence = 0; Api.JetRetrieveColumns(sesid, tableid, new[] { retrievecolumn }, 1); // Retrieve all the columns for (int itag = 1; itag <= retrievecolumn.itagSequence; ++itag) { JET_RETINFO retinfo = new JET_RETINFO { itagSequence = itag }; string s = Encoding.Unicode.GetString(Api.RetrieveColumn(sesid, tableid, tagColumn, RetrieveColumnGrbit.None, retinfo)); Console.WriteLine("{0}: {1}", itag, s); } Api.JetCommitTransaction(sesid, CommitTransactionGrbit.LazyFlush); }
public void VerifyUpdateFromNativeRetrievecolumnSetsColumnidNextTagged() { var setcolumn = new JET_RETRIEVECOLUMN(); var native = new NATIVE_RETRIEVECOLUMN { columnidNextTagged = 0x20 }; setcolumn.UpdateFromNativeRetrievecolumn(native); var expected = new JET_COLUMNID { Value = 0x20 }; Assert.AreEqual(expected, setcolumn.columnidNextTagged); }
public void VerifyUpdateFromNativeRetrievecolumnSetsErr() { var setcolumn = new JET_RETRIEVECOLUMN(); var native = new NATIVE_RETRIEVECOLUMN { err = 1004 }; setcolumn.UpdateFromNativeRetrievecolumn(native); Assert.AreEqual(JET_wrn.ColumnNull, setcolumn.err); }
/// <summary> /// Retrieves multiple column values from the current record in a /// single operation. An array of JET_RETRIEVECOLUMN structures is /// used to describe the set of column values to be retrieved, and /// to describe output buffers for each column value to be retrieved. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to retrieve the data from.</param> /// <param name="retrievecolumns"> /// An array of one or more <see cref="JET_RETRIEVECOLUMN"/> objects /// describing the data to be retrieved. /// </param> /// <param name="numColumns"> /// The number of entries in the columns array. /// </param> /// <returns> /// If any column retrieved is truncated due to an insufficient /// length buffer, then the API will return /// <see cref="JET_wrn.BufferTruncated"/>. However other errors /// JET_wrnColumnNull are returned only in the error field of /// the <see cref="JET_RETRIEVECOLUMN"/> object. /// </returns> public static JET_wrn JetRetrieveColumns(JET_SESID sesid, JET_TABLEID tableid, JET_RETRIEVECOLUMN[] retrievecolumns, int numColumns) { if (null == retrievecolumns) { throw new ArgumentNullException("retrievecolumns"); } if (numColumns < 0 || numColumns > retrievecolumns.Length) { throw new ArgumentOutOfRangeException("numColumns", numColumns, "cannot be negative or greater than retrievecolumns.Length"); } unsafe { NATIVE_RETRIEVECOLUMN* nativeretrievecolumns = stackalloc NATIVE_RETRIEVECOLUMN[numColumns]; int err = Api.PinColumnsAndRetrieve(sesid, tableid, nativeretrievecolumns, retrievecolumns, numColumns, 0); for (int i = 0; i < numColumns; ++i) { retrievecolumns[i].UpdateFromNativeRetrievecolumn(ref nativeretrievecolumns[i]); } return Api.Check(err); } }
/// <summary> /// Retrieves multiple column values from the current record in a /// single operation. An array of JET_RETRIEVECOLUMN structures is /// used to describe the set of column values to be retrieved, and /// to describe output buffers for each column value to be retrieved. /// </summary> /// <param name="sesid">The session to use.</param> /// <param name="tableid">The cursor to retrieve the data from.</param> /// <param name="columns"> /// An array of one or more <see cref="JET_RETRIEVECOLUMN"/> objects /// describing the data to be retrieved. /// </param> /// <param name="numColumns"> /// The number of entries in the columns array. /// </param> /// <returns> /// If any column retrieved is truncated due to an insufficient /// length buffer, then the API will return /// <see cref="JET_wrn.BufferTruncated"/>. However other errors /// JET_wrnColumnNull are returned only in the error field of /// the <see cref="JET_RETRIEVECOLUMN"/> object. /// </returns> public static JET_wrn JetRetrieveColumns(JET_SESID sesid, JET_TABLEID tableid, JET_RETRIEVECOLUMN[] columns, int numColumns) { throw new NotImplementedException("JetRetrieveColumns"); }
public void JetRetrievecolumnToString() { var value = new JET_RETRIEVECOLUMN { columnid = new JET_COLUMNID { Value = 27 } }; Assert.AreEqual("JET_RETRIEVECOLUMN(0x1b)", value.ToString()); }
public void VerifyUpdateFromNativeRetrievecolumnSetsItagSequence() { var setcolumn = new JET_RETRIEVECOLUMN(); var native = new NATIVE_RETRIEVECOLUMN { itagSequence = 7 }; setcolumn.UpdateFromNativeRetrievecolumn(ref native); Assert.AreEqual(7, setcolumn.itagSequence); }