Base class for objects that represent a column value to be set.
Beispiel #1
0
 public static void Free(ColumnValue value)
 {
     var intValue = value as Int32ColumnValue;
     if (intValue != null)
     {
         SharedPools.Default<Int32ColumnValue>().Free(intValue);
     }
 }
Beispiel #2
0
            public static void Free(ColumnValue[] values)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    Free(values[i]);
                }

                s_columnValuePool[values.Length - 3].Free(values);
            }
Beispiel #3
0
        /// <summary>
        /// Recursive SetColumns method for data pinning. This populates the buffer and
        /// calls the inherited SetColumns method.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">
        /// The table to set the columns in. An update should be prepared.
        /// </param>
        /// <param name="columnValues">
        /// Column values to set.
        /// </param>
        /// <param name="nativeColumns">
        /// Structures to put the pinned data in.
        /// </param>
        /// <param name="i">Offset of this object in the array.</param>
        /// <returns>An error code.</returns>
        internal unsafe override int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
        {
            if (null != this.Value)
            {
                fixed (void* buffer = this.Value)
                {
                    return this.SetColumns(
                        sesid, tableid, columnValues, nativeColumns, i, buffer, this.Value.Length, true);
                }
            }

            return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, null, 0, false);
        }
 /// <summary>
 /// Recursive SetColumns method for data pinning. This should populate the buffer and
 /// call the inherited SetColumns method.
 /// </summary>
 /// <param name="sesid">The session to use.</param>
 /// <param name="tableid">
 /// The table to set the columns in. An update should be prepared.
 /// </param>
 /// <param name="columnValues">
 /// Column values to set.
 /// </param>
 /// <param name="nativeColumns">
 /// Structures to put the pinned data in.
 /// </param>
 /// <param name="i">Offset of this object in the array.</param>
 /// <returns>An error code.</returns>
 internal abstract unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i);
 protected void Free(ColumnValue[] values)
 {
     Pool.Free(values);
 }
Beispiel #6
0
        /// <summary>
        /// Retrieve the value for columns whose buffers were truncated.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">The table to use.</param>
        /// <param name="columnValues">The column values.</param>
        /// <param name="nativeRetrievecolumns">
        /// The native retrieve columns that match the column values.
        /// </param>
        private static unsafe void RetrieveTruncatedBuffers(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_RETRIEVECOLUMN* nativeRetrievecolumns)
        {
            for (int i = 0; i < columnValues.Length; ++i)
            {
                if (nativeRetrievecolumns[i].err == (int) JET_wrn.BufferTruncated)
                {
                    var buffer = new byte[nativeRetrievecolumns[i].cbActual];
                    int actualSize;
                    int err;
                    var retinfo = new JET_RETINFO { itagSequence = columnValues[i].ItagSequence };

                    // Pin the buffer and retrieve the data
                    fixed (byte* pinnedBuffer = buffer)
                    {
                        err = Api.Impl.JetRetrieveColumn(
                                      sesid,
                                      tableid,
                                      columnValues[i].Columnid,
                                      new IntPtr(pinnedBuffer),
                                      buffer.Length,
                                      out actualSize,
                                      columnValues[i].RetrieveGrbit,
                                      retinfo);
                    }

                    // Set the error in the ColumnValue before checkin it
                    columnValues[i].Error = (JET_err) err;
                    Api.Check(err);

                    // For BytesColumnValue this will copy the data to a new array.
                    // If this situation becomes common we should simply use the array.
                    columnValues[i].GetValueFromBytes(buffer, 0, actualSize, err);
                }
            }
        }
        public void SetColumnsWithZeroLength()
        {
            var columnValues = new ColumnValue[]
            {
                new StringColumnValue { Columnid = this.columnDict["Unicode"], Value = String.Empty },
                new BytesColumnValue { Columnid = this.columnDict["Binary"], Value = new byte[0] },
            };

            using (var trx = new Transaction(this.session))
            using (var update = new Update(this.session, this.tableid, JET_prep.Insert))
            {
                Api.SetColumns(this.session, this.tableid, columnValues);
                update.Save();
                trx.Commit(CommitTransactionGrbit.None);
            }

            Api.TryMoveFirst(this.session, this.tableid);

            Assert.AreEqual(String.Empty, Api.RetrieveColumnAsString(this.session, this.tableid, this.columnDict["Unicode"]));
            CollectionAssert.AreEqual(new byte[0], Api.RetrieveColumn(this.session, this.tableid, this.columnDict["Binary"]));
        }
        public void RetrieveColumns()
        {
            bool bit = Any.Boolean;
            byte b = Any.Byte;
            short i16 = Any.Int16;
            ushort ui16 = Any.UInt16;
            int i32 = Any.Int32;
            uint ui32 = Any.UInt32;
            long i64 = Any.Int64;
            ulong ui64 = Any.UInt64;
            float f = Any.Float;
            double d = Any.Double;
            DateTime date = Any.DateTime;
            Guid guid = Any.Guid;
            string str = Any.String;
            byte[] bytes = Any.BytesOfLength(1023);

            using (var trx = new Transaction(this.session))
            using (var update = new Update(this.session, this.tableid, JET_prep.Insert))
            {
                Api.SetColumn(this.session, this.tableid, this.columnDict["Boolean"], bit);
                Api.SetColumn(this.session, this.tableid, this.columnDict["Byte"], b);
                Api.SetColumn(this.session, this.tableid, this.columnDict["Int16"], i16);
                Api.SetColumn(this.session, this.tableid, this.columnDict["UInt16"], ui16);
                Api.SetColumn(this.session, this.tableid, this.columnDict["Int32"], i32);
                Api.SetColumn(this.session, this.tableid, this.columnDict["UInt32"], ui32);
                Api.SetColumn(this.session, this.tableid, this.columnDict["Int64"], i64);
                Api.SetColumn(this.session, this.tableid, this.columnDict["UInt64"], ui64);
                Api.SetColumn(this.session, this.tableid, this.columnDict["Float"], f);
                Api.SetColumn(this.session, this.tableid, this.columnDict["Double"], d);
                Api.SetColumn(this.session, this.tableid, this.columnDict["DateTime"], date);
                Api.SetColumn(this.session, this.tableid, this.columnDict["Guid"], guid);
                Api.SetColumn(this.session, this.tableid, this.columnDict["Unicode"], str, Encoding.Unicode);
                Api.SetColumn(this.session, this.tableid, this.columnDict["Binary"], bytes);

                update.SaveAndGotoBookmark();
                trx.Commit(CommitTransactionGrbit.None);
            }

            var columnValues = new ColumnValue[]
            {
                new BoolColumnValue { Columnid = this.columnDict["Boolean"] },
                new ByteColumnValue { Columnid = this.columnDict["Byte"] },
                new Int16ColumnValue { Columnid = this.columnDict["Int16"] },
                new UInt16ColumnValue { Columnid = this.columnDict["UInt16"] },
                new Int32ColumnValue { Columnid = this.columnDict["Int32"] },
                new UInt32ColumnValue { Columnid = this.columnDict["UInt32"] },
                new Int64ColumnValue { Columnid = this.columnDict["Int64"] },
                new UInt64ColumnValue { Columnid = this.columnDict["UInt64"] },
                new FloatColumnValue { Columnid = this.columnDict["Float"] },
                new DoubleColumnValue { Columnid = this.columnDict["Double"] },
                new DateTimeColumnValue { Columnid = this.columnDict["DateTime"] },
                new GuidColumnValue { Columnid = this.columnDict["Guid"] },
                new StringColumnValue { Columnid = this.columnDict["Unicode"] },
                new BytesColumnValue { Columnid = this.columnDict["Binary"] },
            };

            Api.RetrieveColumns(this.session, this.tableid, columnValues);

            Assert.AreEqual(bit, columnValues[0].ValueAsObject);
            Assert.AreEqual(b, columnValues[1].ValueAsObject);
            Assert.AreEqual(i16, columnValues[2].ValueAsObject);
            Assert.AreEqual(ui16, columnValues[3].ValueAsObject);
            Assert.AreEqual(i32, columnValues[4].ValueAsObject);
            Assert.AreEqual(ui32, columnValues[5].ValueAsObject);
            Assert.AreEqual(i64, columnValues[6].ValueAsObject);
            Assert.AreEqual(ui64, columnValues[7].ValueAsObject);
            Assert.AreEqual(f, columnValues[8].ValueAsObject);
            Assert.AreEqual(d, columnValues[9].ValueAsObject);
            Assert.AreEqual(date, columnValues[10].ValueAsObject);
            Assert.AreEqual(guid, columnValues[11].ValueAsObject);
            Assert.AreEqual(str, columnValues[12].ValueAsObject);
            CollectionAssert.AreEqual(bytes, columnValues[13].ValueAsObject as byte[]);
        }
        public void SetColumns()
        {
            bool bit = true;
            byte b = Any.Byte;
            short i16 = Any.Int16;
            ushort ui16 = Any.UInt16;
            int i32 = Any.Int32;
            uint ui32 = Any.UInt32;
            long i64 = Any.Int64;
            ulong ui64 = Any.UInt64;
            float f = Any.Float;
            double d = Any.Double;
            DateTime date = Any.DateTime;
            Guid guid = Any.Guid;
            string s = Any.String;
            byte[] bytes = Any.BytesOfLength(1023);

            var columnValues = new ColumnValue[]
            {
                new BoolColumnValue { Columnid = this.columnDict["Boolean"], Value = bit },
                new ByteColumnValue { Columnid = this.columnDict["Byte"], Value = b },
                new Int16ColumnValue { Columnid = this.columnDict["Int16"], Value = i16 },
                new UInt16ColumnValue { Columnid = this.columnDict["UInt16"], Value = ui16 },
                new Int32ColumnValue { Columnid = this.columnDict["Int32"], Value = i32 },
                new UInt32ColumnValue { Columnid = this.columnDict["UInt32"], Value = ui32 },
                new Int64ColumnValue { Columnid = this.columnDict["Int64"], Value = i64 },
                new UInt64ColumnValue { Columnid = this.columnDict["UInt64"], Value = ui64 },
                new FloatColumnValue { Columnid = this.columnDict["Float"], Value = f },
                new DoubleColumnValue { Columnid = this.columnDict["Double"], Value = d },
                new DateTimeColumnValue { Columnid = this.columnDict["DateTime"], Value = date },
                new GuidColumnValue() { Columnid = this.columnDict["Guid"], Value = guid },
                new StringColumnValue { Columnid = this.columnDict["Unicode"], Value = s },
                new BytesColumnValue { Columnid = this.columnDict["Binary"], Value = bytes },
            };

            using (var trx = new Transaction(this.session))
            using (var update = new Update(this.session, this.tableid, JET_prep.Insert))
            {
                Api.SetColumns(this.session, this.tableid, columnValues);
                update.Save();
                trx.Commit(CommitTransactionGrbit.None);
            }

            Api.TryMoveFirst(this.session, this.tableid);

            Assert.AreEqual(bit, Api.RetrieveColumnAsBoolean(this.session, this.tableid, this.columnDict["Boolean"]));
            Assert.AreEqual(b, Api.RetrieveColumnAsByte(this.session, this.tableid, this.columnDict["Byte"]));
            Assert.AreEqual(i16, Api.RetrieveColumnAsInt16(this.session, this.tableid, this.columnDict["Int16"]));
            Assert.AreEqual(ui16, Api.RetrieveColumnAsUInt16(this.session, this.tableid, this.columnDict["UInt16"]));
            Assert.AreEqual(i32, Api.RetrieveColumnAsInt32(this.session, this.tableid, this.columnDict["Int32"]));
            Assert.AreEqual(ui32, Api.RetrieveColumnAsUInt32(this.session, this.tableid, this.columnDict["UInt32"]));
            Assert.AreEqual(i64, Api.RetrieveColumnAsInt64(this.session, this.tableid, this.columnDict["Int64"]));
            Assert.AreEqual(ui64, Api.RetrieveColumnAsUInt64(this.session, this.tableid, this.columnDict["UInt64"]));
            Assert.AreEqual(f, Api.RetrieveColumnAsFloat(this.session, this.tableid, this.columnDict["Float"]));
            Assert.AreEqual(d, Api.RetrieveColumnAsDouble(this.session, this.tableid, this.columnDict["Double"]));
            Assert.AreEqual(date, Api.RetrieveColumnAsDateTime(this.session, this.tableid, this.columnDict["DateTime"]));
            Assert.AreEqual(guid, Api.RetrieveColumnAsGuid(this.session, this.tableid, this.columnDict["Guid"]));
            Assert.AreEqual(s, Api.RetrieveColumnAsString(this.session, this.tableid, this.columnDict["Unicode"]));
            CollectionAssert.AreEqual(bytes, Api.RetrieveColumn(this.session, this.tableid, this.columnDict["Binary"]));
        }
        public void RetrieveColumnsWithZeroLength()
        {
            using (var trx = new Transaction(this.session))
            using (var update = new Update(this.session, this.tableid, JET_prep.Insert))
            {
                Api.SetColumn(this.session, this.tableid, this.columnDict["Unicode"], String.Empty, Encoding.Unicode);
                Api.SetColumn(this.session, this.tableid, this.columnDict["Binary"], new byte[0]);
                update.SaveAndGotoBookmark();
                trx.Commit(CommitTransactionGrbit.None);
            }

            var columnValues = new ColumnValue[]
            {
                new StringColumnValue { Columnid = this.columnDict["Unicode"] },
                new BytesColumnValue { Columnid = this.columnDict["Binary"] },
            };

            Api.RetrieveColumns(this.session, this.tableid, columnValues);

            Assert.AreEqual(String.Empty, columnValues[0].ValueAsObject);
            CollectionAssert.AreEqual(new byte[0], columnValues[1].ValueAsObject as byte[]);
        }
        public void RetrieveColumnsWithNull()
        {
            using (var trx = new Transaction(this.session))
            using (var update = new Update(this.session, this.tableid, JET_prep.Insert))
            {
                update.SaveAndGotoBookmark();
                trx.Commit(CommitTransactionGrbit.None);
            }

            var columnValues = new ColumnValue[]
            {
                new BoolColumnValue { Columnid = this.columnDict["Boolean"] },
                new ByteColumnValue { Columnid = this.columnDict["Byte"] },
                new Int16ColumnValue { Columnid = this.columnDict["Int16"] },
                new UInt16ColumnValue { Columnid = this.columnDict["UInt16"] },
                new Int32ColumnValue { Columnid = this.columnDict["Int32"] },
                new UInt32ColumnValue { Columnid = this.columnDict["UInt32"] },
                new Int64ColumnValue { Columnid = this.columnDict["Int64"] },
                new UInt64ColumnValue { Columnid = this.columnDict["UInt64"] },
                new FloatColumnValue { Columnid = this.columnDict["Float"] },
                new DoubleColumnValue { Columnid = this.columnDict["Double"] },
                new DateTimeColumnValue { Columnid = this.columnDict["DateTime"] },
                new GuidColumnValue { Columnid = this.columnDict["Guid"] },
                new StringColumnValue { Columnid = this.columnDict["Unicode"] },
                new BytesColumnValue { Columnid = this.columnDict["Binary"] },
            };

            Api.RetrieveColumns(this.session, this.tableid, columnValues);

            foreach (var c in columnValues)
            {
                Assert.IsNull(c.ValueAsObject);
            }
        }
        public void RetrieveColumnsWithMultivalues()
        {
            using (var trx = new Transaction(this.session))
            using (var update = new Update(this.session, this.tableid, JET_prep.Insert))
            {
                Api.JetSetColumn(
                    this.session,
                    this.tableid,
                    this.columnDict["uint64"],
                    BitConverter.GetBytes(5UL),
                    sizeof(ulong),
                    SetColumnGrbit.None,
                    new JET_SETINFO { itagSequence = 1 });
                Api.JetSetColumn(
                    this.session,
                    this.tableid,
                    this.columnDict["uint64"],
                    BitConverter.GetBytes(99UL),
                    sizeof(ulong),
                    SetColumnGrbit.None,
                    new JET_SETINFO { itagSequence = 2 });
                update.SaveAndGotoBookmark();
                trx.Commit(CommitTransactionGrbit.None);
            }

            var columnValues = new ColumnValue[]
            {
                new UInt64ColumnValue { Columnid = this.columnDict["UInt64"], ItagSequence = 1 },
                new UInt64ColumnValue { Columnid = this.columnDict["UInt64"], ItagSequence = 2 },
            };

            Api.RetrieveColumns(this.session, this.tableid, columnValues);

            Assert.AreEqual(5UL, columnValues[0].ValueAsObject);
            Assert.AreEqual(99UL, columnValues[1].ValueAsObject);
        }
        public void RetrieveColumnsWithLargeValues()
        {
            string str = Any.StringOfLength(129 * 1024);
            byte[] bytes = Any.BytesOfLength(127 * 1024);

            using (var trx = new Transaction(this.session))
            using (var update = new Update(this.session, this.tableid, JET_prep.Insert))
            {
                Api.SetColumn(this.session, this.tableid, this.columnDict["Unicode"], str, Encoding.Unicode);
                Api.SetColumn(this.session, this.tableid, this.columnDict["Binary"], bytes);

                update.SaveAndGotoBookmark();
                trx.Commit(CommitTransactionGrbit.None);
            }

            var columnValues = new ColumnValue[]
            {
                new StringColumnValue { Columnid = this.columnDict["Unicode"] },
                new BytesColumnValue { Columnid = this.columnDict["Binary"] },
            };

            Api.RetrieveColumns(this.session, this.tableid, columnValues);

            Assert.AreEqual(str, columnValues[0].ValueAsObject);
            CollectionAssert.AreEqual(bytes, columnValues[1].ValueAsObject as byte[]);
        }
        public void RetrieveColumnsWithInvalidColumn()
        {
            using (var trx = new Transaction(this.session))
            using (var update = new Update(this.session, this.tableid, JET_prep.Insert))
            {
                Api.SetColumn(this.session, this.tableid, this.columnDict["Int64"], Any.Int64);
                update.SaveAndGotoBookmark();
                trx.Commit(CommitTransactionGrbit.None);
            }

            var columnValues = new ColumnValue[]
            {
                new GuidColumnValue { Columnid = this.columnDict["Int64"] },
            };

            Api.RetrieveColumns(this.session, this.tableid, columnValues);
        }
Beispiel #15
0
        /// <summary>
        /// Recursive SetColumns function used to pin data.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">
        /// The table to set the columns in. An update should be prepared.
        /// </param>
        /// <param name="columnValues">
        /// Column values to set.
        /// </param>
        /// <param name="nativeColumns">
        /// Structures to put the pinned data in.
        /// </param>
        /// <param name="i">Offset of this object in the array.</param>
        /// <param name="buffer">The buffer for this object.</param>
        /// <param name="bufferSize">Size of the buffer for ths object.</param>
        /// <param name="hasValue">True if this object is non null.</param>
        /// <returns>An error code.</returns>
        /// <remarks>
        /// This is marked as internal because it uses the NATIVE_SETCOLUMN type
        /// which is also marked as internal. It should be treated as a protected
        /// method though.
        /// </remarks>
        internal unsafe int SetColumns(
            JET_SESID sesid,
            JET_TABLEID tableid,
            ColumnValue[] columnValues,
            NATIVE_SETCOLUMN* nativeColumns,
            int i,
            void* buffer,
            int bufferSize,
            bool hasValue)
        {
            Debug.Assert(this == columnValues[i], "SetColumns should be called on the current object");
            this.MakeNativeSetColumn(ref nativeColumns[i]);

            if (hasValue)
            {
                nativeColumns[i].cbData = checked((uint)bufferSize);
                nativeColumns[i].pvData = new IntPtr(buffer);
                if (0 == bufferSize)
                {
                    nativeColumns[i].grbit |= (uint)SetColumnGrbit.ZeroLength;
                }
            }

            int err = i == columnValues.Length - 1
                          ? Api.Impl.JetSetColumns(sesid, tableid, nativeColumns, columnValues.Length)
                          : columnValues[i + 1].SetColumns(sesid, tableid, columnValues, nativeColumns, i + 1);

            this.Error = (JET_wrn)nativeColumns[i].err;
            return err;
        }
Beispiel #16
0
        /// <summary>
        /// Recursive RetrieveColumns method for data pinning. This should pin a buffer and
        /// call the inherited RetrieveColumns method.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">
        /// The table to retrieve the columns from.
        /// </param>
        /// <param name="columnValues">
        /// Column values to retrieve.
        /// </param>
        internal static void RetrieveColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues)
        {
            const int MaxColumnValues = 1024;
            if (columnValues.Length > MaxColumnValues)
            {
                throw new ArgumentOutOfRangeException("columnValues", columnValues.Length, "Too many column values");    
            }

            unsafe
            {
                byte[] buffer = null;
                NATIVE_RETRIEVECOLUMN* nativeRetrievecolumns = stackalloc NATIVE_RETRIEVECOLUMN[columnValues.Length];

                try
                {
                    buffer = Caches.ColumnCache.Allocate();
                    Debug.Assert(MaxColumnValues * 16 < buffer.Length, "Maximum size of fixed columns could exceed buffer size");

                    fixed (byte* pinnedBuffer = buffer)
                    {
                        byte* currentBuffer = pinnedBuffer;
                        int numVariableLengthColumns = columnValues.Length;

                        // First the fixed-size columns
                        for (int i = 0; i < columnValues.Length; ++i)
                        {
                            if (0 != columnValues[i].Size)
                            {
                                columnValues[i].MakeNativeRetrieveColumn(ref nativeRetrievecolumns[i]);
                                nativeRetrievecolumns[i].pvData = new IntPtr(currentBuffer);
                                nativeRetrievecolumns[i].cbData = checked((uint)columnValues[i].Size);

                                currentBuffer += nativeRetrievecolumns[i].cbData;
                                Debug.Assert(currentBuffer <= pinnedBuffer + buffer.Length, "Moved past end of pinned buffer");

                                numVariableLengthColumns--;
                            }
                        }

                        // Now the variable-length columns
                        if (numVariableLengthColumns > 0)
                        {
                            int bufferUsed = checked((int)(currentBuffer - pinnedBuffer));
                            int bufferRemaining = checked(buffer.Length - bufferUsed);
                            int bufferPerColumn = bufferRemaining / numVariableLengthColumns;
                            Debug.Assert(bufferPerColumn > 0, "Not enough buffer left to retrieve variable length columns");

                            // Now the variable-size columns
                            for (int i = 0; i < columnValues.Length; ++i)
                            {
                                if (0 == columnValues[i].Size)
                                {
                                    columnValues[i].MakeNativeRetrieveColumn(ref nativeRetrievecolumns[i]);
                                    nativeRetrievecolumns[i].pvData = new IntPtr(currentBuffer);
                                    nativeRetrievecolumns[i].cbData = checked((uint)bufferPerColumn);
                                    currentBuffer += nativeRetrievecolumns[i].cbData;
                                    Debug.Assert(currentBuffer <= pinnedBuffer + buffer.Length, "Moved past end of pinned buffer");
                                }
                            }
                        }

                        // Retrieve the columns
                        Api.Check(Api.Impl.JetRetrieveColumns(sesid, tableid, nativeRetrievecolumns, columnValues.Length));

                        // Propagate the warnings.
                        for (int i = 0; i < columnValues.Length; ++i)
                        {
                            columnValues[i].Error = (JET_wrn)nativeRetrievecolumns[i].err;
                        }

                        // Now parse out the columns that were retrieved successfully
                        for (int i = 0; i < columnValues.Length; ++i)
                        {
                            if (nativeRetrievecolumns[i].err != (int)JET_wrn.BufferTruncated)
                            {
                                byte* columnBuffer = (byte*)nativeRetrievecolumns[i].pvData;
                                int startIndex = checked((int)(columnBuffer - pinnedBuffer));
                                columnValues[i].GetValueFromBytes(
                                    buffer,
                                    startIndex,
                                    checked((int)nativeRetrievecolumns[i].cbActual),
                                    nativeRetrievecolumns[i].err);
                            }
                        }
                    }

                    // Finally retrieve the buffers where the columns weren't large enough.
                    RetrieveTruncatedBuffers(sesid, tableid, columnValues, nativeRetrievecolumns);
                }
                finally
                {
                    if (buffer != null)
                    {
                        Caches.ColumnCache.Free(ref buffer);
                    }
                }
            }
        }
        public void SetColumnsWithMultivalues()
        {
            short expected = Any.Int16;

            var columnValues = new ColumnValue[]
            {
                new Int16ColumnValue() { Columnid = this.columnDict["Int16"], Value = 0 },
                new Int16ColumnValue() { Columnid = this.columnDict["Int16"], Value = expected, ItagSequence = 2 },
            };

            using (var trx = new Transaction(this.session))
            using (var update = new Update(this.session, this.tableid, JET_prep.Insert))
            {
                Api.SetColumns(this.session, this.tableid, columnValues);
                update.Save();
                trx.Commit(CommitTransactionGrbit.None);
            }

            Api.TryMoveFirst(this.session, this.tableid);

            short actual = BitConverter.ToInt16(
                Api.RetrieveColumn(
                    this.session,
                    this.tableid,
                    this.columnDict["int16"],
                    RetrieveColumnGrbit.None,
                    new JET_RETINFO { itagSequence = 2 }),
                0);
            Assert.AreEqual(expected, actual);
        }
        public void SetColumnsWithNull()
        {
            var columnValues = new ColumnValue[]
            {
                new BoolColumnValue { Columnid = this.columnDict["Boolean"], Value = null },
                new ByteColumnValue { Columnid = this.columnDict["Byte"], Value = null },
                new Int16ColumnValue { Columnid = this.columnDict["Int16"], Value = null },
                new Int32ColumnValue { Columnid = this.columnDict["Int32"], Value = null },
                new Int64ColumnValue { Columnid = this.columnDict["Int64"], Value = null },
                new FloatColumnValue { Columnid = this.columnDict["Float"], Value = null },
                new DoubleColumnValue { Columnid = this.columnDict["Double"], Value = null },
                new DateTimeColumnValue { Columnid = this.columnDict["DateTime"], Value = null },
                new StringColumnValue { Columnid = this.columnDict["Unicode"], Value = null },
                new BytesColumnValue { Columnid = this.columnDict["Binary"], Value = null },
            };

            using (var trx = new Transaction(this.session))
            using (var update = new Update(this.session, this.tableid, JET_prep.Insert))
            {
                Api.SetColumns(this.session, this.tableid, columnValues);
                update.Save();
                trx.Commit(CommitTransactionGrbit.None);
            }

            Api.TryMoveFirst(this.session, this.tableid);

            Assert.IsNull(Api.RetrieveColumnAsBoolean(this.session, this.tableid, this.columnDict["Boolean"]));
            Assert.IsNull(Api.RetrieveColumnAsByte(this.session, this.tableid, this.columnDict["Byte"]));
            Assert.IsNull(Api.RetrieveColumnAsInt16(this.session, this.tableid, this.columnDict["Int16"]));
            Assert.IsNull(Api.RetrieveColumnAsInt32(this.session, this.tableid, this.columnDict["Int32"]));
            Assert.IsNull(Api.RetrieveColumnAsInt64(this.session, this.tableid, this.columnDict["Int64"]));
            Assert.IsNull(Api.RetrieveColumnAsFloat(this.session, this.tableid, this.columnDict["Float"]));
            Assert.IsNull(Api.RetrieveColumnAsDouble(this.session, this.tableid, this.columnDict["Double"]));
            Assert.IsNull(Api.RetrieveColumnAsDateTime(this.session, this.tableid, this.columnDict["DateTime"]));
            Assert.IsNull(Api.RetrieveColumnAsString(this.session, this.tableid, this.columnDict["Unicode"]));
            Assert.IsNull(Api.RetrieveColumn(this.session, this.tableid, this.columnDict["Binary"]));
        }
        /// <summary>
        /// Retrieve columns using the basic RetrieveColumns API.
        /// </summary>
        private void RetrieveWithRetrieveColumns()
        {
            var boolColumn = new BoolColumnValue { Columnid = this.columnidDict["boolean"] };
            var int32Column = new Int32ColumnValue { Columnid = this.columnidDict["int32"] };
            var int64Column = new Int64ColumnValue { Columnid = this.columnidDict["int64"] };
            var guidColumn = new GuidColumnValue { Columnid = this.columnidDict["guid"] };
            var stringColumn = new StringColumnValue { Columnid = this.columnidDict["unicode"] };

            var retrievecolumns = new ColumnValue[]
            {
                boolColumn,
                int32Column,
                int64Column,
                guidColumn,
                stringColumn,
            };

            for (int i = 0; i < NumRetrieves; ++i)
            {
                Api.JetBeginTransaction(this.session);

                Api.RetrieveColumns(this.session, this.tableid, retrievecolumns);

                bool actualBool = (bool)boolColumn.Value;
                int actualInt32 = (int)int32Column.Value;
                long actualInt64 = (long)int64Column.Value;
                Guid actualGuid = (Guid)guidColumn.Value;
                string actualString = stringColumn.Value;

                Assert.AreEqual(this.expectedBool, actualBool);
                Assert.AreEqual(this.expectedInt32, actualInt32);
                Assert.AreEqual(this.expectedInt64, actualInt64);
                Assert.AreEqual(this.expectedGuid, actualGuid);
                Assert.AreEqual(this.expectedString, actualString);

                Api.JetCommitTransaction(this.session, CommitTransactionGrbit.None);
            }
        }