Ejemplo n.º 1
0
        /// <summary>
        /// Returns all values from array according index. If index are MaxValue, return all values
        /// </summary>
        public static IEnumerable <BsonValue> Array(IEnumerable <BsonValue> values, int index, BsonExpression expr, BsonDocument root)
        {
            foreach (var value in values)
            {
                if (value.IsArray)
                {
                    var arr = value.AsArray;

                    // [<expr>] - index are an expression
                    if (expr.Source != null)
                    {
                        foreach (var item in arr)
                        {
                            // execute for each child value and except a first bool value (returns if true)
                            var c = expr.Execute(root, item, true).First();

                            if (c.IsBoolean && c.AsBoolean == true)
                            {
                                // fill destroy action to remove value from parent array
                                item.Destroy = () => arr.Remove(item);

                                yield return(item);
                            }
                        }
                    }
                    // [*] - index are all values
                    else if (index == int.MaxValue)
                    {
                        foreach (var item in arr)
                        {
                            // fill destroy action to remove value from parent array
                            item.Destroy = () => arr.Remove(item);

                            yield return(item);
                        }
                    }
                    // [n] - fixed index
                    else
                    {
                        var idx = index < 0 ? arr.Count + index : index;

                        if (arr.Count > idx)
                        {
                            var item = arr[idx];

                            // fill destroy action to remove value from parent array
                            item.Destroy = () => arr.Remove(item);

                            yield return(item);
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Create a new index (or do nothing if already exists) to a collection/field
        /// </summary>
        public bool EnsureIndex(string collection, string field, string expression, bool unique = false)
        {
            if (collection.IsNullOrWhiteSpace())
            {
                throw new ArgumentNullException(nameof(collection));
            }
            if (!CollectionIndex.IndexPattern.IsMatch(field))
            {
                throw new ArgumentException("Invalid field format pattern: " + CollectionIndex.IndexPattern.ToString(), "field");
            }
            if (field == "_id")
            {
                return(false);                // always exists
            }
            if (expression != null && expression.Length > 200)
            {
                throw new ArgumentException("expression is limited in 200 characters", "expression");
            }

            return(Transaction <bool>(collection, true, (col) =>
            {
                // check if index already exists
                var current = col.GetIndex(field);

                // if already exists, just exit
                if (current != null)
                {
                    // do not test any difference between current index and new defition
                    return false;
                }

                // create index head
                var index = _indexer.CreateIndex(col);

                index.Field = field;
                index.Expression = expression ?? "$." + field;
                index.Unique = unique;

                _log.Write(Logger.Command, "create index on '{0}' :: {1} unique: {2}", collection, index.Expression, unique);

                // read all objects (read from PK index)
                foreach (var pkNode in new QueryAll("_id", Query.Ascending).Run(col, _indexer))
                {
                    // read binary and deserialize document
                    var buffer = _data.Read(pkNode.DataBlock);
                    var doc = _bsonReader.Deserialize(buffer).AsDocument;
                    var expr = new BsonExpression(index.Expression);

                    // get values from expression in document
                    var keys = expr.Execute(doc, true);

                    // adding index node for each value
                    foreach (var key in keys)
                    {
                        // insert new index node
                        var node = _indexer.AddNode(index, key, pkNode);

                        // link index node to datablock
                        node.DataBlock = pkNode.DataBlock;
                    }

                    // check memory usage
                    _trans.CheckPoint();
                }

                return true;
            }));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Get an IEnumerable of values from a json-like path inside document. Use BsonExpression to parse this path
        /// </summary>
        public IEnumerable <BsonValue> Get(string path, bool includeNullIfEmpty = false)
        {
            var expr = new BsonExpression(new StringScanner(path), true, true);

            return(expr.Execute(this, includeNullIfEmpty));
        }