Пример #1
0
        public void SerializePatchDocument()
        {
            var patchDoc = new PatchDocument(
                new TestOperation {
                Path = "/a/b/c", Value = new JValue("foo")
            },
                new RemoveOperation {
                Path = "/a/b/c"
            },
                new AddOperation {
                Path = "/a/b/c", Value = new JArray(new JValue("foo"), new JValue("bar"))
            },
                new ReplaceOperation {
                Path = "/a/b/c", Value = new JValue(42)
            },
                new MoveOperation {
                FromPath = "/a/b/c", Path = "/a/b/d"
            },
                new CopyOperation {
                FromPath = "/a/b/d", Path = "/a/b/e"
            });

            var outputstream = patchDoc.ToStream();
            var output       = new StreamReader(outputstream).ReadToEnd();

            var jOutput = JToken.Parse(output);

            Assert.Equal(@"[{""op"":""test"",""path"":""/a/b/c"",""value"":""foo""},{""op"":""remove"",""path"":""/a/b/c""},{""op"":""add"",""path"":""/a/b/c"",""value"":[""foo"",""bar""]},{""op"":""replace"",""path"":""/a/b/c"",""value"":42},{""op"":""move"",""path"":""/a/b/d"",""from"":""/a/b/c""},{""op"":""copy"",""path"":""/a/b/e"",""from"":""/a/b/d""}]",
                         jOutput.ToString(Formatting.None));
        }
        /// <summary>
        /// Constructor for given json content and optional JsonSerializer Settings.
        /// </summary>
        /// <param name="patchDocument">json MergePatchDocument content.</param>
        /// <param name="settings">Serializer settings to use. NullValueHandling will always be NullValueHandling.Include though.</param>
        /// <exception cref="ArgumentException">if <paramref name="patchDocument" /> is null or whitespace.</exception>
        /// <exception cref="InvalidJsonMergePatchDocumentException">
        ///     if <paramref name="patchDocument" /> anything other than a
        ///     parsable json object.
        /// </exception>
        public JsonMergePatchDocument(string patchDocument, JsonSerializerSettings settings = null)
        {
            if (string.IsNullOrWhiteSpace(patchDocument))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(patchDocument));
            }

            _serializerSettings = settings ?? new JsonSerializerSettings();
            var serializer = JsonSerializer.Create(_serializerSettings);

            _internalValidator = new InternalValidator <TResource>();
            // Ensure that the serializer does not ignore null values to comply with RFC 7386
            serializer.NullValueHandling = NullValueHandling.Include;
            if (!patchDocument.Trim().StartsWith("{"))
            {
                throw new InvalidJsonMergePatchDocumentException(ErrorMessages.DocumentRootMustBeObject);
            }
            try
            {
                var patchObject = JObject.Parse(patchDocument);
                _internalDocument = new PatchDocument(patchObject, typeof(TResource),
                                                      serializer);
            }
            catch (JsonReaderException ex)
            {
                throw new InvalidJsonMergePatchDocumentException(ErrorMessages.DocumentNotParseable, ex);
            }
        }
Пример #3
0
        public async Task JsonPatchAllAsync()
        {
            var utcNow    = SystemClock.UtcNow;
            var employees = new List <Employee> {
                EmployeeGenerator.Generate(ObjectId.GenerateNewId(utcNow.AddDays(-1)).ToString(), createdUtc: utcNow.AddDays(-1), companyId: "1", yearsEmployed: 0),
                EmployeeGenerator.Generate(createdUtc: utcNow, companyId: "1", yearsEmployed: 0),
                EmployeeGenerator.Generate(createdUtc: utcNow, companyId: "2", yearsEmployed: 0),
            };

            await _employeeRepository.AddAsync(employees, o => o.ImmediateConsistency());

            var patch = new PatchDocument(new ReplaceOperation {
                Path = "name", Value = "Patched"
            });
            await _employeeRepository.PatchAsync(employees.Select(l => l.Id).ToArray(), new Models.JsonPatch(patch), o => o.ImmediateConsistency());

            var results = await _employeeRepository.GetAllByCompanyAsync("1");

            Assert.Equal(2, results.Documents.Count);
            foreach (var document in results.Documents)
            {
                Assert.Equal("1", document.CompanyId);
                Assert.Equal("patched", document.Name);
            }
        }
Пример #4
0
        public void Replace_multiple_property_values_with_jsonpath()
        {
            var sample = JToken.Parse(@"{
    'books': [
        {
          'title' : 'The Great Gatsby',
          'author' : 'F. Scott Fitzgerald'
        },
        {
          'title' : 'The Grapes of Wrath',
          'author' : 'John Steinbeck'
        },
        {
          'title' : 'Some Other Title',
          'author' : 'John Steinbeck'
        }
    ]
}");

            var    patchDocument = new PatchDocument();
            string pointer       = "$.books[?(@.author == 'John Steinbeck')].author";

            patchDocument.AddOperation(new ReplaceOperation {
                Path = pointer, Value = "Eric"
            });

            new JsonPatcher().Patch(ref sample, patchDocument);

            string newPointer = "/books/1/author";

            Assert.Equal("Eric", sample.SelectPatchToken(newPointer).Value <string>());

            newPointer = "/books/2/author";
            Assert.Equal("Eric", sample.SelectPatchToken(newPointer).Value <string>());
        }
Пример #5
0
 public DocumentDatabase(string name, RavenConfiguration configuration, ServerStore serverStore)
 {
     StartTime                 = SystemTime.UtcNow;
     Name                      = name;
     ResourceName              = "db/" + name;
     Configuration             = configuration;
     _logger                   = LoggingSource.Instance.GetLogger <DocumentDatabase>(Name);
     Notifications             = new DocumentsNotifications();
     DocumentsStorage          = new DocumentsStorage(this);
     IndexStore                = new IndexStore(this);
     TransformerStore          = new TransformerStore(this);
     SqlReplicationLoader      = new SqlReplicationLoader(this);
     DocumentReplicationLoader = new DocumentReplicationLoader(this);
     DocumentTombstoneCleaner  = new DocumentTombstoneCleaner(this);
     SubscriptionStorage       = new SubscriptionStorage(this);
     Operations                = new DatabaseOperations(this);
     Metrics                   = new MetricsCountersManager();
     IoMetrics                 = serverStore?.IoMetrics ?? new IoMetrics(256, 256);
     Patch                     = new PatchDocument(this);
     TxMerger                  = new TransactionOperationsMerger(this, DatabaseShutdown);
     HugeDocuments             = new HugeDocuments(configuration.Databases.MaxCollectionSizeHugeDocuments,
                                                   configuration.Databases.MaxWarnSizeHugeDocuments);
     ConfigurationStorage = new ConfigurationStorage(this, serverStore);
     DatabaseInfoCache    = serverStore?.DatabaseInfoCache;
 }
Пример #6
0
        public void Insert_array_elements()
        {
            var sample = PatchTests.GetSample2();

            var patchDocument = new PatchDocument();
            var pointer       = new JsonPointer("/books/0");

            patchDocument.AddOperation(new AddEachOperation()
            {
                Path  = pointer,
                Value = new JArray()
                {
                    new JObject(new[] { new JProperty("author", "James Brown") }),
                    new JObject(new[] { new JProperty("cat", "Garfield") }),
                    new JObject(new[] { new JProperty("producer", "Kingston") }),
                }
            });

            patchDocument.ApplyTo(sample);

            var list = sample["books"] as JArray;

            Assert.Equal(5, list.Count);
            Assert.Equal(list[0]["author"].ToString(), "James Brown");
            Assert.Equal(list[1]["cat"].ToString(), "Garfield");
            Assert.Equal(list[2]["producer"].ToString(), "Kingston");
        }
Пример #7
0
        public void Remove_an_array_element_with_numbered_custom_fields()
        {
            var sample = JToken.Parse(@"{
    'data': {
        '2017PropertyOne' : '2017 property one value',
        '2017PropertyTwo' : '2017 property two value',
        '2017Properties' : ['First value from 2017','Second value from 2017'],
        '2018PropertyOne' : '2018 property value',
        '2018PropertyTwo' : '2018 property two value',
        '2018Properties' : ['First value from 2018','Second value from 2018']
    }
}");

            Assert.NotNull(sample.SelectPatchToken("/data/2017Properties/1"));

            var    patchDocument = new PatchDocument();
            string pointer       = "/data/2017Properties/0";

            patchDocument.AddOperation(new RemoveOperation {
                Path = pointer
            });

            var patcher = new JsonPatcher();

            patcher.Patch(ref sample, patchDocument);

            Assert.Null(sample.SelectPatchToken("/data/2017Properties/1"));
        }
Пример #8
0
 public virtual void Patch(ref TDoc target, PatchDocument document)
 {
     foreach (var operation in document.Operations)
     {
         target = ApplyOperation(operation, target);
     }
 }
Пример #9
0
        public void Remove_array_item_by_matching()
        {
            var sample = JToken.Parse(@"{
    'books': [
        {
          'title' : 'The Great Gatsby',
          'author' : 'F. Scott Fitzgerald'
        },
        {
          'title' : 'The Grapes of Wrath',
          'author' : 'John Steinbeck'
        },
        {
          'title' : 'Some Other Title',
          'author' : 'John Steinbeck'
        }
    ]
}");

            var    patchDocument = new PatchDocument();
            string pointer       = "$.books[?(@.author == 'John Steinbeck')]";

            patchDocument.AddOperation(new RemoveOperation {
                Path = pointer
            });

            new JsonPatcher().Patch(ref sample, patchDocument);

            var list = sample["books"] as JArray;

            Assert.Single(list);
        }
Пример #10
0
        public void LoadPatch1()
        {
            var patchDoc =
                PatchDocument.Load(this.GetType()
                                   .Assembly.GetManifestResourceStream(this.GetType(), "Samples.LoadTest1.json"));

            Assert.NotNull(patchDoc);
            Assert.Equal(6, patchDoc.Operations.Count);
        }
Пример #11
0
        public static PatchDocument PrependOperationPaths(this PatchDocument patchDocument, string pathToAppend)
        {
            foreach (var operation in patchDocument.Operations)
            {
                var oldPath = operation.Path.ToString();
                operation.Path = new JsonPointer($"{pathToAppend}{oldPath}");
            }

            return(patchDocument);
        }
Пример #12
0
        public void CreateEmptyPatch()
        {
            var sample     = GetSample2();
            var sampletext = sample.ToString();

            var patchDocument = new PatchDocument();

            new JsonPatcher().Patch(ref sample, patchDocument);

            Assert.AreEqual(sampletext, sample.ToString());
        }
Пример #13
0
        public void LoadPatch1()
        {
            var names = this.GetType()
                        .Assembly.GetManifestResourceNames();
            var patchDoc =
                PatchDocument.Load(this.GetType()
                                   .Assembly.GetManifestResourceStream("JsonDiffPatch.Tests.Samples.LoadTest1.json"));

            Assert.NotNull(patchDoc);
            Assert.AreEqual(6, patchDoc.Operations.Count);
        }
Пример #14
0
        public void CreateEmptyPatch()
        {
            var sample     = GetSample2();
            var sampletext = sample.ToString();

            var patchDocument = new PatchDocument();

            patchDocument.ApplyTo(new JsonNetTargetAdapter(sample));

            Assert.Equal(sampletext, sample.ToString());
        }
Пример #15
0
        public void Replace_non_existant_property()
        {
            var sample = JToken.Parse(@"{ ""data"": {} }");

            var patchDocument = new PatchDocument();
            var pointer       = "/data/author";

            patchDocument.AddOperation(new ReplaceOperation {
                Path = pointer, Value = "Bob Brown"
            });

            new JsonPatcher().Patch(ref sample, patchDocument);

            Assert.Equal("Bob Brown", sample.SelectPatchToken(pointer).Value <string>());

            sample = JToken.Parse(@"{}");

            patchDocument = new PatchDocument();
            pointer       = "/data/author";

            patchDocument.AddOperation(new ReplaceOperation {
                Path = pointer, Value = "Bob Brown"
            });

            new JsonPatcher().Patch(ref sample, patchDocument);

            Assert.Equal("Bob Brown", sample.SelectPatchToken(pointer).Value <string>());

            sample = JToken.Parse(@"{}");

            patchDocument = new PatchDocument();
            pointer       = "/";

            patchDocument.AddOperation(new ReplaceOperation {
                Path = pointer, Value = "Bob Brown"
            });

            new JsonPatcher().Patch(ref sample, patchDocument);

            Assert.Equal("Bob Brown", sample.SelectPatchToken(pointer).Value <string>());

            sample = JToken.Parse(@"{}");

            patchDocument = new PatchDocument();
            pointer       = "/hey/now/0/you";

            patchDocument.AddOperation(new ReplaceOperation {
                Path = pointer, Value = "Bob Brown"
            });

            new JsonPatcher().Patch(ref sample, patchDocument);

            Assert.Equal("{}", sample.ToString(Formatting.None));
        }
Пример #16
0
        /// <summary>
        /// Removes the relation for the given <paramref name="relationId"/>.
        /// </summary>
        /// <param name="relationId">The relation identifier.</param>
        /// <returns></returns>
        public virtual UpdateWorkItemPatchDocumentBuilder RemoveRelation(int relationId)
        {
            PatchDocument.Add(
                new JsonPatchOperation()
            {
                Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Remove,
                Path      = "/relations/" + relationId
            }
                );

            return(this);
        }
        protected override void ProcessRecord()
        {
            var patchDoc = new PatchDocument(Op, Path, Value);

            patchDoc.Op    = this.Op;
            patchDoc.Path  = this.Path;
            patchDoc.Value = this.Value;
            if (!string.IsNullOrEmpty(From))
            {
                patchDoc.From = From;
            }
            WriteObject(patchDoc);
        }
Пример #18
0
        public string JsonPatchesWorks(string leftString, string patchString)
        {
            var left     = JToken.Parse(leftString);
            var patchDoc = PatchDocument.Parse(patchString);
            var patcher  = new JsonPatcher();

            patcher.Patch(ref left, patchDoc);


            var patchJson = left.ToString(Formatting.None);

            return(patchJson);
        }
Пример #19
0
        public async Task JsonPatch()
        {
            var employee = await _employeeRepository.AddAsync(EmployeeGenerator.Default);

            var patch = new PatchDocument(new ReplaceOperation {
                Path = "name", Value = "Patched"
            });
            await _employeeRepository.PatchAsync(employee.Id, patch);

            employee = await _employeeRepository.GetByIdAsync(employee.Id);

            Assert.Equal("Patched", employee.Name);
            Assert.Equal(2, employee.Version);
        }
Пример #20
0
        public void TestExample1()
        {
            var targetDoc = JToken.Parse("{ 'foo': 'bar'}");
            var patchDoc  = PatchDocument.Parse(@"[
                                                    { 'op': 'add', 'path': '/baz', 'value': 'qux' }
                                                ]");

            new JsonPatcher().Patch(ref targetDoc, patchDoc);

            Assert.True(JToken.DeepEquals(JToken.Parse(@"{
                                                             'foo': 'bar',
                                                             'baz': 'qux'
                                                           }"), targetDoc));
        }
Пример #21
0
        public IPatchDocumentBuilder AppendAddFieldOperation(string fieldPath, object fieldValue)
        {
            var formattedPath = @"/fields/" + fieldPath;

            var patchDocument = new PatchDocument
            {
                Op    = PatchDocumentOperationType.Add,
                Path  = formattedPath,
                Value = fieldValue.ToString()
            };

            _patchDocuments.Add(patchDocument);
            return(this);
        }
Пример #22
0
        public void Remove_a_property()
        {
            var sample = GetSample2();

            var patchDocument = new PatchDocument();
            var pointer       = "/books/0/author";

            patchDocument.AddOperation(new RemoveOperation {
                Path = pointer
            });

            new JsonPatcher().Patch(ref sample, patchDocument);

            Assert.Null(sample.SelectPatchToken(pointer));
        }
Пример #23
0
        public void Replace_a_property_value_with_a_new_value()
        {
            var sample = PatchTests.GetSample2();

            var patchDocument = new PatchDocument();
            var pointer       = "/books/0/author";

            patchDocument.AddOperation(new ReplaceOperation {
                Path = pointer, Value = "Bob Brown"
            });

            new JsonPatcher().Patch(ref sample, patchDocument);

            Assert.Equal("Bob Brown", sample.SelectPatchToken(pointer).Value <string>());
        }
Пример #24
0
        public void Replace_a_property_value_with_a_new_value()
        {
            var sample = PatchTests.GetSample2();

            var patchDocument = new PatchDocument();
            var pointer       = new JsonPointer("/books/0/author");

            patchDocument.AddOperation(new ReplaceOperation()
            {
                Path = pointer, Value = new JValue("Bob Brown")
            });

            patchDocument.ApplyTo(new JsonNetTargetAdapter(sample));

            Assert.Equal("Bob Brown", (string)pointer.Find(sample));
        }
Пример #25
0
        public void Remove_a_property()
        {
            var sample = PatchTests.GetSample2();

            var patchDocument = new PatchDocument();
            var pointer       = new JsonPointer("/books/0/author");

            patchDocument.AddOperation(new RemoveOperation()
            {
                Path = pointer
            });

            patchDocument.ApplyTo(sample);

            Assert.Throws(typeof(ArgumentException), () => { pointer.Find(sample); });
        }
Пример #26
0
        public void Test_a_value()
        {
            var sample = PatchTests.GetSample2();

            var patchDocument = new PatchDocument();
            var pointer       = "/books/0/author";

            patchDocument.AddOperation(new TestOperation {
                Path = pointer, Value = new JValue("Billy Burton")
            });

            Assert.Throws(typeof(InvalidOperationException), () => {
                var patcher = new JsonPatcher();
                patcher.Patch(ref sample, patchDocument);
            });
        }
Пример #27
0
        public void Remove_an_array_element()
        {
            var sample = GetSample2();

            var patchDocument = new PatchDocument();
            var pointer       = "/books/0";

            patchDocument.AddOperation(new RemoveOperation {
                Path = pointer
            });

            var patcher = new JsonPatcher();

            patcher.Patch(ref sample, patchDocument);

            Assert.Null(sample.SelectPatchToken("/books/1"));
        }
Пример #28
0
        public void Append_array_elements_wrongDataType()
        {
            var sample = PatchTests.GetSample2();

            var patchDocument = new PatchDocument();
            var pointer       = new JsonPointer("/books/");

            patchDocument.AddOperation(new AddEachOperation()
            {
                Path  = pointer,
                Value = new JObject(new[] { new JProperty("producer", "Kingston") })
            });

            Assert.Throws(typeof(ArgumentException), () => {
                patchDocument.ApplyTo(sample);
            });
        }
        public virtual async Task <IHttpActionResult> PatchAsync(string id, PatchDocument changes, long?version = null)
        {
            TModel original = await GetModel(id, false);

            if (original == null)
            {
                return(NotFound());
            }

            // if there are no changes in the delta, then ignore the request
            if (changes == null || !changes.Operations.Any())
            {
                return(await OkModel(original));
            }

            var modified = original.Copy();

            if (version.HasValue && _isVersioned)
            {
                ((IVersioned)modified).Version = version.Value;
            }

            // map to update model first so we can restrict what is allowed to be modified
            var updateModel = await Map <TUpdateModel>(modified);

            // Supports either JsonPatch or JSONPath syntax: http://goessner.net/articles/JsonPath/
            var target = JToken.FromObject(updateModel, JsonHelper.DefaultSerializer);

            new JsonPatcher().Patch(ref target, changes);
            updateModel = target.ToObject <TUpdateModel>(JsonHelper.DefaultSerializer);

            await Map(updateModel, modified);

            var permission = await CanUpdateAsync(original, modified);

            if (!permission.Allowed)
            {
                return(Permission(permission));
            }

            modified = await UpdateModelAsync(modified, version);

            modified = await AfterUpdateAsync(modified, original);

            return(await OkModel(modified));
        }
Пример #30
0
        public void Replace_a_property_value_with_an_object()
        {
            var sample = PatchTests.GetSample2();

            var patchDocument = new PatchDocument();
            var pointer       = "/books/0/author";

            patchDocument.AddOperation(new ReplaceOperation {
                Path = pointer, Value = new JObject(new[] { new JProperty("hello", "world") })
            });

            new JsonPatcher().Patch(ref sample, patchDocument);

            var newPointer = "/books/0/author/hello";

            Assert.Equal("world", sample.SelectPatchToken(newPointer).Value <string>());
        }