UpdateCompiler Mul(BsonDocument document, string name, BsonValue value) { var r = document.EnsurePath(name); BsonValue old; if (r.Document != null) { if (r.Document.TryGetValue(r.Key, out old)) { if (!old.IsNumeric) { throw new MongoException(string.Format(null, @"Field ""{0}"" must be numeric.", name)); } } else { old = 0; } r.Document[r.Key] = MyValue.Mul(old, value); } else if (!r.Array.InsertOutOfRange(r.Index, () => MyValue.Mul(0, value))) { old = r.Array[r.Index]; if (!old.IsNumeric) { throw new MongoException(string.Format(null, @"Item ""{0}"" must be numeric.", name)); } r.Array[r.Index] = MyValue.Mul(old, value); } return(this); }
static void Push(BsonDocument document, string name, BsonValue value, bool all, int position) { var r = document.EnsurePath(name); BsonValue v2 = BsonNull.Value; if (r.Array != null) { if (!r.Array.InsertOutOfRange(r.Index, () => v2 = new BsonArray())) { v2 = r.Array[r.Index]; } } else if (!r.Document.TryGetValue(r.Key, out v2)) { v2 = new BsonArray(); r.Document.Add(r.Key, v2); } if (v2.BsonType != BsonType.Array) { throw new InvalidOperationException(string.Format(null, @"Value ""{0}"" must be array.", name)); } var array = v2.AsBsonArray; if (all) { // Mongo 3.6 deals with negative, counts from the end if (position < 0) { position = array.Count + position; if (position < 0) { position = 0; } } if (position >= array.Count) { array.AddRange(value.AsBsonArray); } else { var array2 = value.AsBsonArray; for (int i = array2.Count; --i >= 0;) { array.Insert(position, array2[i]); } } } else { // position is not used in this case array.Add(value); } }
UpdateCompiler CurrentDate(BsonDocument document, string name) { var value = new BsonDateTime(DateTime.Now); var r = document.EnsurePath(name); if (r.Document != null) { r.Document[r.Key] = value; } else if (!r.Array.InsertOutOfRange(r.Index, () => value)) { r.Array[r.Index] = value; } return(this); }
UpdateCompiler Set(BsonDocument document, string name, BsonValue value) { value.ValidateNames(); var r = document.EnsurePath(name); if (r.Document != null) { r.Document[r.Key] = value; } else if (!r.Array.InsertOutOfRange(r.Index, () => value)) { r.Array[r.Index] = value; } return(this); }
UpdateCompiler Rename(BsonDocument document, string name, string newName) { var r1 = document.ResolvePath(name, ResolvePathOptions.NoArray); //_131028_234439 Weird, we can rename in arrays but follow Mongo that cannot. if (r1 != null) { BsonValue value; if (r1.Document.TryGetValue(r1.Key, out value)) { var r2 = document.EnsurePath(newName); r1.Document.Remove(r1.Key); r2.Document[r2.Key] = value; } } return(this); }
UpdateCompiler AddToSet(BsonDocument document, string name, BsonValue value, bool each) { var r = document.EnsurePath(name); BsonValue vArray; if (r.Array != null) { if (r.Array.InsertOutOfRange(r.Index, () => new BsonArray() { value })) { return(this); } vArray = r.Array[r.Index]; } else if (!r.Document.TryGetValue(r.Key, out vArray)) { r.Document.Add(r.Key, new BsonArray() { value }); return(this); } if (vArray.BsonType != BsonType.Array) { throw new InvalidOperationException(string.Format(null, @"Value ""{0}"" must be array.", name)); } if (each && value.BsonType == BsonType.Array) { vArray.AsBsonArray.AddToSetEach(value.AsBsonArray); } else { vArray.AsBsonArray.AddToSet(value); } return(this); }
static void Bitwise(BsonDocument document, string name, BsonValue value, int type) { var r = document.EnsurePath(name); BsonValue old; if (r.Array != null) { r.Array.InsertOutOfRange(r.Index, () => 0); old = r.Array[r.Index]; if (old.BsonType != BsonType.Int32 && old.BsonType != BsonType.Int64) { throw new MongoException(string.Format(null, @"Item ""{0}"" must be Int32 or Int64.", name)); } switch (type) { case 0: r.Array[r.Index] = MyValue.BitwiseAnd(old, value); break; case 1: r.Array[r.Index] = MyValue.BitwiseOr(old, value); break; default: r.Array[r.Index] = MyValue.BitwiseXor(old, value); break; } } else if (r.Document.TryGetValue(r.Key, out old)) { if (old.BsonType != BsonType.Int32 && old.BsonType != BsonType.Int64) { throw new MongoException(string.Format(null, @"Field ""{0}"" must be Int32 or Int64.", name)); } switch (type) { case 0: r.Document[r.Key] = MyValue.BitwiseAnd(old, value); break; case 1: r.Document[r.Key] = MyValue.BitwiseOr(old, value); break; default: r.Document[r.Key] = MyValue.BitwiseXor(old, value); break; } } }
UpdateCompiler Min(BsonDocument document, string name, BsonValue value) { value.ValidateNames(); var r = document.EnsurePath(name); if (r.Document != null) { BsonValue old; if (!r.Document.TryGetValue(r.Key, out old) || value.CompareTo(old) < 0) { r.Document[r.Key] = value; } } else if (!r.Array.InsertOutOfRange(r.Index, () => value)) { if (value.CompareTo(r.Array[r.Index]) < 0) { r.Array[r.Index] = value; } } return(this); }
UpdateCompiler Set(BsonDocument document, string name, BsonValue value) { var r = document.EnsurePath(name); if (r.Document != null) { r.Document[r.Key] = value; } else if (!r.Array.InsertOutOfRange(r.Index, () => value)) { r.Array[r.Index] = value; } return this; }
UpdateCompiler Rename(BsonDocument document, string name, string newName) { var r1 = document.ResolvePath(name, true); //_131028_234439 Weird, we can rename in arrays but follow Mongo that cannot. if (r1 != null) { BsonValue value; if (r1.Document.TryGetValue(r1.Key, out value)) { var r2 = document.EnsurePath(newName); r1.Document.Remove(r1.Key); r2.Document[r2.Key] = value; } } return this; }
UpdateCompiler Inc(BsonDocument document, string name, BsonValue value) { var r = document.EnsurePath(name); BsonValue old; if (r.Document != null) { if (r.Document.TryGetValue(r.Key, out old)) { if (!old.IsNumeric) throw new MongoException(string.Format(null, @"Field ""{0}"" must be numeric.", name)); value = MyValue.Add(old, value); } r.Document[r.Key] = value; } else if (!r.Array.InsertOutOfRange(r.Index, () => value)) { old = r.Array[r.Index]; if (!old.IsNumeric) throw new MongoException(string.Format(null, @"Item ""{0}"" must be numeric.", name)); r.Array[r.Index] = MyValue.Add(old, value); } return this; }
UpdateCompiler AddToSet(BsonDocument document, string name, BsonValue value, bool each) { var r = document.EnsurePath(name); BsonValue vArray; if (r.Array != null) { if (r.Array.InsertOutOfRange(r.Index, () => new BsonArray() { value })) return this; vArray = r.Array[r.Index]; } else if (!r.Document.TryGetValue(r.Key, out vArray)) { r.Document.Add(r.Key, new BsonArray() { value }); return this; } if (vArray.BsonType != BsonType.Array) throw new InvalidOperationException(string.Format(null, @"Value ""{0}"" must be array.", name)); if (each && value.BsonType == BsonType.Array) vArray.AsBsonArray.AddToSetEach(value.AsBsonArray); else vArray.AsBsonArray.AddToSet(value); return this; }
static void Push(BsonDocument document, string name, BsonValue value, bool all) { var r = document.EnsurePath(name); BsonValue v2 = BsonNull.Value; if (r.Array != null) { if (!r.Array.InsertOutOfRange(r.Index, () => v2 = new BsonArray())) v2 = r.Array[r.Index]; } else if (!r.Document.TryGetValue(r.Key, out v2)) { v2 = new BsonArray(); r.Document.Add(r.Key, v2); } if (v2.BsonType != BsonType.Array) throw new InvalidOperationException(string.Format(null, @"Value ""{0}"" must be array.", name)); var array = v2.AsBsonArray; if (all) array.AddRange(value.AsBsonArray); else array.Add(value); }