コード例 #1
0
        /// <summary>
        /// Create a new permanent index in all documents inside this collections if index not exists already. Returns true if index was created or false if already exits
        /// </summary>
        /// <param name="field">Document field name (case sensitive)</param>
        /// <param name="unique">Create a unique values index?</param>
        public virtual bool EnsureIndex(string field, bool unique = false)
        {
            if (string.IsNullOrEmpty(field))
            {
                throw new ArgumentNullException("field");
            }

            if (!Regex.IsMatch(field, CollectionIndex.FIELD_PATTERN) || field.Length > CollectionIndex.FIELD_MAX_LENGTH)
            {
                throw new LiteException("Invalid field format.");
            }

            if (typeof(T) != typeof(BsonDocument) && typeof(T).GetProperty(field) == null)
            {
                throw new LiteException(string.Format("Property name {0} not found in {1} class", field, typeof(T).Name));
            }

            // do not create collection at this point
            var col = this.GetCollectionPage(false);

            // check if index already exists (collection must exists)
            if (col != null && col.Indexes.FirstOrDefault(x => x.Field.Equals(field, StringComparison.InvariantCultureIgnoreCase)) != null)
            {
                return(false);
            }
            ;

            // start transaction
            _engine.Transaction.Begin();

            try
            {
                // if not collection yet, create a new now
                if (col == null)
                {
                    col     = _engine.Collections.Add(this.Name);
                    _pageID = col.PageID;
                }

                // get index slot
                var slot = col.GetFreeIndex();

                // create index head
                var index = _engine.Indexer.CreateIndex(col.Indexes[slot]);

                index.Field  = field;
                index.Unique = unique;

                // read all objects (read from PK index)
                foreach (var node in _engine.Indexer.FindAll(col.PK))
                {
                    var dataBlock = _engine.Data.Read(node.DataBlock, true);

                    // read object
                    var doc = BsonSerializer.Deserialize <T>(dataBlock.Key, dataBlock.Buffer);

                    // adding index
                    var key = BsonSerializer.GetFieldValue(doc, field);

                    var newNode = _engine.Indexer.AddNode(index, key);

                    // adding this new index Node to indexRef
                    dataBlock.IndexRef[slot] = newNode.Position;

                    // link index node to datablock
                    newNode.DataBlock = dataBlock.Position;

                    // mark datablock page as dirty
                    dataBlock.Page.IsDirty = true;
                }

                _engine.Transaction.Commit();
            }
            catch (Exception ex)
            {
                _engine.Transaction.Rollback();
                throw ex;
            }

            return(true);
        }
コード例 #2
0
ファイル: Collection.Update.cs プロジェクト: nivlac64/eve-plh
        /// <summary>
        /// Update a document in this collection. Returns false if not found document in collection
        /// </summary>
        public virtual bool Update(T doc)
        {
            if (doc == null)
            {
                throw new ArgumentNullException("doc");
            }

            // gets document Id
            var id = BsonSerializer.GetIdValue(doc);

            if (id == null)
            {
                throw new LiteException("Document Id can't be null");
            }

            // serialize object
            var bytes = BsonSerializer.Serialize(doc);

            // start transaction
            _engine.Transaction.Begin();

            try
            {
                var col = this.GetCollectionPage(false);

                // if no collection, no updates
                if (col == null)
                {
                    _engine.Transaction.Abort();
                    return(false);
                }

                // find indexNode from pk index
                var indexNode = _engine.Indexer.FindOne(col.PK, id);

                // if not found document, no updates
                if (indexNode == null)
                {
                    _engine.Transaction.Abort();
                    return(false);
                }

                // update data storage
                var dataBlock = _engine.Data.Update(col, indexNode.DataBlock, bytes);

                // delete/insert indexes - do not touch on PK
                for (byte i = 1; i < col.Indexes.Length; i++)
                {
                    var index = col.Indexes[i];

                    if (!index.IsEmpty)
                    {
                        var key = BsonSerializer.GetFieldValue(doc, index.Field);

                        var node = _engine.Indexer.GetNode(dataBlock.IndexRef[i]);

                        // check if my index node was changed
                        if (node.Key.CompareTo(new IndexKey(key)) != 0)
                        {
                            // remove old index node
                            _engine.Indexer.Delete(index, node.Position);

                            // and add a new one
                            var newNode = _engine.Indexer.AddNode(index, key);

                            // point my index to data object
                            newNode.DataBlock = dataBlock.Position;

                            // point my dataBlock
                            dataBlock.IndexRef[i] = newNode.Position;

                            dataBlock.Page.IsDirty = true;
                        }
                    }
                }

                _engine.Transaction.Commit();

                return(true);
            }
            catch (Exception ex)
            {
                _engine.Transaction.Rollback();
                throw ex;
            }
        }
コード例 #3
0
ファイル: Collection.Insert.cs プロジェクト: nivlac64/eve-plh
        /// <summary>
        /// Insert a new document to this collection. Document Id must be a new value in collection
        /// </summary>
        public virtual void Insert(T doc)
        {
            if (doc == null)
            {
                throw new ArgumentNullException("doc");
            }

            // gets document Id
            var id = BsonSerializer.GetIdValue(doc);

            if (id == null)
            {
                throw new LiteException("Document Id can't be null");
            }

            // serialize object
            var bytes = BsonSerializer.Serialize(doc);

            _engine.Transaction.Begin();

            try
            {
                var col = this.GetCollectionPage(true);

                // storage in data pages - returns dataBlock address
                var dataBlock = _engine.Data.Insert(col, new IndexKey(id), bytes);

                // store id in a PK index [0 array]
                var pk = _engine.Indexer.AddNode(col.PK, id);

                // do links between index <-> data block
                pk.DataBlock          = dataBlock.Position;
                dataBlock.IndexRef[0] = pk.Position;

                // for each index, insert new IndexNode
                for (byte i = 1; i < col.Indexes.Length; i++)
                {
                    var index = col.Indexes[i];

                    if (!index.IsEmpty)
                    {
                        var key = BsonSerializer.GetFieldValue(doc, index.Field);

                        var node = _engine.Indexer.AddNode(index, key);

                        // point my index to data object
                        node.DataBlock = dataBlock.Position;

                        // point my dataBlock
                        dataBlock.IndexRef[i] = node.Position;
                    }
                }

                _engine.Transaction.Commit();
            }
            catch (Exception ex)
            {
                _engine.Transaction.Rollback();
                throw ex;
            }
        }