From 07be001e54492fa19ad69c0773dddf5263bfc516 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 23 Jul 2020 15:32:55 +0200 Subject: [PATCH] #410 - Make it possible to write delete/update operations without using matching. Fluent operations now allow statement execution without the need to specify a Query object allowing for shorter statements. --- .../r2dbc/core/ReactiveDeleteOperation.java | 4 +- .../r2dbc/core/ReactiveUpdateOperation.java | 4 +- .../ReactiveDeleteOperationUnitTests.java | 38 +++++++++++++++++- .../ReactiveUpdateOperationUnitTests.java | 40 ++++++++++++++++++- 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/springframework/data/r2dbc/core/ReactiveDeleteOperation.java b/src/main/java/org/springframework/data/r2dbc/core/ReactiveDeleteOperation.java index 27aa2150..a1cb0092 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/ReactiveDeleteOperation.java +++ b/src/main/java/org/springframework/data/r2dbc/core/ReactiveDeleteOperation.java @@ -56,7 +56,7 @@ public interface ReactiveDeleteOperation { /** * Table override (optional). */ - interface DeleteWithTable { + interface DeleteWithTable extends TerminatingDelete { /** * Explicitly set the {@link String name} of the table on which to perform the delete. @@ -88,7 +88,7 @@ public interface ReactiveDeleteOperation { /** * Required {@link Query filter}. */ - interface DeleteWithQuery { + interface DeleteWithQuery extends TerminatingDelete { /** * Define the {@link Query} used to filter elements in the delete. diff --git a/src/main/java/org/springframework/data/r2dbc/core/ReactiveUpdateOperation.java b/src/main/java/org/springframework/data/r2dbc/core/ReactiveUpdateOperation.java index 11fae61f..fc2ba7b9 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/ReactiveUpdateOperation.java +++ b/src/main/java/org/springframework/data/r2dbc/core/ReactiveUpdateOperation.java @@ -60,7 +60,7 @@ public interface ReactiveUpdateOperation { /** * Table override (optional). */ - interface UpdateWithTable { + interface UpdateWithTable extends TerminatingUpdate { /** * Explicitly set the {@link String name} of the table on which to perform the update. @@ -92,7 +92,7 @@ public interface ReactiveUpdateOperation { /** * Define a {@link Query} used as the filter for the {@link Update}. */ - interface UpdateWithQuery { + interface UpdateWithQuery extends TerminatingUpdate { /** * Filter rows to update by the given {@link Query}. diff --git a/src/test/java/org/springframework/data/r2dbc/core/ReactiveDeleteOperationUnitTests.java b/src/test/java/org/springframework/data/r2dbc/core/ReactiveDeleteOperationUnitTests.java index 5f886706..05d8701b 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/ReactiveDeleteOperationUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/core/ReactiveDeleteOperationUnitTests.java @@ -51,13 +51,49 @@ public class ReactiveDeleteOperationUnitTests { entityTemplate = new R2dbcEntityTemplate(client); } - @Test // gh-220 + @Test // gh-410 public void shouldDelete() { MockResult result = MockResult.builder().rowsUpdated(1).build(); recorder.addStubbing(s -> s.startsWith("DELETE"), result); + entityTemplate.delete(Person.class) // + .all() // + .as(StepVerifier::create) // + .expectNext(1) // + .verifyComplete(); + + StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("DELETE")); + + assertThat(statement.getSql()).isEqualTo("DELETE FROM person"); + } + + @Test // gh-410 + public void shouldDeleteWithTable() { + + MockResult result = MockResult.builder().rowsUpdated(1).build(); + + recorder.addStubbing(s -> s.startsWith("DELETE"), result); + + entityTemplate.delete(Person.class) // + .from("table").all() // + .as(StepVerifier::create) // + .expectNext(1) // + .verifyComplete(); + + StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("DELETE")); + + assertThat(statement.getSql()).isEqualTo("DELETE FROM table"); + } + + @Test // gh-220 + public void shouldDeleteWithQuery() { + + MockResult result = MockResult.builder().rowsUpdated(1).build(); + + recorder.addStubbing(s -> s.startsWith("DELETE"), result); + entityTemplate.delete(Person.class) // .matching(query(where("name").is("Walter"))) // .all() // diff --git a/src/test/java/org/springframework/data/r2dbc/core/ReactiveUpdateOperationUnitTests.java b/src/test/java/org/springframework/data/r2dbc/core/ReactiveUpdateOperationUnitTests.java index fcdd03e2..f29797b4 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/ReactiveUpdateOperationUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/core/ReactiveUpdateOperationUnitTests.java @@ -52,13 +52,51 @@ public class ReactiveUpdateOperationUnitTests { entityTemplate = new R2dbcEntityTemplate(client); } - @Test // gh-220 + @Test // gh-410 public void shouldUpdate() { MockResult result = MockResult.builder().rowsUpdated(1).build(); recorder.addStubbing(s -> s.startsWith("UPDATE"), result); + entityTemplate.update(Person.class) // + .apply(Update.update("name", "Heisenberg")) // + .as(StepVerifier::create) // + .expectNext(1) // + .verifyComplete(); + + StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("UPDATE")); + + assertThat(statement.getSql()).isEqualTo("UPDATE person SET THE_NAME = $1"); + assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Heisenberg")); + } + + @Test // gh-410 + public void shouldUpdateWithTable() { + + MockResult result = MockResult.builder().rowsUpdated(1).build(); + + recorder.addStubbing(s -> s.startsWith("UPDATE"), result); + + entityTemplate.update(Person.class) // + .inTable("table").apply(Update.update("name", "Heisenberg")) // + .as(StepVerifier::create) // + .expectNext(1) // + .verifyComplete(); + + StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("UPDATE")); + + assertThat(statement.getSql()).isEqualTo("UPDATE table SET THE_NAME = $1"); + assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Heisenberg")); + } + + @Test // gh-220 + public void shouldUpdateWithQuery() { + + MockResult result = MockResult.builder().rowsUpdated(1).build(); + + recorder.addStubbing(s -> s.startsWith("UPDATE"), result); + entityTemplate.update(Person.class) // .matching(query(where("name").is("Walter"))) // .apply(Update.update("name", "Heisenberg")) //