From 41247d49baf355e80352fae450f9165d14b17bfd Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 26 Oct 2020 17:47:20 +0100 Subject: [PATCH] R2DBC javadoc and code style revision See gh-25065 --- .../connection/ConnectionFactoryUtils.java | 77 +++++-------- .../r2dbc/connection/init/ScriptUtils.java | 38 +++---- .../AbstractRoutingConnectionFactory.java | 10 +- .../lookup/MapConnectionFactoryLookup.java | 1 - .../r2dbc/core/BindParameterSource.java | 6 +- .../r2dbc/core/ColumnMapRowMapper.java | 2 +- .../r2dbc/core/DatabaseClient.java | 55 +++++----- .../r2dbc/core/DefaultDatabaseClient.java | 19 ++-- .../core/DefaultDatabaseClientBuilder.java | 8 +- .../r2dbc/core/DefaultFetchSpec.java | 7 +- .../r2dbc/core/ExecuteFunction.java | 2 +- .../springframework/r2dbc/core/FetchSpec.java | 4 +- .../r2dbc/core/MapBindParameterSource.java | 22 ++-- .../r2dbc/core/NamedParameterUtils.java | 101 ++++++------------ .../springframework/r2dbc/core/Parameter.java | 23 ++-- .../springframework/r2dbc/core/ParsedSql.java | 6 +- .../r2dbc/core/PreparedOperation.java | 5 +- .../r2dbc/core/QueryOperation.java | 2 +- .../r2dbc/core/RowsFetchSpec.java | 7 +- .../r2dbc/core/SqlProvider.java | 2 +- .../r2dbc/core/StatementFilterFunction.java | 9 ++ .../r2dbc/core/StatementFilterFunctions.java | 47 -------- .../r2dbc/core/UpdatedRowsFetchSpec.java | 2 +- .../core/binding/AnonymousBindMarkers.java | 4 +- .../r2dbc/core/binding/BindMarker.java | 6 +- .../r2dbc/core/binding/BindMarkers.java | 1 - .../core/binding/BindMarkersFactory.java | 15 +-- .../binding/BindMarkersFactoryResolver.java | 51 +++------ .../r2dbc/core/binding/Bindings.java | 33 +++--- .../core/binding/IndexedBindMarkers.java | 9 +- .../r2dbc/core/binding/MutableBindings.java | 14 +-- .../r2dbc/core/binding/NamedBindMarkers.java | 6 +- 32 files changed, 219 insertions(+), 375 deletions(-) delete mode 100644 spring-r2dbc/src/main/java/org/springframework/r2dbc/core/StatementFilterFunctions.java diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/ConnectionFactoryUtils.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/ConnectionFactoryUtils.java index 59e1a4e722c..dc3fab49d32 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/ConnectionFactoryUtils.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/ConnectionFactoryUtils.java @@ -29,8 +29,6 @@ import io.r2dbc.spi.R2dbcTimeoutException; import io.r2dbc.spi.R2dbcTransientException; import io.r2dbc.spi.R2dbcTransientResourceException; import io.r2dbc.spi.Wrapped; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Mono; import org.springframework.core.Ordered; @@ -69,11 +67,6 @@ public abstract class ConnectionFactoryUtils { */ public static final int CONNECTION_SYNCHRONIZATION_ORDER = 1000; - private static final Log logger = LogFactory.getLog(ConnectionFactoryUtils.class); - - - private ConnectionFactoryUtils() {} - /** * Obtain a {@link Connection} from the given {@link ConnectionFactory}. @@ -112,48 +105,34 @@ public abstract class ConnectionFactoryUtils { if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) { conHolder.requested(); if (!conHolder.hasConnection()) { - - if (logger.isDebugEnabled()) { - logger.debug("Fetching resumed R2DBC Connection from ConnectionFactory"); - } return fetchConnection(connectionFactory).doOnNext(conHolder::setConnection); } return Mono.just(conHolder.getConnection()); } // Else we either got no holder or an empty thread-bound holder here. - if (logger.isDebugEnabled()) { - logger.debug("Fetching R2DBC Connection from ConnectionFactory"); - } - Mono con = fetchConnection(connectionFactory); - if (synchronizationManager.isSynchronizationActive()) { - - return con.flatMap(connection -> { - return Mono.just(connection).doOnNext(conn -> { - - // Use same Connection for further R2DBC actions within the transaction. - // Thread-bound object will get removed by synchronization at transaction completion. - ConnectionHolder holderToUse = conHolder; - if (holderToUse == null) { - holderToUse = new ConnectionHolder(conn); - } - else { - holderToUse.setConnection(conn); - } - holderToUse.requested(); - synchronizationManager - .registerSynchronization(new ConnectionSynchronization(holderToUse, connectionFactory)); - holderToUse.setSynchronizedWithTransaction(true); - if (holderToUse != conHolder) { - synchronizationManager.bindResource(connectionFactory, holderToUse); - } - }) // Unexpected exception from external delegation call -> close Connection and rethrow. - .onErrorResume(e -> releaseConnection(connection, connectionFactory).then(Mono.error(e))); - }); + return con.flatMap(connection -> Mono.just(connection).doOnNext(conn -> { + // Use same Connection for further R2DBC actions within the transaction. + // Thread-bound object will get removed by synchronization at transaction completion. + ConnectionHolder holderToUse = conHolder; + if (holderToUse == null) { + holderToUse = new ConnectionHolder(conn); + } + else { + holderToUse.setConnection(conn); + } + holderToUse.requested(); + synchronizationManager + .registerSynchronization(new ConnectionSynchronization(holderToUse, connectionFactory)); + holderToUse.setSynchronizedWithTransaction(true); + if (holderToUse != conHolder) { + synchronizationManager.bindResource(connectionFactory, holderToUse); + } + }) // Unexpected exception from external delegation call -> close Connection and rethrow. + .onErrorResume(e -> releaseConnection(connection, connectionFactory).then(Mono.error(e)))); } - return con; }).onErrorResume(NoTransactionException.class, e -> Mono.from(connectionFactory.create())); } @@ -356,9 +335,7 @@ public abstract class ConnectionFactoryUtils { @Override public Mono suspend() { if (this.holderActive) { - return TransactionSynchronizationManager.forCurrentTransaction() - .flatMap(synchronizationManager -> { - + return TransactionSynchronizationManager.forCurrentTransaction().flatMap(synchronizationManager -> { synchronizationManager.unbindResource(this.connectionFactory); if (this.connectionHolder.hasConnection() && !this.connectionHolder.isOpen()) { // Release Connection on suspend if the application doesn't keep @@ -371,7 +348,6 @@ public abstract class ConnectionFactoryUtils { return Mono.empty(); }); } - return Mono.empty(); } @@ -388,11 +364,10 @@ public abstract class ConnectionFactoryUtils { @Override public Mono beforeCompletion() { - // Release Connection early if the holder is not open anymore - // (that is, not used by another resource - // that has its own cleanup via transaction synchronization), - // to avoid issues with strict transaction implementations that expect - // the close call before transaction completion. + // Release Connection early if the holder is not open anymore (that is, + // not used by another resource that has its own cleanup via transaction + // synchronization), to avoid issues with strict transaction implementations + // that expect the close call before transaction completion. if (!this.connectionHolder.isOpen()) { return TransactionSynchronizationManager.forCurrentTransaction().flatMap(synchronizationManager -> { synchronizationManager.unbindResource(this.connectionFactory); @@ -414,8 +389,7 @@ public abstract class ConnectionFactoryUtils { if (this.holderActive) { // The bound ConnectionHolder might not be available anymore, // since afterCompletion might get called from a different thread. - return TransactionSynchronizationManager.forCurrentTransaction() - .flatMap(synchronizationManager -> { + return TransactionSynchronizationManager.forCurrentTransaction().flatMap(synchronizationManager -> { synchronizationManager.unbindResourceIfPossible(this.connectionFactory); this.holderActive = false; if (this.connectionHolder.hasConnection()) { @@ -426,7 +400,6 @@ public abstract class ConnectionFactoryUtils { return Mono.empty(); }); } - this.connectionHolder.reset(); return Mono.empty(); } diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/init/ScriptUtils.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/init/ScriptUtils.java index b34274b40dc..d914ffb4e44 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/init/ScriptUtils.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/init/ScriptUtils.java @@ -107,8 +107,6 @@ public abstract class ScriptUtils { private static final Log logger = LogFactory.getLog(ScriptUtils.class); - // utility constructor - private ScriptUtils() {} /** * Split an SQL script into separate statements delimited by the provided @@ -335,14 +333,11 @@ public abstract class ScriptUtils { return DataBufferUtils.join(DataBufferUtils.read(resource.getResource(), dataBufferFactory, 8192)) .handle((it, sink) -> { - try (InputStream is = it.asInputStream()) { - - InputStreamReader in = resource.getCharset() != null ? new InputStreamReader(is, resource.getCharset()) - : new InputStreamReader(is); + InputStreamReader in = (resource.getCharset() != null ? + new InputStreamReader(is, resource.getCharset()) : new InputStreamReader(is)); LineNumberReader lnr = new LineNumberReader(in); String script = readScript(lnr, commentPrefixes, separator, blockCommentEndDelimiter); - sink.next(script); sink.complete(); } @@ -548,9 +543,9 @@ public abstract class ScriptUtils { * @see org.springframework.r2dbc.connection.ConnectionFactoryUtils#releaseConnection */ public static Mono executeSqlScript(Connection connection, EncodedResource resource, - DataBufferFactory dataBufferFactory, boolean continueOnError, boolean ignoreFailedDrops, String commentPrefix, - @Nullable String separator, String blockCommentStartDelimiter, String blockCommentEndDelimiter) - throws ScriptException { + DataBufferFactory dataBufferFactory, boolean continueOnError, boolean ignoreFailedDrops, + String commentPrefix, @Nullable String separator, String blockCommentStartDelimiter, + String blockCommentEndDelimiter) throws ScriptException { return executeSqlScript(connection, resource, dataBufferFactory, continueOnError, ignoreFailedDrops, new String[] { commentPrefix }, separator, @@ -587,10 +582,10 @@ public abstract class ScriptUtils { * @see org.springframework.r2dbc.connection.ConnectionFactoryUtils#getConnection * @see org.springframework.r2dbc.connection.ConnectionFactoryUtils#releaseConnection */ - public static Mono executeSqlScript(Connection connection, EncodedResource resource, DataBufferFactory dataBufferFactory, - boolean continueOnError, - boolean ignoreFailedDrops, String[] commentPrefixes, @Nullable String separator, - String blockCommentStartDelimiter, String blockCommentEndDelimiter) throws ScriptException { + public static Mono executeSqlScript(Connection connection, EncodedResource resource, + DataBufferFactory dataBufferFactory, boolean continueOnError, boolean ignoreFailedDrops, + String[] commentPrefixes, @Nullable String separator, String blockCommentStartDelimiter, + String blockCommentEndDelimiter) throws ScriptException { if (logger.isDebugEnabled()) { logger.debug("Executing SQL script from " + resource); @@ -622,17 +617,15 @@ public abstract class ScriptUtils { }); if (logger.isDebugEnabled()) { - executeScript = executeScript.doOnComplete(() -> { - long elapsedTime = System.currentTimeMillis() - startTime; logger.debug("Executed SQL script from " + resource + " in " + elapsedTime + " ms."); }); } return executeScript.onErrorMap(ex -> !(ex instanceof ScriptException), - ex -> new UncategorizedScriptException("Failed to execute database script from resource [" + resource + "]", - ex)) + ex -> new UncategorizedScriptException( + "Failed to execute database script from resource [" + resource + "]", ex)) .then(); } @@ -644,22 +637,21 @@ public abstract class ScriptUtils { .collect(Collectors.summingLong(count -> count)); if (logger.isDebugEnabled()) { - execution = execution.doOnNext(rowsAffected -> logger.debug(rowsAffected + " returned as update count for SQL: " + statement)); + execution = execution.doOnNext(rowsAffected -> + logger.debug(rowsAffected + " returned as update count for SQL: " + statement)); } return execution.onErrorResume(ex -> { - boolean dropStatement = StringUtils.startsWithIgnoreCase(statement.trim(), "drop"); if (continueOnError || (dropStatement && ignoreFailedDrops)) { if (logger.isDebugEnabled()) { - logger.debug(ScriptStatementFailedException.buildErrorMessage(statement, statementNumber.get(), resource), - ex); + logger.debug(ScriptStatementFailedException.buildErrorMessage( + statement, statementNumber.get(), resource), ex); } } else { return Mono.error(new ScriptStatementFailedException(statement, statementNumber.get(), resource, ex)); } - return Mono.empty(); }).then(); } diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/lookup/AbstractRoutingConnectionFactory.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/lookup/AbstractRoutingConnectionFactory.java index 821b6945239..c02cc563731 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/lookup/AbstractRoutingConnectionFactory.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/lookup/AbstractRoutingConnectionFactory.java @@ -167,6 +167,7 @@ public abstract class AbstractRoutingConnectionFactory implements ConnectionFact */ protected ConnectionFactory resolveSpecifiedConnectionFactory(Object connectionFactory) throws IllegalArgumentException { + if (connectionFactory instanceof ConnectionFactory) { return (ConnectionFactory) connectionFactory; } @@ -174,17 +175,14 @@ public abstract class AbstractRoutingConnectionFactory implements ConnectionFact return this.connectionFactoryLookup.getConnectionFactory((String) connectionFactory); } else { - throw new IllegalArgumentException( - "Illegal connection factory value - only 'io.r2dbc.spi.ConnectionFactory' and 'String' supported: " - + connectionFactory); + throw new IllegalArgumentException("Illegal connection factory value - " + + "only 'io.r2dbc.spi.ConnectionFactory' and 'String' supported: " + connectionFactory); } } @Override public Mono create() { - return determineTargetConnectionFactory() // - .map(ConnectionFactory::create) // - .flatMap(Mono::from); + return determineTargetConnectionFactory().map(ConnectionFactory::create).flatMap(Mono::from); } @Override diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/lookup/MapConnectionFactoryLookup.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/lookup/MapConnectionFactoryLookup.java index 1598d1da4cb..2f8c2ed8754 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/lookup/MapConnectionFactoryLookup.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/lookup/MapConnectionFactoryLookup.java @@ -56,7 +56,6 @@ public class MapConnectionFactoryLookup implements ConnectionFactoryLookup { /** * Create a new instance of the {@link MapConnectionFactoryLookup} class. - * * @param connectionFactoryName the name under which the supplied {@link ConnectionFactory} is to be added * @param connectionFactory the {@link ConnectionFactory} to be added */ diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/BindParameterSource.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/BindParameterSource.java index ebc5bb19506..61211b98f5f 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/BindParameterSource.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/BindParameterSource.java @@ -46,7 +46,7 @@ interface BindParameterSource { /** * Return the parameter value for the requested named parameter. * @param paramName the name of the parameter - * @return the value of the specified parameter, can be {@code null} + * @return the value of the specified parameter (can be {@code null}) * @throws IllegalArgumentException if there is no value * for the requested parameter */ @@ -64,8 +64,8 @@ interface BindParameterSource { } /** - * Return parameter names of the underlying parameter source. - * @return parameter names of the underlying parameter source. + * Return the parameter names of the underlying parameter source. + * @return an iterator over the parameter names */ Iterable getParameterNames(); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ColumnMapRowMapper.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ColumnMapRowMapper.java index 5067a2bc6c7..1dbb5c61b41 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ColumnMapRowMapper.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ColumnMapRowMapper.java @@ -48,7 +48,7 @@ import org.springframework.util.LinkedCaseInsensitiveMap; */ public class ColumnMapRowMapper implements BiFunction> { - /** Default instance. */ + /** A default {@code ColumnMapRowMapper} instance. */ public final static ColumnMapRowMapper INSTANCE = new ColumnMapRowMapper(); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DatabaseClient.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DatabaseClient.java index 83e4c692a85..324e419ce00 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DatabaseClient.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DatabaseClient.java @@ -66,7 +66,7 @@ public interface DatabaseClient extends ConnectionAccessor { * SQL call along with options leading to the execution. The SQL string can * contain either native parameter bind markers or named parameters (e.g. * {@literal :foo, :bar}) when {@link NamedParameterExpander} is enabled. - * @param sql must not be {@code null} or empty + * @param sql the SQL statement * @return a new {@link GenericExecuteSpec} * @see NamedParameterExpander * @see DatabaseClient.Builder#namedParameters(boolean) @@ -80,7 +80,7 @@ public interface DatabaseClient extends ConnectionAccessor { * bind markers or named parameters (e.g. {@literal :foo, :bar}) when * {@link NamedParameterExpander} is enabled. *

Accepts {@link PreparedOperation} as SQL and binding {@link Supplier} - * @param sqlSupplier must not be {@code null} + * @param sqlSupplier a supplier for the SQL statement * @return a new {@link GenericExecuteSpec} * @see NamedParameterExpander * @see DatabaseClient.Builder#namedParameters(boolean) @@ -115,34 +115,31 @@ public interface DatabaseClient extends ConnectionAccessor { /** * Configure the {@link BindMarkersFactory BindMarkers} to be used. - * @param bindMarkers must not be {@code null} */ Builder bindMarkers(BindMarkersFactory bindMarkers); /** * Configure the {@link ConnectionFactory R2DBC connector}. - * @param factory must not be {@code null} */ Builder connectionFactory(ConnectionFactory factory); /** * Configure a {@link ExecuteFunction} to execute {@link Statement} objects. - * @param executeFunction must not be {@code null} * @see Statement#execute() */ Builder executeFunction(ExecuteFunction executeFunction); /** - * Configure whether to use named parameter expansion. Defaults to {@code true}. - * @param enabled {@code true} to use named parameter expansion. - * {@code false} to disable named parameter expansion. + * Configure whether to use named parameter expansion. + * Defaults to {@code true}. + * @param enabled {@code true} to use named parameter expansion; + * {@code false} to disable named parameter expansion * @see NamedParameterExpander */ Builder namedParameters(boolean enabled); /** * Configures a {@link Consumer} to configure this builder. - * @param builderConsumer must not be {@code null}. */ Builder apply(Consumer builderConsumer); @@ -162,28 +159,28 @@ public interface DatabaseClient extends ConnectionAccessor { * Bind a non-{@code null} value to a parameter identified by its * {@code index}. {@code value} can be either a scalar value or {@link Parameter}. * @param index zero based index to bind the parameter to - * @param value must not be {@code null}. Can be either a scalar value or {@link Parameter} + * @param value either a scalar value or {@link Parameter} */ GenericExecuteSpec bind(int index, Object value); /** * Bind a {@code null} value to a parameter identified by its {@code index}. * @param index zero based index to bind the parameter to - * @param type must not be {@code null} + * @param type the parameter type */ GenericExecuteSpec bindNull(int index, Class type); /** * Bind a non-{@code null} value to a parameter identified by its {@code name}. - * @param name must not be {@code null} or empty - * @param value must not be {@code null} + * @param name the name of the parameter + * @param value the value to bind */ GenericExecuteSpec bind(String name, Object value); /** * Bind a {@code null} value to a parameter identified by its {@code name}. - * @param name must not be {@code null} or empty - * @param type must not be {@code null} + * @param name the name of the parameter + * @param type the parameter type */ GenericExecuteSpec bindNull(String name, Class type); @@ -195,11 +192,11 @@ public interface DatabaseClient extends ConnectionAccessor { * DatabaseClient client = …; * client.sql("SELECT book_id FROM book").filter(statement -> statement.fetchSize(100)) * - * @param filter the filter to be added to the chain + * @param filterFunction the filter to be added to the chain */ - default GenericExecuteSpec filter(Function filter) { - Assert.notNull(filter, "Statement FilterFunction must not be null"); - return filter((statement, next) -> next.execute(filter.apply(statement))); + default GenericExecuteSpec filter(Function filterFunction) { + Assert.notNull(filterFunction, "Filter function must not be null"); + return filter((statement, next) -> next.execute(filterFunction.apply(statement))); } /** @@ -216,9 +213,9 @@ public interface DatabaseClient extends ConnectionAccessor { /** * Configure a result mapping {@link Function function} and enter the execution stage. - * @param mappingFunction must not be {@code null} - * @param result type. - * @return a {@link FetchSpec} for configuration what to fetch. Guaranteed to be not {@code null}. + * @param mappingFunction a function that maps from {@link Row} to the result type + * @param the result type + * @return a {@link FetchSpec} for configuration what to fetch */ default RowsFetchSpec map(Function mappingFunction) { Assert.notNull(mappingFunction, "Mapping function must not be null"); @@ -226,10 +223,11 @@ public interface DatabaseClient extends ConnectionAccessor { } /** - * Configure a result mapping {@link BiFunction function} and enter the execution stage. - * @param mappingFunction must not be {@code null} - * @param result type. - * @return a {@link FetchSpec} for configuration what to fetch. Guaranteed to be not {@code null}. + * Configure a result mapping {@link BiFunction function} and enter the execution stage. + * @param mappingFunction a function that maps from {@link Row} and {@link RowMetadata} + * to the result type + * @param the result type + * @return a {@link FetchSpec} for configuration what to fetch */ RowsFetchSpec map(BiFunction mappingFunction); @@ -239,8 +237,9 @@ public interface DatabaseClient extends ConnectionAccessor { FetchSpec> 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). + * 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 then(); } diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClient.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClient.java index c0d1a7a226d..366254ae4cf 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClient.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClient.java @@ -104,17 +104,14 @@ class DefaultDatabaseClient implements DatabaseClient { } @Override - public Mono inConnection(Function> action) - throws DataAccessException { + public Mono inConnection(Function> action) throws DataAccessException { Assert.notNull(action, "Callback object must not be null"); Mono connectionMono = getConnection().map( connection -> new ConnectionCloseHolder(connection, this::closeConnection)); return Mono.usingWhen(connectionMono, connectionCloseHolder -> { - // Create close-suppressing Connection proxy Connection connectionToUse = createConnectionProxy(connectionCloseHolder.connection); - try { return action.apply(connectionToUse); } @@ -129,18 +126,14 @@ class DefaultDatabaseClient implements DatabaseClient { } @Override - public Flux inConnectionMany(Function> action) - throws DataAccessException { + public Flux inConnectionMany(Function> action) throws DataAccessException { Assert.notNull(action, "Callback object must not be null"); Mono connectionMono = getConnection().map( connection -> new ConnectionCloseHolder(connection, this::closeConnection)); return Flux.usingWhen(connectionMono, connectionCloseHolder -> { - - // Create close-suppressing Connection proxy, also preparing returned - // Statements. + // Create close-suppressing Connection proxy, also preparing returned Statements. Connection connectionToUse = createConnectionProxy(connectionCloseHolder.connection); - try { return action.apply(connectionToUse); } @@ -237,7 +230,7 @@ class DefaultDatabaseClient implements DatabaseClient { this.byIndex = Collections.emptyMap(); this.byName = Collections.emptyMap(); this.sqlSupplier = sqlSupplier; - this.filterFunction = StatementFilterFunctions.empty(); + this.filterFunction = StatementFilterFunction.EMPTY_FILTER; } DefaultGenericExecuteSpec(Map byIndex, Map byName, @@ -309,7 +302,8 @@ class DefaultDatabaseClient implements DatabaseClient { @Override public DefaultGenericExecuteSpec filter(StatementFilterFunction filter) { Assert.notNull(filter, "Statement FilterFunction must not be null"); - return new DefaultGenericExecuteSpec(this.byIndex, this.byName, this.sqlSupplier, this.filterFunction.andThen(filter)); + return new DefaultGenericExecuteSpec( + this.byIndex, this.byName, this.sqlSupplier, this.filterFunction.andThen(filter)); } @Override @@ -458,7 +452,6 @@ class DefaultDatabaseClient implements DatabaseClient { Assert.state(StringUtils.hasText(sql), "SQL returned by SQL supplier must not be empty!"); return sql; } - } diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClientBuilder.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClientBuilder.java index add092bc728..c8811043aed 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClientBuilder.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClientBuilder.java @@ -81,7 +81,6 @@ class DefaultDatabaseClientBuilder implements DatabaseClient.Builder { Assert.notNull(this.connectionFactory, "ConnectionFactory must not be null"); BindMarkersFactory bindMarkers = this.bindMarkers; - if (bindMarkers == null) { if (this.namedParameters) { bindMarkers = BindMarkersFactoryResolver.resolve(this.connectionFactory); @@ -91,13 +90,12 @@ class DefaultDatabaseClientBuilder implements DatabaseClient.Builder { } } - return new DefaultDatabaseClient(bindMarkers, this.connectionFactory, - this.executeFunction, this.namedParameters); + return new DefaultDatabaseClient( + bindMarkers, this.connectionFactory, this.executeFunction, this.namedParameters); } @Override - public DatabaseClient.Builder apply( - Consumer builderConsumer) { + public DatabaseClient.Builder apply(Consumer builderConsumer) { Assert.notNull(builderConsumer, "BuilderConsumer must not be null"); builderConsumer.accept(this); return this; diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultFetchSpec.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultFetchSpec.java index ef2177ce1ee..85d8bd311a1 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultFetchSpec.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultFetchSpec.java @@ -52,6 +52,7 @@ class DefaultFetchSpec implements FetchSpec { Function> resultFunction, Function> updatedRowsFunction, BiFunction mappingFunction) { + this.sql = sql; this.connectionAccessor = connectionAccessor; this.resultFunction = resultFunction; @@ -64,18 +65,14 @@ class DefaultFetchSpec implements FetchSpec { public Mono one() { return all().buffer(2) .flatMap(list -> { - if (list.isEmpty()) { return Mono.empty(); } - if (list.size() > 1) { return Mono.error(new IncorrectResultSizeDataAccessException( - String.format("Query [%s] returned non unique result.", - this.sql), + String.format("Query [%s] returned non unique result.", this.sql), 1)); } - return Mono.just(list.get(0)); }).next(); } diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ExecuteFunction.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ExecuteFunction.java index 550974e5e4c..c60888f6ebf 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ExecuteFunction.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ExecuteFunction.java @@ -48,7 +48,7 @@ import org.reactivestreams.Publisher; public interface ExecuteFunction { /** - * Execute the given {@link Statement} for a stream of {@link Result}s. + * Execute the given {@link Statement} for a stream of {@link Result} objects. * @param statement the request to execute * @return the delayed result stream */ diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/FetchSpec.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/FetchSpec.java index 667da788340..0724b67a974 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/FetchSpec.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/FetchSpec.java @@ -25,4 +25,6 @@ package org.springframework.r2dbc.core; * @see RowsFetchSpec * @see UpdatedRowsFetchSpec */ -public interface FetchSpec extends RowsFetchSpec, UpdatedRowsFetchSpec {} +public interface FetchSpec extends RowsFetchSpec, UpdatedRowsFetchSpec { + +} diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/MapBindParameterSource.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/MapBindParameterSource.java index 14c8754fb45..e08ca268215 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/MapBindParameterSource.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/MapBindParameterSource.java @@ -40,30 +40,23 @@ class MapBindParameterSource implements BindParameterSource { * Create a new empty {@link MapBindParameterSource}. */ MapBindParameterSource() { - this(new LinkedHashMap<>()); + this.values = new LinkedHashMap<>(); } /** - * Creates a new {@link MapBindParameterSource} given {@link Map} of - * {@link Parameter}. - * - * @param values the parameter mapping. + * Creates a new {@link MapBindParameterSource} given {@link Map} of {@link Parameter}. + * @param values the parameter mapping */ MapBindParameterSource(Map values) { - Assert.notNull(values, "Values must not be null"); - this.values = values; } /** - * Add a key-value pair to the {@link MapBindParameterSource}. The value must not be - * {@code null}. - * - * @param paramName must not be {@code null}. - * @param value must not be {@code null}. - * @return {@code this} {@link MapBindParameterSource} + * Add a key-value pair to the {@link MapBindParameterSource}. + * @param paramName the name of the parameter + * @param value the parameter value to add (must not be {@code null}) */ MapBindParameterSource addValue(String paramName, Object value) { Assert.notNull(paramName, "Parameter name must not be null"); @@ -91,8 +84,7 @@ class MapBindParameterSource implements BindParameterSource { @Override public Object getValue(String paramName) throws IllegalArgumentException { if (!hasValue(paramName)) { - throw new IllegalArgumentException( - "No value registered for key '" + paramName + "'"); + throw new IllegalArgumentException("No value registered for key '" + paramName + "'"); } return this.values.get(paramName).getValue(); } diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java index fe988f1b349..96a5be28322 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java @@ -87,10 +87,9 @@ abstract class NamedParameterUtils { /** * Parse the SQL statement and locate any placeholders or named parameters. - * Namedparameters are substituted for a R2DBC placeholder. - * + * Named parameters are substituted for a R2DBC placeholder. * @param sql the SQL statement - * @return the parsed statement, represented as {@link ParsedSql} instance. + * @return the parsed statement, represented as {@link ParsedSql} instance */ public static ParsedSql parseSqlStatement(String sql) { Assert.notNull(sql, "SQL must not be null"); @@ -134,20 +133,22 @@ abstract class NamedParameterUtils { while (statement[j] != '}') { j++; if (j >= statement.length) { - throw new InvalidDataAccessApiUsageException("Non-terminated named parameter declaration " + - "at position " + i + " in statement: " + sql); + throw new InvalidDataAccessApiUsageException( + "Non-terminated named parameter declaration at position " + i + + " in statement: " + sql); } if (statement[j] == ':' || statement[j] == '{') { - throw new InvalidDataAccessApiUsageException("Parameter name contains invalid character '" + - statement[j] + "' at position " + i + " in statement: " + sql); + throw new InvalidDataAccessApiUsageException( + "Parameter name contains invalid character '" + statement[j] + + "' at position " + i + " in statement: " + sql); } } if (j - i > 2) { parameter = sql.substring(i + 2, j); - namedParameterCount = addNewNamedParameter(namedParameters, - namedParameterCount, parameter); - totalParameterCount = addNamedParameter(parameterList, - totalParameterCount, escapes, i, j + 1, parameter); + namedParameterCount = addNewNamedParameter( + namedParameters, namedParameterCount, parameter); + totalParameterCount = addNamedParameter( + parameterList, totalParameterCount, escapes, i, j + 1, parameter); } j++; } @@ -157,10 +158,10 @@ abstract class NamedParameterUtils { } if (j - i > 1) { parameter = sql.substring(i + 1, j); - namedParameterCount = addNewNamedParameter(namedParameters, - namedParameterCount, parameter); - totalParameterCount = addNamedParameter(parameterList, - totalParameterCount, escapes, i, j, parameter); + namedParameterCount = addNewNamedParameter( + namedParameters, namedParameterCount, parameter); + totalParameterCount = addNamedParameter( + parameterList, totalParameterCount, escapes, i, j, parameter); } } i = j - 1; @@ -190,8 +191,8 @@ abstract class NamedParameterUtils { return parsedSql; } - private static int addNamedParameter( - List parameterList, int totalParameterCount, int escapes, int i, int j, String parameter) { + private static int addNamedParameter(List parameterList, + int totalParameterCount, int escapes, int i, int j, String parameter) { parameterList.add(new ParameterHolder(parameter, i - escapes, j - escapes)); totalParameterCount++; @@ -256,10 +257,9 @@ abstract class NamedParameterUtils { /** * Parse the SQL statement and locate any placeholders or named parameters. Named * parameters are substituted for a R2DBC placeholder, and any select list is expanded - * to the required number of placeholders. Select lists may contain an array of - * objects, and in that case the placeholders will be grouped and enclosed with - * parentheses. This allows for the use of "expression lists" in the SQL statement - * like:

+ * to the required number of placeholders. Select lists may contain an array of objects, + * and in that case the placeholders will be grouped and enclosed with parentheses. + * This allows for the use of "expression lists" in the SQL statement like: * {@code select id, name, state from table where (name, age) in (('John', 35), ('Ann', 50))} *

The parameter values passed in are used to determine the number of placeholders to * be used for a select list. Select lists should be limited to 100 or fewer elements. @@ -269,17 +269,19 @@ abstract class NamedParameterUtils { * @param bindMarkersFactory the bind marker factory. * @param paramSource the source for named parameters * @return the expanded query that accepts bind parameters and allows for execution - * without further translation + * without further translation * @see #parseSqlStatement */ public static PreparedOperation substituteNamedParameters(ParsedSql parsedSql, BindMarkersFactory bindMarkersFactory, BindParameterSource paramSource) { + NamedParameters markerHolder = new NamedParameters(bindMarkersFactory); String originalSql = parsedSql.getOriginalSql(); List paramNames = parsedSql.getParameterNames(); if (paramNames.isEmpty()) { return new ExpandedQuery(originalSql, markerHolder, paramSource); } + StringBuilder actualSql = new StringBuilder(originalSql.length()); int lastIndex = 0; for (int i = 0; i < paramNames.size(); i++) { @@ -318,7 +320,6 @@ abstract class NamedParameterUtils { actualSql.append(marker.getPlaceholder(counter)); counter++; } - } } else { @@ -343,6 +344,7 @@ abstract class NamedParameterUtils { return (c < 128 && separatorIndex[c]) || Character.isWhitespace(c); } + // ------------------------------------------------------------------------- // Convenience methods operating on a plain SQL String // ------------------------------------------------------------------------- @@ -359,6 +361,7 @@ abstract class NamedParameterUtils { */ public static PreparedOperation substituteNamedParameters(String sql, BindMarkersFactory bindMarkersFactory, BindParameterSource paramSource) { + ParsedSql parsedSql = parseSqlStatement(sql); return substituteNamedParameters(parsedSql, bindMarkersFactory, paramSource); } @@ -407,9 +410,9 @@ abstract class NamedParameterUtils { public int hashCode() { return Objects.hash(this.parameterName, this.startIndex, this.endIndex); } - } + /** * Holder for bind markers progress. */ @@ -426,7 +429,6 @@ abstract class NamedParameterUtils { this.identifiable = factory.identifiablePlaceholders(); } - /** * Get the {@link NamedParameter} identified by {@code namedParameter}. * Parameter objects get created if they do not yet exist. @@ -434,20 +436,16 @@ abstract class NamedParameterUtils { * @return the named parameter */ NamedParameter getOrCreate(String namedParameter) { - List reference = this.references.computeIfAbsent( - namedParameter, ignore -> new ArrayList<>()); - + namedParameter, key -> new ArrayList<>()); if (reference.isEmpty()) { NamedParameter param = new NamedParameter(namedParameter); reference.add(param); return param; } - if (this.identifiable) { return reference.get(0); } - NamedParameter param = new NamedParameter(namedParameter); reference.add(param); return param; @@ -458,13 +456,13 @@ abstract class NamedParameterUtils { return this.references.get(name); } + class NamedParameter { private final String namedParameter; private final List placeholders = new ArrayList<>(); - NamedParameter(String namedParameter) { this.namedParameter = namedParameter; } @@ -475,9 +473,7 @@ abstract class NamedParameterUtils { * @return the placeholder to be used in the SQL statement */ String addPlaceholder() { - - BindMarker bindMarker = NamedParameters.this.bindMarkers.next( - this.namedParameter); + BindMarker bindMarker = NamedParameters.this.bindMarkers.next(this.namedParameter); this.placeholders.add(bindMarker); return bindMarker.getPlaceholder(); } @@ -487,17 +483,15 @@ abstract class NamedParameterUtils { } String getPlaceholder(int counter) { - while (counter + 1 > this.placeholders.size()) { addPlaceholder(); } - return this.placeholders.get(counter).getPlaceholder(); } } - } + /** * Expanded query that allows binding of parameters using parameter names that were * used to expand the query. Binding unrolls {@link Collection}s and nested arrays. @@ -510,35 +504,25 @@ abstract class NamedParameterUtils { private final BindParameterSource parameterSource; - - ExpandedQuery(String expandedSql, NamedParameters parameters, - BindParameterSource parameterSource) { + ExpandedQuery(String expandedSql, NamedParameters parameters, BindParameterSource parameterSource) { this.expandedSql = expandedSql; this.parameters = parameters; this.parameterSource = parameterSource; } - @SuppressWarnings("unchecked") public void bind(BindTarget target, String identifier, Object value) { - List bindMarkers = getBindMarkers(identifier); - if (bindMarkers == null) { target.bind(identifier, value); return; } - if (value instanceof Collection) { Collection collection = (Collection) value; - Iterator iterator = collection.iterator(); Iterator markers = bindMarkers.iterator(); - while (iterator.hasNext()) { - Object valueToBind = iterator.next(); - if (valueToBind instanceof Object[]) { Object[] objects = (Object[]) valueToBind; for (Object object : objects) { @@ -557,24 +541,19 @@ abstract class NamedParameterUtils { } } - private void bind(BindTarget target, Iterator markers, - Object valueToBind) { - + private void bind(BindTarget target, Iterator markers, Object valueToBind) { Assert.isTrue(markers.hasNext(), () -> String.format( "No bind marker for value [%s] in SQL [%s]. Check that the query was expanded using the same arguments.", valueToBind, toQuery())); - markers.next().bind(target, valueToBind); } public void bindNull(BindTarget target, String identifier, Class valueType) { List bindMarkers = getBindMarkers(identifier); - if (bindMarkers == null) { target.bindNull(identifier, valueType); return; } - for (BindMarker bindMarker : bindMarkers) { bindMarker.bindNull(target, valueType); } @@ -582,19 +561,14 @@ abstract class NamedParameterUtils { @Nullable List getBindMarkers(String identifier) { - List parameters = this.parameters.getMarker( - identifier); - + List parameters = this.parameters.getMarker(identifier); if (parameters == null) { return null; } - List markers = new ArrayList<>(); - for (NamedParameters.NamedParameter parameter : parameters) { markers.addAll(parameter.placeholders); } - return markers; } @@ -605,14 +579,10 @@ abstract class NamedParameterUtils { @Override public void bindTo(BindTarget target) { - for (String namedParameter : this.parameterSource.getParameterNames()) { - Object value = this.parameterSource.getValue(namedParameter); - if (value == null) { - bindNull(target, namedParameter, - this.parameterSource.getType(namedParameter)); + bindNull(target, namedParameter, this.parameterSource.getType(namedParameter)); } else { bind(target, namedParameter, value); @@ -624,7 +594,6 @@ abstract class NamedParameterUtils { public String toQuery() { return this.expandedSql; } - } } diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/Parameter.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/Parameter.java index 714bfe55049..69f9ed92bd7 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/Parameter.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/Parameter.java @@ -27,6 +27,7 @@ import org.springframework.util.ObjectUtils; * A database value that can be set in a statement. * * @author Mark Paluch + * @author Juergen Hoeller * @since 5.3 */ public final class Parameter { @@ -36,6 +37,7 @@ public final class Parameter { private final Class type; + private Parameter(@Nullable Object value, Class type) { Assert.notNull(type, "Type must not be null"); this.value = value; @@ -45,7 +47,7 @@ public final class Parameter { /** * Create a new {@link Parameter} from {@code value}. - * @param value must not be {@code null} + * @param value the parameter value * @return the {@link Parameter} value for {@code value} */ public static Parameter from(Object value) { @@ -55,12 +57,12 @@ public final class Parameter { /** * Create a new {@link Parameter} from {@code value} and {@code type}. - * @param value can be {@code null} - * @param type must not be {@code null} + * @param value the parameter value (can be {@code null}) + * @param type the parameter type * @return the {@link Parameter} value for {@code value} */ public static Parameter fromOrEmpty(@Nullable Object value, Class type) { - return value == null ? empty(type) : new Parameter(value, ClassUtils.getUserClass(value)); + return (value == null ? empty(type) : new Parameter(value, ClassUtils.getUserClass(value))); } /** @@ -74,7 +76,7 @@ public final class Parameter { /** - * Return the column value. Can be {@code null}. + * Return the column value (can be {@code null}). * @see #hasValue() */ @Nullable @@ -83,14 +85,14 @@ public final class Parameter { } /** - * Returns the column value type. Must be also present if the {@code value} is {@code null}. + * Return the column value type. Must be also present if the {@code value} is {@code null}. */ public Class getType() { return this.type; } /** - * Returns whether this {@link Parameter} has a value. + * Return whether this {@link Parameter} has a value. * @return {@code false} if {@link #getValue()} is {@code null} */ public boolean hasValue() { @@ -98,7 +100,7 @@ public final class Parameter { } /** - * Returns whether this {@link Parameter} has a empty. + * Return whether this {@link Parameter} has a empty. * @return {@code true} if {@link #getValue()} is {@code null} */ public boolean isEmpty() { @@ -115,7 +117,8 @@ public final class Parameter { return false; } Parameter other = (Parameter) obj; - return ObjectUtils.nullSafeEquals(this.value, other.value) && ObjectUtils.nullSafeEquals(this.type, other.type); + return (ObjectUtils.nullSafeEquals(this.value, other.value) && + ObjectUtils.nullSafeEquals(this.type, other.type)); } @Override @@ -125,7 +128,7 @@ public final class Parameter { @Override public String toString() { - return "Parameter[value=" + this.value + ", type=" + this.type + ']'; + return "Parameter[value=" + this.value + ",type=" + this.type.getName() + "]"; } } diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ParsedSql.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ParsedSql.java index 818cae130ec..0ae2ccf00c1 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ParsedSql.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ParsedSql.java @@ -28,11 +28,11 @@ import java.util.List; */ class ParsedSql { - private String originalSql; + private final String originalSql; - private List parameterNames = new ArrayList<>(); + private final List parameterNames = new ArrayList<>(); - private List parameterIndexes = new ArrayList<>(); + private final List parameterIndexes = new ArrayList<>(); private int namedParameterCount; diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/PreparedOperation.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/PreparedOperation.java index 83e0ac0aa08..6164063f68a 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/PreparedOperation.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/PreparedOperation.java @@ -24,6 +24,7 @@ import org.springframework.r2dbc.core.binding.BindTarget; * Extension to {@link QueryOperation} for a prepared SQL query * {@link Supplier} with bound parameters. Contains parameter * bindings that can be {@link #bindTo bound} bound to a {@link BindTarget}. + * *

Can be executed with {@link org.springframework.r2dbc.core.DatabaseClient}. * * @author Mark Paluch @@ -35,13 +36,13 @@ public interface PreparedOperation extends QueryOperation { /** * Return the underlying query source. - * @return the query source, such as a statement/criteria object. + * @return the query source, such as a statement/criteria object */ T getSource(); /** * Apply bindings to {@link BindTarget}. - * @param target the target to apply bindings to. + * @param target the target to apply bindings to */ void bindTo(BindTarget target); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/QueryOperation.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/QueryOperation.java index 56321a19084..b7b0d639f2d 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/QueryOperation.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/QueryOperation.java @@ -32,7 +32,7 @@ import java.util.function.Supplier; public interface QueryOperation extends Supplier { /** - * Returns the string-representation of this operation to + * Return the string-representation of this operation to * be used with {@link io.r2dbc.spi.Statement} creation. * @return the operation as SQL string * @see io.r2dbc.spi.Connection#createStatement(String) diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/RowsFetchSpec.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/RowsFetchSpec.java index 4307858a10a..310b9235389 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/RowsFetchSpec.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/RowsFetchSpec.java @@ -30,21 +30,20 @@ public interface RowsFetchSpec { /** * Get exactly zero or one result. - * - * @return a mono emitting one element. {@link Mono#empty()} if no match found. + * @return a Mono emitting one element, or {@link Mono#empty()} if no match found. * Completes with {@code IncorrectResultSizeDataAccessException} if more than one match found */ Mono one(); /** * Get the first or no result. - * @return a mono emitting the first element. {@link Mono#empty()} if no match found + * @return a Mono emitting the first element, or {@link Mono#empty()} if no match found */ Mono first(); /** * Get all matching elements. - * @return a flux emitting all results + * @return a Flux emitting all results */ Flux all(); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/SqlProvider.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/SqlProvider.java index 731142d7f41..a46c98af84c 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/SqlProvider.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/SqlProvider.java @@ -33,7 +33,7 @@ public interface SqlProvider { /** * Return the SQL string for this object, i.e. * typically the SQL used for creating statements. - * @return the SQL string, or {@code null} + * @return the SQL string, or {@code null} if not available */ @Nullable String getSql(); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/StatementFilterFunction.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/StatementFilterFunction.java index 281c22574ad..37f98a81a6d 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/StatementFilterFunction.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/StatementFilterFunction.java @@ -24,18 +24,27 @@ import org.springframework.util.Assert; /** * Represents a function that filters an {@link ExecuteFunction execute function}. + * *

The filter is executed when a {@link org.reactivestreams.Subscriber} subscribes * to the {@link Publisher} returned by the {@link DatabaseClient}. + * *

StatementFilterFunctions are typically used to specify additional details on * the Statement objects such as {@code fetchSize} or key generation. * * @author Mark Paluch + * @author Juergen Hoeller * @since 5.3 * @see ExecuteFunction */ @FunctionalInterface public interface StatementFilterFunction { + /** + * An empty {@link StatementFilterFunction} that delegates to {@link ExecuteFunction}. + */ + StatementFilterFunction EMPTY_FILTER = (statement, next) -> next.execute(statement); + + /** * Apply this filter to the given {@link Statement} and {@link ExecuteFunction}. *

The given {@link ExecuteFunction} represents the next entity in the chain, diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/StatementFilterFunctions.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/StatementFilterFunctions.java deleted file mode 100644 index c79c16a2c80..00000000000 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/StatementFilterFunctions.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.r2dbc.core; - -import io.r2dbc.spi.Result; -import io.r2dbc.spi.Statement; -import org.reactivestreams.Publisher; - -/** - * Collection of default {@link StatementFilterFunction}s. - * - * @author Mark Paluch - * @since 5.3 - */ -enum StatementFilterFunctions implements StatementFilterFunction { - - EMPTY_FILTER; - - - @Override - public Publisher filter(Statement statement, ExecuteFunction next) { - return next.execute(statement); - } - - /** - * Return an empty {@link StatementFilterFunction} that delegates to {@link ExecuteFunction}. - * @return an empty {@link StatementFilterFunction} that delegates to {@link ExecuteFunction}. - */ - public static StatementFilterFunction empty() { - return EMPTY_FILTER; - } - -} diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/UpdatedRowsFetchSpec.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/UpdatedRowsFetchSpec.java index b9b20fbb2c3..4af2ffc834b 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/UpdatedRowsFetchSpec.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/UpdatedRowsFetchSpec.java @@ -28,7 +28,7 @@ public interface UpdatedRowsFetchSpec { /** * Get the number of updated rows. - * @return a mono emitting the number of updated rows + * @return a Mono emitting the number of updated rows */ Mono rowsUpdated(); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/AnonymousBindMarkers.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/AnonymousBindMarkers.java index 60cae994f32..49860a04099 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/AnonymousBindMarkers.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/AnonymousBindMarkers.java @@ -34,8 +34,8 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; */ class AnonymousBindMarkers implements BindMarkers { - private static final AtomicIntegerFieldUpdater COUNTER_INCREMENTER = AtomicIntegerFieldUpdater - .newUpdater(AnonymousBindMarkers.class, "counter"); + private static final AtomicIntegerFieldUpdater COUNTER_INCREMENTER = + AtomicIntegerFieldUpdater.newUpdater(AnonymousBindMarkers.class, "counter"); private final String placeholder; diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarker.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarker.java index 7e90397e2b8..5fb53c47c19 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarker.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarker.java @@ -39,8 +39,8 @@ public interface BindMarker { /** * Bind the given {@code value} to the {@link Statement} using the underlying binding strategy. * @param bindTarget the target to bind the value to - * @param value the actual value. Must not be {@code null} - * Use {@link #bindNull(BindTarget, Class)} for {@code null} values + * @param value the actual value (must not be {@code null}; + * use {@link #bindNull(BindTarget, Class)} for {@code null} values) * @see Statement#bind */ void bind(BindTarget bindTarget, Object value); @@ -48,7 +48,7 @@ public interface BindMarker { /** * Bind a {@code null} value to the {@link Statement} using the underlying binding strategy. * @param bindTarget the target to bind the value to - * @param valueType value type, must not be {@code null} + * @param valueType the value type (must not be {@code null}) * @see Statement#bindNull */ void bindNull(BindTarget bindTarget, Class valueType); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkers.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkers.java index 13e2537198b..af5a9fd48ca 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkers.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkers.java @@ -36,7 +36,6 @@ public interface BindMarkers { /** * Create a new {@link BindMarker}. - * @return a new {@link BindMarker} */ BindMarker next(); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactory.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactory.java index 3281dd00a53..90cff2a4eb5 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactory.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactory.java @@ -40,24 +40,20 @@ public interface BindMarkersFactory { /** * Create a new {@link BindMarkers} instance. - * @return a new {@link BindMarkers} instance */ BindMarkers create(); /** - * Return whether the {@link BindMarkersFactory} uses identifiable - * placeholders. - * @return whether the {@link BindMarkersFactory} uses identifiable - * placeholders. {@code false} if multiple placeholders cannot be - * distinguished by just the {@link BindMarker#getPlaceholder() placeholder} - * identifier. + * Return whether the {@link BindMarkersFactory} uses identifiable placeholders: + * {@code false} if multiple placeholders cannot be distinguished by just the + * {@link BindMarker#getPlaceholder() placeholder} identifier. */ default boolean identifiablePlaceholders() { return true; } - // Static, factory methods + // Static factory methods /** * Create index-based {@link BindMarkers} using indexes to bind parameters. @@ -88,12 +84,10 @@ public interface BindMarkersFactory { static BindMarkersFactory anonymous(String placeholder) { Assert.hasText(placeholder, "Placeholder must not be empty!"); return new BindMarkersFactory() { - @Override public BindMarkers create() { return new AnonymousBindMarkers(placeholder); } - @Override public boolean identifiablePlaceholders() { return false; @@ -140,6 +134,7 @@ public interface BindMarkersFactory { */ static BindMarkersFactory named(String prefix, String namePrefix, int maxLength, Function hintFilterFunction) { + Assert.notNull(prefix, "Prefix must not be null"); Assert.notNull(namePrefix, "Index prefix must not be null"); Assert.notNull(hintFilterFunction, "Hint filter function must not be null"); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolver.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolver.java index 18ada18f34e..e8eead572f8 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolver.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolver.java @@ -45,31 +45,25 @@ public final class BindMarkersFactoryResolver { /** - * Retrieve a {@link BindMarkersFactory} by inspecting {@link ConnectionFactory} and - * its metadata. - * + * Retrieve a {@link BindMarkersFactory} by inspecting {@link ConnectionFactory} + * and its metadata. * @param connectionFactory the connection factory to inspect * @return the resolved {@link BindMarkersFactory} - * @throws NoBindMarkersFactoryException if no {@link BindMarkersFactory} can be - * resolved + * @throws NoBindMarkersFactoryException if no {@link BindMarkersFactory} can be resolved */ public static BindMarkersFactory resolve(ConnectionFactory connectionFactory) { - for (BindMarkerFactoryProvider detector : DETECTORS) { - BindMarkersFactory bindMarkersFactory = detector.getBindMarkers( - connectionFactory); + BindMarkersFactory bindMarkersFactory = detector.getBindMarkers(connectionFactory); if (bindMarkersFactory != null) { return bindMarkersFactory; } } - - throw new NoBindMarkersFactoryException( - String.format("Cannot determine a BindMarkersFactory for %s using %s", - connectionFactory.getMetadata().getName(), connectionFactory)); + throw new NoBindMarkersFactoryException(String.format( + "Cannot determine a BindMarkersFactory for %s using %s", + connectionFactory.getMetadata().getName(), connectionFactory)); } - // utility constructor. private BindMarkersFactoryResolver() { } @@ -84,16 +78,13 @@ public final class BindMarkersFactoryResolver { public interface BindMarkerFactoryProvider { /** - * Returns a {@link BindMarkersFactory} for a {@link ConnectionFactory}. - * - * @param connectionFactory the connection factory to be used with the - * {@link BindMarkersFactory}. + * Return a {@link BindMarkersFactory} for a {@link ConnectionFactory}. + * @param connectionFactory the connection factory to be used with the {@link BindMarkersFactory} * @return the {@link BindMarkersFactory} if the {@link BindMarkerFactoryProvider} - * can provide a bind marker factory object, otherwise {@code null} + * can provide a bind marker factory object, otherwise {@code null} */ @Nullable BindMarkersFactory getBindMarkers(ConnectionFactory connectionFactory); - } @@ -102,18 +93,15 @@ public final class BindMarkersFactoryResolver { * {@link BindMarkersFactory}. */ @SuppressWarnings("serial") - public static class NoBindMarkersFactoryException - extends NonTransientDataAccessException { + public static class NoBindMarkersFactoryException extends NonTransientDataAccessException { /** * Constructor for NoBindMarkersFactoryException. - * * @param msg the detail message */ public NoBindMarkersFactoryException(String msg) { super(msg); } - } @@ -125,13 +113,13 @@ public final class BindMarkersFactoryResolver { */ static class BuiltInBindMarkersFactoryProvider implements BindMarkerFactoryProvider { - private static final Map BUILTIN = new LinkedCaseInsensitiveMap<>( - Locale.ENGLISH); + private static final Map BUILTIN = + new LinkedCaseInsensitiveMap<>(Locale.ENGLISH); static { BUILTIN.put("H2", BindMarkersFactory.indexed("$", 1)); BUILTIN.put("Microsoft SQL Server", BindMarkersFactory.named("@", "P", 32, - BuiltInBindMarkersFactoryProvider::filterBindMarker)); + BuiltInBindMarkersFactoryProvider::filterBindMarker)); BUILTIN.put("MySQL", BindMarkersFactory.anonymous("?")); BUILTIN.put("MariaDB", BindMarkersFactory.anonymous("?")); BUILTIN.put("PostgreSQL", BindMarkersFactory.indexed("$", 1)); @@ -142,40 +130,31 @@ public final class BindMarkersFactoryResolver { public BindMarkersFactory getBindMarkers(ConnectionFactory connectionFactory) { ConnectionFactoryMetadata metadata = connectionFactory.getMetadata(); BindMarkersFactory r2dbcDialect = BUILTIN.get(metadata.getName()); - if (r2dbcDialect != null) { return r2dbcDialect; } - - for (String it : BUILTIN.keySet()) { if (metadata.getName().contains(it)) { return BUILTIN.get(it); } } - return null; } private static String filterBindMarker(CharSequence input) { - StringBuilder builder = new StringBuilder(); - + StringBuilder builder = new StringBuilder(input.length()); for (int i = 0; i < input.length(); i++) { - char ch = input.charAt(i); // ascii letter or digit if (Character.isLetterOrDigit(ch) && ch < 127) { builder.append(ch); } } - if (builder.length() == 0) { return ""; } - return "_" + builder.toString(); } - } } diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/Bindings.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/Bindings.java index 34bfae03b8f..63cf20dc5fc 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/Bindings.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/Bindings.java @@ -55,11 +55,11 @@ public class Bindings implements Iterable { } /** - * Create {@link Bindings} from a {@link Map}. - * @param bindings must not be {@code null} + * Create {@link Bindings} from the given collection. + * @param bindings a collection of {@link Binding} objects */ public Bindings(Collection bindings) { - Assert.notNull(bindings, "Bindings must not be null"); + Assert.notNull(bindings, "Collection must not be null"); Map mapping = CollectionUtils.newLinkedHashMap(bindings.size()); bindings.forEach(binding -> mapping.put(binding.getBindMarker(), binding)); this.bindings = mapping; @@ -75,10 +75,10 @@ public class Bindings implements Iterable { } /** - * Merge this bindings with an other {@link Bindings} object and create a new merged - * {@link Bindings} object. + * Merge this bindings with an other {@link Bindings} object and + * create a new merged {@link Bindings} object. * @param other the object to merge with - * @return a new, merged {@link Bindings} object + * @return a newly merged {@link Bindings} object */ public Bindings and(Bindings other) { return merge(this, other); @@ -116,25 +116,23 @@ public class Bindings implements Iterable { /** - * Create a new, empty {@link Bindings} object. - * @return a new, empty {@link Bindings} object. + * Return an empty {@link Bindings} object. */ public static Bindings empty() { return EMPTY; } /** - * Merge this bindings with an other {@link Bindings} object and create a new merged - * {@link Bindings} object. + * Merge this bindings with an other {@link Bindings} object and + * create a new merged {@link Bindings} object. * @param left the left object to merge with * @param right the right object to merge with - * @return a new, merged {@link Bindings} object + * @return a newly merged {@link Bindings} object */ public static Bindings merge(Bindings left, Bindings right) { Assert.notNull(left, "Left side Bindings must not be null"); Assert.notNull(right, "Right side Bindings must not be null"); - List result = new ArrayList<>( - left.getBindings().size() + right.getBindings().size()); + List result = new ArrayList<>(left.getBindings().size() + right.getBindings().size()); result.addAll(left.getBindings().values()); result.addAll(right.getBindings().values()); return new Bindings(result); @@ -154,7 +152,6 @@ public class Bindings implements Iterable { /** * Return the associated {@link BindMarker}. - * @return the associated {@link BindMarker}. */ public BindMarker getBindMarker() { return this.marker; @@ -162,8 +159,8 @@ public class Bindings implements Iterable { /** * Return whether the binding has a value associated with it. - * @return {@code true} if there is a value present, otherwise {@code false} - * for a {@code NULL} binding. + * @return {@code true} if there is a value present, + * otherwise {@code false} for a {@code NULL} binding */ public abstract boolean hasValue(); @@ -177,8 +174,8 @@ public class Bindings implements Iterable { /** * Return the binding value. - * @return value of this binding. Can be {@code null} - * if this is a {@code NULL} binding. + * @return the value of this binding + * (can be {@code null} if this is a {@code NULL} binding) */ @Nullable public abstract Object getValue(); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/IndexedBindMarkers.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/IndexedBindMarkers.java index c3cfc6ffcfa..5f14d937b4f 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/IndexedBindMarkers.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/IndexedBindMarkers.java @@ -22,14 +22,15 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; * Index-based bind marker. This implementation creates indexed bind * markers using a numeric index and an optional prefix for bind markers * to be represented within the query string. + * * @author Mark Paluch * @author Jens Schauder * @since 5.3 */ class IndexedBindMarkers implements BindMarkers { - private static final AtomicIntegerFieldUpdater COUNTER_INCREMENTER = AtomicIntegerFieldUpdater - .newUpdater(IndexedBindMarkers.class, "counter"); + private static final AtomicIntegerFieldUpdater COUNTER_INCREMENTER = + AtomicIntegerFieldUpdater.newUpdater(IndexedBindMarkers.class, "counter"); private final int offset; @@ -59,6 +60,7 @@ class IndexedBindMarkers implements BindMarkers { return new IndexedBindMarker(this.prefix + "" + (index + this.offset), index); } + /** * A single indexed bind marker. * @author Mark Paluch @@ -69,13 +71,11 @@ class IndexedBindMarkers implements BindMarkers { private final int index; - IndexedBindMarker(String placeholder, int index) { this.placeholder = placeholder; this.index = index; } - @Override public String getPlaceholder() { return this.placeholder; @@ -94,7 +94,6 @@ class IndexedBindMarkers implements BindMarkers { public int getIndex() { return this.index; } - } } diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/MutableBindings.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/MutableBindings.java index 82d8ac92e7c..16758b41bac 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/MutableBindings.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/MutableBindings.java @@ -36,7 +36,7 @@ public class MutableBindings extends Bindings { /** * Create new {@link MutableBindings}. - * @param markers must not be {@code null}. + * @param markers the {@link BindMarkers} to wrap */ public MutableBindings(BindMarkers markers) { super(new LinkedHashMap<>()); @@ -66,8 +66,8 @@ public class MutableBindings extends Bindings { /** * Bind a value to {@link BindMarker}. - * @param marker must not be {@code null} - * @param value must not be {@code null} + * @param marker the {@link BindMarker} to bind to + * @param value the value to bind */ public MutableBindings bind(BindMarker marker, Object value) { Assert.notNull(marker, "BindMarker must not be null"); @@ -79,7 +79,7 @@ public class MutableBindings extends Bindings { /** * Bind a value and return the related {@link BindMarker}. * Increments {@link BindMarkers} state. - * @param value must not be {@code null} + * @param value the value to bind */ public BindMarker bind(Object value) { Assert.notNull(value, "Value must not be null"); @@ -90,8 +90,8 @@ public class MutableBindings extends Bindings { /** * Bind a {@code NULL} value to {@link BindMarker}. - * @param marker must not be {@code null} - * @param valueType must not be {@code null} + * @param marker the {@link BindMarker} to bind to + * @param valueType the value type */ public MutableBindings bindNull(BindMarker marker, Class valueType) { Assert.notNull(marker, "BindMarker must not be null"); @@ -103,7 +103,7 @@ public class MutableBindings extends Bindings { /** * Bind a {@code NULL} value and return the related {@link BindMarker}. * Increments {@link BindMarkers} state. - * @param valueType must not be {@code null} + * @param valueType the value type */ public BindMarker bindNull(Class valueType) { Assert.notNull(valueType, "Value type must not be null"); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/NamedBindMarkers.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/NamedBindMarkers.java index fab7caf028f..ac2f0157aff 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/NamedBindMarkers.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/NamedBindMarkers.java @@ -29,8 +29,8 @@ import org.springframework.util.Assert; */ class NamedBindMarkers implements BindMarkers { - private static final AtomicIntegerFieldUpdater COUNTER_INCREMENTER = AtomicIntegerFieldUpdater - .newUpdater(NamedBindMarkers.class, "counter"); + private static final AtomicIntegerFieldUpdater COUNTER_INCREMENTER = + AtomicIntegerFieldUpdater.newUpdater(NamedBindMarkers.class, "counter"); private final String prefix; @@ -88,7 +88,6 @@ class NamedBindMarkers implements BindMarkers { private final String identifier; NamedBindMarker(String placeholder, String identifier) { - this.placeholder = placeholder; this.identifier = identifier; } @@ -107,7 +106,6 @@ class NamedBindMarkers implements BindMarkers { public void bindNull(BindTarget target, Class valueType) { target.bindNull(this.identifier, valueType); } - } }