private static void HandleAdd <TOut>( Operation operation, MapDescription map, string path, ConversionResult <TOut> conversion) { var lastDot = path.LastIndexOf(".", StringComparison.InvariantCulture); if (lastDot > 0) { // target location may not exists, however, only last property may not exists, but all previous should var existance = path.Substring(0, lastDot); conversion.Filters.Add(Builders <TOut> .Filter.Exists(existance)); } object val; try { val = ConvertType(map, operation.value); } catch { conversion.Errors.Add(new OperationError(string.Format(ConversionErrorFormat, path), OperationErrorType.TypeError, operation)); return; } var update = ConstructTypedSet <TOut>(path, map, val); conversion.Updates.Add(update); }
private static object ConvertType(MapDescription map, object value) { // Actually, i wanted to implement something cool, but after i saw // https://github.com/aspnet/JsonPatch/blob/98e2d5d4c729770e5e8e146602ab2b6c5bdc439a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs#L1012 // i decided, that everything is ok :) var serialized = JsonConvert.SerializeObject(value); return(BsonSerializer.Deserialize(serialized, map.Type)); }
private static UpdateDefinition <TOut> ConstructTypedSet <TOut>(string path, MapDescription map, object value) { // TODO add caching var genericUpdate = OperationUpdateDefinitionType.MakeGenericType(typeof(TOut), map.Type); var genericField = GenericStringFieldDefinition.MakeGenericType(typeof(TOut), map.Type); var fieldDefinition = Activator.CreateInstance(genericField, path, null); //public OperatorUpdateDefinition(string operatorName, FieldDefinition<TDocument, TField> field, TField value) var updateDefinition = Activator.CreateInstance(genericUpdate, "$set", fieldDefinition, value); return((UpdateDefinition <TOut>)updateDefinition); }
private static void HandleRemove <TOut>( Operation op, MapDescription map, string path, ConversionResult <TOut> conversion) { if (map.IsIndexer) { conversion.Errors.Add(new OperationError(NotSupportedByMongo, OperationErrorType.NotSupported, op)); return; } var filter = Builders <TOut> .Filter.Exists(new StringFieldDefinition <TOut>(path)); conversion.Filters.Add(filter); conversion.Updates.Add(Builders <TOut> .Update.Unset(path)); }
private static void HandleReplace <TOut>( Operation op, MapDescription map, string path, ConversionResult <TOut> conversion) { var val = op.value; try { val = ConvertType(map, val); } catch { conversion.Errors.Add(new OperationError(string.Format(ConversionErrorFormat, path), OperationErrorType.TypeError, op)); return; } var filter = Builders <TOut> .Filter.Exists(new StringFieldDefinition <TOut>(path)); var update = ConstructTypedSet <TOut>(path, map, val); conversion.Filters.Add(filter); conversion.Updates.Add(update); }