Esempio n. 1
1
		private void ModifyValue(PatchRequest patchCmd, string propName, JProperty property)
        {
			EnsurePreviousValueMatchCurrentValue(patchCmd, property);
            if (property == null)
                throw new InvalidOperationException("Cannot modify value from  '" + propName + "' because it was not found");

            var nestedCommands = patchCmd.Nested;
            if (nestedCommands == null)
                throw new InvalidOperationException("Cannot understand modified value from  '" + propName +
                                                    "' because could not find nested array of commands");
            
            switch (property.Value.Type)
            {
                case JTokenType.Object:
                    foreach (var cmd in nestedCommands)
                    {
                        var nestedDoc = property.Value.Value<JObject>();
						new JsonPatcher(nestedDoc).Apply(cmd);
                    }
                    break;
                case JTokenType.Array:
					var position = patchCmd.Position;
					if (position == null)
                         throw new InvalidOperationException("Cannot modify value from  '" + propName +
                                                             "' because position element does not exists or not an integer");
                    var value = property.Value.Value<JArray>()[position];
					foreach (var cmd in nestedCommands)
					{
                    	new JsonPatcher(value.Value<JObject>()).Apply(cmd);
                    }
            		break;
                default:
                    throw new InvalidOperationException("Can't understand how to deal with: " + property.Value.Type);
            }
        }
Esempio n. 2
0
        public void CanConvertToAndFromJsonWithNestedPatchRequests()
        {
            var patch = new PatchRequest
                            {
                                Name = "Comments",
                                Type = PatchCommandType.Modify,
                                Position = 0,
                                Nested = new[]
                                             {
                                                 new PatchRequest
                                                     {
                                                         Name = "AuthorId",
                                                         Type = PatchCommandType.Set,
                                                         Value = "authors/456"
                                                     },
                                                    new PatchRequest
                                                     {
                                                         Name = "AuthorName",
                                                         Type = PatchCommandType.Set,
                                                         Value = "Tolkien"
                                                     },
                                             }
                            };

            var jsonPatch = patch.ToJson();
            var backToPatch = PatchRequest.FromJson(jsonPatch);
            Assert.Equal(patch.Name, backToPatch.Name);
            Assert.Equal(patch.Nested.Length, backToPatch.Nested.Length);

        }
Esempio n. 3
0
		private void CopyProperty(PatchRequest patchCmd, string propName, JProperty property)
    	{
			EnsurePreviousValueMatchCurrentValue(patchCmd, property);
			if (property == null)
				throw new InvalidOperationException("Cannot copy value from  '" + propName + "' because it was not found");

			document[patchCmd.Value.Value<string>()] = property.Value;
    	}
Esempio n. 4
0
 public JObject Apply(PatchRequest[] patch)
 {
     foreach (var patchCmd in patch)
     {
         Apply(patchCmd);
     }
     return document;
 }
		public JArray UpdateByIndex(string indexName, IndexQuery queryToUpdate, PatchRequest[] patchRequests, bool allowStale)
		{
			return PerformBulkOperation(indexName, queryToUpdate, allowStale, (docId, tx) =>
			{
				var patchResult = database.ApplyPatch(docId, null, patchRequests, tx);
				return new { Document = docId, Result = patchResult };
			});
		}
Esempio n. 6
0
		private void RenameProperty(PatchRequest patchCmd, string propName, JProperty property)
		{
			EnsurePreviousValueMatchCurrentValue(patchCmd, property);
			if (property == null)
				return;

			document[patchCmd.Value.Value<string>()] = property.Value;
			document.Remove(propName);
		}
Esempio n. 7
0
 private void AddProperty(PatchRequest patchCmd, string propName, JProperty property)
 {
     EnsurePreviousValueMatchCurrentValue(patchCmd, property);
     if (property == null)
     {
         property = new JProperty(propName);
         document.Add(property);
     }
     property.Value = patchCmd.Value;
 }
Esempio n. 8
0
        private void AddValue(PatchRequest patchCmd, string propName, JProperty property)
        {
            EnsurePreviousValueMatchCurrentValue(patchCmd, property);
            if (property == null)
            {
                property = new JProperty(propName, new JArray());
                document.Add(property);
            }
            var array = property.Value as JArray;
            if (array == null)
                throw new InvalidOperationException("Cannot insert value to '" + propName + "' because it is not an array");

            array.Add(patchCmd.Value);
        }
Esempio n. 9
0
        private void AddValue(PatchRequest patchCmd, string propName, RavenJToken token)
        {
            EnsurePreviousValueMatchCurrentValue(patchCmd, token);
            if (token == null)
            {
                token = new RavenJArray();
                document[propName] = token;
            }
            var array = GetArray(token, propName);

            array = new RavenJArray(array);
            document[propName] = array;
            array.Add(patchCmd.Value);
        }
Esempio n. 10
0
        public void CanConvertToAndFromJsonWithEmptyNestedPatchRequests()
        {
            var patch = new PatchRequest
                            {
                                Name = "Comments",
                                Type = PatchCommandType.Modify,
                                Position = 0,
                                Nested = new PatchRequest[] { }
                            };

            var jsonPatch = patch.ToJson();
            var backToPatch = PatchRequest.FromJson(jsonPatch);
            Assert.Equal(patch.Name, backToPatch.Name);
            Assert.Equal(patch.Nested.Length, backToPatch.Nested.Length);
        }
Esempio n. 11
0
        private void RemoveValue(PatchRequest patchCmd, string propName, RavenJToken token)
        {
            EnsurePreviousValueMatchCurrentValue(patchCmd, token);
            if (token == null)
            {
                token = new RavenJArray();
                document[propName] = token;
            }
            var array = GetArray(token, propName);

            if (array.IsSnapshot)
            {
                array = new RavenJArray(array);
                document[propName] = array;
            }

            var position = patchCmd.Position;
            var value    = patchCmd.Value;

            if (position == null && (value == null || value.Type == JTokenType.Null))
            {
                throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because position element does not exists or not an integer and no value was present");
            }
            if (position != null && value != null && value.Type != JTokenType.Null)
            {
                throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because both a position and a value are set");
            }
            if (position != null && (position.Value < 0 || position.Value >= array.Length))
            {
                throw new IndexOutOfRangeException("Cannot remove value from  '" + propName +
                                                   "' because position element is out of bound bounds");
            }

            if (value != null && value.Type != JTokenType.Null)
            {
                foreach (var ravenJToken in array.Where(x => RavenJToken.DeepEquals(x, value)).ToList())
                {
                    array.Remove(ravenJToken);
                }

                return;
            }

            if (position != null)
            {
                array.RemoveAt(position.Value);
            }
        }
Esempio n. 12
0
        private void ModifyValue(PatchRequest patchCmd, string propName)
        {
            var property = document.Property(propName);

            EnsurePreviousValueMatchCurrentValue(patchCmd, property);
            if (property == null)
            {
                throw new InvalidOperationException("Cannot modify value from  '" + propName + "' because it was not found");
            }

            var nestedCommands = patchCmd.Nested;

            if (nestedCommands == null)
            {
                throw new InvalidOperationException("Cannot understand modified value from  '" + propName +
                                                    "' because could not find nested array of commands");
            }

            switch (property.Value.Type)
            {
            case JTokenType.Object:
                foreach (var cmd in nestedCommands)
                {
                    var nestedDoc = property.Value.Value <JObject>();
                    new JsonPatcher(nestedDoc).Apply(cmd);
                }
                break;

            case JTokenType.Array:
                var position = patchCmd.Position;
                if (position == null)
                {
                    throw new InvalidOperationException("Cannot modify value from  '" + propName +
                                                        "' because position element does not exists or not an integer");
                }
                var value = property.Value.Value <JArray>()[position];
                foreach (var cmd in nestedCommands)
                {
                    new JsonPatcher(value.Value <JObject>()).Apply(cmd);
                }
                break;

            default:
                throw new InvalidOperationException("Can't understand how to deal with: " + property.Value.Type);
            }
        }
Esempio n. 13
0
        private void AddValue(PatchRequest patchCmd, string propName, JProperty property)
        {
            EnsurePreviousValueMatchCurrentValue(patchCmd, property);
            if (property == null)
            {
                property = new JProperty(propName, new JArray());
                document.Add(property);
            }
            var array = property.Value as JArray;

            if (array == null)
            {
                throw new InvalidOperationException("Cannot insert value to '" + propName + "' because it is not an array");
            }

            array.Add(patchCmd.Value);
        }
Esempio n. 14
0
        private void RemoveValue(PatchRequest patchCmd, string propName, RavenJToken token)
        {
            EnsurePreviousValueMatchCurrentValue(patchCmd, token);
            if (token == null)
            {
                token = new RavenJArray();
                document[propName] = token;
            }
            var array = GetArray(token, propName);

            var position = patchCmd.Position;
            var value    = patchCmd.Value;

            if (position == null && (value == null || value.Type == JTokenType.Null))
            {
                throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because position element does not exists or not an integer and no value was present");
            }
            if (position != null && value != null && value.Type != JTokenType.Null)
            {
                throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because both a position and a value are set");
            }
            if (position != null && (position.Value < 0 || position.Value >= array.Length))
            {
                throw new IndexOutOfRangeException("Cannot remove value from  '" + propName +
                                                   "' because position element is out of bound bounds");
            }

            if (value != null && value.Type != JTokenType.Null)
            {
                var equalityComparer = new RavenJTokenEqualityComparer();
                var singleOrDefault  = array.FirstOrDefault(x => equalityComparer.Equals(x, value));
                if (singleOrDefault == null)
                {
                    return;
                }
                array.Remove(singleOrDefault);
                return;
            }

            if (position != null)
            {
                array.RemoveAt(position.Value);
            }
        }
Esempio n. 15
0
        private void Apply(PatchRequest patchCmd)
        {
            if (patchCmd.Type == null)
            {
                throw new InvalidOperationException("Patch property must have a type property");
            }
            if (patchCmd.Name == null)
            {
                throw new InvalidOperationException("Patch property must have a name property");
            }
            switch (patchCmd.Type.ToLowerInvariant())
            {
            case "set":
                AddProperty(patchCmd, patchCmd.Name);
                break;

            case "unset":
                RemoveProperty(patchCmd, patchCmd.Name);
                break;

            case "add":
                AddValue(patchCmd, patchCmd.Name);
                break;

            case "insert":
                InsertValue(patchCmd, patchCmd.Name);
                break;

            case "remove":
                RemoveValue(patchCmd, patchCmd.Name);
                break;

            case "modify":
                ModifyValue(patchCmd, patchCmd.Name);
                break;

            case "inc":
                IncrementProperty(patchCmd, patchCmd.Name);
                break;

            default:
                throw new ArgumentException("Cannot understand command: " + patchCmd.Type);
            }
        }
Esempio n. 16
0
        private void RemoveValue(PatchRequest patchCmd, string propName, JProperty property)
        {
            EnsurePreviousValueMatchCurrentValue(patchCmd, property);
            if (property == null)
            {
                property = new JProperty(propName, new JArray());
                document.Add(property);
            }
            var array = property.Value as JArray;

            if (array == null)
            {
                throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because it is not an array");
            }
            var position = patchCmd.Position;
            var value    = patchCmd.Value;

            if (position == null && value == null)
            {
                throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because position element does not exists or not an integer and no value was present");
            }
            if (position != null && value != null)
            {
                throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because both a position and a value are set");
            }
            if (position < 0 || position >= array.Count)
            {
                throw new IndexOutOfRangeException("Cannot remove value from  '" + propName +
                                                   "' because position element is out of bound bounds");
            }

            if (value != null)
            {
                var equalityComparer = new JTokenEqualityComparer();
                var singleOrDefault  = array.FirstOrDefault(x => equalityComparer.Equals(x, value));
                if (singleOrDefault == null)
                {
                    return;
                }
                array.Remove(singleOrDefault);
                return;
            }
            array.RemoveAt(position.Value);
        }
Esempio n. 17
0
		private void Apply(PatchRequest patchCmd)
		{
			if (patchCmd.Name == null)
				throw new InvalidOperationException("Patch property must have a name property");
			foreach (var token in document.SelectTokenWithRavenSyntaxReturningFlatStructure( patchCmd.Name ))
			{
				JProperty property = null;
				if (token != null)
					property = token.Parent as JProperty;
				switch (patchCmd.Type)
				{
					case PatchCommandType.Set:
						AddProperty(patchCmd, patchCmd.Name, property);
						break;
					case PatchCommandType.Unset:
						RemoveProperty(patchCmd, patchCmd.Name, property);
						break;
					case PatchCommandType.Add:
						AddValue(patchCmd, patchCmd.Name, property);
						break;
					case PatchCommandType.Insert:
						InsertValue(patchCmd, patchCmd.Name, property);
						break;
					case PatchCommandType.Remove:
						RemoveValue(patchCmd, patchCmd.Name, property);
						break;
					case PatchCommandType.Modify:
						ModifyValue(patchCmd, patchCmd.Name, property);
						break;
					case PatchCommandType.Inc:
						IncrementProperty(patchCmd, patchCmd.Name, property);
						break;
					case PatchCommandType.Copy:
						CopyProperty(patchCmd, patchCmd.Name, property);
						break;
					case PatchCommandType.Rename:
						RenameProperty(patchCmd, patchCmd.Name, property);
						break;
					default:
						throw new ArgumentException("Cannot understand command: " + patchCmd.Type);
				}
			}
		}
Esempio n. 18
0
 private static void EnsurePreviousValueMatchCurrentValue(PatchRequest patchCmd, JProperty property)
 {
     var prevVal = patchCmd.PrevVal;
     if (prevVal == null)
         return;
     switch (prevVal.Type)
     {
         case JTokenType.Undefined:
             if (property != null)
                 throw new ConcurrencyException();
             break;
         default:
             if(property == null)
                 throw new ConcurrencyException();
             var equalityComparer = new JTokenEqualityComparer();
             if (equalityComparer.Equals(property.Value, prevVal) == false)
                 throw new ConcurrencyException();
             break;
     }
 }
Esempio n. 19
0
 private void IncrementProperty(PatchRequest patchCmd, string propName, JProperty property)
 {
     if (patchCmd.Value.Type != JTokenType.Integer)
     {
         throw new InvalidOperationException("Cannot increment when value is not an integer");
     }
     EnsurePreviousValueMatchCurrentValue(patchCmd, property);
     if (property == null)
     {
         property = new JProperty(propName, patchCmd.Value);
         document.Add(property);
         return;
     }
     if (property.Value == null || property.Value.Type == JTokenType.Null)
     {
         property.Value = patchCmd.Value;
     }
     else
     {
         property.Value = JToken.FromObject(property.Value.Value <int>() + patchCmd.Value.Value <int>());
     }
 }
Esempio n. 20
0
        private void Apply(PatchRequest patchCmd)
        {
            if (patchCmd.Type == null)
                throw new InvalidOperationException("Patch property must have a type property");
            if (patchCmd.Name == null)
                throw new InvalidOperationException("Patch property must have a name property");
        	var token = document.SelectToken(patchCmd.Name);
        	JProperty property = null;
			if (token != null)
				property = token.Parent as JProperty;
        	switch (patchCmd.Type.ToLowerInvariant())
            {
                case "set":
					AddProperty(patchCmd, patchCmd.Name, property);
                    break;
                case "unset":
					RemoveProperty(patchCmd, patchCmd.Name, property);
                    break;
                case "add":
					AddValue(patchCmd, patchCmd.Name, property);
                    break;
                case "insert":
					InsertValue(patchCmd, patchCmd.Name, property);
                    break;
                case "remove":
					RemoveValue(patchCmd, patchCmd.Name, property);
                    break;
                case "modify":
					ModifyValue(patchCmd, patchCmd.Name, property);
                    break;
                case "inc":
					IncrementProperty(patchCmd, patchCmd.Name, property);
                    break;
                default:
					throw new ArgumentException("Cannot understand command: " + patchCmd.Type);
            }
        }
Esempio n. 21
0
 private void RemoveValue(PatchRequest patchCmd, string propName)
 {
     var property = document.Property(propName);
     EnsurePreviousValueMatchCurrentValue(patchCmd, property);
     if (property == null)
     {
         property = new JProperty(propName, new JArray());
         document.Add(property);
     }
     var array = property.Value as JArray;
     if (array == null)
         throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because it is not an array");
     var position = patchCmd.Position;
     if (position == null)
         throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because position element does not exists or not an integer");
     if (position < 0 || position >= array.Count)
         throw new IndexOutOfRangeException("Cannot remove value from  '" + propName +
                                            "' because position element is out of bound bounds");
     array.RemoveAt(position.Value);
 }
Esempio n. 22
0
 private void RemoveProperty(PatchRequest patchCmd, string propName)
 {
     var property = document.Property(propName);
     EnsurePreviousValueMatchCurrentValue(patchCmd, property);
     EnsurePreviousValueMatchCurrentValue(patchCmd, property);
     if (property != null)
         property.Remove();
 }
Esempio n. 23
0
 private void IncrementProperty(PatchRequest patchCmd, string propName)
 {
     if(patchCmd.Value.Type != JTokenType.Integer)
         throw new InvalidOperationException("Cannot increment when value is not an integer");
     var property = document.Property(propName);
     EnsurePreviousValueMatchCurrentValue(patchCmd, property);
     if (property == null)
     {
         property = new JProperty(propName);
         document.Add(property);
     }
     if (property.Value == null || property.Value.Type == JTokenType.Null)
         property.Value = patchCmd.Value;
     else
         property.Value = JToken.FromObject(property.Value.Value<int>() + patchCmd.Value.Value<int>());
 }
Esempio n. 24
0
 private void SetProperty(PatchRequest patchCmd, string propName, RavenJToken property)
 {
     EnsurePreviousValueMatchCurrentValue(patchCmd, property);
     document[propName] = patchCmd.Value;
 }
Esempio n. 25
0
		private void RemoveProperty(PatchRequest patchCmd, string propName, JProperty property)
        {
			EnsurePreviousValueMatchCurrentValue(patchCmd, property);
            EnsurePreviousValueMatchCurrentValue(patchCmd, property);
            if (property != null)
                property.Remove();
        }
Esempio n. 26
0
		private void RemoveValue(PatchRequest patchCmd, string propName, JProperty property)
		{
			EnsurePreviousValueMatchCurrentValue(patchCmd, property);
			if (property == null)
			{
				property = new JProperty(propName, new JArray());
				document.Add(property);
			}
			var array = GetArray(property, propName);

			var position = patchCmd.Position;
			var value = patchCmd.Value;
			if (position == null && value == null)
				throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because position element does not exists or not an integer and no value was present");
			if (position != null && value != null)
				throw new InvalidOperationException("Cannot remove value from  '" + propName + "' because both a position and a value are set");
			if (position < 0 || position >= array.Count)
				throw new IndexOutOfRangeException("Cannot remove value from  '" + propName +
												   "' because position element is out of bound bounds");

			if (value != null)
			{
				var equalityComparer = new JTokenEqualityComparer();
				var singleOrDefault = array.FirstOrDefault(x => equalityComparer.Equals(x, value));
				if (singleOrDefault == null)
					return;
				array.Remove(singleOrDefault);
				return;
			}
			array.RemoveAt(position.Value);

		}
Esempio n. 27
0
		private void ModifyValue(PatchRequest patchCmd, string propName, JProperty property)
		{
			EnsurePreviousValueMatchCurrentValue(patchCmd, property);
			if (property == null)
				throw new InvalidOperationException("Cannot modify value from  '" + propName + "' because it was not found");

			var nestedCommands = patchCmd.Nested;
			if (nestedCommands == null)
				throw new InvalidOperationException("Cannot understand modified value from  '" + propName +
													"' because could not find nested array of commands");

			var arrayOrValue = TryGetArray(property) ?? property.Value;
			switch (arrayOrValue.Type)
			{
				case JTokenType.Object:
					foreach (var cmd in nestedCommands)
					{
						var nestedDoc = property.Value.Value<JObject>();
						new JsonPatcher(nestedDoc).Apply(cmd);
					}
					break;
				case JTokenType.Array:
					var position = patchCmd.Position;
					var allPositionsIsSelected = patchCmd.AllPositions.HasValue ? patchCmd.AllPositions.Value : false;
					if (position == null && !allPositionsIsSelected)
						throw new InvalidOperationException("Cannot modify value from  '" + propName +
						                                    "' because position element does not exists or not an integer and allPositions is not set");
					var valueList = new List<JToken>();
					if (allPositionsIsSelected)
					{
						valueList.AddRange(arrayOrValue);
					}
					else
					{
						valueList.Add(arrayOrValue[position]);
					}

					foreach (var value in valueList)
					{
						foreach (var cmd in nestedCommands)
						{
							new JsonPatcher(value.Value<JObject>()).Apply(cmd);
						}
					}
					break;
				default:
					throw new InvalidOperationException("Can't understand how to deal with: " + property.Value.Type);
			}
		}
Esempio n. 28
0
		public PatchResult ApplyPatch(string docId, Guid? etag, PatchRequest[] patchDoc, TransactionInformation transactionInformation)
		{
			var result = PatchResult.Patched;
			TransactionalStorage.Batch(actions =>
			{
				var doc = actions.Documents.DocumentByKey(docId, transactionInformation);
				if (doc == null)
				{
					result = PatchResult.DocumentDoesNotExists;
				}
				else if (etag != null && doc.Etag != etag.Value)
				{
					throw new ConcurrencyException("Could not patch document '" + docId+ "' because non current etag was used")
					{
						ActualETag = doc.Etag,
						ExpectedETag = etag.Value,
					};
				}
				else
				{
					var jsonDoc = doc.ToJson();
					new JsonPatcher(jsonDoc).Apply(patchDoc);
					Put(doc.Key, doc.Etag, jsonDoc, doc.Metadata, transactionInformation);
					result = PatchResult.Patched;
				}

				workContext.ShouldNotifyAboutWork();
			});

			return result;
		}
Esempio n. 29
0
		private void AddValue(PatchRequest patchCmd, string propName, JProperty property)
		{
			EnsurePreviousValueMatchCurrentValue(patchCmd, property);
			if (property == null)
			{
				property = new JProperty(propName, new JArray());
				document.Add(property);
			}
			var array = GetArray(property, propName);

			array.Add(patchCmd.Value);
		}