Ejemplo n.º 1
0
        public void VerifyUpdateFromNativeRetrievecolumnSetsErr()
        {
            var setcolumn = new JET_RETRIEVECOLUMN();
            var native    = new NATIVE_RETRIEVECOLUMN {
                err = 1004
            };

            setcolumn.UpdateFromNativeRetrievecolumn(ref native);
            Assert.AreEqual(JET_wrn.ColumnNull, setcolumn.err);
        }
Ejemplo n.º 2
0
        public void VerifyCheckThrowsExceptionWhenCbDataIsNegative()
        {
            var setcolumn = new JET_RETRIEVECOLUMN
            {
                cbData = -1,
                pvData = new byte[1],
            };

            setcolumn.CheckDataSize();
        }
Ejemplo n.º 3
0
        public void VerifyUpdateFromNativeRetrievecolumnSetsItagSequence()
        {
            var setcolumn = new JET_RETRIEVECOLUMN();
            var native    = new NATIVE_RETRIEVECOLUMN {
                itagSequence = 7
            };

            setcolumn.UpdateFromNativeRetrievecolumn(ref native);
            Assert.AreEqual(7, setcolumn.itagSequence);
        }
Ejemplo n.º 4
0
        public void VerifyUpdateFromNativeRetrievecolumnSetsCbactual()
        {
            var setcolumn = new JET_RETRIEVECOLUMN();
            var native    = new NATIVE_RETRIEVECOLUMN {
                cbActual = 0x100
            };

            setcolumn.UpdateFromNativeRetrievecolumn(ref native);
            Assert.AreEqual(0x100, setcolumn.cbActual);
        }
Ejemplo n.º 5
0
        public void VerifyCheckThrowsExceptionWhenIbDataIsTooLong()
        {
            var setcolumn = new JET_RETRIEVECOLUMN
            {
                ibData = 9,
                pvData = new byte[9],
            };

            setcolumn.CheckDataSize();
        }
Ejemplo n.º 6
0
        public void JetRetrievecolumnToString()
        {
            var value = new JET_RETRIEVECOLUMN {
                columnid = new JET_COLUMNID {
                    Value = 27
                }
            };

            Assert.AreEqual("JET_RETRIEVECOLUMN(0x1b)", value.ToString());
        }
Ejemplo n.º 7
0
        protected int GetMultiValueCount(EsentTable table, JET_COLUMNID columnid)
        {
            JET_RETRIEVECOLUMN col = new JET_RETRIEVECOLUMN
            {
                columnid     = columnid,
                itagSequence = 0
            };

            Api.JetRetrieveColumns(table.Session, table, new[] { col }, 1);
            return(col.itagSequence);
        }
Ejemplo n.º 8
0
        // Get the count of the values stored in the multi-valued column.
        int GetValuesCount(EseCursorBase cur, JET_COLUMNID idColumn)
        {
            // See http://stackoverflow.com/questions/2929587 for more info
            JET_RETRIEVECOLUMN jrc = new JET_RETRIEVECOLUMN();

            jrc.columnid     = idColumn;
            jrc.itagSequence = 0;
            Api.JetRetrieveColumns(cur.idSession, cur.idTable, new JET_RETRIEVECOLUMN[1] {
                jrc
            }, 1);
            return(jrc.itagSequence);
        }
Ejemplo n.º 9
0
        public void VerifyUpdateFromNativeRetrievecolumnSetsColumnidNextTagged()
        {
            var setcolumn = new JET_RETRIEVECOLUMN();
            var native    = new NATIVE_RETRIEVECOLUMN {
                columnidNextTagged = 0x20
            };

            setcolumn.UpdateFromNativeRetrievecolumn(ref native);
            var expected = new JET_COLUMNID {
                Value = 0x20
            };

            Assert.AreEqual(expected, setcolumn.columnidNextTagged);
        }
 public void Setup()
 {
     this.managed = new JET_RETRIEVECOLUMN
     {
         cbData   = 1,
         columnid = new JET_COLUMNID {
             Value = 2
         },
         grbit        = RetrieveColumnGrbit.RetrieveCopy,
         ibLongValue  = 3,
         itagSequence = 4,
     };
     this.managed.GetNativeRetrievecolumn(ref this.native);
 }
        public void RemoveChannel(string channel)
        {
            Api.JetPrepareUpdate(_sesid, _table, JET_prep.Replace);
            try
            {
                // Get the existing channels
                var column = new JET_RETRIEVECOLUMN
                {
                    columnid = _channelColumn,
                    grbit    = RetrieveColumnGrbit.RetrieveTag
                };

                Api.JetRetrieveColumns(_sesid, _table, new[] { column }, 1);

                int count = column.itagSequence;
                for (int i = 1; i <= count; i++)
                {
                    JET_RETINFO retinfo = new JET_RETINFO {
                        itagSequence = i
                    };
                    byte[] data = Api.RetrieveColumn(_sesid, _table, _channelColumn, RetrieveColumnGrbit.None, retinfo);
                    if (channel.Equals(Encoding.ASCII.GetString(data), StringComparison.OrdinalIgnoreCase))
                    {
                        JET_SETINFO setInfo = new JET_SETINFO();
                        setInfo.itagSequence = i;
                        Api.JetSetColumn(
                            _sesid,
                            _table,
                            _channelColumn,
                            null,
                            0,
                            SetColumnGrbit.None,
                            setInfo
                            );
                        break;
                    }
                }

                Api.JetUpdate(_sesid, _table);
            }
            catch (Exception)
            {
                Api.JetPrepareUpdate(_sesid, _table, JET_prep.Cancel);
                throw;
            }
        }
        private void SetEntry(CacheEntry entry, JET_prep updateType)
        {
            Api.JetPrepareUpdate(_sesid, _table, updateType);
            try
            {
                // The easy part set the key
                Api.SetColumn(
                    _sesid,
                    _table,
                    _keyColumn,
                    entry.Key,
                    Encoding.Unicode
                    );

                Api.SetColumn(
                    _sesid,
                    _table,
                    _dataColumn,
                    entry.Data
                    );

                Api.SetColumn(
                    _sesid,
                    _table,
                    _callbacksColumn,
                    entry.PostEvicationCallbacks
                    );

                // Avoid race conditions on update by making sure the record
                // is clear
                if (updateType == JET_prep.Replace)
                {
                    // Get the existing channels
                    var column = new JET_RETRIEVECOLUMN
                    {
                        columnid = _dependencyColumn,
                        grbit    = RetrieveColumnGrbit.RetrieveTag
                    };
                    Api.JetRetrieveColumns(_sesid, _table, new[] { column }, 1);

                    // This is a bit tricky, note that when an item is removed all the
                    // itag sequences update to be one lower
                    int count = column.itagSequence;
                    for (int i = 0; i < count; i++)
                    {
                        JET_SETINFO setInfo = new JET_SETINFO {
                            itagSequence = 1
                        };
                        Api.JetSetColumn(
                            _sesid,
                            _table,
                            _dependencyColumn,
                            null,
                            0,
                            SetColumnGrbit.UniqueMultiValues,
                            setInfo
                            );
                    }

                    Api.SetColumn(_sesid, _table, _absoluteExpirationColumn, null);
                    Api.SetColumn(_sesid, _table, _lastAccessedColumn, null);
                    Api.SetColumn(_sesid, _table, _slidingExpirationColumn, null);
                }


                if (entry.AbsoluteExpiration > 0)
                {
                    Api.SetColumn(
                        _sesid,
                        _table,
                        _absoluteExpirationColumn,
                        entry.AbsoluteExpiration
                        );
                }
                else if (entry.SlidingExpiration > 0)
                {
                    Api.SetColumn(
                        _sesid,
                        _table,
                        _lastAccessedColumn,
                        Convert.ToInt64(entry.LastAccessed)
                        );

                    Api.SetColumn(
                        _sesid,
                        _table,
                        _slidingExpirationColumn,
                        entry.SlidingExpiration
                        );
                }

                // Loop through all the channels and create them,
                // as this is a new record there is no need for checks
                foreach (var dependency in entry.Dependencies)
                {
                    // Using tag sequence 0 wil mean the items are
                    // automatically pushed into the mv-column
                    JET_SETINFO setInfo = new JET_SETINFO();
                    setInfo.itagSequence = 0;

                    // Note the use of ASCII to take up half the space
                    // there is no reason either subscriber or channel
                    // will have more than this
                    byte[] data = Encoding.ASCII.GetBytes(dependency);
                    Api.JetSetColumn(
                        _sesid,
                        _table,
                        _dependencyColumn,
                        data,
                        data.Length,
                        SetColumnGrbit.UniqueMultiValues,
                        setInfo
                        );
                }

                Api.JetUpdate(_sesid, _table);
            }
            catch (Exception exp)
            {
                Api.JetPrepareUpdate(_sesid, _table, JET_prep.Cancel);
                throw exp;
            }
        }
        public void Append(IEnumerable <string> channels)
        {
            Api.JetPrepareUpdate(_sesid, _table, JET_prep.Replace);
            try
            {
                // Get the existing channels
                var column = new JET_RETRIEVECOLUMN
                {
                    columnid = _channelColumn,
                    grbit    = RetrieveColumnGrbit.RetrieveTag
                };

                Api.JetRetrieveColumns(_sesid, _table, new[] { column }, 1);

                int count    = column.itagSequence;
                var existing = new string[count];
                for (int i = 1; i <= count; i++)
                {
                    JET_RETINFO retinfo = new JET_RETINFO {
                        itagSequence = i
                    };
                    byte[] data    = Api.RetrieveColumn(_sesid, _table, _channelColumn, RetrieveColumnGrbit.None, retinfo);
                    var    channel = Encoding.ASCII.GetString(data);
                    existing[i - 1] = channel;
                }

                // Loop through all the channels and create them,
                // as this is a new record there is no need for checks
                foreach (var channel in channels)
                {
                    // Only add the new ones
                    if (Array.IndexOf(existing, channel) > -1)
                    {
                        continue;
                    }

                    // Using tag sequence 0 wil mean the items are
                    // automatically pushed into the mv-column
                    count++;
                    JET_SETINFO setInfo = new JET_SETINFO();
                    setInfo.itagSequence = count;

                    // Note the use of ASCII to take up half the space
                    // there is no reason either subscriber or channel
                    // will have more than this
                    byte[] data = Encoding.ASCII.GetBytes(channel);
                    Api.JetSetColumn(
                        _sesid,
                        _table,
                        _channelColumn,
                        data,
                        data.Length,
                        SetColumnGrbit.UniqueMultiValues,
                        setInfo
                        );
                }

                Api.JetUpdate(_sesid, _table);
            }
            catch (Exception)
            {
                Api.JetPrepareUpdate(_sesid, _table, JET_prep.Cancel);
                throw;
            }
        }
Ejemplo n.º 14
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);
        }