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)); }
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)); }
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)); } }
public bool IsCollectionCommand(StringScanner s, string command) { return(s.Match(@"db\.[\w-]+\." + command)); }
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); } }