public void CanLoadPutDocumentsMultipleTimesInPatcher() { using (var store = NewDocumentStore()) { using (var s = store.OpenSession()) { s.Store(new OpCounter(), "opCounter"); s.SaveChanges(); } var patcher = new ScriptedJsonPatcher(store.DocumentDatabase); using (var scope = new ScriptedIndexResultsJsonPatcherScope(store.DocumentDatabase, new HashSet <string> { "dogs" })) { patcher.Apply(scope, new RavenJObject(), new ScriptedPatchRequest { Script = @"var opCounterId = 'opCounter'; var opCounter = LoadDocument(opCounterId) || {}; opCounter.Index++; PutDocument(opCounterId, opCounter); opCounter = LoadDocument(opCounterId) opCounter.Deletes++; PutDocument(opCounterId, opCounter); " }); store.DocumentDatabase.TransactionalStorage.Batch(accessor => { foreach (var operation in scope.GetOperations()) { switch (operation.Type) { case ScriptedJsonPatcher.OperationType.Put: store.DocumentDatabase.Documents.Put(operation.Document.Key, operation.Document.Etag, operation.Document.DataAsJson, operation.Document.Metadata, null); break; case ScriptedJsonPatcher.OperationType.Delete: store.DocumentDatabase.Documents.Delete(operation.DocumentKey, null, null); break; default: throw new ArgumentOutOfRangeException("operation.Type"); } } }); } using (var s = store.OpenSession()) { var opCounter = s.Load <OpCounter>("opCounter"); Assert.Equal(1, opCounter.Deletes); Assert.Equal(1, opCounter.Index); } } }
public void ScriptPatchShouldGenerateNiceException() { using (var store = NewDocumentStore()) { using (var session = store.OpenSession()) { session.Store(new SimpleUser { FirstName = "John", LastName = "Smith" }); session.SaveChanges(); } store .DatabaseCommands .Put( Constants.RavenJavascriptFunctions, null, RavenJObject.FromObject(new { Functions = @"exports.a = function(value) { return b(value); }; exports.b = function(v) { return c(v); } exports.c = function(v) { throw 'oops'; } " }), new RavenJObject()); WaitForIndexing(store); var patcher = new ScriptedJsonPatcher(store.SystemDatabase); using (var scope = new ScriptedIndexResultsJsonPatcherScope(store.SystemDatabase, new HashSet <string>())) { var e = Assert.Throws <InvalidOperationException>(() => patcher.Apply(scope, new RavenJObject(), new ScriptedPatchRequest { Script = @"var s = 1234; a(s);" })); Assert.Equal(@"Unable to execute JavaScript: var s = 1234; a(s); Error: oops Stacktrace: [email protected]:3 [email protected]:2 [email protected]:1 [email protected]:2 anonymous [email protected]:1", e.Message); } } }
public void ScriptedIndexResultsPatcherShouldNotPatchDocumentsThatAreIndirectlyReferencedByIndexRaw() { using (var store = NewDocumentStore(activeBundles: "ScriptedIndexResults")) { new CustomerOrderTotal().Execute(store); using (var session = store.OpenSession()) { session.Store(new Customer { Name = "Customer1", StoredTotal = 100, Id = "customers/1" }); session.SaveChanges(); session.Store(new Order { Customers = new List <string> { "customers/1" }, OrderItems = 10 }); session.SaveChanges(); } WaitForIndexing(store); var patcher = new ScriptedJsonPatcher(store.SystemDatabase); using (var scope = new ScriptedIndexResultsJsonPatcherScope(store.SystemDatabase, new HashSet <string> { "Orders" })) { var e = Assert.Throws <InvalidOperationException>(() => patcher.Apply(scope, new RavenJObject(), new ScriptedPatchRequest { Script = @"var customer = LoadDocument('customers/1') if(customer == null) return; if(customer.StoredTotal != this.TotalOrderItems){ customer.StoredTotal = this.TotalOrderItems; PutDocument('customers/1', customer); }" })); Assert.Equal("Cannot PUT document 'customers/1' to prevent infinite indexing loop. Avoid modifying documents that could be indirectly referenced by index.", e.InnerException.Message); } } }