Esempio n. 1
0
        public Query ReadQuery(StringScanner s, bool required)
        {
            s.Scan(@"\s*");

            if (required && s.HasTerminated)
            {
                throw LiteException.SyntaxError(s, "Unexpected finish of line");
            }

            if (s.HasTerminated || s.Match(@"skip\s+\d") || s.Match(@"limit\s+\d") || s.Match(@"include[s]?\s+[\$\w]"))
            {
                return(Query.All());
            }

            return(this.ReadInlineQuery(s));
        }
Esempio n. 2
0
        public KeyValuePair <int, int> ReadSkipLimit(StringScanner s)
        {
            var skip  = 0;
            var limit = int.MaxValue;

            if (s.Match(@"\s*skip\s+\d+"))
            {
                skip = Convert.ToInt32(s.Scan(@"\s*skip\s+(\d+)\s*", 1));
            }

            if (s.Match(@"\s*limit\s+\d+"))
            {
                limit = Convert.ToInt32(s.Scan(@"\s*limit\s+(\d+)\s*", 1));
            }

            // skip can be before or after limit command
            if (s.Match(@"\s*skip\s+\d+"))
            {
                skip = Convert.ToInt32(s.Scan(@"\s*skip\s+(\d+)\s*", 1));
            }

            return(new KeyValuePair <int, int>(skip, limit));
        }
Esempio n. 3
0
        public IEnumerable <BsonValue> Execute(StringScanner s, LiteEngine engine)
        {
            var col = this.ReadCollection(engine, s);

            // single document update
            if (s.Match(@"\s*\{"))
            {
                var doc = JsonSerializer.Deserialize(s.ToString()).AsDocument;

                s.ThrowIfNotFinish();

                yield return(engine.Update(col, doc));
            }
            // query update
            else
            {
                // db.colName.update
                //     field = value,
                //     array += valueToAdd,
                // where _id = 1
                //   and ...

                var query   = Query.All();
                var updates = new Update();

                while (!s.HasTerminated)
                {
                    var path   = BsonExpression.ReadExpression(s, true, true).Source;
                    var action = s.Scan(@"\s*\+?=\s*").Trim().ThrowIfEmpty("Invalid operator (support = or +=)", s);
                    var value  = this.ReadBsonValue(s);
                    var expr   = value == null?BsonExpression.ReadExpression(s, true, false)?.Source : null;

                    if (action == "+=" && value != null)
                    {
                        updates.Add(path, value);
                    }
                    else if (action == "+=" && expr != null)
                    {
                        updates.AddExpr(path, expr);
                    }
                    else if (action == "=" && value != null)
                    {
                        updates.Set(path, value);
                    }
                    else if (action == "=" && expr != null)
                    {
                        updates.SetExpr(path, expr);
                    }
                    else
                    {
                        throw LiteException.SyntaxError(s);
                    }

                    s.Scan(@"\s*");

                    if (s.Scan(@",\s*").Length > 0)
                    {
                        continue;
                    }
                    else if (s.Scan(@"where\s*").Length > 0 || s.HasTerminated)
                    {
                        break;
                    }
                    else
                    {
                        throw LiteException.SyntaxError(s);
                    }
                }

                if (!s.HasTerminated)
                {
                    query = this.ReadQuery(s, false);
                }

                s.ThrowIfNotFinish();

                yield return(engine.Update(col, query, updates));
            }
        }
Esempio n. 4
0
 public bool IsCollectionCommand(StringScanner s, string command)
 {
     return(s.Match(@"db\.[\w-]+\." + command));
 }
Esempio n. 5
0
        public IEnumerable <BsonValue> Execute(StringScanner s, LiteEngine engine)
        {
            var col = this.ReadCollection(engine, s);

            // single document update
            if (s.Match(@"\s*\{"))
            {
                var doc = JsonSerializer.Deserialize(s.ToString()).AsDocument;

                s.ThrowIfNotFinish();

                yield return(engine.Update(col, doc));
            }
            // query update
            else
            {
                // db.colName.update
                //     field = value,
                //     array += valueToAdd,
                // where _id = 1
                //   and ...

                var updates = new List <UpdateData>();
                var query   = Query.All();

                while (!s.HasTerminated)
                {
                    var path   = BsonExpression.ReadExpression(s, true, true).Source;
                    var action = s.Scan(@"\s*\+?=\s*").Trim().ThrowIfEmpty("Invalid operator (support = or +=)", s);
                    var value  = this.ReadBsonValue(s);
                    var expr   = value == null?BsonExpression.ReadExpression(s, true, false) : null;

                    if (action != "+=" && action != "=")
                    {
                        throw LiteException.SyntaxError(s);
                    }
                    if (value == null && expr == null)
                    {
                        throw LiteException.SyntaxError(s);
                    }

                    updates.Add(new UpdateData {
                        Path = path, Value = value, Expr = expr, Add = action == "+="
                    });

                    s.Scan(@"\s*");

                    if (s.Scan(@",\s*").Length > 0)
                    {
                        continue;
                    }
                    else if (s.Scan(@"where\s*").Length > 0 || s.HasTerminated)
                    {
                        break;
                    }
                    else
                    {
                        throw LiteException.SyntaxError(s);
                    }
                }

                if (!s.HasTerminated)
                {
                    query = this.ReadQuery(s, false);
                }

                s.ThrowIfNotFinish();

                // execute command
                var count = 0;

                foreach (var doc in engine.Find(col, query))
                {
                    var docChanged = false;

                    foreach (var update in updates)
                    {
                        var itemChanged = false;

                        if (update.Value == null)
                        {
                            itemChanged = doc.Set(update.Path, update.Expr, update.Add);
                        }
                        else
                        {
                            itemChanged = doc.Set(update.Path, update.Value, update.Add);
                        }

                        if (itemChanged)
                        {
                            docChanged = true;
                        }
                    }

                    // execute update only if document was changed
                    if (docChanged)
                    {
                        engine.Update(col, doc);

                        count++;
                    }
                }

                yield return(count);
            }
        }