#8 - Replace exchange() method with map(…) and then() methods.

DatabaseClient now no longer exposes the exchange() method but rather provides map(…) and then(…) methods.
Calling map(…) extracts values from tabular results by propagating the mapping function to Result.map(…).
then() allows statement execution without returning the result propagating only completion and error signals.

Original pull request: #33.
This commit is contained in:
Mark Paluch
2018-11-28 14:40:26 +01:00
committed by Jens Schauder
parent 536d484012
commit 5a5310af4d
8 changed files with 297 additions and 119 deletions

View File

@@ -156,17 +156,26 @@ public interface DatabaseClient {
*/
<R> TypedExecuteSpec<R> as(Class<R> resultType);
/**
* Configure a result mapping {@link java.util.function.BiFunction function}.
*
* @param mappingFunction must not be {@literal null}.
* @param <R> result type.
* @return
*/
<R> FetchSpec<R> map(BiFunction<Row, RowMetadata, R> mappingFunction);
/**
* Perform the SQL call and retrieve the result.
*/
FetchSpec<Map<String, Object>> fetch();
/**
* Perform the SQL request and return a {@link SqlResult}.
* Perform the SQL call and return a {@link Mono} that completes without result on statement completion.
*
* @return a {@code Mono} for the result
* @return a {@link Mono} ignoring its payload (actively dropping).
*/
Mono<SqlResult<Map<String, Object>>> exchange();
Mono<Void> then();
}
/**
@@ -183,17 +192,26 @@ public interface DatabaseClient {
*/
<R> TypedExecuteSpec<R> as(Class<R> resultType);
/**
* Configure a result mapping {@link java.util.function.BiFunction function}.
*
* @param mappingFunction must not be {@literal null}.
* @param <R> result type.
* @return
*/
<R> FetchSpec<R> map(BiFunction<Row, RowMetadata, R> mappingFunction);
/**
* Perform the SQL call and retrieve the result.
*/
FetchSpec<T> fetch();
/**
* Perform the SQL request and return a {@link SqlResult}.
* Perform the SQL call and return a {@link Mono} that completes without result on statement completion.
*
* @return a {@code Mono} for the result
* @return a {@link Mono} ignoring its payload (actively dropping).
*/
Mono<SqlResult<T>> exchange();
Mono<Void> then();
}
/**
@@ -229,7 +247,7 @@ public interface DatabaseClient {
* @param table must not be {@literal null} or empty.
* @return
*/
GenericInsertSpec into(String table);
GenericInsertSpec<Map<String, Object>> into(String table);
/**
* Specify the target table to insert to using the {@link Class entity class}.
@@ -254,17 +272,19 @@ public interface DatabaseClient {
*/
<R> TypedSelectSpec<R> as(Class<R> resultType);
/**
* Configure a result mapping {@link java.util.function.BiFunction function}.
*
* @param mappingFunction must not be {@literal null}.
* @param <R> result type.
* @return
*/
<R> FetchSpec<R> map(BiFunction<Row, RowMetadata, R> mappingFunction);
/**
* Perform the SQL call and retrieve the result.
*/
FetchSpec<Map<String, Object>> fetch();
/**
* Perform the SQL request and return a {@link SqlResult}.
*
* @return a {@code Mono} for the result
*/
Mono<SqlResult<Map<String, Object>>> exchange();
}
/**
@@ -279,28 +299,21 @@ public interface DatabaseClient {
* @param resultType must not be {@literal null}.
* @param <R> result type.
*/
<R> TypedSelectSpec<R> as(Class<R> resultType);
<R> FetchSpec<R> as(Class<R> resultType);
/**
* Configure a result mapping {@link java.util.function.Function}.
* Configure a result mapping {@link java.util.function.BiFunction function}.
*
* @param mappingFunction must not be {@literal null}.
* @param <R> result type.
* @return
*/
<R> TypedSelectSpec<R> extract(BiFunction<Row, RowMetadata, R> mappingFunction);
<R> FetchSpec<R> map(BiFunction<Row, RowMetadata, R> mappingFunction);
/**
* Perform the SQL call and retrieve the result.
*/
FetchSpec<T> fetch();
/**
* Perform the SQL request and return a {@link SqlResult}.
*
* @return a {@code Mono} for the result
*/
Mono<SqlResult<T>> exchange();
}
/**
@@ -332,8 +345,10 @@ public interface DatabaseClient {
/**
* Contract for specifying {@code INSERT} options leading to the exchange.
*
* @param <T> Result type of tabular insert results.
*/
interface GenericInsertSpec extends InsertSpec {
interface GenericInsertSpec<T> extends InsertSpec<T> {
/**
* Specify a field and non-{@literal null} value to insert.
@@ -341,7 +356,7 @@ public interface DatabaseClient {
* @param field must not be {@literal null} or empty.
* @param value must not be {@literal null}
*/
GenericInsertSpec value(String field, Object value);
GenericInsertSpec<T> value(String field, Object value);
/**
* Specify a {@literal null} value to insert.
@@ -349,7 +364,7 @@ public interface DatabaseClient {
* @param field must not be {@literal null} or empty.
* @param type must not be {@literal null}.
*/
GenericInsertSpec nullValue(String field, Class<?> type);
GenericInsertSpec<T> nullValue(String field, Class<?> type);
}
/**
@@ -363,7 +378,7 @@ public interface DatabaseClient {
* @param objectToInsert
* @return
*/
InsertSpec using(T objectToInsert);
InsertSpec<Map<String, Object>> using(T objectToInsert);
/**
* Use the given {@code tableName} as insert target.
@@ -374,30 +389,43 @@ public interface DatabaseClient {
TypedInsertSpec<T> table(String tableName);
/**
* Insert the given {@link Publisher} to insert one or more objects.
* Insert the given {@link Publisher} to insert one or more objects. Inserts only a single object when calling
* {@link FetchSpec#one()} or {@link FetchSpec#first()}.
*
* @param objectToInsert
* @return
* @see InsertSpec#fetch()
*/
InsertSpec using(Publisher<T> objectToInsert);
InsertSpec<Map<String, Object>> using(Publisher<T> objectToInsert);
}
/**
* Contract for specifying {@code INSERT} options leading to the exchange.
*
* @param <T> Result type of tabular insert results.
*/
interface InsertSpec {
interface InsertSpec<T> {
/**
* Perform the SQL call.
* Configure a result mapping {@link java.util.function.BiFunction function}.
*
* @param mappingFunction must not be {@literal null}.
* @param <R> result type.
* @return
*/
<R> FetchSpec<R> map(BiFunction<Row, RowMetadata, R> mappingFunction);
/**
* Perform the SQL call and retrieve the result.
*/
FetchSpec<T> fetch();
/**
* Perform the SQL call and return a {@link Mono} that completes without result on statement completion.
*
* @return a {@link Mono} ignoring its payload (actively dropping).
*/
Mono<Void> then();
/**
* Perform the SQL request and return a {@link SqlResult}.
*
* @return a {@code Mono} for the result
*/
Mono<SqlResult<Map<String, Object>>> exchange();
}
/**

View File

@@ -41,6 +41,7 @@ import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -220,6 +221,15 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
return new DefaultTypedExecuteSpec<>(byIndex, byName, sqlSupplier, typeToRead);
}
/**
* Customization hook.
*/
protected <T> DefaultTypedExecuteSpec<T> createTypedExecuteSpec(Map<Integer, SettableValue> byIndex,
Map<String, SettableValue> byName, Supplier<String> sqlSupplier,
BiFunction<Row, RowMetadata, T> mappingFunction) {
return new DefaultTypedExecuteSpec<>(byIndex, byName, sqlSupplier, mappingFunction);
}
/**
* Customization hook.
*/
@@ -295,6 +305,13 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
this.sqlSupplier = sqlSupplier;
}
ExecuteSpecSupport(ExecuteSpecSupport other) {
this.byIndex = other.byIndex;
this.byName = other.byName;
this.sqlSupplier = other.sqlSupplier;
}
protected String getSql() {
String sql = sqlSupplier.get();
@@ -396,14 +413,22 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
return createTypedExecuteSpec(this.byIndex, this.byName, this.sqlSupplier, resultType);
}
@Override
public <R> FetchSpec<R> map(BiFunction<Row, RowMetadata, R> mappingFunction) {
Assert.notNull(mappingFunction, "Mapping function must not be null!");
return exchange(getSql(), mappingFunction);
}
@Override
public FetchSpec<Map<String, Object>> fetch() {
return exchange(getSql(), ColumnMapRowMapper.INSTANCE);
}
@Override
public Mono<SqlResult<Map<String, Object>>> exchange() {
return Mono.just(exchange(getSql(), ColumnMapRowMapper.INSTANCE));
public Mono<Void> then() {
return fetch().rowsUpdated().then();
}
@Override
@@ -456,6 +481,14 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
this.mappingFunction = dataAccessStrategy.getRowMapper(typeToRead);
}
DefaultTypedExecuteSpec(Map<Integer, SettableValue> byIndex, Map<String, SettableValue> byName,
Supplier<String> sqlSupplier, BiFunction<Row, RowMetadata, T> mappingFunction) {
super(byIndex, byName, sqlSupplier);
this.typeToRead = null;
this.mappingFunction = mappingFunction;
}
@Override
public <R> TypedExecuteSpec<R> as(Class<R> resultType) {
@@ -464,14 +497,22 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
return createTypedExecuteSpec(this.byIndex, this.byName, this.sqlSupplier, resultType);
}
@Override
public <R> FetchSpec<R> map(BiFunction<Row, RowMetadata, R> mappingFunction) {
Assert.notNull(mappingFunction, "Mapping function must not be null!");
return exchange(getSql(), mappingFunction);
}
@Override
public FetchSpec<T> fetch() {
return exchange(getSql(), mappingFunction);
}
@Override
public Mono<SqlResult<T>> exchange() {
return Mono.just(exchange(getSql(), mappingFunction));
public Mono<Void> then() {
return fetch().rowsUpdated().then();
}
@Override
@@ -603,10 +644,21 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
@Override
public <R> TypedSelectSpec<R> as(Class<R> resultType) {
Assert.notNull(resultType, "Result type must not be null!");
return new DefaultTypedSelectSpec<>(table, projectedFields, sort, page, resultType,
dataAccessStrategy.getRowMapper(resultType));
}
@Override
public <R> FetchSpec<R> map(BiFunction<Row, RowMetadata, R> mappingFunction) {
Assert.notNull(mappingFunction, "Mapping function must not be null!");
return exchange(mappingFunction);
}
@Override
public DefaultGenericSelectSpec project(String... selectedFields) {
return (DefaultGenericSelectSpec) super.project(selectedFields);
@@ -627,11 +679,6 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
return exchange(ColumnMapRowMapper.INSTANCE);
}
@Override
public Mono<SqlResult<Map<String, Object>>> exchange() {
return Mono.just(exchange(ColumnMapRowMapper.INSTANCE));
}
private <R> SqlResult<R> exchange(BiFunction<Row, RowMetadata, R> mappingFunction) {
Set<String> columns;
@@ -660,7 +707,7 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
@SuppressWarnings("unchecked")
private class DefaultTypedSelectSpec<T> extends DefaultSelectSpecSupport implements TypedSelectSpec<T> {
private final Class<?> typeToRead;
private final @Nullable Class<T> typeToRead;
private final BiFunction<Row, RowMetadata, T> mappingFunction;
DefaultTypedSelectSpec(Class<T> typeToRead) {
@@ -671,7 +718,12 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
this.mappingFunction = dataAccessStrategy.getRowMapper(typeToRead);
}
DefaultTypedSelectSpec(String table, List<String> projectedFields, Sort sort, Pageable page, Class<?> typeToRead,
DefaultTypedSelectSpec(String table, List<String> projectedFields, Sort sort, Pageable page,
BiFunction<Row, RowMetadata, T> mappingFunction) {
this(table, projectedFields, sort, page, null, mappingFunction);
}
DefaultTypedSelectSpec(String table, List<String> projectedFields, Sort sort, Pageable page, Class<T> typeToRead,
BiFunction<Row, RowMetadata, T> mappingFunction) {
super(table, projectedFields, sort, page);
this.typeToRead = typeToRead;
@@ -679,20 +731,19 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
}
@Override
public <R> TypedSelectSpec<R> as(Class<R> resultType) {
public <R> FetchSpec<R> as(Class<R> resultType) {
Assert.notNull(resultType, "Result type must not be null!");
return new DefaultTypedSelectSpec<>(table, projectedFields, sort, page, typeToRead,
dataAccessStrategy.getRowMapper(resultType));
return exchange(dataAccessStrategy.getRowMapper(resultType));
}
@Override
public <R> TypedSelectSpec<R> extract(BiFunction<Row, RowMetadata, R> mappingFunction) {
public <R> FetchSpec<R> map(BiFunction<Row, RowMetadata, R> mappingFunction) {
Assert.notNull(mappingFunction, "Mapping function must not be null!");
return new DefaultTypedSelectSpec<>(table, projectedFields, sort, page, typeToRead, mappingFunction);
return exchange(mappingFunction);
}
@Override
@@ -711,15 +762,10 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
}
@Override
public FetchSpec<T> fetch() {
public SqlResult<T> fetch() {
return exchange(mappingFunction);
}
@Override
public Mono<SqlResult<T>> exchange() {
return Mono.just(exchange(mappingFunction));
}
private <R> SqlResult<R> exchange(BiFunction<Row, RowMetadata, R> mappingFunction) {
List<String> columns;
@@ -749,13 +795,13 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
class DefaultInsertIntoSpec implements InsertIntoSpec {
@Override
public GenericInsertSpec into(String table) {
return new DefaultGenericInsertSpec(table, Collections.emptyMap());
public GenericInsertSpec<Map<String, Object>> into(String table) {
return new DefaultGenericInsertSpec<>(table, Collections.emptyMap(), ColumnMapRowMapper.INSTANCE);
}
@Override
public <T> TypedInsertSpec<T> into(Class<T> table) {
return new DefaultTypedInsertSpec<>(table);
return new DefaultTypedInsertSpec<>(table, ColumnMapRowMapper.INSTANCE);
}
}
@@ -763,10 +809,11 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
* Default implementation of {@link DatabaseClient.GenericInsertSpec}.
*/
@RequiredArgsConstructor
class DefaultGenericInsertSpec implements GenericInsertSpec {
class DefaultGenericInsertSpec<T> implements GenericInsertSpec<T> {
private final String table;
private final Map<String, SettableValue> byName;
private final BiFunction<Row, RowMetadata, T> mappingFunction;
@Override
public GenericInsertSpec value(String field, Object value) {
@@ -776,7 +823,7 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
Map<String, SettableValue> byName = new LinkedHashMap<>(this.byName);
byName.put(field, new SettableValue(field, value, null));
return new DefaultGenericInsertSpec(this.table, byName);
return new DefaultGenericInsertSpec<>(this.table, byName, this.mappingFunction);
}
@Override
@@ -787,20 +834,28 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
Map<String, SettableValue> byName = new LinkedHashMap<>(this.byName);
byName.put(field, new SettableValue(field, null, type));
return new DefaultGenericInsertSpec(this.table, byName);
return new DefaultGenericInsertSpec<>(this.table, byName, this.mappingFunction);
}
@Override
public <R> FetchSpec<R> map(BiFunction<Row, RowMetadata, R> mappingFunction) {
Assert.notNull(mappingFunction, "Mapping function must not be null!");
return exchange(mappingFunction);
}
@Override
public FetchSpec<T> fetch() {
return exchange(this.mappingFunction);
}
@Override
public Mono<Void> then() {
return exchange((row, md) -> row).all().then();
return fetch().rowsUpdated().then();
}
@Override
public Mono<SqlResult<Map<String, Object>>> exchange() {
return Mono.just(exchange(ColumnMapRowMapper.INSTANCE));
}
private <T> SqlResult<T> exchange(BiFunction<Row, RowMetadata, T> mappingFunction) {
private <R> SqlResult<R> exchange(BiFunction<Row, RowMetadata, R> mappingFunction) {
if (byName.isEmpty()) {
throw new IllegalStateException("Insert fields is empty!");
@@ -809,7 +864,7 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
BindableOperation bindableInsert = dataAccessStrategy.insertAndReturnGeneratedKeys(table, byName.keySet());
String sql = bindableInsert.toQuery();
Function<Connection, Statement> insertFunction = it -> {
Function<Connection, Statement<?>> insertFunction = it -> {
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL statement [" + sql + "]");
@@ -837,17 +892,19 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
* Default implementation of {@link DatabaseClient.TypedInsertSpec}.
*/
@RequiredArgsConstructor
class DefaultTypedInsertSpec<T> implements TypedInsertSpec<T>, InsertSpec {
class DefaultTypedInsertSpec<T, R> implements TypedInsertSpec<T>, InsertSpec<R> {
private final Class<?> typeToInsert;
private final String table;
private final Publisher<T> objectToInsert;
private final BiFunction<Row, RowMetadata, R> mappingFunction;
DefaultTypedInsertSpec(Class<?> typeToInsert) {
DefaultTypedInsertSpec(Class<?> typeToInsert, BiFunction<Row, RowMetadata, R> mappingFunction) {
this.typeToInsert = typeToInsert;
this.table = dataAccessStrategy.getTableName(typeToInsert);
this.objectToInsert = Mono.empty();
this.mappingFunction = mappingFunction;
}
@Override
@@ -855,7 +912,7 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
Assert.hasText(tableName, "Table name must not be null or empty!");
return new DefaultTypedInsertSpec<>(typeToInsert, tableName, objectToInsert);
return new DefaultTypedInsertSpec<>(typeToInsert, tableName, objectToInsert, this.mappingFunction);
}
@Override
@@ -863,7 +920,7 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
Assert.notNull(objectToInsert, "Object to insert must not be null!");
return new DefaultTypedInsertSpec<>(typeToInsert, table, Mono.just(objectToInsert));
return new DefaultTypedInsertSpec<>(typeToInsert, table, Mono.just(objectToInsert), this.mappingFunction);
}
@Override
@@ -871,7 +928,20 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
Assert.notNull(objectToInsert, "Publisher to insert must not be null!");
return new DefaultTypedInsertSpec<>(typeToInsert, table, objectToInsert);
return new DefaultTypedInsertSpec<>(typeToInsert, table, objectToInsert, this.mappingFunction);
}
@Override
public <MR> FetchSpec<MR> map(BiFunction<Row, RowMetadata, MR> mappingFunction) {
Assert.notNull(mappingFunction, "Mapping function must not be null!");
return exchange(mappingFunction);
}
@Override
public FetchSpec<R> fetch() {
return exchange(this.mappingFunction);
}
@Override
@@ -879,12 +949,33 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
return Mono.from(objectToInsert).flatMapMany(toInsert -> exchange(toInsert, (row, md) -> row).all()).then();
}
@Override
public Mono<SqlResult<Map<String, Object>>> exchange() {
return Mono.from(objectToInsert).map(toInsert -> exchange(toInsert, ColumnMapRowMapper.INSTANCE));
private <MR> FetchSpec<MR> exchange(BiFunction<Row, RowMetadata, MR> mappingFunction) {
return new FetchSpec<MR>() {
@Override
public Mono<MR> one() {
return Mono.from(objectToInsert).flatMap(toInsert -> exchange(toInsert, mappingFunction).one());
}
@Override
public Mono<MR> first() {
return Mono.from(objectToInsert).flatMap(toInsert -> exchange(toInsert, mappingFunction).first());
}
@Override
public Flux<MR> all() {
return Flux.from(objectToInsert).flatMap(toInsert -> exchange(toInsert, mappingFunction).all());
}
@Override
public Mono<Integer> rowsUpdated() {
return Mono.from(objectToInsert).flatMapMany(toInsert -> exchange(toInsert, mappingFunction).rowsUpdated())
.collect(Collectors.summingInt(Integer::intValue));
}
};
}
private <R> SqlResult<R> exchange(Object toInsert, BiFunction<Row, RowMetadata, R> mappingFunction) {
private <MR> SqlResult<MR> exchange(Object toInsert, BiFunction<Row, RowMetadata, MR> mappingFunction) {
List<SettableValue> insertValues = dataAccessStrategy.getValuesToInsert(toInsert);
Set<String> columns = new LinkedHashSet<>();
@@ -919,7 +1010,8 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
return new DefaultSqlResult<>(DefaultDatabaseClient.this, //
sql, //
resultFunction, //
it -> resultFunction.apply(it).flatMap(Result::getRowsUpdated).next(), //
it -> resultFunction.apply(it).flatMap(Result::getRowsUpdated)
.collect(Collectors.summingInt(Integer::intValue)), //
mappingFunction);
}
}

View File

@@ -34,6 +34,33 @@ import org.springframework.jdbc.core.SqlProvider;
*/
class DefaultSqlResult<T> implements SqlResult<T> {
private final static SqlResult<?> EMPTY = new SqlResult<Object>() {
@Override
public <R> SqlResult<R> map(BiFunction<Row, RowMetadata, R> mappingFunction) {
return DefaultSqlResult.empty();
}
@Override
public Mono<Object> one() {
return Mono.empty();
}
@Override
public Mono<Object> first() {
return Mono.empty();
}
@Override
public Flux<Object> all() {
return Flux.empty();
}
@Override
public Mono<Integer> rowsUpdated() {
return Mono.empty();
}
};
private final ConnectionAccessor connectionAccessor;
private final String sql;
private final Function<Connection, Flux<Result>> resultFunction;
@@ -71,11 +98,22 @@ class DefaultSqlResult<T> implements SqlResult<T> {
});
}
/**
* Returns an empty {@link SqlResult}.
*
* @param <R>
* @return
*/
@SuppressWarnings("unchecked")
public static <R> SqlResult<R> empty() {
return (SqlResult<R>) EMPTY;
}
/* (non-Javadoc)
* @see org.springframework.data.jdbc.core.function.SqlResult#extract(java.util.function.BiFunction)
* @see org.springframework.data.jdbc.core.function.SqlResult#map(java.util.function.BiFunction)
*/
@Override
public <R> SqlResult<R> extract(BiFunction<Row, RowMetadata, R> mappingFunction) {
public <R> SqlResult<R> map(BiFunction<Row, RowMetadata, R> mappingFunction) {
return new DefaultSqlResult<>(connectionAccessor, sql, resultFunction, updatedRowsFunction, mappingFunction);
}

View File

@@ -34,5 +34,5 @@ public interface SqlResult<T> extends FetchSpec<T> {
* @param <R>
* @return a new {@link SqlResult} with {@link BiFunction mapping function} applied.
*/
<R> SqlResult<R> extract(BiFunction<Row, RowMetadata, R> mappingFunction);
<R> SqlResult<R> map(BiFunction<Row, RowMetadata, R> mappingFunction);
}

View File

@@ -32,7 +32,6 @@ import org.springframework.data.r2dbc.function.BindIdOperation;
import org.springframework.data.r2dbc.function.BindableOperation;
import org.springframework.data.r2dbc.function.DatabaseClient;
import org.springframework.data.r2dbc.function.DatabaseClient.GenericExecuteSpec;
import org.springframework.data.r2dbc.function.FetchSpec;
import org.springframework.data.r2dbc.function.ReactiveDataAccessStrategy;
import org.springframework.data.r2dbc.function.convert.MappingR2dbcConverter;
import org.springframework.data.r2dbc.function.convert.SettableValue;
@@ -66,8 +65,8 @@ public class SimpleR2dbcRepository<T, ID> implements ReactiveCrudRepository<T, I
return databaseClient.insert() //
.into(entity.getJavaType()) //
.using(objectToSave) //
.exchange() //
.flatMap(it -> it.extract(converter.populateIdIfNecessary(objectToSave)).one());
.map(converter.populateIdIfNecessary(objectToSave)) //
.one();
}
Object id = entity.getRequiredId(objectToSave);
@@ -83,8 +82,7 @@ public class SimpleR2dbcRepository<T, ID> implements ReactiveCrudRepository<T, I
update.bindId(wrapper, id);
return wrapper.getBoundOperation().as(entity.getJavaType()) //
.exchange() //
.flatMap(FetchSpec::rowsUpdated) //
.then() //
.thenReturn(objectToSave);
}
@@ -156,8 +154,9 @@ public class SimpleR2dbcRepository<T, ID> implements ReactiveCrudRepository<T, I
select.bindId(wrapper, id);
return wrapper.getBoundOperation().as(entity.getJavaType()) //
.exchange() //
.flatMap(it -> it.extract((r, md) -> r).first()).hasElement();
.map((r, md) -> r) //
.first() //
.hasElement();
}
/* (non-Javadoc)
@@ -220,8 +219,8 @@ public class SimpleR2dbcRepository<T, ID> implements ReactiveCrudRepository<T, I
return databaseClient.execute()
.sql(String.format("SELECT COUNT(%s) FROM %s", getIdColumnName(), entity.getTableName())) //
.exchange() //
.flatMap(it -> it.extract((r, md) -> r.get(0, Long.class)).first()) //
.map((r, md) -> r.get(0, Long.class)) //
.first() //
.defaultIfEmpty(0L);
}
@@ -312,7 +311,6 @@ public class SimpleR2dbcRepository<T, ID> implements ReactiveCrudRepository<T, I
public Mono<Void> deleteAll() {
return databaseClient.execute().sql(String.format("DELETE FROM %s", entity.getTableName())) //
.exchange() //
.then();
}