예제 #1
0
        internal override IEnumerable <IndexNode> ExecuteIndex(IndexService indexer, CollectionIndex index)
        {
            // find first indexNode
            var value = _value.Normalize(index.Options);
            var node  = indexer.Find(index, value, true, Query.Ascending);

            if (node == null)
            {
                yield break;
            }

            // move until next is last
            while (node != null)
            {
                var diff = node.Key.CompareTo(value);

                if (diff == 1 || (_equals && diff == 0))
                {
                    if (node.IsHeadTail(index))
                    {
                        yield break;
                    }

                    yield return(node);
                }

                node = indexer.GetNode(node.Next[0]);
            }
        }
예제 #2
0
        internal override IEnumerable <IndexNode> ExecuteIndex(IndexService indexer, CollectionIndex index)
        {
            var start = _start.Normalize(index.Options);
            var end   = _end.Normalize(index.Options);

            // define order
            var order = start.CompareTo(end) <= 0 ? Query.Ascending : Query.Descending;

            // find first indexNode
            var node = indexer.Find(index, start, true, order);

            // navigate using next[0] do next node - if less or equals returns
            while (node != null)
            {
                var diff = node.Key.CompareTo(end);

                if (diff == 0 || diff != order)
                {
                    yield return(node);
                }
                else
                {
                    break;
                }

                node = indexer.GetNode(node.NextPrev(0, order));
            }
        }
예제 #3
0
        internal override IEnumerable <IndexNode> ExecuteIndex(IndexService indexer, CollectionIndex index)
        {
            var value = _value.Normalize(index.Options);
            var node  = indexer.Find(index, value, false, Query.Ascending);

            if (node == null)
            {
                yield break;
            }

            yield return(node);

            if (index.Options.Unique == false)
            {
                // navigate using next[0] do next node - if equals, returns
                while (!node.Next[0].IsEmpty && ((node = indexer.GetNode(node.Next[0])).Key.CompareTo(value) == 0))
                {
                    if (node.IsHeadTail(index))
                    {
                        yield break;
                    }

                    yield return(node);
                }
            }
        }
예제 #4
0
        internal override IEnumerable <IndexNode> ExecuteIndex(IndexService indexer, CollectionIndex index)
        {
            // find first indexNode
            var value = _value.Normalize(index.Options);
            var node  = indexer.Find(index, value, true, Query.Ascending);
            var str   = value.AsString;

            // navigate using next[0] do next node - if less or equals returns
            while (node != null)
            {
                var valueString = node.Key.AsString;

                // value will not be null because null occurs before string (bsontype sort order)
                if (valueString.StartsWith(str))
                {
                    if (!node.DataBlock.IsEmpty)
                    {
                        yield return(node);
                    }
                }
                else
                {
                    break; // if not more startswith, stop scanning
                }

                node = indexer.GetNode(node.Next[0]);
            }
        }
예제 #5
0
        internal override IEnumerable <IndexNode> ExecuteIndex(IndexService indexer, CollectionIndex index)
        {
            var v = _value.Normalize(index.Options);

            return(indexer
                   .FindAll(index, Query.Ascending)
                   .Where(x => x.Key.IsString && x.Key.AsString.Contains(v)));
        }
예제 #6
0
        internal override IEnumerable <IndexNode> ExecuteIndex(IndexService indexer, CollectionIndex index)
        {
            var value = _value.Normalize(index.Options);

            foreach (var node in indexer.FindAll(index, Query.Ascending))
            {
                var diff = node.Key.CompareTo(value);

                if (diff == 1 || (!_equals && diff == 0))
                {
                    break;
                }

                if (node.IsHeadTail(index))
                {
                    yield break;
                }

                yield return(node);
            }
        }
예제 #7
0
        /// <summary>
        /// Remove an document in collection using Document Id - returns false if not found document
        /// </summary>
        public virtual bool Delete(BsonValue id)
        {
            if (id == null || id.IsNull)
            {
                throw new ArgumentNullException("id");
            }

            // start transaction
            this.Database.Transaction.Begin();

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

                // if collection not exists, document do not exists too
                if (col == null)
                {
                    this.Database.Transaction.Abort();
                    return(false);
                }

                // normalize id before find
                var value = id.Normalize(col.PK.Options);

                // find indexNode using PK index
                var node = this.Database.Indexer.Find(col.PK, value, false, Query.Ascending);

                // if not found, abort transaction and returns false
                if (node == null)
                {
                    this.Database.Transaction.Abort();
                    return(false);
                }

                this.Delete(col, node);

                this.Database.Transaction.Commit();

                return(true);
            }
            catch
            {
                this.Database.Transaction.Rollback();
                throw;
            }
        }
예제 #8
0
 /// <summary>
 /// Insert a new node index inside an collection index. Flip coin to know level
 /// </summary>
 public IndexNode AddNode(CollectionIndex index, BsonValue key)
 {
     // call AddNode normalizing value
     return(this.AddNode(index, key.Normalize(index.Options), this.FlipCoin()));
 }
예제 #9
0
        internal override IEnumerable <IndexNode> ExecuteIndex(IndexService indexer, CollectionIndex index)
        {
            var value = _value.Normalize(index.Options);

            return(indexer.FindAll(index, Query.Ascending).Where(x => x.Key.CompareTo(value) != 0));
        }
예제 #10
0
        private bool UpdateDoc(BsonValue id, BsonDocument doc)
        {
            // serialize object
            var bytes = BsonSerializer.Serialize(doc);

            // start transaction
            this.Database.Transaction.Begin();

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

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

                // normalize id before find
                var value = id.Normalize(col.PK.Options);

                // find indexNode from pk index
                var indexNode = this.Database.Indexer.Find(col.PK, value, false, Query.Ascending);

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

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

                // delete/insert indexes - do not touch on PK
                foreach (var index in col.GetIndexes(false))
                {
                    var key = doc.Get(index.Field);

                    var node = this.Database.Indexer.GetNode(dataBlock.IndexRef[index.Slot]);

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

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

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

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

                        dataBlock.Page.IsDirty = true;
                    }
                }

                this.Database.Transaction.Commit();

                return(true);
            }
            catch
            {
                this.Database.Transaction.Rollback();
                throw;
            }
        }
예제 #11
0
 internal override void NormalizeValues(IndexOptions options)
 {
     _value = _value.Normalize(options);
 }