Exemple #1
0
 public BasePipe(TransactionService transaction, IDocumentLookup lookup, SortDisk tempDisk, bool utcDate)
 {
     _transaction = transaction;
     _lookup      = lookup;
     _tempDisk    = tempDisk;
     _utcDate     = utcDate;
 }
Exemple #2
0
 public BasePipe(TransactionService transaction, IDocumentLookup lookup, SortDisk tempDisk, EnginePragmas pragmas)
 {
     _transaction = transaction;
     _lookup      = lookup;
     _tempDisk    = tempDisk;
     _pragmas     = pragmas;
 }
Exemple #3
0
        public DocumentGroup(BsonValue key, BsonDocument root, IEnumerable <BsonDocument> source, IDocumentLookup lookup)
        {
            this.Root = root;

            _key        = key;
            _enumerator = source.GetEnumerator();
            _lookup     = lookup;
        }
Exemple #4
0
        /// <summary>
        /// INCLUDE: Do include in result document according path expression - Works only with DocumentLookup
        /// </summary>
        protected async IAsyncEnumerable <BsonDocument> Include(IAsyncEnumerable <BsonDocument> source, BsonExpression path)
        {
            // cached services
            string          last     = null;
            Snapshot        snapshot = null;
            IndexService    indexer  = null;
            DataService     data     = null;
            CollectionIndex index    = null;
            IDocumentLookup lookup   = null;

            await foreach (var doc in source)
            {
                foreach (var value in path.Execute(doc, _pragmas.Collation)
                         .Where(x => x.IsDocument || x.IsArray)
                         .ToList())
                {
                    // if value is document, convert this ref document into full document (do another query)
                    if (value.IsDocument)
                    {
                        await DoInclude(value.AsDocument);
                    }
                    else
                    {
                        // if value is array, do same per item
                        foreach (var item in value.AsArray
                                 .Where(x => x.IsDocument)
                                 .Select(x => x.AsDocument))
                        {
                            await DoInclude(item);
                        }
                    }
                }

                yield return(doc);
            }

            async Task DoInclude(BsonDocument value)
            {
                // works only if is a document
                var refId  = value["$id"];
                var refCol = value["$ref"];

                // if has no reference, just go out
                if (refId.IsNull || !refCol.IsString)
                {
                    return;
                }

                // do some cache re-using when is same $ref (almost always is the same $ref collection)
                if (last != refCol.AsString)
                {
                    last = refCol.AsString;

                    // initialize services
                    snapshot = await _transaction.CreateSnapshot(LockMode.Read, last, false);

                    indexer = new IndexService(snapshot, _pragmas.Collation);
                    data    = new DataService(snapshot);

                    lookup = new DatafileLookup(data, _pragmas.UtcDate, null);

                    index = snapshot.CollectionPage?.PK;
                }

                // fill only if index and ref node exists
                if (index != null)
                {
                    var node = await indexer.Find(index, refId, false, Query.Ascending);

                    if (node != null)
                    {
                        // load document based on dataBlock position
                        var refDoc = await lookup.Load(node);

                        //do not remove $id
                        value.Remove("$ref");

                        // copy values from refDocument into current documet (except _id - will keep $id)
                        foreach (var element in refDoc.Where(x => x.Key != "_id"))
                        {
                            value[element.Key] = element.Value;
                        }
                    }
                    else
                    {
                        // set in ref document that was not found
                        value["$missing"] = true;
                    }
                }
            }
        }
Exemple #5
0
 public BasePipe(TransactionService transaction, IDocumentLookup lookup, EnginePragmas pragmas)
 {
     _transaction = transaction;
     _lookup      = lookup;
     _pragmas     = pragmas;
 }
Exemple #6
0
 public GroupByPipe(TransactionService transaction, IDocumentLookup loader, SortDisk tempDisk, bool utcDate)
     : base(transaction, loader, tempDisk, utcDate)
 {
 }
Exemple #7
0
 public DocumentCacheEnumerable(IEnumerable <BsonDocument> source, IDocumentLookup lookup)
 {
     _enumerator = source.GetEnumerator();
     _lookup     = lookup;
 }
Exemple #8
0
 public QueryPipe(TransactionService transaction, IDocumentLookup loader, SortDisk tempDisk, EnginePragmas pragmas)
     : base(transaction, loader, tempDisk, pragmas)
 {
 }
Exemple #9
0
        /// <summary>
        /// INCLUDE: Do include in result document according path expression - Works only with DocumentLookup
        /// </summary>
        protected IEnumerable <BsonDocument> Include(IEnumerable <BsonDocument> source, BsonExpression path)
        {
            // cached services
            string          last     = null;
            Snapshot        snapshot = null;
            IndexService    indexer  = null;
            DataService     data     = null;
            CollectionIndex index    = null;
            IDocumentLookup lookup   = null;

            foreach (var doc in source)
            {
                foreach (var value in path.Execute(doc)
                         .Where(x => x.IsDocument)
                         .Select(x => x.AsDocument)
                         .ToList())
                {
                    // works only if is a document
                    var refId  = value["$id"];
                    var refCol = value["$ref"];

                    // if has no reference, just go out
                    if (refId.IsNull || !refCol.IsString)
                    {
                        continue;
                    }

                    // do some cache re-using when is same $ref (almost always is the same $ref collection)
                    if (last != refCol.AsString)
                    {
                        last = refCol.AsString;

                        // initialize services
                        snapshot = _transaction.CreateSnapshot(LockMode.Read, last, false);
                        indexer  = new IndexService(snapshot);
                        data     = new DataService(snapshot);

                        lookup = new DatafileLookup(data, _utcDate, null);

                        index = snapshot.CollectionPage?.PK;
                    }

                    // fill only if index and ref node exists
                    if (index != null)
                    {
                        var node = indexer.Find(index, refId, false, Query.Ascending);

                        if (node != null)
                        {
                            // load document based on dataBlock position
                            var refDoc = lookup.Load(node);

                            value.Remove("$id");
                            value.Remove("$ref");

                            refDoc.CopyTo(value);
                        }
                    }
                }

                yield return(doc);
            }
        }