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]); } }
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)); } }
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); } } }
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]); } }
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))); }
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); } }
/// <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; } }
/// <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())); }
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)); }
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; } }
internal override void NormalizeValues(IndexOptions options) { _value = _value.Normalize(options); }