Beispiel #1
0
        /// <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);
                }
            }
        }
Beispiel #2
0
        public void ConvertSetinfoToNative()
        {
            var setinfo = new JET_SETINFO { ibLongValue = 1, itagSequence = 2 };

            NATIVE_SETINFO native = setinfo.GetNativeSetinfo();
            Assert.AreEqual(1U, native.ibLongValue);
            Assert.AreEqual(2U, native.itagSequence);
        }
        /// <summary>
        /// Sets the length of the stream.
        /// </summary>
        /// <param name="value">The desired length, in bytes.</param>
        public override void SetLength(long value)
        {
            if (value > MaxLongValueSize || value < 0)
            {
                throw new ArgumentOutOfRangeException("value", value, "A LongValueStream cannot be longer than 0x7FFFFFF or less than 0 bytes");
            }

            if (value < this.Length && value > 0)
            {
                // BUG: Shrinking the column multiple times and then growing it can sometimes hit an unpleasant
                // ESENT defect which causes a hang. To make sure we never have that problem we read out the data,
                // and insert into a new long-value. This is not efficient.
                var data    = new byte[value];
                var retinfo = new JET_RETINFO {
                    itagSequence = this.Itag, ibLongValue = 0
                };
                int actualDataSize;
                Api.JetRetrieveColumn(
                    this.sesid,
                    this.tableid,
                    this.columnid,
                    data,
                    data.Length,
                    out actualDataSize,
                    RetrieveGrbit,
                    retinfo);

                var setinfo = new JET_SETINFO {
                    itagSequence = this.Itag
                };
                Api.JetSetColumn(this.sesid, this.tableid, this.columnid, data, data.Length, SetColumnGrbit.None, setinfo);
            }
            else
            {
                var setinfo = new JET_SETINFO {
                    itagSequence = this.Itag
                };
                SetColumnGrbit grbit = (0 == value) ? SetColumnGrbit.ZeroLength : SetColumnGrbit.SizeLV;
                Api.JetSetColumn(this.sesid, this.tableid, this.columnid, null, checked ((int)value), grbit, setinfo);
            }

            // Setting the length moves the offset back to the end of the data
            if (this.ibLongValue > value)
            {
                this.ibLongValue = checked ((int)value);
            }
        }
        /// <summary>
        /// Writes a sequence of bytes to the current stream and advances the current
        /// position within this stream by the number of bytes written.
        /// </summary>
        /// <param name="buffer">The buffer to write from.</param>
        /// <param name="offset">The offset in the buffer to write.</param>
        /// <param name="count">The number of bytes to write.</param>
        public override void Write(byte[] buffer, int offset, int count)
        {
            CheckBufferArguments(buffer, offset, count);

            int         length = checked ((int)this.Length);
            JET_SETINFO setinfo;

            int newIbLongValue = checked (this.ibLongValue + count);

            // If our current position is beyond the end of the LV extend
            // the LV to the write point
            if (this.ibLongValue > length)
            {
                setinfo = new JET_SETINFO {
                    itagSequence = this.Itag
                };
                Api.JetSetColumn(this.sesid, this.tableid, this.columnid, null, this.ibLongValue, SetColumnGrbit.SizeLV, setinfo);
                length = this.ibLongValue;
            }

            SetColumnGrbit grbit;

            if (this.ibLongValue == length)
            {
                grbit = SetColumnGrbit.AppendLV;
            }
            else if (newIbLongValue >= length)
            {
                grbit = SetColumnGrbit.OverwriteLV | SetColumnGrbit.SizeLV;
            }
            else
            {
                grbit = SetColumnGrbit.OverwriteLV;
            }

            setinfo = new JET_SETINFO {
                itagSequence = this.Itag, ibLongValue = this.ibLongValue
            };
            Api.JetSetColumn(this.sesid, this.tableid, this.columnid, buffer, count, offset, grbit, setinfo);

            checked
            {
                this.ibLongValue += count;
            }
        }
Beispiel #5
0
        /// <summary>
        /// Writes a sequence of bytes to the current stream and advances the current
        /// position within this stream by the number of bytes written.
        /// </summary>
        /// <param name="buffer">The buffer to write from.</param>
        /// <param name="offset">The offset in the buffer to write.</param>
        /// <param name="count">The number of bytes to write.</param>
        public override void Write(byte[] buffer, int offset, int count)
        {
            CheckBufferArguments(buffer, offset, count);

            int length = checked((int)this.Length);
            JET_SETINFO setinfo;

            int newIbLongValue = checked(this.ibLongValue + count);

            // If our current position is beyond the end of the LV extend
            // the LV to the write point
            if (this.ibLongValue > length)
            {
                setinfo = new JET_SETINFO { itagSequence = this.Itag };
                Api.JetSetColumn(this.sesid, this.tableid, this.columnid, null, this.ibLongValue, SetColumnGrbit.SizeLV, setinfo);
                length = this.ibLongValue;
            }

            SetColumnGrbit grbit;
            if (this.ibLongValue == length)
            {
                grbit = SetColumnGrbit.AppendLV;
            }
            else if (newIbLongValue >= length)
            {
                grbit = SetColumnGrbit.OverwriteLV | SetColumnGrbit.SizeLV;
            }
            else
            {
                grbit = SetColumnGrbit.OverwriteLV;
            }

            setinfo = new JET_SETINFO { itagSequence = this.Itag, ibLongValue = this.ibLongValue };
            Api.JetSetColumn(this.sesid, this.tableid, this.columnid, buffer, count, offset, grbit, setinfo);

            checked
            {
                this.ibLongValue += count;                
            }
        }
 /// <summary>
 /// Updates a record setting the given column set to the specified value.
 /// </summary>
 /// <param name="columnid">The column to set.</param>
 /// <param name="data">The data to set.</param>
 /// <param name="itagSequence">The itag sequence to set.</param>
 private void SetColumn(JET_COLUMNID columnid, byte[] data, int itagSequence)
 {
     var setinfo = new JET_SETINFO
         {
         ibLongValue = 0,
         itagSequence = itagSequence,
         };
     Api.JetSetColumn(this.sesid, this.tableid, columnid, data, (null == data) ? 0 : data.Length, SetColumnGrbit.None, setinfo);
 }
Beispiel #7
0
        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);
        }
 /// <summary>
 /// Updates a record setting the given column set to the specified value.
 /// </summary>
 /// <param name="columnid">The column to set.</param>
 /// <param name="data">The data to set.</param>
 /// <param name="itagSequence">The itag sequence to set.</param>
 private void SetColumn(JET_COLUMNID columnid, byte[] data, int itagSequence)
 {
     Api.JetBeginTransaction(this.sesid);
     Api.JetPrepareUpdate(this.sesid, this.tableid, JET_prep.Replace);
     var setinfo = new JET_SETINFO
         {
         ibLongValue = 0,
         itagSequence = itagSequence,
         };
     Api.JetSetColumn(this.sesid, this.tableid, columnid, data, (null == data) ? 0 : data.Length, SetColumnGrbit.None, setinfo);
     Api.JetUpdate(this.sesid, this.tableid);
     Api.JetCommitTransaction(this.sesid, CommitTransactionGrbit.LazyFlush);
 }
Beispiel #9
0
        public void ConvertSetinfoToNativeWhenItagSequenceIsNegative()
        {
            var setinfo = new JET_SETINFO { ibLongValue = 0, itagSequence = Int32.MinValue };

            NATIVE_SETINFO native = setinfo.GetNativeSetinfo();
        }
Beispiel #10
0
 /// <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 JET_coltyp.LongText or JET_coltyp.LongBinary. 
 /// </summary>
 /// <remarks>
 /// This method takes an IntPtr and is intended for internal use only.
 /// </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="grbit">SetColumn options.</param>
 /// <param name="setinfo">Used to specify itag or long-value offset.</param>
 /// <returns>A warning value.</returns>
 internal static JET_wrn JetSetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, IntPtr data, int dataSize, SetColumnGrbit grbit, JET_SETINFO setinfo)
 {
     return Api.Check(Impl.JetSetColumn(sesid, tableid, columnid, data, dataSize, grbit, setinfo));
 }
Beispiel #11
0
 /// <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>
 /// The SetColumn methods provide datatype-specific overrides which may be more efficient.
 /// </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="grbit">SetColumn options.</param>
 /// <param name="setinfo">Used to specify itag or long-value offset.</param>
 /// <returns>A warning code.</returns>
 public static JET_wrn JetSetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data, int dataSize, SetColumnGrbit grbit, JET_SETINFO setinfo)
 {
     return Api.JetSetColumn(sesid, tableid, columnid, data, dataSize, 0, grbit, setinfo);
 }
Beispiel #12
0
        // insert a record and update its long-values
        private void UpdateLongValues()
        {
            Console.WriteLine("\tUpdate Long-Values");
            JET_TABLEID tableid;
            Api.JetOpenTable(this.sesid, this.dbid, this.table, null, 0, OpenTableGrbit.None, out tableid);

            int recordID = NumRecords + 17;
            var rand = new Random(recordID);

            var data = new byte[this.columnInfos.Length][];

            Api.JetBeginTransaction(this.sesid);

            // insert the record
            using (var update = new Update(this.sesid, tableid, JET_prep.Insert))
            {
                for (int i = 0; i < this.columnInfos.Length; ++i)
                {
                    data[i] = null;
                    if (String.Equals(
                        this.columnInfos[i].Name, "recordID", StringComparison.InvariantCultureIgnoreCase))
                    {
                        // this is the primary index column, set it to the recordID
                        data[i] = BitConverter.GetBytes(recordID);
                    }
                    else if (this.columnInfos[i].Coltyp == JET_coltyp.LongBinary
                             || this.columnInfos[i].Coltyp == JET_coltyp.LongText)
                    {
                        data[i] = DataGenerator.GetRandomColumnData(
                            this.columnInfos[i].Coltyp, this.columnInfos[i].Cp, rand);
                    }

                    if (null != data[i])
                    {
                        Api.SetColumn(this.sesid, tableid, this.columnInfos[i].Columnid, data[i]);
                    }
                }

                update.SaveAndGotoBookmark();
            }

            this.CheckColumns(this.sesid, tableid, data);

            // update the record
            using (var update = new Update(this.sesid, tableid, JET_prep.Replace))
            {
                for (int i = 0; i < this.columnInfos.Length; ++i)
                {
                    if (this.columnInfos[i].Coltyp == JET_coltyp.LongBinary
                        || this.columnInfos[i].Coltyp == JET_coltyp.LongText)
                    {
                        int size = Api.RetrieveColumnSize(this.sesid, tableid, this.columnInfos[i].Columnid).Value;
                        BasicClass.Assert(size == data[i].Length, "Invalid column size");

                        var setinfo = new JET_SETINFO();
                        setinfo.ibLongValue = size / 2;
                        setinfo.itagSequence = 1;

                        // the data that will be added to the column
                        byte[] newdata = DataGenerator.GetRandomColumnData(
                            this.columnInfos[i].Coltyp, this.columnInfos[i].Cp, rand);

                        // what the final data should be
                        byte[] finaldata = null;

                        switch (rand.Next(2))
                        {
                            case 0: // append
                                Api.SetColumn(
                                    this.sesid, tableid, this.columnInfos[i].Columnid, newdata, SetColumnGrbit.AppendLV);
                                finaldata = new byte[size + newdata.Length];
                                Array.Copy(data[i], finaldata, size);
                                Array.Copy(newdata, 0, finaldata, size, newdata.Length);
                                break;
                            case 1: // overwrite and set size
                                Api.JetSetColumn(
                                    this.sesid,
                                    tableid,
                                    this.columnInfos[i].Columnid,
                                    newdata,
                                    newdata.Length,
                                    SetColumnGrbit.SizeLV | SetColumnGrbit.OverwriteLV,
                                    setinfo);
                                finaldata = new byte[setinfo.ibLongValue + newdata.Length];
                                Array.Copy(data[i], finaldata, setinfo.ibLongValue);
                                Array.Copy(newdata, 0, finaldata, setinfo.ibLongValue, newdata.Length);
                                break;
                        }

                        data[i] = finaldata;
                    }
                }

                update.SaveAndGotoBookmark();
            }

            this.CheckColumns(this.sesid, tableid, data);

            Api.JetCommitTransaction(this.sesid, CommitTransactionGrbit.LazyFlush);
            Api.JetCloseTable(this.sesid, tableid);
        }
 public void JetSetColumnThrowsExceptionWhenIbLongValueIsNegative()
 {
     var setinfo = new JET_SETINFO { ibLongValue = -1 };
     Api.JetSetColumn(this.sesid, this.tableid, this.columnid, null, 0, SetColumnGrbit.None, setinfo);
 }
Beispiel #14
0
 public void JetSetinfoToString()
 {
     var value = new JET_SETINFO { ibLongValue = 1, itagSequence = 2 };
     Assert.AreEqual("JET_SETINFO(ibLongValue=1,itagSequence=2)", value.ToString());
 }
Beispiel #15
0
        /// <summary>
        /// Sets the length of the stream.
        /// </summary>
        /// <param name="value">The desired length, in bytes.</param>
        public override void SetLength(long value)
        {
            if (value > MaxLongValueSize || value < 0)
            {
                throw new ArgumentOutOfRangeException("value", value, "A LongValueStream cannot be longer than 0x7FFFFFF or less than 0 bytes");
            }

            if (value < this.Length && value > 0)
            {
                // BUG: Shrinking the column multiple times and then growing it can sometimes hit an unpleasant
                // ESENT defect which causes a hang. To make sure we never have that problem we read out the data,
                // and insert into a new long-value. This is not efficient.
                var data = new byte[value];
                var retinfo = new JET_RETINFO { itagSequence = this.Itag, ibLongValue = 0 };
                int actualDataSize;
                Api.JetRetrieveColumn(
                    this.sesid,
                    this.tableid,
                    this.columnid,
                    data,
                    data.Length,
                    out actualDataSize,
                    RetrieveGrbit,
                    retinfo);

                var setinfo = new JET_SETINFO { itagSequence = this.Itag };
                Api.JetSetColumn(this.sesid, this.tableid, this.columnid, data, data.Length, SetColumnGrbit.None, setinfo);
            }
            else
            {
                var setinfo = new JET_SETINFO { itagSequence = this.Itag };
                SetColumnGrbit grbit = (0 == value) ? SetColumnGrbit.ZeroLength : SetColumnGrbit.SizeLV;
                Api.JetSetColumn(this.sesid, this.tableid, this.columnid, null, checked((int)value), grbit, setinfo);                
            }

            // Setting the length moves the offset back to the end of the data
            if (this.ibLongValue > value)
            {
                this.ibLongValue = checked((int)value);
            }
        }
Beispiel #16
0
 /// <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 JET_coltyp.LongText or JET_coltyp.LongBinary.
 /// </summary>
 /// <remarks>
 /// This method takes an IntPtr and is intended for internal use only.
 /// </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="grbit">SetColumn options.</param>
 /// <param name="setinfo">Used to specify itag or long-value offset.</param>
 /// <returns>A warning value.</returns>
 internal static JET_wrn JetSetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, IntPtr data, int dataSize, SetColumnGrbit grbit, JET_SETINFO setinfo)
 {
     return(Api.Check(Impl.JetSetColumn(sesid, tableid, columnid, data, dataSize, grbit, setinfo)));
 }
Beispiel #17
0
        /// <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>
        /// Insert a record with the given column values. After the insert the cursor is 
        /// positioned on the record.
        /// </summary>
        /// <param name="key">
        /// The key of the record.
        /// </param>
        /// <param name="values">
        /// The column values to insert.
        /// </param>
        private void InsertRecord(int key, params string[] values)
        {
            using (var transaction = new Transaction(this.sesid))
            using (var update = new Update(this.sesid, this.tableid, JET_prep.Insert))
            {
                Api.SetColumn(this.sesid, this.tableid, this.keyColumn, key);
                foreach (string value in values)
                {
                    var setinfo = new JET_SETINFO
                    {
                        ibLongValue = 0,
                        itagSequence = 0,
                    };
                    byte[] data = Encoding.Unicode.GetBytes(value);
                    Api.JetSetColumn(
                        this.sesid, this.tableid, this.multiValueColumn, data, data.Length, SetColumnGrbit.None, setinfo);
                }

                update.SaveAndGotoBookmark();
                transaction.Commit(CommitTransactionGrbit.None);
            }
        }
Beispiel #19
0
        /// <summary>
        /// Sets the column.
        /// </summary>
        /// <param name="columnid">The columnid.</param>
        /// <param name="coltyp">The coltyp.</param>
        /// <param name="isAscii">Whether a textual column is Ascii.</param>
        /// <param name="index">The index.</param>
        /// <param name="obj">The object.</param>
        /// <exception cref="System.InvalidOperationException">You may only update fields through Cursor.EditRecord.</exception>
        /// <remarks>
        /// Itags start at 1, so we add 1 to the index
        /// </remarks>
        private void SetColumn(JET_COLUMNID columnid, JET_coltyp coltyp, bool isAscii, int index, object obj)
        {
            lock (this.isamSession)
            {
                this.cursor.CheckDisposed();

                if ((this.grbit & RetrieveColumnGrbit.RetrieveCopy) == 0)
                {
                    this.cursor.CheckRecord();
                    throw new InvalidOperationException("You may only update fields through Cursor.EditRecord.");
                }

                // if this is a Sort or PreSortTemporary TT and we are setting
                // an LV column then always attempt to use intrinsic LVs
                SetColumnGrbit grbitSet = SetColumnGrbit.None;
                if ((this.cursor.TableDefinition.Type == TableType.Sort
                     || this.cursor.TableDefinition.Type == TableType.PreSortTemporary)
                    && (coltyp == JET_coltyp.LongText || coltyp == JET_coltyp.LongBinary))
                {
                    grbitSet = grbitSet | SetColumnGrbit.IntrinsicLV;
                }

                JET_SETINFO setinfo = new JET_SETINFO();
                setinfo.ibLongValue = 0;
                setinfo.itagSequence = index + 1;

                byte[] bytes = Converter.BytesFromObject(coltyp, isAscii, obj);
                int bytesLength = bytes == null ? 0 : bytes.Length;

                Api.JetSetColumn(this.isamSession.Sesid, this.tableid, columnid, bytes, bytesLength, grbitSet, setinfo);

                this.updateID++;
            }
        }