Browse Source

Polishing.

Use FilterFunction instead of nullable fetchSize to avoid unconditional capturing lambdas and improve defaulting.

Add since tag.

See #1652
Original pull request: #1898
pull/1905/head
Mark Paluch 1 year ago
parent
commit
90b6d8e8a8
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 8
      spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplate.java
  2. 6
      spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/core/ReactiveSelectOperation.java
  3. 4
      spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/core/ReactiveSelectOperationSupport.java
  4. 47
      spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplateUnitTests.java
  5. 26
      spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/core/ReactiveSelectOperationUnitTests.java

8
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplate.java

@ -18,6 +18,7 @@ package org.springframework.data.r2dbc.core; @@ -18,6 +18,7 @@ package org.springframework.data.r2dbc.core;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.Row;
import io.r2dbc.spi.RowMetadata;
import io.r2dbc.spi.Statement;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@ -320,7 +321,8 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw @@ -320,7 +321,8 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw
<T, P extends Publisher<T>> P doSelect(Query query, Class<?> entityClass, SqlIdentifier tableName,
Class<T> returnType, Function<RowsFetchSpec<T>, P> resultHandler, @Nullable Integer fetchSize) {
RowsFetchSpec<T> fetchSpec = doSelect(query, entityClass, tableName, returnType, fetchSize);
RowsFetchSpec<T> fetchSpec = doSelect(query, entityClass, tableName, returnType,
fetchSize != null ? statement -> statement.fetchSize(fetchSize) : Function.identity());
P result = resultHandler.apply(fetchSpec);
@ -332,7 +334,7 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw @@ -332,7 +334,7 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw
}
private <T> RowsFetchSpec<T> doSelect(Query query, Class<?> entityType, SqlIdentifier tableName,
Class<T> returnType, @Nullable Integer fetchSize) {
Class<T> returnType, Function<? super Statement, ? extends Statement> filterFunction) {
StatementMapper statementMapper = dataAccessStrategy.getStatementMapper().forType(entityType);
@ -360,7 +362,7 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw @@ -360,7 +362,7 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw
PreparedOperation<?> operation = statementMapper.getMappedObject(selectSpec);
return getRowsFetchSpec(
databaseClient.sql(operation).filter((statement) -> statement.fetchSize(Optional.ofNullable(fetchSize).orElse(0))),
databaseClient.sql(operation).filter(filterFunction),
entityType,
returnType
);

6
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/core/ReactiveSelectOperation.java

@ -118,10 +118,12 @@ public interface ReactiveSelectOperation { @@ -118,10 +118,12 @@ public interface ReactiveSelectOperation {
interface SelectWithQuery<T> extends TerminatingSelect<T> {
/**
* Specifies the fetch size for this query
* Specifies the fetch size for this query.
*
* @param fetchSize
* @return
* @return new instance of {@link SelectWithQuery}.
* @since 3.4
* @see io.r2dbc.spi.Statement#fetchSize(int)
*/
SelectWithQuery<T> withFetchSize(int fetchSize);

4
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/core/ReactiveSelectOperationSupport.java

@ -54,7 +54,6 @@ class ReactiveSelectOperationSupport implements ReactiveSelectOperation { @@ -54,7 +54,6 @@ class ReactiveSelectOperationSupport implements ReactiveSelectOperation {
private final Class<T> returnType;
private final Query query;
private final @Nullable SqlIdentifier tableName;
private final @Nullable Integer fetchSize;
ReactiveSelectSupport(R2dbcEntityTemplate template, Class<?> domainType, Class<T> returnType, Query query,
@ -86,9 +85,6 @@ class ReactiveSelectOperationSupport implements ReactiveSelectOperation { @@ -86,9 +85,6 @@ class ReactiveSelectOperationSupport implements ReactiveSelectOperation {
@Override
public SelectWithQuery<T> withFetchSize(int fetchSize) {
Assert.notNull(returnType, "FetchSize must not be null");
return new ReactiveSelectSupport<>(template, domainType, returnType, query, tableName, fetchSize);
}

47
spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplateUnitTests.java

@ -99,7 +99,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -99,7 +99,7 @@ public class R2dbcEntityTemplateUnitTests {
new MappingR2dbcConverter(new R2dbcMappingContext(), conversions));
}
@Test // gh-220
@Test // GH-220
void shouldCountBy() {
MockResult result = MockResult.builder().row(MockRow.builder().identified(0, Long.class, 1L).build()).build();
@ -117,8 +117,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -117,8 +117,7 @@ public class R2dbcEntityTemplateUnitTests {
assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter"));
}
@Test
// GH-1690
@Test // GH-1690
void shouldApplyInterfaceProjection() {
MockRowMetadata metadata = MockRowMetadata.builder()
@ -165,7 +164,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -165,7 +164,7 @@ public class R2dbcEntityTemplateUnitTests {
assertThat(statement.getSql()).isEqualTo("SELECT foo.* FROM foo WHERE foo.THE_NAME = $1");
}
@Test // gh-469
@Test // GH-469
void shouldProjectExistsResult() {
MockResult result = MockResult.builder().row(MockRow.builder().identified(0, Object.class, null).build()).build();
@ -180,7 +179,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -180,7 +179,7 @@ public class R2dbcEntityTemplateUnitTests {
.verifyComplete();
}
@Test // gh-1310
@Test // GH-1310
void shouldProjectExistsResultWithoutId() {
MockResult result = MockResult.builder().row(MockRow.builder().identified(0, Object.class, null).build()).build();
@ -192,7 +191,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -192,7 +191,7 @@ public class R2dbcEntityTemplateUnitTests {
.expectNext(true).verifyComplete();
}
@Test // gh-1310
@Test // GH-1310
void shouldProjectCountResultWithoutId() {
MockResult result = MockResult.builder().row(MockRow.builder().identified(0, Long.class, 1L).build()).build();
@ -204,7 +203,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -204,7 +203,7 @@ public class R2dbcEntityTemplateUnitTests {
.expectNext(1L).verifyComplete();
}
@Test // gh-469
@Test // GH-469
void shouldExistsByCriteria() {
MockRowMetadata metadata = MockRowMetadata.builder()
@ -224,7 +223,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -224,7 +223,7 @@ public class R2dbcEntityTemplateUnitTests {
assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter"));
}
@Test // gh-220
@Test // GH-220
void shouldSelectByCriteria() {
recorder.addStubbing(s -> s.startsWith("SELECT"), Collections.emptyList());
@ -240,7 +239,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -240,7 +239,7 @@ public class R2dbcEntityTemplateUnitTests {
assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter"));
}
@Test // gh-215
@Test // GH-215
void selectShouldInvokeCallback() {
MockRowMetadata metadata = MockRowMetadata.builder()
@ -266,7 +265,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -266,7 +265,7 @@ public class R2dbcEntityTemplateUnitTests {
assertThat(callback.getValues()).hasSize(1);
}
@Test // gh-220
@Test // GH-220
void shouldSelectOne() {
recorder.addStubbing(s -> s.startsWith("SELECT"), Collections.emptyList());
@ -282,7 +281,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -282,7 +281,7 @@ public class R2dbcEntityTemplateUnitTests {
assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter"));
}
@Test // gh-220, gh-758
@Test // GH-220, GH-758
void shouldSelectOneDoNotOverrideExistingLimit() {
recorder.addStubbing(s -> s.startsWith("SELECT"), Collections.emptyList());
@ -299,7 +298,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -299,7 +298,7 @@ public class R2dbcEntityTemplateUnitTests {
assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter"));
}
@Test // gh-220
@Test // GH-220
void shouldUpdateByQuery() {
MockRowMetadata metadata = MockRowMetadata.builder()
@ -321,7 +320,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -321,7 +320,7 @@ public class R2dbcEntityTemplateUnitTests {
Parameter.from("Walter"));
}
@Test // gh-220
@Test // GH-220
void shouldDeleteByQuery() {
MockRowMetadata metadata = MockRowMetadata.builder()
@ -341,7 +340,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -341,7 +340,7 @@ public class R2dbcEntityTemplateUnitTests {
assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter"));
}
@Test // gh-220
@Test // GH-220
void shouldDeleteEntity() {
Person person = Person.empty() //
@ -358,7 +357,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -358,7 +357,7 @@ public class R2dbcEntityTemplateUnitTests {
assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter"));
}
@Test // gh-365
@Test // GH-365
void shouldInsertVersioned() {
MockRowMetadata metadata = MockRowMetadata.builder().build();
@ -379,7 +378,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -379,7 +378,7 @@ public class R2dbcEntityTemplateUnitTests {
Parameter.from(1L));
}
@Test // gh-557, gh-402
@Test // GH-557, GH-402
void shouldSkipDefaultIdValueOnInsert() {
MockRowMetadata metadata = MockRowMetadata.builder().build();
@ -397,7 +396,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -397,7 +396,7 @@ public class R2dbcEntityTemplateUnitTests {
assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("bar"));
}
@Test // gh-557, gh-402
@Test // GH-557, GH-402
void shouldSkipDefaultIdValueOnVersionedInsert() {
MockRowMetadata metadata = MockRowMetadata.builder().build();
@ -419,7 +418,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -419,7 +418,7 @@ public class R2dbcEntityTemplateUnitTests {
Parameter.from("bar"));
}
@Test // gh-451
@Test // GH-451
void shouldInsertCorrectlyVersionedAndAudited() {
MockRowMetadata metadata = MockRowMetadata.builder().build();
@ -447,7 +446,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -447,7 +446,7 @@ public class R2dbcEntityTemplateUnitTests {
"INSERT INTO with_auditing_and_optimistic_locking (version, name, created_date, last_modified_date) VALUES ($1, $2, $3, $4)");
}
@Test // gh-451
@Test // GH-451
void shouldUpdateCorrectlyVersionedAndAudited() {
MockRowMetadata metadata = MockRowMetadata.builder().build();
@ -476,7 +475,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -476,7 +475,7 @@ public class R2dbcEntityTemplateUnitTests {
"UPDATE with_auditing_and_optimistic_locking SET version = $1, name = $2, created_date = $3, last_modified_date = $4");
}
@Test // gh-215
@Test // GH-215
void insertShouldInvokeCallback() {
MockRowMetadata metadata = MockRowMetadata.builder().build();
@ -504,7 +503,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -504,7 +503,7 @@ public class R2dbcEntityTemplateUnitTests {
Parameter.from("before-save"));
}
@Test // gh-365
@Test // GH-365
void shouldUpdateVersioned() {
MockRowMetadata metadata = MockRowMetadata.builder().build();
@ -526,7 +525,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -526,7 +525,7 @@ public class R2dbcEntityTemplateUnitTests {
Parameter.from(1L));
}
@Test // gh-215
@Test // GH-215
void updateShouldInvokeCallback() {
MockRowMetadata metadata = MockRowMetadata.builder().build();
@ -559,7 +558,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -559,7 +558,7 @@ public class R2dbcEntityTemplateUnitTests {
Parameter.from("before-save"));
}
@Test // gh-637
@Test // GH-637
void insertIncludesInsertOnlyColumns() {
MockRowMetadata metadata = MockRowMetadata.builder().build();
@ -578,7 +577,7 @@ public class R2dbcEntityTemplateUnitTests { @@ -578,7 +577,7 @@ public class R2dbcEntityTemplateUnitTests {
Parameter.from("insert this"));
}
@Test // gh-637
@Test // GH-637
void updateExcludesInsertOnlyColumns() {
MockRowMetadata metadata = MockRowMetadata.builder().build();

26
spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/core/ReactiveSelectOperationUnitTests.java

@ -24,11 +24,11 @@ import io.r2dbc.spi.test.MockColumnMetadata; @@ -24,11 +24,11 @@ import io.r2dbc.spi.test.MockColumnMetadata;
import io.r2dbc.spi.test.MockResult;
import io.r2dbc.spi.test.MockRow;
import io.r2dbc.spi.test.MockRowMetadata;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.r2dbc.dialect.PostgresDialect;
import org.springframework.data.r2dbc.testing.StatementRecorder;
@ -56,7 +56,7 @@ public class ReactiveSelectOperationUnitTests { @@ -56,7 +56,7 @@ public class ReactiveSelectOperationUnitTests {
entityTemplate = new R2dbcEntityTemplate(client, new DefaultReactiveDataAccessStrategy(PostgresDialect.INSTANCE));
}
@Test // gh-220
@Test // GH-220
void shouldSelectAll() {
MockRowMetadata metadata = MockRowMetadata.builder()
@ -80,7 +80,7 @@ public class ReactiveSelectOperationUnitTests { @@ -80,7 +80,7 @@ public class ReactiveSelectOperationUnitTests {
.isEqualTo("SELECT person.* FROM person WHERE person.THE_NAME = $1 LIMIT 10 OFFSET 20");
}
@Test // gh-220
@Test // GH-220
void shouldSelectAs() {
MockRowMetadata metadata = MockRowMetadata.builder()
@ -128,7 +128,7 @@ public class ReactiveSelectOperationUnitTests { @@ -128,7 +128,7 @@ public class ReactiveSelectOperationUnitTests {
assertThat(statement.getSql()).isEqualTo("SELECT person.id, person.a_different_name FROM person WHERE person.THE_NAME = $1");
}
@Test // gh-220
@Test // GH-220
void shouldSelectFromTable() {
MockRowMetadata metadata = MockRowMetadata.builder()
@ -152,7 +152,7 @@ public class ReactiveSelectOperationUnitTests { @@ -152,7 +152,7 @@ public class ReactiveSelectOperationUnitTests {
assertThat(statement.getSql()).isEqualTo("SELECT the_table.* FROM the_table WHERE the_table.THE_NAME = $1");
}
@Test // gh-220
@Test // GH-220
void shouldSelectFirst() {
MockRowMetadata metadata = MockRowMetadata.builder()
@ -175,7 +175,7 @@ public class ReactiveSelectOperationUnitTests { @@ -175,7 +175,7 @@ public class ReactiveSelectOperationUnitTests {
assertThat(statement.getSql()).isEqualTo("SELECT person.* FROM person WHERE person.THE_NAME = $1 LIMIT 1");
}
@Test // gh-220
@Test // GH-220
void shouldSelectOne() {
MockRowMetadata metadata = MockRowMetadata.builder()
@ -198,7 +198,7 @@ public class ReactiveSelectOperationUnitTests { @@ -198,7 +198,7 @@ public class ReactiveSelectOperationUnitTests {
assertThat(statement.getSql()).isEqualTo("SELECT person.* FROM person WHERE person.THE_NAME = $1 LIMIT 2");
}
@Test // gh-220
@Test // GH-220
void shouldSelectExists() {
MockRowMetadata metadata = MockRowMetadata.builder()
@ -221,7 +221,7 @@ public class ReactiveSelectOperationUnitTests { @@ -221,7 +221,7 @@ public class ReactiveSelectOperationUnitTests {
assertThat(statement.getSql()).isEqualTo("SELECT 1 FROM person WHERE person.THE_NAME = $1 LIMIT 1");
}
@Test // gh-220
@Test // GH-220
void shouldSelectCount() {
MockRowMetadata metadata = MockRowMetadata.builder()
@ -244,8 +244,9 @@ public class ReactiveSelectOperationUnitTests { @@ -244,8 +244,9 @@ public class ReactiveSelectOperationUnitTests {
assertThat(statement.getSql()).isEqualTo("SELECT COUNT(*) FROM person WHERE person.THE_NAME = $1");
}
@Test // gh-1652
void shouldBeAbleToProvideFetchSize() {
@Test // GH-1652
void shouldConsiderFetchSize() {
MockRowMetadata metadata = MockRowMetadata.builder()
.columnMetadata(MockColumnMetadata.builder().name("id").type(R2dbcType.INTEGER).build())
.build();
@ -256,8 +257,7 @@ public class ReactiveSelectOperationUnitTests { @@ -256,8 +257,7 @@ public class ReactiveSelectOperationUnitTests {
recorder.addStubbing(s -> s.startsWith("SELECT"), result);
entityTemplate.select(Person.class) //
.withFetchSize(10)
.matching(query(where("name").is("Walter")).limit(10).offset(20)) //
.withFetchSize(10) //
.all() //
.as(StepVerifier::create) //
.expectNextCount(1) //
@ -265,8 +265,6 @@ public class ReactiveSelectOperationUnitTests { @@ -265,8 +265,6 @@ public class ReactiveSelectOperationUnitTests {
StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("SELECT"));
assertThat(statement.getSql())
.isEqualTo("SELECT person.* FROM person WHERE person.THE_NAME = $1 LIMIT 10 OFFSET 20");
assertThat(statement.getFetchSize()).isEqualTo(10);
}

Loading…
Cancel
Save