public WriteConcernResult Remove(IMongoQuery query, RemoveFlags flags, WriteConcern writeConcern, bool needResult) { var predicate = QueryCompiler.GetFunction(query.ToBsonDocument()); int documentsAffected = 0; for (int i = 0; i < Documents.Count; ++i) { if (!predicate(Documents[i])) { continue; } RemoveDocumentAt(i); ++documentsAffected; if ((flags & RemoveFlags.Single) > 0) { break; } --i; } return(needResult ? new WriteConcernResult(NewResponse(documentsAffected, false, null, null)) : null); }
public object FindAndRemoveAs(Type documentType, IMongoQuery query, IMongoSortBy sortBy) { foreach (var document in QueryCompiler.Query(Documents, Documents2, query, sortBy, 0, 0)) { RemoveDocument(document); return(BsonSerializer.Deserialize(document, documentType)); } return(null); }
public IEnumerable <object> FindAs(Type documentType, IMongoQuery query, QueryFlags modes, IMongoSortBy sortBy, int skip, int first, IMongoFields fields) { var iter = QueryCompiler.Query(Documents, Documents2, query, sortBy, skip, first); if (fields == null) { return(iter.Select(x => BsonSerializer.Deserialize(x, documentType))); } var project = FieldCompiler.GetFunction(fields); return(iter.Select(project).Select(x => BsonSerializer.Deserialize(x, documentType))); }
public object FindAndModifyAs(Type documentType, IMongoQuery query, IMongoSortBy sortBy, IMongoUpdate update, IMongoFields fields, bool returnNew, bool upsert, out UpdateResult result) { foreach (var document in QueryCompiler.Query(Documents, Documents2, query, sortBy, 0, 0)) { // if old is needed then deep(!) clone before update //_131103_185751 BsonDocument output = null; if (!returnNew) { output = document.DeepClone().AsBsonDocument; } UpdateDocument(document, UpdateCompiler.GetFunction((IConvertibleToBsonDocument)update, null, false)); if (returnNew) { output = document; } // project if (fields != null) { var project = FieldCompiler.GetFunction(fields); output = project(output); } // if old is needed then return it as already deep cloned result = new SimpleUpdateResult(1, true); if (!returnNew && documentType == typeof(Dictionary)) { return(new Dictionary(output)); } else { // deserialize to required type return(BsonSerializer.Deserialize(output, documentType)); } } // not found, insert if (upsert) { var document = InsertNewDocument(query, update); result = new SimpleUpdateResult(1, false); return(returnNew ? BsonSerializer.Deserialize(document, documentType) : null); } result = new SimpleUpdateResult(0, false); return(null); }
static Expression PushEachExpression(Expression that, Expression field, BsonDocument document) { int position = -1; BsonArray each = null; BsonValue sort = null, slice = null; foreach (var e in document.Elements) { //TODO switch (e.Name) { case "$each": if (e.Value.BsonType != BsonType.Array) { throw new ArgumentException("Push all/each value must be array."); } each = e.Value.AsBsonArray; break; case "$sort": sort = e.Value; break; case "$slice": if (!e.Value.IsNumeric) { throw new ArgumentException("$slice must be a numeric value."); } slice = e.Value; break; case "$position": if (!e.Value.IsNumeric) { throw new ArgumentException("$position must be a numeric value."); } position = e.Value.ToInt32(); if (position < 0) { throw new ArgumentException("$position must not be negative."); } break; default: throw new ArgumentException(string.Format(null, "Unrecognized clause in $push: ({0}).", e.Name)); } } if (sort != null) { switch (sort.BsonType) { case BsonType.Int32: switch (sort.AsInt32) { case 1: each = new BsonArray(each.OrderBy(x => x)); break; //TODO comparer? case -1: each = new BsonArray(each.OrderByDescending(x => x)); break; //TODO comparer? default: throw new ArgumentException("Numeric $sort value must be either 1 or -1."); } break; case BsonType.Document: //TODO not needed in Mongo v2.6 foreach (var d1 in each) { if (d1.BsonType != BsonType.Document) { throw new ArgumentException("$sort requires $each to be an array of objects."); } } each = new BsonArray(QueryCompiler.Query(each.Cast <BsonDocument>(), null, null, new SortByDocument(sort.AsBsonDocument), 0, 0)); break; default: throw new ArgumentException("$sort value must be 1, -1, or a document."); } } if (slice != null) { each = each.Slice(0, slice.ToInt32()); } return(Expression.Call(that, GetMethod("PushAll"), Data, field, Expression.Constant(each, typeof(BsonValue)), Expression.Constant(position, typeof(int)))); }
static void Pull(BsonDocument document, string name, BsonValue value, bool all) { var r = document.ResolvePath(name); if (r == null) { return; //_140322_065637 } BsonValue vArray; if (r.Array != null) { vArray = r.Array[r.Index]; } else if (!r.Document.TryGetValue(r.Key, out vArray)) { return; } if (vArray.BsonType != BsonType.Array) { throw new InvalidOperationException(string.Format(null, @"Value ""{0}"" must be array.", name)); } var array = vArray.AsBsonArray; if (!all && value.BsonType == BsonType.Document) { //_131130_103226 Created in Update.Pull(query) var wrapper = value as BsonDocumentWrapper; if (wrapper != null) { value = (BsonValue)wrapper.WrappedObject; } var predicate = QueryCompiler.GetFunction(value.AsBsonDocument); for (int i = array.Count; --i >= 0;) { var v = array[i]; if (v.BsonType == BsonType.Document && predicate(v.AsBsonDocument)) { array.RemoveAt(i); } } } else { BsonArray values = all ? value.AsBsonArray : null; for (int i = array.Count; --i >= 0;) { if (values == null) { if (value.CompareTo(array[i]) == 0) { array.RemoveAt(i); } } else { if (values.ContainsByCompareTo(array[i])) { array.RemoveAt(i); } } } } }
IEnumerable <BsonDocument> QueryDocuments(IMongoQuery query) { return(Documents.Where(QueryCompiler.GetFunction(query.ToBsonDocument()))); }
} //! DB text // Assume that keys are already unique, so we avoid many checks. FieldCompiler(IMongoFields fields) { var document = ((IConvertibleToBsonDocument)fields).ToBsonDocument(); if (document.ElementCount == 0) { _All = true; return; } foreach (var e in document) { var name = e.Name; var value = e.Value; if (value.IsNumeric) { if (e.Value.ToInt32() != 0) { // include if (_Exclude != null) { ThrowMix(); } if (_Include == null) { _Include = new List <string>(); } if (name != MyValue.Id) { _Include.Add(name); } } else { // exclude if (name == MyValue.Id) { _Id = false; continue; } if (_Include != null) { ThrowMix(); } if (_Exclude == null) { _Exclude = new List <string>(); } _Exclude.Add(name); } continue; } BsonDocument selector; if (value.BsonType != BsonType.Document || (selector = value.AsBsonDocument).ElementCount != 1) { throw new InvalidOperationException("Invalid type of fields."); } var element = selector.GetElement(0); var oper = element.Name; var arg = element.Value; // case slice if (oper == "$slice") { if (arg.IsNumeric) { _Slice.Add(name, new int[] { 0, arg.ToInt32() }); continue; } BsonArray array; if (arg.BsonType != BsonType.Array || (array = arg.AsBsonArray).Count != 2) { throw new InvalidOperationException("Invalid $slice argument."); } int n = array[1].ToInt32(); if (n <= 0) { throw new InvalidOperationException("$slice limit must be positive."); //! DB text } _Slice.Add(name, new int[] { array[0].ToInt32(), n }); continue; } // case match if (oper != "$elemMatch") { throw new InvalidOperationException("Invalid field operator."); } if (arg.BsonType != BsonType.Document) { throw new InvalidOperationException("Invalid field match argument."); } _ElemMatch.Add(name, QueryCompiler.GetFunction(arg.AsBsonDocument)); } }
IEnumerable <BsonDocument> QueryDocuments(IMongoQuery query) { return(Documents.Where(QueryCompiler.GetFunction((IConvertibleToBsonDocument)query))); }