From 9d2f78794a83dae31f4c3a3f744c6b243d22ee98 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Fri, 29 May 2020 15:46:24 +0200 Subject: [PATCH 1/2] updateDocument with different return type --- .../java/com/arangodb/ArangoCollection.java | 17 +++++++++++++++++ .../arangodb/async/ArangoCollectionAsync.java | 19 +++++++++++++++++++ .../internal/ArangoCollectionAsyncImpl.java | 15 +++++++++++---- .../internal/ArangoCollectionImpl.java | 8 +++++++- .../internal/InternalArangoCollection.java | 10 +++++----- .../com/arangodb/ArangoCollectionTest.java | 17 +++++++++++++++++ .../arangodb/async/ArangoCollectionTest.java | 18 ++++++++++++++++++ 7 files changed, 94 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/arangodb/ArangoCollection.java b/src/main/java/com/arangodb/ArangoCollection.java index 25a83511b..47727d4ff 100644 --- a/src/main/java/com/arangodb/ArangoCollection.java +++ b/src/main/java/com/arangodb/ArangoCollection.java @@ -271,6 +271,23 @@ MultiDocumentEntity> replaceDocuments( DocumentUpdateEntity updateDocument(String key, T value, DocumentUpdateOptions options) throws ArangoDBException; + /** + * Partially updates the document identified by document-key. The value must contain a document with the attributes + * to patch (the patch document). All attributes from the patch document will be added to the existing document if + * they do not yet exist, and overwritten in the existing document if they do exist there. + * + * @param key The key of the document + * @param value A representation of a single document (POJO, VPackSlice or String for JSON) + * @param options Additional options, can be null + * @param returnType Type of the returned newDocument and/or oldDocument + * @return information about the document + * @throws ArangoDBException + * @see API + * Documentation + */ + DocumentUpdateEntity updateDocument(String key, T value, DocumentUpdateOptions options, Class returnType) + throws ArangoDBException; + /** * Partially updates documents, the documents to update are specified by the _key attributes in the objects on * values. Vales must contain a list of document updates with the attributes to patch (the patch documents). All diff --git a/src/main/java/com/arangodb/async/ArangoCollectionAsync.java b/src/main/java/com/arangodb/async/ArangoCollectionAsync.java index 3438a6a9a..a0c0d4559 100644 --- a/src/main/java/com/arangodb/async/ArangoCollectionAsync.java +++ b/src/main/java/com/arangodb/async/ArangoCollectionAsync.java @@ -265,6 +265,25 @@ CompletableFuture> updateDocument( final T value, final DocumentUpdateOptions options); + /** + * Partially updates the document identified by document-key. The value must contain a document with the attributes + * to patch (the patch document). All attributes from the patch document will be added to the existing document if + * they do not yet exist, and overwritten in the existing document if they do exist there. + * + * @param key The key of the document + * @param value A representation of a single document (POJO, VPackSlice or String for Json) + * @param options Additional options, can be null + * @param returnType Type of the returned newDocument and/or oldDocument + * @return information about the document + * @see API + * Documentation + */ + CompletableFuture> updateDocument( + final String key, + final T value, + final DocumentUpdateOptions options, + final Class returnType); + /** * Partially updates documents, the documents to update are specified by the _key attributes in the objects on * values. Vales must contain a list of document updates with the attributes to patch (the patch documents). All diff --git a/src/main/java/com/arangodb/async/internal/ArangoCollectionAsyncImpl.java b/src/main/java/com/arangodb/async/internal/ArangoCollectionAsyncImpl.java index 4d5ffcd35..f7ae39536 100644 --- a/src/main/java/com/arangodb/async/internal/ArangoCollectionAsyncImpl.java +++ b/src/main/java/com/arangodb/async/internal/ArangoCollectionAsyncImpl.java @@ -167,9 +167,7 @@ public CompletableFuture>> repla @Override public CompletableFuture> updateDocument(final String key, final T value) { - final DocumentUpdateOptions options = new DocumentUpdateOptions(); - return executor.execute(updateDocumentRequest(key, value, options), - updateDocumentResponseDeserializer(value, options)); + return updateDocument(key, value, new DocumentUpdateOptions()); } @Override @@ -177,8 +175,17 @@ public CompletableFuture> updateDocument( final String key, final T value, final DocumentUpdateOptions options) { + return updateDocument(key, value, options, (Class) value.getClass()); + } + + @Override + public CompletableFuture> updateDocument( + final String key, + final T value, + final DocumentUpdateOptions options, + final Class returnType) { return executor.execute(updateDocumentRequest(key, value, options), - updateDocumentResponseDeserializer(value, options)); + updateDocumentResponseDeserializer(value, options, returnType)); } @Override diff --git a/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java b/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java index 1fd8fddcc..cc06bb467 100644 --- a/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java +++ b/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java @@ -168,8 +168,14 @@ public DocumentUpdateEntity updateDocument(final String key, final T valu @Override public DocumentUpdateEntity updateDocument( final String key, final T value, final DocumentUpdateOptions options) throws ArangoDBException { + return updateDocument(key, value, options, (Class) value.getClass()); + } + + @Override + public DocumentUpdateEntity updateDocument( + final String key, final T value, final DocumentUpdateOptions options, final Class returnType) throws ArangoDBException { return executor.execute(updateDocumentRequest(key, value, options), - updateDocumentResponseDeserializer(value, options)); + updateDocumentResponseDeserializer(value, options, returnType)); } @Override diff --git a/src/main/java/com/arangodb/internal/InternalArangoCollection.java b/src/main/java/com/arangodb/internal/InternalArangoCollection.java index bffa80ee3..e659b1d07 100644 --- a/src/main/java/com/arangodb/internal/InternalArangoCollection.java +++ b/src/main/java/com/arangodb/internal/InternalArangoCollection.java @@ -357,18 +357,18 @@ protected Request updateDocumentRequest(final String key, final T value, fin return request; } - protected ResponseDeserializer> updateDocumentResponseDeserializer( - final T value, final DocumentUpdateOptions options) { + protected ResponseDeserializer> updateDocumentResponseDeserializer( + final T value, final DocumentUpdateOptions options, final Class returnType) { return response -> { final VPackSlice body = response.getBody(); - final DocumentUpdateEntity doc = util().deserialize(body, DocumentUpdateEntity.class); + final DocumentUpdateEntity doc = util().deserialize(body, DocumentUpdateEntity.class); final VPackSlice newDoc = body.get(NEW); if (newDoc.isObject()) { - doc.setNew(util(Serializer.CUSTOM).deserialize(newDoc, value.getClass())); + doc.setNew(util(Serializer.CUSTOM).deserialize(newDoc, returnType)); } final VPackSlice oldDoc = body.get(OLD); if (oldDoc.isObject()) { - doc.setOld(util(Serializer.CUSTOM).deserialize(oldDoc, value.getClass())); + doc.setOld(util(Serializer.CUSTOM).deserialize(oldDoc, returnType)); } if (options == null || Boolean.TRUE != options.getSilent()) { final Map values = new HashMap<>(); diff --git a/src/test/java/com/arangodb/ArangoCollectionTest.java b/src/test/java/com/arangodb/ArangoCollectionTest.java index 081e1bcaa..eedb60974 100644 --- a/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -435,6 +435,23 @@ public void updateDocument() { assertThat(readResult.getProperties().keySet(), hasItem("c")); } + @Test + public void updateDocumentWithDifferentReturnType() { + final String key = "key-" + UUID.randomUUID().toString(); + final BaseDocument doc = new BaseDocument(key); + doc.addAttribute("a", "test"); + collection.insertDocument(doc); + + final DocumentUpdateEntity updateResult = collection + .updateDocument(key, Collections.singletonMap("b", "test"), new DocumentUpdateOptions().returnNew(true), BaseDocument.class); + assertThat(updateResult, is(notNullValue())); + assertThat(updateResult.getKey(), is(key)); + BaseDocument updated = updateResult.getNew(); + assertThat(updated, is(notNullValue())); + assertThat(updated.getAttribute("a"), is("test")); + assertThat(updated.getAttribute("b"), is("test")); + } + @Test public void updateDocumentUpdateRev() { final BaseDocument doc = new BaseDocument(); diff --git a/src/test/java/com/arangodb/async/ArangoCollectionTest.java b/src/test/java/com/arangodb/async/ArangoCollectionTest.java index c52a75035..ed05b072a 100644 --- a/src/test/java/com/arangodb/async/ArangoCollectionTest.java +++ b/src/test/java/com/arangodb/async/ArangoCollectionTest.java @@ -284,6 +284,24 @@ public void updateDocument() throws InterruptedException, ExecutionException { assertThat(readResult.getProperties().keySet(), hasItem("c")); } + @Test + public void updateDocumentWithDifferentReturnType() throws ExecutionException, InterruptedException { + ArangoCollectionAsync collection = db.collection(COLLECTION_NAME); + final String key = "key-" + UUID.randomUUID().toString(); + final BaseDocument doc = new BaseDocument(key); + doc.addAttribute("a", "test"); + collection.insertDocument(doc); + + final DocumentUpdateEntity updateResult = collection + .updateDocument(key, Collections.singletonMap("b", "test"), new DocumentUpdateOptions().returnNew(true), BaseDocument.class).get(); + assertThat(updateResult, is(notNullValue())); + assertThat(updateResult.getKey(), is(key)); + BaseDocument updated = updateResult.getNew(); + assertThat(updated, is(notNullValue())); + assertThat(updated.getAttribute("a"), is("test")); + assertThat(updated.getAttribute("b"), is("test")); + } + @Test public void updateDocumentIfMatch() throws InterruptedException, ExecutionException { final BaseDocument doc = new BaseDocument(); From 8c46d79a18b042c867b4647ce934d7ecd2b1da3b Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Fri, 29 May 2020 16:18:44 +0200 Subject: [PATCH 2/2] updateDocuments with different return type --- .../java/com/arangodb/ArangoCollection.java | 17 +++++++++ .../arangodb/async/ArangoCollectionAsync.java | 18 +++++++++ .../internal/ArangoCollectionAsyncImpl.java | 14 +++++-- .../internal/ArangoCollectionImpl.java | 8 +++- .../internal/InternalArangoCollection.java | 12 ++---- .../com/arangodb/ArangoCollectionTest.java | 30 +++++++++++++++ .../arangodb/async/ArangoCollectionTest.java | 37 ++++++++++++++++++- 7 files changed, 120 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/arangodb/ArangoCollection.java b/src/main/java/com/arangodb/ArangoCollection.java index 47727d4ff..120e24d4c 100644 --- a/src/main/java/com/arangodb/ArangoCollection.java +++ b/src/main/java/com/arangodb/ArangoCollection.java @@ -318,6 +318,23 @@ DocumentUpdateEntity updateDocument(String key, T value, DocumentUpdat MultiDocumentEntity> updateDocuments( Collection values, DocumentUpdateOptions options) throws ArangoDBException; + /** + * Partially updates documents, the documents to update are specified by the _key attributes in the objects on + * values. Vales must contain a list of document updates with the attributes to patch (the patch documents). All + * attributes from the patch documents will be added to the existing documents if they do not yet exist, and + * overwritten in the existing documents if they do exist there. + * + * @param values A list of documents (POJO, VPackSlice or String for JSON) + * @param options Additional options, can be null + * @param returnType Type of the returned newDocument and/or oldDocument + * @return information about the documents + * @throws ArangoDBException + * @see API + * Documentation + */ + MultiDocumentEntity> updateDocuments( + Collection values, DocumentUpdateOptions options, Class returnType) throws ArangoDBException; + /** * Deletes the document with the given {@code key} from the collection. * diff --git a/src/main/java/com/arangodb/async/ArangoCollectionAsync.java b/src/main/java/com/arangodb/async/ArangoCollectionAsync.java index a0c0d4559..dab91f734 100644 --- a/src/main/java/com/arangodb/async/ArangoCollectionAsync.java +++ b/src/main/java/com/arangodb/async/ArangoCollectionAsync.java @@ -313,6 +313,24 @@ CompletableFuture>> updateDocume final Collection values, final DocumentUpdateOptions options); + /** + * Partially updates documents, the documents to update are specified by the _key attributes in the objects on + * values. Vales must contain a list of document updates with the attributes to patch (the patch documents). All + * attributes from the patch documents will be added to the existing documents if they do not yet exist, and + * overwritten in the existing documents if they do exist there. + * + * @param values A list of documents (POJO, VPackSlice or String for Json) + * @param options Additional options, can be null + * @param returnType Type of the returned newDocument and/or oldDocument + * @return information about the documents + * @see API + * Documentation + */ + CompletableFuture>> updateDocuments( + final Collection values, + final DocumentUpdateOptions options, + final Class returnType); + /** * Removes a document * diff --git a/src/main/java/com/arangodb/async/internal/ArangoCollectionAsyncImpl.java b/src/main/java/com/arangodb/async/internal/ArangoCollectionAsyncImpl.java index f7ae39536..33cf69687 100644 --- a/src/main/java/com/arangodb/async/internal/ArangoCollectionAsyncImpl.java +++ b/src/main/java/com/arangodb/async/internal/ArangoCollectionAsyncImpl.java @@ -191,18 +191,24 @@ public CompletableFuture> updateDocument( @Override public CompletableFuture>> updateDocuments( final Collection values) { - final DocumentUpdateOptions params = new DocumentUpdateOptions(); - return executor.execute(updateDocumentsRequest(values, params), - updateDocumentsResponseDeserializer(values, params)); + return updateDocuments(values, new DocumentUpdateOptions()); } @Override public CompletableFuture>> updateDocuments( final Collection values, final DocumentUpdateOptions options) { + return updateDocuments(values, options, values.isEmpty() ? null : (Class) values.iterator().next().getClass()); + } + + @Override + public CompletableFuture>> updateDocuments( + final Collection values, + final DocumentUpdateOptions options, + final Class returnType) { final DocumentUpdateOptions params = (options != null ? options : new DocumentUpdateOptions()); return executor.execute(updateDocumentsRequest(values, params), - updateDocumentsResponseDeserializer(values, params)); + updateDocumentsResponseDeserializer(returnType)); } @Override diff --git a/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java b/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java index cc06bb467..907639bbb 100644 --- a/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java +++ b/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java @@ -187,9 +187,15 @@ public MultiDocumentEntity> updateDocuments(final Co @Override public MultiDocumentEntity> updateDocuments( final Collection values, final DocumentUpdateOptions options) throws ArangoDBException { + return updateDocuments(values, options, values.isEmpty() ? null : (Class) values.iterator().next().getClass()); + } + + @Override + public MultiDocumentEntity> updateDocuments( + final Collection values, final DocumentUpdateOptions options, final Class returnType) throws ArangoDBException { final DocumentUpdateOptions params = (options != null ? options : new DocumentUpdateOptions()); return executor - .execute(updateDocumentsRequest(values, params), updateDocumentsResponseDeserializer(values, params)); + .execute(updateDocumentsRequest(values, params), updateDocumentsResponseDeserializer(returnType)); } @Override diff --git a/src/main/java/com/arangodb/internal/InternalArangoCollection.java b/src/main/java/com/arangodb/internal/InternalArangoCollection.java index e659b1d07..34aeeb447 100644 --- a/src/main/java/com/arangodb/internal/InternalArangoCollection.java +++ b/src/main/java/com/arangodb/internal/InternalArangoCollection.java @@ -399,14 +399,8 @@ protected Request updateDocumentsRequest(final Collection values, final D @SuppressWarnings("unchecked") protected ResponseDeserializer>> updateDocumentsResponseDeserializer( - final Collection values, final DocumentUpdateOptions params) { + final Class returnType) { return response -> { - Class type = null; - if (Boolean.TRUE == params.getReturnNew() || Boolean.TRUE == params.getReturnOld()) { - if (!values.isEmpty()) { - type = (Class) values.iterator().next().getClass(); - } - } final MultiDocumentEntity> multiDocument = new MultiDocumentEntity<>(); final Collection> docs = new ArrayList<>(); final Collection errors = new ArrayList<>(); @@ -423,11 +417,11 @@ protected ResponseDeserializer>> final DocumentUpdateEntity doc = util().deserialize(next, DocumentUpdateEntity.class); final VPackSlice newDoc = next.get(NEW); if (newDoc.isObject()) { - doc.setNew(util(Serializer.CUSTOM).deserialize(newDoc, type)); + doc.setNew(util(Serializer.CUSTOM).deserialize(newDoc, returnType)); } final VPackSlice oldDoc = next.get(OLD); if (oldDoc.isObject()) { - doc.setOld(util(Serializer.CUSTOM).deserialize(oldDoc, type)); + doc.setOld(util(Serializer.CUSTOM).deserialize(oldDoc, returnType)); } docs.add(doc); documentsAndErrors.add(doc); diff --git a/src/test/java/com/arangodb/ArangoCollectionTest.java b/src/test/java/com/arangodb/ArangoCollectionTest.java index eedb60974..530c35c3f 100644 --- a/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -2211,6 +2211,36 @@ public void updateDocuments() { assertThat(updateResult.getErrors().size(), is(0)); } + @Test + public void updateDocumentsWithDifferentReturnType() { + List keys = IntStream.range(0, 3).mapToObj(it -> "key-" + UUID.randomUUID().toString()).collect(Collectors.toList()); + List docs = keys.stream() + .map(BaseDocument::new) + .peek(it -> it.addAttribute("a", "test")) + .collect(Collectors.toList()); + + collection.insertDocuments(docs); + + List> modifiedDocs = docs.stream() + .peek(it -> it.addAttribute("b", "test")) + .map(it -> { + Map map = new HashMap<>(); + map.put("_key", it.getKey()); + map.put("a", it.getAttribute("a")); + map.put("b", it.getAttribute("b")); + return map; + }) + .collect(Collectors.toList()); + + final MultiDocumentEntity> updateResult = collection + .updateDocuments(modifiedDocs, new DocumentUpdateOptions().returnNew(true), BaseDocument.class); + assertThat(updateResult.getDocuments().size(), is(3)); + assertThat(updateResult.getErrors().size(), is(0)); + assertThat(updateResult.getDocuments().stream().map(DocumentUpdateEntity::getNew) + .allMatch(it -> it.getAttribute("a").equals("test") && it.getAttribute("b").equals("test")), + is(true)); + } + @Test public void updateDocumentsOne() { final Collection values = new ArrayList<>(); diff --git a/src/test/java/com/arangodb/async/ArangoCollectionTest.java b/src/test/java/com/arangodb/async/ArangoCollectionTest.java index ed05b072a..11f4e7547 100644 --- a/src/test/java/com/arangodb/async/ArangoCollectionTest.java +++ b/src/test/java/com/arangodb/async/ArangoCollectionTest.java @@ -31,10 +31,12 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.Matchers.*; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; @@ -290,7 +292,7 @@ public void updateDocumentWithDifferentReturnType() throws ExecutionException, I final String key = "key-" + UUID.randomUUID().toString(); final BaseDocument doc = new BaseDocument(key); doc.addAttribute("a", "test"); - collection.insertDocument(doc); + collection.insertDocument(doc).get(); final DocumentUpdateEntity updateResult = collection .updateDocument(key, Collections.singletonMap("b", "test"), new DocumentUpdateOptions().returnNew(true), BaseDocument.class).get(); @@ -1860,6 +1862,37 @@ public void updateDocuments() throws InterruptedException, ExecutionException { .get(); } + @Test + public void updateDocumentsWithDifferentReturnType() throws ExecutionException, InterruptedException { + ArangoCollectionAsync collection = db.collection(COLLECTION_NAME); + List keys = IntStream.range(0, 3).mapToObj(it -> "key-" + UUID.randomUUID().toString()).collect(Collectors.toList()); + List docs = keys.stream() + .map(BaseDocument::new) + .peek(it -> it.addAttribute("a", "test")) + .collect(Collectors.toList()); + + collection.insertDocuments(docs).get(); + + List> modifiedDocs = docs.stream() + .peek(it -> it.addAttribute("b", "test")) + .map(it -> { + Map map = new HashMap<>(); + map.put("_key", it.getKey()); + map.put("a", it.getAttribute("a")); + map.put("b", it.getAttribute("b")); + return map; + }) + .collect(Collectors.toList()); + + final MultiDocumentEntity> updateResult = collection + .updateDocuments(modifiedDocs, new DocumentUpdateOptions().returnNew(true), BaseDocument.class).get(); + assertThat(updateResult.getDocuments().size(), is(3)); + assertThat(updateResult.getErrors().size(), is(0)); + assertThat(updateResult.getDocuments().stream().map(DocumentUpdateEntity::getNew) + .allMatch(it -> it.getAttribute("a").equals("test") && it.getAttribute("b").equals("test")), + is(true)); + } + @Test public void updateDocumentsOne() throws InterruptedException, ExecutionException { final Collection values = new ArrayList<>();