public List <UpdateDefinition <BsonDocument> > BuildUpdatesForSave( UpdateDefinition <BsonDocument> update, TrackableSetTracker <T> tracker, params object[] keyValues) { var updates = new List <UpdateDefinition <BsonDocument> >(); var keyNamespace = DocumentHelper.ToDotPath(keyValues); if (tracker.AddValues.Any()) { updates.Add(update == null ? Builders <BsonDocument> .Update.AddToSetEach(keyNamespace, tracker.AddValues) : update.AddToSetEach(keyNamespace, tracker.AddValues)); update = null; } if (tracker.RemoveValues.Any()) { updates.Add(update == null ? Builders <BsonDocument> .Update.PullAll(keyNamespace, tracker.RemoveValues) : update.PullAll(keyNamespace, tracker.RemoveValues)); update = null; } if (update != null) { updates.Add(update); } return(updates); }
// public int Serialize(ref byte[] bytes, int offset, TrackableSetTracker<T> value, IFormatterResolver formatterResolver) // { // var tracker = value; // var startOffset = offset; // offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, tracker.ChangeMap.Count); // foreach (var item in tracker.ChangeMap) // { // var changed = new Changed(item.Value == TrackableSetOperation.Add, item.Key); // offset += formatterResolver.GetFormatterWithVerify<Changed>() // .Serialize(ref bytes, offset, changed, formatterResolver); // } // // return offset - startOffset; // } // // public TrackableSetTracker<T> Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) // { // var tracker = new TrackableSetTracker<T>(); // var startOffset = offset; // var length = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize); // offset += readSize; // // for (int i = 0; i < length; i++) // { // var item = formatterResolver.GetFormatterWithVerify<Changed>() // .Deserialize(bytes, offset, formatterResolver, out readSize); // offset += readSize; // if(item.Add) // tracker.TrackAdd(item.Value); // else // tracker.TrackRemove(item.Value); // } // // readSize = offset - startOffset; // return tracker; // } public static void Serialize(ref MessagePackWriter writer, TrackableSetTracker <T> value, MessagePackSerializerOptions options) { var tracker = value; writer.WriteArrayHeader(tracker.ChangeMap.Count); foreach (var item in tracker.ChangeMap) { writer.Write(item.Value == TrackableSetOperation.Add); MessagePackSerializer.Serialize(ref writer, item.Key, options); } }
public async Task SaveAsync(IDatabase db, TrackableSetTracker <T> tracker, RedisKey key) { var addValues = tracker.AddValues.Select(_valueToRedisValue).ToArray(); var removeValues = tracker.RemoveValues.Select(_valueToRedisValue).ToArray(); if (addValues.Length > 0) { await db.SetAddAsync(key, addValues); } if (removeValues.Length > 0) { await db.SetRemoveAsync(key, removeValues); } }
public async Task <int> SaveAsync(DbConnection connection, TrackableSetTracker <T> tracker, params object[] keyValues) { if (tracker.HasChange == false) { return(0); } var sql = BuildSqlForSave(tracker, keyValues); using (var command = _sqlProvider.CreateDbCommand(sql, connection)) { return(await command.ExecuteNonQueryAsync()); } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType != JsonToken.StartObject) { return(null); } var tracker = new TrackableSetTracker <T>(); reader.Read(); while (true) { if (reader.TokenType != JsonToken.PropertyName) { break; } var str = (string)reader.Value; reader.Read(); var add = (str == "+"); if (reader.TokenType != JsonToken.StartArray) { break; } reader.Read(); while (reader.TokenType != JsonToken.EndArray) { var value = serializer.Deserialize <T>(reader); reader.Read(); if (add) { tracker.TrackAdd(value); } else { tracker.TrackRemove(value); } } reader.Read(); } return(tracker); }
public static TrackableSetTracker <T> Convert(TrackableSetTrackerSurrogate <T> surrogate) { if (surrogate == null) { return(null); } var tracker = new TrackableSetTracker <T>(); foreach (var value in surrogate.AddValues) { tracker.TrackAdd(value); } foreach (var value in surrogate.RemoveValues) { tracker.TrackRemove(value); } return(tracker); }
public void TestSet_ApplyToTracker_Work() { var set = CreateTestSetWithTracker(); set.Remove(2); set.Add(4); var tracker2 = new TrackableSetTracker <int>(); set.Tracker.ApplyTo(tracker2); var set2 = CreateTestSet(); tracker2.ApplyTo(set2); Assert.Equal( new[] { 1, 3, 4 }, set2.OrderBy(v => v)); }
public static TrackableSetTracker <T> Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { var tracker = new TrackableSetTracker <T>(); var length = reader.ReadArrayHeader(); for (int i = 0; i < length; i++) { var isAdd = reader.ReadBoolean(); var value = MessagePackSerializer.Deserialize <T>(ref reader, options); if (isAdd) { tracker.TrackAdd(value); } else { tracker.TrackRemove(value); } } return(tracker); }
public static TrackableSetTrackerSurrogate <T> Convert(TrackableSetTracker <T> tracker) { if (tracker == null) { return(null); } var surrogate = new TrackableSetTrackerSurrogate <T>(); foreach (var change in tracker.ChangeMap) { if (change.Value == TrackableSetOperation.Add) { surrogate.AddValues.Add(change.Key); } else { surrogate.RemoveValues.Add(change.Key); } } return(surrogate); }
public async Task SaveAsync(IMongoCollection <BsonDocument> collection, TrackableSetTracker <T> tracker, params object[] keyValues) { if (keyValues.Length < 2) { throw new ArgumentException("At least 2 keyValue required."); } if (tracker.HasChange == false) { return; } var filter = Builders <BsonDocument> .Filter.Eq("_id", keyValues[0]); foreach (var update in BuildUpdatesForSave(null, tracker, keyValues.Skip(1).ToArray())) { await collection.UpdateOneAsync( filter, update, new UpdateOptions { IsUpsert = true }); } }
public string BuildSqlForSave(TrackableSetTracker <T> tracker, params object[] keyValues) { if (keyValues.Length != _headKeyColumns.Length) { throw new ArgumentException("Number of keyValues should be same with the number of head columns"); } var sqlAdd = new StringBuilder(); var removeValues = new List <T>(); // generate sql command for each changes var insertCount = 0; foreach (var i in tracker.ChangeMap) { switch (i.Value) { case TrackableSetOperation.Add: if (insertCount == 0) { sqlAdd.Append("INSERT INTO ").Append(_tableEscapedName); sqlAdd.Append(" (").Append(_allColumnString).Append(") VALUES\n"); } else { sqlAdd.Append(",\n"); } sqlAdd.Append(" ("); for (var k = 0; k < _headKeyColumns.Length; k++) { sqlAdd.Append(_headKeyColumns[k].ConvertToSqlValue(keyValues[k])); sqlAdd.Append(","); } sqlAdd.Append(_valueColumn.ConvertToSqlValue(i.Key)); sqlAdd.Append(")"); insertCount += 1; if (insertCount >= 1000) { sqlAdd.Append(";\n"); insertCount = 0; } break; case TrackableSetOperation.Remove: removeValues.Add(i.Key); break; } } if (insertCount > 0) { sqlAdd.Append(";\n"); } // merge insert, update and delete sql into one sql var sql = new StringBuilder(); sql.Append(sqlAdd); if (removeValues.Any()) { sql.Append("DELETE FROM ").Append(_tableEscapedName).Append(" WHERE "); for (var k = 0; k < _headKeyColumns.Length; k++) { sql.Append(_headKeyColumns[k].EscapedName).Append("="); sql.Append(_headKeyColumns[k].ConvertToSqlValue(keyValues[k])); sql.Append(" AND "); } sql.Append(_valueColumn.EscapedName).Append(" IN ("); var concating = false; foreach (var id in removeValues) { if (concating == false) { concating = true; } else { sql.Append(","); } sql.Append(_valueColumn.ConvertToSqlValue(id)); } sql.Append(");\n"); } return(sql.ToString()); }
public void TestSet_RollbackToTracker_Work() { var set = CreateTestSetWithTracker(); set.Remove(2); set.Add(4); var tracker2 = new TrackableSetTracker<int>(); set.Tracker.ApplyTo(tracker2); set.Tracker.RollbackTo(tracker2); var set2 = CreateTestSet(); tracker2.ApplyTo(set2); Assert.Equal( new[] { 1, 2, 3 }, set2.OrderBy(v => v)); }
public void Serialize(ref MessagePackWriter writer, TrackableSetTracker <T> value, MessagePackSerializerOptions options) { TrackableSetTrackerMessagePackFormatter <T> .Serialize(ref writer, value, options); }