diff --git a/pom.xml b/pom.xml index e94e7af9..da8dc746 100644 --- a/pom.xml +++ b/pom.xml @@ -1,11 +1,13 @@ - + 4.0.0 org.springframework.data spring-data-r2dbc - 1.2.0-SNAPSHOT + 1.2.0-gh-368-SNAPSHOT Spring Data R2DBC Spring Data module for R2DBC @@ -107,6 +109,11 @@ ${springdata.relational} + + org.springframework + spring-r2dbc + + org.springframework spring-tx diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index 18e5f7e9..16c2c6f9 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -52,3 +52,4 @@ include::reference/kotlin.adoc[leveloffset=+1] :numbered!: include::{spring-data-commons-docs}/repository-query-keywords-reference.adoc[leveloffset=+1] include::{spring-data-commons-docs}/repository-query-return-types-reference.adoc[leveloffset=+1] +include::reference/r2dbc-upgrading.adoc[leveloffset=+1] diff --git a/src/main/asciidoc/new-features.adoc b/src/main/asciidoc/new-features.adoc index d4bb2a13..0bf96c1c 100644 --- a/src/main/asciidoc/new-features.adoc +++ b/src/main/asciidoc/new-features.adoc @@ -4,6 +4,7 @@ [[new-features.1-2-0]] == What's New in Spring Data R2DBC 1.2.0 +* Deprecate Spring Data R2DBC `DatabaseClient` and move off deprecated API in favor of Spring R2DBC. Consult the <> for further details. * Support for <>. * <> through `@EnableR2dbcAuditing`. diff --git a/src/main/asciidoc/reference/r2dbc-upgrading.adoc b/src/main/asciidoc/reference/r2dbc-upgrading.adoc new file mode 100644 index 00000000..0507840a --- /dev/null +++ b/src/main/asciidoc/reference/r2dbc-upgrading.adoc @@ -0,0 +1,58 @@ +[appendix] +[[migration-guide]] += Migration Guide + +The following sections explain how to migrate to a newer version of Spring Data R2DBC. + +[[upgrading.1.1-1.2]] +== Upgrading from 1.1.x to 1.2.x + +Spring Data R2DBC was developed with the intent to evaluate how well R2DBC can integrate with Spring applications. +One of the main aspects was to move core support into Spring Framework once R2DBC support has proven useful. +Spring Framework 5.3 ships with a new module: Spring R2DBC (`spring-r2dbc`). + +`spring-r2dbc` ships core R2DBC functionality (a slim variant of `DatabaseClient`, Transaction Manager, Connection Factory initialization, Exception translation) that was initially provided by Spring Data R2DBC. The 1.2.0 release aligns with what's provided in Spring R2DBC by making several changes outlined in the following sections. + +Spring R2DBC's `DatabaseClient` is a more lightweight implementation that encapsulates a pure SQL-oriented interface. +You will notice that the method to run SQL statements changed from `DatabaseClient.execute(…)` to `DatabaseClient.sql(…)`. +The fluent API for CRUD operations has moved into `R2dbcEntityTemplate`. + +[[upgrading.1.1-1.2.deprecation]] +=== Deprecations + +* Deprecation of `o.s.d.r2dbc.core.DatabaseClient` and its support classes `ConnectionAccessor`, `FetchSpec`, `SqlProvider` and a few more. +Named parameter support classes such as `NamedParameterExpander` are encapsulated by Spring R2DBC's `DatabaseClient` implementation hence we're not providing replacements as this was internal API in the first place. +Use `o.s.r2dbc.core.DatabaseClient` and their Spring R2DBC replacements available from `org.springframework.r2dbc.core`. +Entity-based methods (`select`/`insert`/`update`/`delete`) methods are available through `R2dbcEntityTemplate` which was introduced with version 1.1. +* Deprecation of `o.s.d.r2dbc.connectionfactory`, `o.s.d.r2dbc.connectionfactory.init`, and `o.s.d.r2dbc.connectionfactory.lookup` packages. +Use Spring R2DBC's variant which you can find at `o.s.r2dbc.connection`. +* Deprecation of `o.s.d.r2dbc.convert.ColumnMapRowMapper`. +Use `o.s.r2dbc.core.ColumnMapRowMapper` instead. +* Deprecation of binding support classes `o.s.d.r2dbc.dialect.Bindings`, `BindMarker`, `BindMarkers`, `BindMarkersFactory` and related types. +Use replacements from `org.springframework.r2dbc.core.binding`. +* Deprecation of `BadSqlGrammarException`, `UncategorizedR2dbcException` and exception translation at `o.s.d.r2dbc.support`. +Spring R2DBC provides a slim exception translation variant without an SPI for now available through `o.s.r2dbc.connection.ConnectionFactoryUtils#convertR2dbcException`. + +[[upgrading.1.1-1.2.replacements]] +=== Usage of replacements provided by Spring R2DBC + +To ease migration, several deprecated types are now subtypes of their replacements provided by Spring R2DBC. Spring Data R2DBC has changes several methods or introduced new methods accepting Spring R2DBC types. +Specifically the following classes are changed: + +* `R2dbcEntityTemplate` +* `R2dbcDialect` +* Types in `org.springframework.data.r2dbc.query` + +We recommend that you review and update your imports if you work with these types directly. + +=== Breaking Changes + +* `OutboundRow` and statement mappers switched from using `SettableValue` to `Parameter` +* Repository factory support requires `o.s.r2dbc.core.DatabaseClient` instead of `o.s.data.r2dbc.core.DatabaseClient`. + +[[upgrading.1.1-1.2.dependencies]] +=== Dependency Changes + +To make use of Spring R2DBC, make sure to include the following dependency: + +* `org.springframework:spring-r2dbc` diff --git a/src/main/java/org/springframework/data/r2dbc/BadSqlGrammarException.java b/src/main/java/org/springframework/data/r2dbc/BadSqlGrammarException.java index 779cea78..63686414 100644 --- a/src/main/java/org/springframework/data/r2dbc/BadSqlGrammarException.java +++ b/src/main/java/org/springframework/data/r2dbc/BadSqlGrammarException.java @@ -17,8 +17,6 @@ import io.r2dbc.spi.R2dbcException; -import org.springframework.dao.InvalidDataAccessResourceUsageException; - /** * Exception thrown when SQL specified is invalid. Such exceptions always have a {@link io.r2dbc.spi.R2dbcException} * root cause. @@ -28,13 +26,13 @@ * without affecting code using this class. * * @author Mark Paluch + * @deprecated since 1.2, use directly Spring R2DBC's {@link org.springframework.r2dbc.BadSqlGrammarException} instead. */ -public class BadSqlGrammarException extends InvalidDataAccessResourceUsageException { +@Deprecated +public class BadSqlGrammarException extends org.springframework.r2dbc.BadSqlGrammarException { private static final long serialVersionUID = 3814579246913482054L; - private final String sql; - /** * Creates a new {@link BadSqlGrammarException}. * @@ -43,10 +41,7 @@ public class BadSqlGrammarException extends InvalidDataAccessResourceUsageExcept * @param ex the root cause. */ public BadSqlGrammarException(String task, String sql, R2dbcException ex) { - - super(task + "; bad SQL grammar [" + sql + "]", ex); - - this.sql = sql; + super(task, sql, ex); } /** @@ -60,6 +55,6 @@ public R2dbcException getR2dbcException() { * Return the SQL that caused the problem. */ public String getSql() { - return this.sql; + return super.getSql(); } } diff --git a/src/main/java/org/springframework/data/r2dbc/InvalidResultAccessException.java b/src/main/java/org/springframework/data/r2dbc/InvalidResultAccessException.java index e79f59e2..8ac229db 100644 --- a/src/main/java/org/springframework/data/r2dbc/InvalidResultAccessException.java +++ b/src/main/java/org/springframework/data/r2dbc/InvalidResultAccessException.java @@ -24,13 +24,15 @@ * Exception thrown when a {@link io.r2dbc.spi.Result} has been accessed in an invalid fashion. Such exceptions always * have a {@link io.r2dbc.spi.R2dbcException} root cause. *

- * This typically happens when an invalid {@link org.springframework.data.r2dbc.core.FetchSpec} column index or name - * has been specified. + * This typically happens when an invalid {@link org.springframework.data.r2dbc.core.FetchSpec} column index or name has + * been specified. * * @author Mark Paluch * @see BadSqlGrammarException + * @deprecated since 1.2, not in use anymore. */ @SuppressWarnings("serial") +@Deprecated public class InvalidResultAccessException extends InvalidDataAccessResourceUsageException { private final @Nullable String sql; diff --git a/src/main/java/org/springframework/data/r2dbc/UncategorizedR2dbcException.java b/src/main/java/org/springframework/data/r2dbc/UncategorizedR2dbcException.java index d74bd5be..e54b2823 100644 --- a/src/main/java/org/springframework/data/r2dbc/UncategorizedR2dbcException.java +++ b/src/main/java/org/springframework/data/r2dbc/UncategorizedR2dbcException.java @@ -17,23 +17,19 @@ import io.r2dbc.spi.R2dbcException; -import org.springframework.dao.UncategorizedDataAccessException; import org.springframework.lang.Nullable; /** * Exception thrown when we can't classify a {@link R2dbcException} into one of our generic data access exceptions. * * @author Mark Paluch + * @deprecated since 1.2, use Spring R2DBC's {@link org.springframework.r2dbc.UncategorizedR2dbcException} instead. */ -public class UncategorizedR2dbcException extends UncategorizedDataAccessException { +@Deprecated +public class UncategorizedR2dbcException extends org.springframework.r2dbc.UncategorizedR2dbcException { private static final long serialVersionUID = 361587356435210266L; - /** - * SQL that led to the problem - */ - private final @Nullable String sql; - /** * Creates a new {@link UncategorizedR2dbcException}. * @@ -42,10 +38,7 @@ public class UncategorizedR2dbcException extends UncategorizedDataAccessExceptio * @param ex the root cause */ public UncategorizedR2dbcException(String task, @Nullable String sql, R2dbcException ex) { - - super(String.format("%s; uncategorized R2dbcException%s; %s", task, sql != null ? " for SQL [" + sql + "]" : "", - ex.getMessage()), ex); - this.sql = sql; + super(task, sql, ex); } /** @@ -62,6 +55,6 @@ public R2dbcException getR2dbcException() { */ @Nullable public String getSql() { - return this.sql; + return super.getSql(); } } diff --git a/src/main/java/org/springframework/data/r2dbc/config/AbstractR2dbcConfiguration.java b/src/main/java/org/springframework/data/r2dbc/config/AbstractR2dbcConfiguration.java index 765160e0..019aed38 100644 --- a/src/main/java/org/springframework/data/r2dbc/config/AbstractR2dbcConfiguration.java +++ b/src/main/java/org/springframework/data/r2dbc/config/AbstractR2dbcConfiguration.java @@ -30,21 +30,18 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.CustomConversions; import org.springframework.data.convert.CustomConversions.StoreConversions; -import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.r2dbc.convert.MappingR2dbcConverter; import org.springframework.data.r2dbc.convert.R2dbcCustomConversions; -import org.springframework.data.r2dbc.core.DatabaseClient; import org.springframework.data.r2dbc.core.DefaultReactiveDataAccessStrategy; +import org.springframework.data.r2dbc.core.R2dbcEntityTemplate; import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy; import org.springframework.data.r2dbc.dialect.DialectResolver; import org.springframework.data.r2dbc.dialect.R2dbcDialect; import org.springframework.data.r2dbc.mapping.R2dbcMappingContext; -import org.springframework.data.r2dbc.support.R2dbcExceptionSubclassTranslator; -import org.springframework.data.r2dbc.support.R2dbcExceptionTranslator; -import org.springframework.data.r2dbc.support.SqlStateR2dbcExceptionTranslator; import org.springframework.data.relational.core.conversion.BasicRelationalConverter; import org.springframework.data.relational.core.mapping.NamingStrategy; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.util.Assert; /** @@ -100,26 +97,34 @@ public R2dbcDialect getDialect(ConnectionFactory connectionFactory) { * @throws IllegalArgumentException if any of the required args is {@literal null}. */ @Bean({ "r2dbcDatabaseClient", "databaseClient" }) - public DatabaseClient databaseClient(ReactiveDataAccessStrategy dataAccessStrategy, - R2dbcExceptionTranslator exceptionTranslator) { + public DatabaseClient databaseClient() { - Assert.notNull(dataAccessStrategy, "DataAccessStrategy must not be null!"); - Assert.notNull(exceptionTranslator, "ExceptionTranslator must not be null!"); - - SpelAwareProxyProjectionFactory projectionFactory = new SpelAwareProxyProjectionFactory(); - if (context != null) { - projectionFactory.setBeanFactory(context); - projectionFactory.setBeanClassLoader(context.getClassLoader()); - } + ConnectionFactory connectionFactory = lookupConnectionFactory(); return DatabaseClient.builder() // - .connectionFactory(lookupConnectionFactory()) // - .dataAccessStrategy(dataAccessStrategy) // - .exceptionTranslator(exceptionTranslator) // - .projectionFactory(projectionFactory) // + .connectionFactory(connectionFactory) // + .bindMarkers(getDialect(connectionFactory).getBindMarkersFactory()) // .build(); } + /** + * Register {@link R2dbcEntityTemplate} using {@link #databaseClient()} and {@link #connectionFactory()}. + * + * @param databaseClient must not be {@literal null}. + * @param dataAccessStrategy must not be {@literal null}. + * @return + * @since 1.2 + */ + @Bean + public R2dbcEntityTemplate r2dbcEntityTemplate(DatabaseClient databaseClient, + ReactiveDataAccessStrategy dataAccessStrategy) { + + Assert.notNull(databaseClient, "DatabaseClient must not be null!"); + Assert.notNull(dataAccessStrategy, "ReactiveDataAccessStrategy must not be null!"); + + return new R2dbcEntityTemplate(databaseClient, dataAccessStrategy); + } + /** * Register a {@link R2dbcMappingContext} and apply an optional {@link NamingStrategy}. * @@ -200,19 +205,6 @@ protected StoreConversions getStoreConversions() { return StoreConversions.of(dialect.getSimpleTypeHolder(), converters); } - /** - * Creates a {@link R2dbcExceptionTranslator} using the configured {@link #connectionFactory() ConnectionFactory}. - * - * @return must not be {@literal null}. - * @see #connectionFactory() - * @see R2dbcExceptionSubclassTranslator - * @see SqlStateR2dbcExceptionTranslator - */ - @Bean - public R2dbcExceptionTranslator exceptionTranslator() { - return new R2dbcExceptionSubclassTranslator(); - } - ConnectionFactory lookupConnectionFactory() { ApplicationContext context = this.context; diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionFactoryUtils.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionFactoryUtils.java index 871077f5..9cb1107f 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionFactoryUtils.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionFactoryUtils.java @@ -22,11 +22,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.core.Ordered; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.lang.Nullable; -import org.springframework.transaction.NoTransactionException; -import org.springframework.transaction.reactive.TransactionSynchronization; import org.springframework.transaction.reactive.TransactionSynchronizationManager; import org.springframework.util.Assert; @@ -39,7 +36,9 @@ * * @author Mark Paluch * @author Christoph Strobl + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection} instead. */ +@Deprecated public abstract class ConnectionFactoryUtils { /** @@ -66,8 +65,7 @@ private ConnectionFactoryUtils() {} * @see #releaseConnection */ public static Mono getConnection(ConnectionFactory connectionFactory) { - return doGetConnection(connectionFactory) - .onErrorMap(e -> new DataAccessResourceFailureException("Failed to obtain R2DBC Connection", e)); + return org.springframework.r2dbc.connection.ConnectionFactoryUtils.getConnection(connectionFactory); } /** @@ -81,64 +79,7 @@ public static Mono getConnection(ConnectionFactory connectionFactory * @return a R2DBC {@link io.r2dbc.spi.Connection} from the given {@link io.r2dbc.spi.ConnectionFactory}. */ public static Mono doGetConnection(ConnectionFactory connectionFactory) { - - Assert.notNull(connectionFactory, "ConnectionFactory must not be null!"); - - return TransactionSynchronizationManager.forCurrentTransaction().flatMap(synchronizationManager -> { - - ConnectionHolder conHolder = (ConnectionHolder) synchronizationManager.getResource(connectionFactory); - 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(it -> { - - return Mono.just(it).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); - } - }).onErrorResume(e -> { - // Unexpected exception from external delegation call -> close Connection and rethrow. - return releaseConnection(it, connectionFactory).then(Mono.error(e)); - }); - }); - } - - return con; - }) // - .onErrorResume(NoTransactionException.class, e -> { - return Mono.from(connectionFactory.create()); - }); + return org.springframework.r2dbc.connection.ConnectionFactoryUtils.doGetConnection(connectionFactory); } /** @@ -181,17 +122,8 @@ public static Mono releaseConnection(io.r2dbc.spi.Connection con, Connecti public static Mono doReleaseConnection(io.r2dbc.spi.Connection connection, ConnectionFactory connectionFactory) { - return TransactionSynchronizationManager.forCurrentTransaction().flatMap(it -> { - - ConnectionHolder conHolder = (ConnectionHolder) it.getResource(connectionFactory); - if (conHolder != null && connectionEquals(conHolder, connection)) { - // It's the transactional Connection: Don't close it. - conHolder.released(); - } - return Mono.from(connection.close()); - }).onErrorResume(NoTransactionException.class, e -> { - return doCloseConnection(connection, connectionFactory); - }); + return org.springframework.r2dbc.connection.ConnectionFactoryUtils.doReleaseConnection(connection, + connectionFactory); } /** @@ -244,37 +176,7 @@ public static Mono doCloseConnection(Connection connection, @Nullable Conn */ public static Mono currentConnectionFactory(ConnectionFactory connectionFactory) { - return TransactionSynchronizationManager.forCurrentTransaction() - .filter(TransactionSynchronizationManager::isSynchronizationActive).filter(it -> { - - ConnectionHolder conHolder = (ConnectionHolder) it.getResource(connectionFactory); - if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) { - return true; - } - return false; - }).map(it -> connectionFactory); - } - - /** - * Determine whether the given two {@link io.r2dbc.spi.Connection}s are equal, asking the target - * {@link io.r2dbc.spi.Connection} in case of a proxy. Used to detect equality even if the user passed in a raw target - * Connection while the held one is a proxy. - * - * @param conHolder the {@link .ConnectionHolder} for the held {@link io.r2dbc.spi.Connection} (potentially a proxy). - * @param passedInCon the {@link io.r2dbc.spi.Connection} passed-in by the user (potentially a target - * {@link io.r2dbc.spi.Connection} without proxy). - * @return whether the given Connections are equal - * @see #getTargetConnection - */ - private static boolean connectionEquals(ConnectionHolder conHolder, Connection passedInCon) { - - if (!conHolder.hasConnection()) { - return false; - } - Connection heldCon = conHolder.getConnection(); - // Explicitly check for identity too: for Connection handles that do not implement - // "equals" properly). - return (heldCon == passedInCon || heldCon.equals(passedInCon) || getTargetConnection(heldCon).equals(passedInCon)); + return org.springframework.r2dbc.connection.ConnectionFactoryUtils.currentConnectionFactory(connectionFactory); } /** @@ -315,112 +217,4 @@ private static int getConnectionSynchronizationOrder(ConnectionFactory connectio return order; } - /** - * Callback for resource cleanup at the end of a non-native R2DBC transaction. - */ - private static class ConnectionSynchronization implements TransactionSynchronization, Ordered { - - private final ConnectionHolder connectionHolder; - - private final ConnectionFactory connectionFactory; - - private int order; - - private boolean holderActive = true; - - ConnectionSynchronization(ConnectionHolder connectionHolder, ConnectionFactory connectionFactory) { - this.connectionHolder = connectionHolder; - this.connectionFactory = connectionFactory; - this.order = getConnectionSynchronizationOrder(connectionFactory); - } - - @Override - public int getOrder() { - return this.order; - } - - @Override - public Mono suspend() { - if (this.holderActive) { - - return TransactionSynchronizationManager.forCurrentTransaction().flatMap(it -> { - - it.unbindResource(this.connectionFactory); - if (this.connectionHolder.hasConnection() && !this.connectionHolder.isOpen()) { - // Release Connection on suspend if the application doesn't keep - // a handle to it anymore. We will fetch a fresh Connection if the - // application accesses the ConnectionHolder again after resume, - // assuming that it will participate in the same transaction. - return releaseConnection(this.connectionHolder.getConnection(), this.connectionFactory) - .doOnTerminate(() -> this.connectionHolder.setConnection(null)); - } - return Mono.empty(); - }); - } - - return Mono.empty(); - } - - @Override - public Mono resume() { - if (this.holderActive) { - return TransactionSynchronizationManager.forCurrentTransaction().doOnNext(it -> { - it.bindResource(this.connectionFactory, this.connectionHolder); - }).then(); - } - return Mono.empty(); - } - - @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. - if (!this.connectionHolder.isOpen()) { - return TransactionSynchronizationManager.forCurrentTransaction().flatMap(it -> { - - it.unbindResource(this.connectionFactory); - this.holderActive = false; - if (this.connectionHolder.hasConnection()) { - return releaseConnection(this.connectionHolder.getConnection(), this.connectionFactory); - } - return Mono.empty(); - }); - } - - return Mono.empty(); - } - - @Override - public Mono afterCompletion(int status) { - - // If we haven't closed the Connection in beforeCompletion, - // close it now. The holder might have been used for other - // cleanup in the meantime, for example by a Hibernate Session. - if (this.holderActive) { - // The thread-bound ConnectionHolder might not be available anymore, - // since afterCompletion might get called from a different thread. - return TransactionSynchronizationManager.forCurrentTransaction().flatMap(it -> { - - it.unbindResourceIfPossible(this.connectionFactory); - this.holderActive = false; - if (this.connectionHolder.hasConnection()) { - return releaseConnection(this.connectionHolder.getConnection(), this.connectionFactory) - .doOnTerminate(() -> { - // Reset the ConnectionHolder: It might remain bound to the context. - this.connectionHolder.setConnection(null); - }); - } - - return Mono.empty(); - }); - } - - this.connectionHolder.reset(); - return Mono.empty(); - } - } } diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionHandle.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionHandle.java index dd3c6063..938d59ed 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionHandle.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionHandle.java @@ -23,8 +23,10 @@ * @author Mark Paluch * @see SimpleConnectionHandle * @see ConnectionHolder + * @deprecated since 1.2 in favor of Spring R2DBC without replacement. */ @FunctionalInterface +@Deprecated public interface ConnectionHandle { /** diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionHolder.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionHolder.java index 284c20c1..ea976f33 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionHolder.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionHolder.java @@ -22,8 +22,8 @@ import org.springframework.util.Assert; /** - * Resource holder wrapping a R2DBC {@link Connection}. {@link R2dbcTransactionManager} binds instances of - * this class to the thread, for a specific {@link ConnectionFactory}. + * Resource holder wrapping a R2DBC {@link Connection}. {@link R2dbcTransactionManager} binds instances of this class to + * the thread, for a specific {@link ConnectionFactory}. *

* Inherits rollback-only support for nested R2DBC transactions and reference count functionality from the base class. *

@@ -33,7 +33,9 @@ * @author Christoph Strobl * @see R2dbcTransactionManager * @see ConnectionFactoryUtils + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection} instead. */ +@Deprecated public class ConnectionHolder extends ResourceHolderSupport { @Nullable private ConnectionHandle connectionHandle; diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionProxy.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionProxy.java index c607a88d..a2783267 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionProxy.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/ConnectionProxy.java @@ -26,7 +26,9 @@ * * @author Mark Paluch * @author Christoph Strobl + * @deprecated since 1.2 in favor of Spring R2DBC. Use R2DBC's {@link Wrapped} mechanism instead. */ +@Deprecated public interface ConnectionProxy extends Connection, Wrapped { /** diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/DelegatingConnectionFactory.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/DelegatingConnectionFactory.java index 12f7eac8..903f8eea 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/DelegatingConnectionFactory.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/DelegatingConnectionFactory.java @@ -32,7 +32,9 @@ * * @author Mark Paluch * @see #create + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection} instead. */ +@Deprecated public class DelegatingConnectionFactory implements ConnectionFactory, Wrapped { private final ConnectionFactory targetConnectionFactory; diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/R2dbcTransactionManager.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/R2dbcTransactionManager.java index e7c1d262..686e1219 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/R2dbcTransactionManager.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/R2dbcTransactionManager.java @@ -17,27 +17,9 @@ import io.r2dbc.spi.Connection; import io.r2dbc.spi.ConnectionFactory; -import io.r2dbc.spi.IsolationLevel; -import io.r2dbc.spi.R2dbcException; -import io.r2dbc.spi.Result; -import reactor.core.publisher.Mono; - -import java.time.Duration; import org.springframework.beans.factory.InitializingBean; -import org.springframework.dao.DataAccessException; import org.springframework.data.r2dbc.core.DatabaseClient; -import org.springframework.data.r2dbc.support.R2dbcExceptionSubclassTranslator; -import org.springframework.data.r2dbc.support.R2dbcExceptionTranslator; -import org.springframework.lang.Nullable; -import org.springframework.transaction.CannotCreateTransactionException; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionException; -import org.springframework.transaction.TransactionSystemException; -import org.springframework.transaction.reactive.AbstractReactiveTransactionManager; -import org.springframework.transaction.reactive.GenericReactiveTransaction; -import org.springframework.transaction.reactive.TransactionSynchronizationManager; -import org.springframework.util.Assert; /** * {@link org.springframework.transaction.ReactiveTransactionManager} implementation for a single R2DBC @@ -73,14 +55,12 @@ * @see ConnectionFactoryUtils#releaseConnection * @see TransactionAwareConnectionFactoryProxy * @see DatabaseClient + * @deprecated since 1.2 in favor of Spring R2DBC. Use + * {@link org.springframework.r2dbc.connection.R2dbcTransactionManager} instead. */ -public class R2dbcTransactionManager extends AbstractReactiveTransactionManager implements InitializingBean { - - private ConnectionFactory connectionFactory; - - private boolean enforceReadOnly = false; - - private R2dbcExceptionTranslator exceptionTranslator = new R2dbcExceptionSubclassTranslator(); +@Deprecated +public class R2dbcTransactionManager extends org.springframework.r2dbc.connection.R2dbcTransactionManager + implements InitializingBean { /** * Create a new @link ConnectionFactoryTransactionManager} instance. A ConnectionFactory has to be set to be able to @@ -100,506 +80,4 @@ public R2dbcTransactionManager(ConnectionFactory connectionFactory) { setConnectionFactory(connectionFactory); afterPropertiesSet(); } - - /** - * Set the R2DBC {@link ConnectionFactory} that this instance should manage transactions for. - *

- * This will typically be a locally defined {@link ConnectionFactory}, for example an connection pool. - *

- * The {@link ConnectionFactory} specified here should be the target {@link ConnectionFactory} to manage transactions - * for, not a TransactionAwareConnectionFactoryProxy. Only data access code may work with - * TransactionAwareConnectionFactoryProxy, while the transaction manager needs to work on the underlying target - * {@link ConnectionFactory}. If there's nevertheless a TransactionAwareConnectionFactoryProxy passed in, it will be - * unwrapped to extract its target {@link ConnectionFactory}. - *

- * The {@link ConnectionFactory} passed in here needs to return independent {@link Connection}s. The - * {@link Connection}s may come from a pool (the typical case), but the {@link ConnectionFactory} must not return - * scoped {@link Connection} or the like. - * - * @see TransactionAwareConnectionFactoryProxy - */ - public void setConnectionFactory(@Nullable ConnectionFactory connectionFactory) { - this.connectionFactory = connectionFactory; - } - - /** - * Return the R2DBC {@link ConnectionFactory} that this instance manages transactions for. - */ - @Nullable - public ConnectionFactory getConnectionFactory() { - return this.connectionFactory; - } - - /** - * Set the exception translator for this instance. - *

- * If no custom translator is provided, a default {@link R2dbcExceptionSubclassTranslator} is used which translates - * {@link R2dbcException}'s subclasses into Springs {@link DataAccessException} hierarchy. - * - * @see R2dbcExceptionSubclassTranslator - * @since 1.1 - */ - public void setExceptionTranslator(R2dbcExceptionTranslator exceptionTranslator) { - this.exceptionTranslator = exceptionTranslator; - } - - /** - * Obtain the {@link ConnectionFactory} for actual use. - * - * @return the {@link ConnectionFactory} (never {@literal null}) - * @throws IllegalStateException in case of no ConnectionFactory set - */ - protected ConnectionFactory obtainConnectionFactory() { - ConnectionFactory connectionFactory = getConnectionFactory(); - Assert.state(connectionFactory != null, "No ConnectionFactory set"); - return connectionFactory; - } - - /** - * Specify whether to enforce the read-only nature of a transaction (as indicated by - * {@link TransactionDefinition#isReadOnly()} through an explicit statement on the transactional connection: "SET - * TRANSACTION READ ONLY" as understood by Oracle, MySQL and Postgres. - *

- * The exact treatment, including any SQL statement executed on the connection, can be customized through through - * {@link #prepareTransactionalConnection}. - * - * @see #prepareTransactionalConnection - */ - public void setEnforceReadOnly(boolean enforceReadOnly) { - this.enforceReadOnly = enforceReadOnly; - } - - /** - * Return whether to enforce the read-only nature of a transaction through an explicit statement on the transactional - * connection. - * - * @see #setEnforceReadOnly - */ - public boolean isEnforceReadOnly() { - return this.enforceReadOnly; - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() { - if (getConnectionFactory() == null) { - throw new IllegalArgumentException("Property 'connectionFactory' is required"); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doGetTransaction(org.springframework.transaction.reactive.TransactionSynchronizationManager) - */ - @Override - protected Object doGetTransaction(TransactionSynchronizationManager synchronizationManager) - throws TransactionException { - - ConnectionFactoryTransactionObject txObject = new ConnectionFactoryTransactionObject(); - ConnectionHolder conHolder = (ConnectionHolder) synchronizationManager.getResource(obtainConnectionFactory()); - txObject.setConnectionHolder(conHolder, false); - return txObject; - } - - /* - * (non-Javadoc) - * @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#isExistingTransaction(java.lang.Object) - */ - @Override - protected boolean isExistingTransaction(Object transaction) { - - ConnectionFactoryTransactionObject txObject = (ConnectionFactoryTransactionObject) transaction; - return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive()); - } - - /* - * (non-Javadoc) - * @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doBegin(org.springframework.transaction.reactive.TransactionSynchronizationManager, java.lang.Object, org.springframework.transaction.TransactionDefinition) - */ - @Override - protected Mono doBegin(TransactionSynchronizationManager synchronizationManager, Object transaction, - TransactionDefinition definition) throws TransactionException { - - ConnectionFactoryTransactionObject txObject = (ConnectionFactoryTransactionObject) transaction; - - return Mono.defer(() -> { - - Mono connection = null; - - if (!txObject.hasConnectionHolder() || txObject.getConnectionHolder().isSynchronizedWithTransaction()) { - Mono newCon = Mono.from(obtainConnectionFactory().create()); - - connection = newCon.doOnNext(it -> { - - if (this.logger.isDebugEnabled()) { - this.logger.debug("Acquired Connection [" + newCon + "] for R2DBC transaction"); - } - txObject.setConnectionHolder(new ConnectionHolder(it), true); - }); - } else { - txObject.getConnectionHolder().setSynchronizedWithTransaction(true); - connection = Mono.just(txObject.getConnectionHolder().getConnection()); - } - - return connection.flatMap(con -> { - - return prepareTransactionalConnection(con, definition, transaction).then(Mono.from(con.beginTransaction())) - .doOnSuccess(v -> { - txObject.getConnectionHolder().setTransactionActive(true); - - Duration timeout = determineTimeout(definition); - if (!timeout.isNegative() && !timeout.isZero()) { - txObject.getConnectionHolder().setTimeoutInMillis(timeout.toMillis()); - } - - // Bind the connection holder to the thread. - if (txObject.isNewConnectionHolder()) { - synchronizationManager.bindResource(obtainConnectionFactory(), txObject.getConnectionHolder()); - } - }).thenReturn(con).onErrorResume(e -> { - - if (txObject.isNewConnectionHolder()) { - return ConnectionFactoryUtils.releaseConnection(con, obtainConnectionFactory()).doOnTerminate(() -> { - - txObject.setConnectionHolder(null, false); - }).then(Mono.error(e)); - } - return Mono.error(e); - }); - }).onErrorResume(e -> { - - CannotCreateTransactionException ex = new CannotCreateTransactionException( - "Could not open R2DBC Connection for transaction", - e instanceof R2dbcException ? potentiallyTranslateException("Open R2DBC Connection", (R2dbcException) e) - : e); - - return Mono.error(ex); - }); - }).then(); - } - - /** - * Determine the actual timeout to use for the given definition. Will fall back to this manager's default timeout if - * the transaction definition doesn't specify a non-default value. - * - * @param definition the transaction definition - * @return the actual timeout to use - * @see org.springframework.transaction.TransactionDefinition#getTimeout() - */ - protected Duration determineTimeout(TransactionDefinition definition) { - if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) { - return Duration.ofSeconds(definition.getTimeout()); - } - return Duration.ZERO; - } - - /* - * (non-Javadoc) - * @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doSuspend(org.springframework.transaction.reactive.TransactionSynchronizationManager, java.lang.Object) - */ - @Override - protected Mono doSuspend(TransactionSynchronizationManager synchronizationManager, Object transaction) - throws TransactionException { - - return Mono.defer(() -> { - - ConnectionFactoryTransactionObject txObject = (ConnectionFactoryTransactionObject) transaction; - txObject.setConnectionHolder(null); - return Mono.justOrEmpty(synchronizationManager.unbindResource(obtainConnectionFactory())); - }); - } - - /* - * (non-Javadoc) - * @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doResume(org.springframework.transaction.reactive.TransactionSynchronizationManager, java.lang.Object, java.lang.Object) - */ - @Override - protected Mono doResume(TransactionSynchronizationManager synchronizationManager, Object transaction, - Object suspendedResources) throws TransactionException { - - return Mono.defer(() -> { - - ConnectionFactoryTransactionObject txObject = (ConnectionFactoryTransactionObject) transaction; - txObject.setConnectionHolder(null); - synchronizationManager.bindResource(obtainConnectionFactory(), suspendedResources); - - return Mono.empty(); - }); - } - - /* - * (non-Javadoc) - * @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doCommit(org.springframework.transaction.reactive.TransactionSynchronizationManager, org.springframework.transaction.reactive.GenericReactiveTransaction) - */ - @Override - protected Mono doCommit(TransactionSynchronizationManager TransactionSynchronizationManager, - GenericReactiveTransaction status) throws TransactionException { - - ConnectionFactoryTransactionObject txObject = (ConnectionFactoryTransactionObject) status.getTransaction(); - Connection connection = txObject.getConnectionHolder().getConnection(); - if (status.isDebug()) { - this.logger.debug("Committing R2DBC transaction on Connection [" + connection + "]"); - } - - return Mono.from(connection.commitTransaction()) - .onErrorMap(R2dbcException.class, ex -> translateException("R2DBC commit", ex)); - } - - /* - * (non-Javadoc) - * @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doRollback(org.springframework.transaction.reactive.TransactionSynchronizationManager, org.springframework.transaction.reactive.GenericReactiveTransaction) - */ - @Override - protected Mono doRollback(TransactionSynchronizationManager TransactionSynchronizationManager, - GenericReactiveTransaction status) throws TransactionException { - - ConnectionFactoryTransactionObject txObject = (ConnectionFactoryTransactionObject) status.getTransaction(); - Connection connection = txObject.getConnectionHolder().getConnection(); - if (status.isDebug()) { - this.logger.debug("Rolling back R2DBC transaction on Connection [" + connection + "]"); - } - - return Mono.from(connection.rollbackTransaction()) - .onErrorMap(R2dbcException.class, ex -> translateException("R2DBC rollback", ex)); - } - - /* - * (non-Javadoc) - * @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doSetRollbackOnly(org.springframework.transaction.reactive.TransactionSynchronizationManager, org.springframework.transaction.reactive.GenericReactiveTransaction) - */ - @Override - protected Mono doSetRollbackOnly(TransactionSynchronizationManager synchronizationManager, - GenericReactiveTransaction status) throws TransactionException { - - return Mono.fromRunnable(() -> { - - ConnectionFactoryTransactionObject txObject = (ConnectionFactoryTransactionObject) status.getTransaction(); - - if (status.isDebug()) { - this.logger - .debug("Setting R2DBC transaction [" + txObject.getConnectionHolder().getConnection() + "] rollback-only"); - } - txObject.setRollbackOnly(); - }); - } - - /* - * (non-Javadoc) - * @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doCleanupAfterCompletion(org.springframework.transaction.reactive.TransactionSynchronizationManager, java.lang.Object) - */ - @Override - protected Mono doCleanupAfterCompletion(TransactionSynchronizationManager synchronizationManager, - Object transaction) { - - return Mono.defer(() -> { - - ConnectionFactoryTransactionObject txObject = (ConnectionFactoryTransactionObject) transaction; - - // Remove the connection holder from the context, if exposed. - if (txObject.isNewConnectionHolder()) { - synchronizationManager.unbindResource(obtainConnectionFactory()); - } - - // Reset connection. - Connection con = txObject.getConnectionHolder().getConnection(); - - Mono afterCleanup = Mono.empty(); - - if (txObject.isMustRestoreAutoCommit()) { - afterCleanup = afterCleanup.then(Mono.from(con.setAutoCommit(true))); - } - - if (txObject.getPreviousIsolationLevel() != null) { - afterCleanup = afterCleanup - .then(Mono.from(con.setTransactionIsolationLevel(txObject.getPreviousIsolationLevel()))); - } - - return afterCleanup.then(Mono.defer(() -> { - - try { - if (txObject.isNewConnectionHolder()) { - if (this.logger.isDebugEnabled()) { - this.logger.debug("Releasing R2DBC Connection [" + con + "] after transaction"); - } - return ConnectionFactoryUtils.releaseConnection(con, obtainConnectionFactory()); - } - } finally { - txObject.getConnectionHolder().clear(); - } - - return Mono.empty(); - })); - }); - } - - /** - * Prepare the transactional {@link Connection} right after transaction begin. - *

- * The default implementation executes a "SET TRANSACTION READ ONLY" statement if the {@link #setEnforceReadOnly - * "enforceReadOnly"} flag is set to {@literal true} and the transaction definition indicates a read-only transaction. - *

- * The "SET TRANSACTION READ ONLY" is understood by Oracle, MySQL and Postgres and may work with other databases as - * well. If you'd like to adapt this treatment, override this method accordingly. - * - * @param con the transactional R2DBC Connection - * @param definition the current transaction definition - * @param transaction the transaction object - * @see #setEnforceReadOnly - */ - protected Mono prepareTransactionalConnection(Connection con, TransactionDefinition definition, - Object transaction) { - - ConnectionFactoryTransactionObject txObject = (ConnectionFactoryTransactionObject) transaction; - - Mono prepare = Mono.empty(); - - if (isEnforceReadOnly() && definition.isReadOnly()) { - - prepare = Mono.from(con.createStatement("SET TRANSACTION READ ONLY").execute()) // - .flatMapMany(Result::getRowsUpdated) // - .then(); - } - - // Apply specific isolation level, if any. - IsolationLevel isolationLevelToUse = resolveIsolationLevel(definition.getIsolationLevel()); - if (isolationLevelToUse != null && definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { - - if (this.logger.isDebugEnabled()) { - this.logger - .debug("Changing isolation level of R2DBC Connection [" + con + "] to " + isolationLevelToUse.asSql()); - } - IsolationLevel currentIsolation = con.getTransactionIsolationLevel(); - if (!currentIsolation.asSql().equalsIgnoreCase(isolationLevelToUse.asSql())) { - - txObject.setPreviousIsolationLevel(currentIsolation); - prepare = prepare.then(Mono.from(con.setTransactionIsolationLevel(isolationLevelToUse))); - } - } - - // Switch to manual commit if necessary. This is very expensive in some JDBC drivers, - // so we don't want to do it unnecessarily (for example if we've explicitly - // configured the connection pool to set it already). - if (con.isAutoCommit()) { - txObject.setMustRestoreAutoCommit(true); - if (this.logger.isDebugEnabled()) { - this.logger.debug("Switching R2DBC Connection [" + con + "] to manual commit"); - } - prepare = prepare.then(Mono.from(con.setAutoCommit(false))); - } - - return prepare; - } - - /** - * Resolve the {@link TransactionDefinition#getIsolationLevel() isolation level constant} to a R2DBC - * {@link IsolationLevel}. If you'd like to extend isolation level translation for vendor-specific - * {@link IsolationLevel}s, override this method accordingly. - * - * @param isolationLevel the isolation level to translate. - * @return the resolved isolation level. Can be {@literal null} if not resolvable or the isolation level should remain - * {@link TransactionDefinition#ISOLATION_DEFAULT default}. - * @see TransactionDefinition#getIsolationLevel() - */ - @Nullable - protected IsolationLevel resolveIsolationLevel(int isolationLevel) { - - switch (isolationLevel) { - case TransactionDefinition.ISOLATION_READ_COMMITTED: - return IsolationLevel.READ_COMMITTED; - case TransactionDefinition.ISOLATION_READ_UNCOMMITTED: - return IsolationLevel.READ_UNCOMMITTED; - case TransactionDefinition.ISOLATION_REPEATABLE_READ: - return IsolationLevel.REPEATABLE_READ; - case TransactionDefinition.ISOLATION_SERIALIZABLE: - return IsolationLevel.SERIALIZABLE; - } - - return null; - } - - /** - * Translate the given R2DBC commit/rollback exception to a common Spring exception to propagate from the - * {@link #commit}/{@link #rollback} call. - *

- * The default implementation throws a {@link TransactionSystemException}. Subclasses may specifically identify - * concurrency failures etc. - * - * @param task the task description (commit or rollback). - * @param ex the SQLException thrown from commit/rollback. - * @return the translated exception to throw, either a {@link org.springframework.dao.DataAccessException} or a - * {@link org.springframework.transaction.TransactionException} - * @since 1.1 - */ - protected RuntimeException translateException(String task, R2dbcException ex) { - - Exception translated = potentiallyTranslateException(task, ex); - return new TransactionSystemException(task + " failed", translated); - } - - private Exception potentiallyTranslateException(String task, R2dbcException ex) { - - DataAccessException translated = exceptionTranslator.translate(task, null, ex); - return translated != null ? translated : ex; - } - - /** - * ConnectionFactory transaction object, representing a ConnectionHolder. Used as transaction object by - * ConnectionFactoryTransactionManager. - */ - private static class ConnectionFactoryTransactionObject { - - private @Nullable ConnectionHolder connectionHolder; - - private @Nullable IsolationLevel previousIsolationLevel; - - private boolean newConnectionHolder; - - private boolean mustRestoreAutoCommit; - - void setConnectionHolder(@Nullable ConnectionHolder connectionHolder, boolean newConnectionHolder) { - setConnectionHolder(connectionHolder); - this.newConnectionHolder = newConnectionHolder; - } - - boolean isNewConnectionHolder() { - return this.newConnectionHolder; - } - - void setRollbackOnly() { - getConnectionHolder().setRollbackOnly(); - } - - public void setConnectionHolder(@Nullable ConnectionHolder connectionHolder) { - this.connectionHolder = connectionHolder; - } - - public ConnectionHolder getConnectionHolder() { - Assert.state(this.connectionHolder != null, "No ConnectionHolder available"); - return this.connectionHolder; - } - - public boolean hasConnectionHolder() { - return (this.connectionHolder != null); - } - - public void setPreviousIsolationLevel(@Nullable IsolationLevel previousIsolationLevel) { - this.previousIsolationLevel = previousIsolationLevel; - } - - @Nullable - public IsolationLevel getPreviousIsolationLevel() { - return this.previousIsolationLevel; - } - - public void setMustRestoreAutoCommit(boolean mustRestoreAutoCommit) { - this.mustRestoreAutoCommit = mustRestoreAutoCommit; - } - - public boolean isMustRestoreAutoCommit() { - return this.mustRestoreAutoCommit; - } - } } diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/SimpleConnectionHandle.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/SimpleConnectionHandle.java index 40c27edf..27206cf1 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/SimpleConnectionHandle.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/SimpleConnectionHandle.java @@ -24,7 +24,9 @@ * * @author Mark Paluch * @author Christoph Strobl + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection} instead. */ +@Deprecated public class SimpleConnectionHandle implements ConnectionHandle { private final Connection connection; diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/SingleConnectionConnectionFactory.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/SingleConnectionConnectionFactory.java index 115d758a..488a23a7 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/SingleConnectionConnectionFactory.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/SingleConnectionConnectionFactory.java @@ -53,7 +53,9 @@ * @see #create() * @see io.r2dbc.spi.Connection#close() * @see ConnectionFactoryUtils#releaseConnection(io.r2dbc.spi.Connection, ConnectionFactory) + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection} instead. */ +@Deprecated public class SingleConnectionConnectionFactory extends DelegatingConnectionFactory implements SmartConnectionFactory, DisposableBean { diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/SmartConnectionFactory.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/SmartConnectionFactory.java index 802dd141..09f13362 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/SmartConnectionFactory.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/SmartConnectionFactory.java @@ -27,7 +27,9 @@ * * @author Mark Paluch * @see ConnectionFactoryUtils#closeConnection + * @deprecated since 1.2 in favor of Spring R2DBC without replacement. */ +@Deprecated public interface SmartConnectionFactory extends ConnectionFactory { /** diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/TransactionAwareConnectionFactoryProxy.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/TransactionAwareConnectionFactoryProxy.java index a3e7294f..29bbad80 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/TransactionAwareConnectionFactoryProxy.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/TransactionAwareConnectionFactoryProxy.java @@ -60,7 +60,9 @@ * @see Connection#close * @see ConnectionFactoryUtils#doGetConnection * @see ConnectionFactoryUtils#doReleaseConnection + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection} instead. */ +@Deprecated public class TransactionAwareConnectionFactoryProxy extends DelegatingConnectionFactory { /** diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/CannotReadScriptException.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/CannotReadScriptException.java index 0164c874..9c7c3b89 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/CannotReadScriptException.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/CannotReadScriptException.java @@ -21,7 +21,9 @@ * Thrown by {@link ScriptUtils} if an SQL script cannot be read. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.init} instead. */ +@Deprecated public class CannotReadScriptException extends ScriptException { private static final long serialVersionUID = 7253084944991764250L; diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/CompositeDatabasePopulator.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/CompositeDatabasePopulator.java index 4b35bc42..75e42c44 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/CompositeDatabasePopulator.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/CompositeDatabasePopulator.java @@ -31,7 +31,9 @@ * executing all scripts. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.init} instead. */ +@Deprecated public class CompositeDatabasePopulator implements DatabasePopulator { private final List populators = new ArrayList<>(4); diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ConnectionFactoryInitializer.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ConnectionFactoryInitializer.java index dd492a9f..d770bf9c 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ConnectionFactoryInitializer.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ConnectionFactoryInitializer.java @@ -28,7 +28,9 @@ * * @author Mark Paluch * @see DatabasePopulator + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.init} instead. */ +@Deprecated public class ConnectionFactoryInitializer implements InitializingBean, DisposableBean { private @Nullable ConnectionFactory connectionFactory; diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/DatabasePopulator.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/DatabasePopulator.java index 9e1cf051..d471d542 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/DatabasePopulator.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/DatabasePopulator.java @@ -25,8 +25,10 @@ * @see ResourceDatabasePopulator * @see DatabasePopulatorUtils * @see ConnectionFactoryInitializer + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.init} instead. */ @FunctionalInterface +@Deprecated public interface DatabasePopulator { /** diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/DatabasePopulatorUtils.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/DatabasePopulatorUtils.java index c185385e..6d6e61f6 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/DatabasePopulatorUtils.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/DatabasePopulatorUtils.java @@ -27,7 +27,10 @@ * Utility methods for executing a {@link DatabasePopulator}. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use + * {@link org.springframework.r2dbc.connection.init.DatabasePopulator#populate(ConnectionFactory)} instead. */ +@Deprecated public abstract class DatabasePopulatorUtils { // utility constructor diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ResourceDatabasePopulator.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ResourceDatabasePopulator.java index 24fa7dba..3b0b4c42 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ResourceDatabasePopulator.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ResourceDatabasePopulator.java @@ -45,7 +45,9 @@ * @author Mark Paluch * @see DatabasePopulatorUtils * @see ScriptUtils + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.init} instead. */ +@Deprecated public class ResourceDatabasePopulator implements DatabasePopulator { List scripts = new ArrayList<>(); diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptException.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptException.java index 068843c3..9f67503c 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptException.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptException.java @@ -22,7 +22,9 @@ * Root of the hierarchy of data access exceptions that are related to processing of SQL scripts. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.init} instead. */ +@Deprecated public abstract class ScriptException extends DataAccessException { /** diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptParseException.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptParseException.java index fe43adcf..b3e8dcfc 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptParseException.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptParseException.java @@ -22,7 +22,9 @@ * Thrown by {@link ScriptUtils} if an SQL script cannot be properly parsed. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.init} instead. */ +@Deprecated public class ScriptParseException extends ScriptException { private static final long serialVersionUID = 6130513243627087332L; diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptStatementFailedException.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptStatementFailedException.java index 0da186e2..f81be868 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptStatementFailedException.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptStatementFailedException.java @@ -21,7 +21,9 @@ * Thrown by {@link ScriptUtils} if a statement in an SQL script failed when executing it against the target database. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.init} instead. */ +@Deprecated public class ScriptStatementFailedException extends ScriptException { private static final long serialVersionUID = 912676424615782262L; diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptUtils.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptUtils.java index 71f2c136..5cb3500d 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptUtils.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/ScriptUtils.java @@ -48,7 +48,9 @@ * Mainly for internal use within the framework. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.init} instead. */ +@Deprecated public abstract class ScriptUtils { /** diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/UncategorizedScriptException.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/UncategorizedScriptException.java index 59d89413..62b840b0 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/UncategorizedScriptException.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/UncategorizedScriptException.java @@ -20,7 +20,9 @@ * for example, a {@link io.r2dbc.spi.R2dbcException} from R2DBC that we cannot pinpoint more precisely. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.init} instead. */ +@Deprecated public class UncategorizedScriptException extends ScriptException { private static final long serialVersionUID = -3196706179230349902L; diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/package-info.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/package-info.java index 113c6ba2..d76b4824 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/package-info.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/init/package-info.java @@ -1,5 +1,6 @@ /** - * Provides extensible support for initializing databases through scripts. + * Provides extensible support for initializing databases through scripts. Deprecated since 1.2 in favor of Spring + * R2DBC. Use {@link org.springframework.r2dbc.connection.init} instead. */ @org.springframework.lang.NonNullApi @org.springframework.lang.NonNullFields diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/AbstractRoutingConnectionFactory.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/AbstractRoutingConnectionFactory.java index d868a9fc..ec9a17a2 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/AbstractRoutingConnectionFactory.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/AbstractRoutingConnectionFactory.java @@ -42,7 +42,9 @@ * @see #setTargetConnectionFactories * @see #setDefaultTargetConnectionFactory * @see #determineCurrentLookupKey() + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.lookup} instead. */ +@Deprecated public abstract class AbstractRoutingConnectionFactory implements ConnectionFactory, InitializingBean { private static final Object FALLBACK_MARKER = new Object(); diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/BeanFactoryConnectionFactoryLookup.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/BeanFactoryConnectionFactoryLookup.java index f70fc793..8ba60057 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/BeanFactoryConnectionFactoryLookup.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/BeanFactoryConnectionFactoryLookup.java @@ -30,7 +30,9 @@ * * @author Mark Paluch * @see BeanFactory + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.lookup} instead. */ +@Deprecated public class BeanFactoryConnectionFactoryLookup implements ConnectionFactoryLookup, BeanFactoryAware { @Nullable private BeanFactory beanFactory; diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/ConnectionFactoryLookup.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/ConnectionFactoryLookup.java index 2d66c822..fdc8179d 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/ConnectionFactoryLookup.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/ConnectionFactoryLookup.java @@ -21,8 +21,10 @@ * Strategy interface for looking up {@link ConnectionFactory} by name. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.lookup} instead. */ @FunctionalInterface +@Deprecated public interface ConnectionFactoryLookup { /** diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/ConnectionFactoryLookupFailureException.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/ConnectionFactoryLookupFailureException.java index 3783dfa6..c70a8340 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/ConnectionFactoryLookupFailureException.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/ConnectionFactoryLookupFailureException.java @@ -22,8 +22,10 @@ * {@link io.r2dbc.spi.ConnectionFactory} could not be obtained. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.lookup} instead. */ @SuppressWarnings("serial") +@Deprecated public class ConnectionFactoryLookupFailureException extends NonTransientDataAccessException { /** diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/MapConnectionFactoryLookup.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/MapConnectionFactoryLookup.java index 12ddea3d..99e059fa 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/MapConnectionFactoryLookup.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/MapConnectionFactoryLookup.java @@ -31,7 +31,9 @@ * * @author Mark Paluch * @author Jens Schauder + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.lookup} instead. */ +@Deprecated public class MapConnectionFactoryLookup implements ConnectionFactoryLookup { private final Map connectionFactories = new HashMap<>(); diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/SingleConnectionFactoryLookup.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/SingleConnectionFactoryLookup.java index 28d6d123..521a215c 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/SingleConnectionFactoryLookup.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/SingleConnectionFactoryLookup.java @@ -24,7 +24,9 @@ * returned for any connection factory name. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.lookup} instead. */ +@Deprecated public class SingleConnectionFactoryLookup implements ConnectionFactoryLookup { private final ConnectionFactory connectionFactory; @@ -41,7 +43,7 @@ public SingleConnectionFactoryLookup(ConnectionFactory connectionFactory) { this.connectionFactory = connectionFactory; } - /* + /* * (non-Javadoc) * @see org.springframework.data.r2dbc.connectionfactory.lookup.ConnectionFactoryLookup#getConnectionFactory(java.lang.String) */ diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/package-info.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/package-info.java index efb4e618..e3b10279 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/package-info.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/lookup/package-info.java @@ -1,5 +1,6 @@ /** - * Provides a strategy for looking up R2DBC ConnectionFactories by name. + * Provides a strategy for looking up R2DBC ConnectionFactories by name. Deprecated since 1.2 in favor of Spring R2DBC. + * Use {@link org.springframework.r2dbc.connection.lookup} instead. */ @org.springframework.lang.NonNullApi @org.springframework.lang.NonNullFields diff --git a/src/main/java/org/springframework/data/r2dbc/connectionfactory/package-info.java b/src/main/java/org/springframework/data/r2dbc/connectionfactory/package-info.java index 6e09329b..b55ff510 100644 --- a/src/main/java/org/springframework/data/r2dbc/connectionfactory/package-info.java +++ b/src/main/java/org/springframework/data/r2dbc/connectionfactory/package-info.java @@ -1,5 +1,6 @@ /** - * Connection and ConnectionFactory specifics for R2DBC. + * Connection and ConnectionFactory specifics for R2DBC. Deprecated since 1.2 in favor of Spring R2DBC. Use + * {@link org.springframework.r2dbc.connection} instead. */ @org.springframework.lang.NonNullApi @org.springframework.lang.NonNullFields diff --git a/src/main/java/org/springframework/data/r2dbc/convert/ColumnMapRowMapper.java b/src/main/java/org/springframework/data/r2dbc/convert/ColumnMapRowMapper.java index f719aaed..7fff70fb 100644 --- a/src/main/java/org/springframework/data/r2dbc/convert/ColumnMapRowMapper.java +++ b/src/main/java/org/springframework/data/r2dbc/convert/ColumnMapRowMapper.java @@ -19,7 +19,6 @@ import io.r2dbc.spi.Row; import io.r2dbc.spi.RowMetadata; -import java.util.Collection; import java.util.Map; import java.util.function.BiFunction; @@ -40,26 +39,15 @@ * names in the same casing as exposed by the driver. * * @author Mark Paluch + * @deprecated since 1.2, use Spring R2DBC's {@link org.springframework.r2dbc.core.ColumnMapRowMapper} directly. */ -public class ColumnMapRowMapper implements BiFunction> { +public class ColumnMapRowMapper extends org.springframework.r2dbc.core.ColumnMapRowMapper { public final static ColumnMapRowMapper INSTANCE = new ColumnMapRowMapper(); @Override public Map apply(Row row, RowMetadata rowMetadata) { - - Collection columns = IterableUtils.toCollection(rowMetadata.getColumnMetadatas()); - int columnCount = columns.size(); - Map mapOfColValues = createColumnMap(columnCount); - - int index = 0; - for (ColumnMetadata column : columns) { - - String key = getColumnKey(column.getName()); - Object obj = getColumnValue(row, index++); - mapOfColValues.put(key, obj); - } - return mapOfColValues; + return super.apply(row, rowMetadata); } /** @@ -72,7 +60,7 @@ public Map apply(Row row, RowMetadata rowMetadata) { * @see LinkedCaseInsensitiveMap */ protected Map createColumnMap(int columnCount) { - return new LinkedCaseInsensitiveMap<>(columnCount); + return super.createColumnMap(columnCount); } /** @@ -83,7 +71,7 @@ protected Map createColumnMap(int columnCount) { * @see ColumnMetadata#getName() */ protected String getColumnKey(String columnName) { - return columnName; + return super.getColumnKey(columnName); } /** @@ -97,6 +85,6 @@ protected String getColumnKey(String columnName) { */ @Nullable protected Object getColumnValue(Row row, int index) { - return row.get(index); + return super.getColumnValue(row, index); } } diff --git a/src/main/java/org/springframework/data/r2dbc/convert/IterableUtils.java b/src/main/java/org/springframework/data/r2dbc/convert/IterableUtils.java deleted file mode 100644 index 1a441e16..00000000 --- a/src/main/java/org/springframework/data/r2dbc/convert/IterableUtils.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2018-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.data.r2dbc.convert; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.springframework.util.Assert; - -/** - * @author Mark Paluch - */ -class IterableUtils { - - static Collection toCollection(Iterable iterable) { - - Assert.notNull(iterable, "Iterable must not be null!"); - - if (iterable instanceof Collection) { - return (Collection) iterable; - } - - List result = new ArrayList<>(); - - for (T element : iterable) { - result.add(element); - } - - return result; - } - - static List toList(Iterable iterable) { - - Assert.notNull(iterable, "Iterable must not be null!"); - - if (iterable instanceof List) { - return (List) iterable; - } - - List result = new ArrayList<>(); - - for (T element : iterable) { - result.add(element); - } - - return result; - } -} diff --git a/src/main/java/org/springframework/data/r2dbc/convert/MappingR2dbcConverter.java b/src/main/java/org/springframework/data/r2dbc/convert/MappingR2dbcConverter.java index 965875ba..80951fd9 100644 --- a/src/main/java/org/springframework/data/r2dbc/convert/MappingR2dbcConverter.java +++ b/src/main/java/org/springframework/data/r2dbc/convert/MappingR2dbcConverter.java @@ -32,7 +32,7 @@ import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentPropertyAccessor; -import org.springframework.data.mapping.PreferredConstructor.Parameter; +import org.springframework.data.mapping.PreferredConstructor; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.ConvertingPropertyAccessor; import org.springframework.data.mapping.model.ParameterValueProvider; @@ -48,6 +48,7 @@ import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.Parameter; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -357,7 +358,7 @@ private void writeProperties(OutboundRow sink, RelationalPersistentEntity ent } private void writeSimpleInternal(OutboundRow sink, Object value, RelationalPersistentProperty property) { - sink.put(property.getColumnName(), SettableValue.from(getPotentiallyConvertedSimpleWrite(value))); + sink.put(property.getColumnName(), Parameter.from(getPotentiallyConvertedSimpleWrite(value))); } private void writePropertyInternal(OutboundRow sink, Object value, RelationalPersistentProperty property) { @@ -374,7 +375,7 @@ private void writePropertyInternal(OutboundRow sink, Object value, RelationalPer } List collectionInternal = createCollection(asCollection(value), property); - sink.put(property.getColumnName(), SettableValue.from(collectionInternal)); + sink.put(property.getColumnName(), Parameter.from(collectionInternal)); return; } @@ -431,7 +432,7 @@ private List writeCollectionInternal(Collection source, @Nullable Typ private void writeNullInternal(OutboundRow sink, RelationalPersistentProperty property) { - sink.put(property.getColumnName(), SettableValue.empty(getPotentiallyConvertedSimpleNullType(property.getType()))); + sink.put(property.getColumnName(), Parameter.empty(getPotentiallyConvertedSimpleNullType(property.getType()))); } private Class getPotentiallyConvertedSimpleNullType(Class type) { @@ -640,7 +641,7 @@ public RowParameterValueProvider(Row resultSet, RowMetadata metadata, Relational */ @Override @Nullable - public T getParameterValue(Parameter parameter) { + public T getParameterValue(PreferredConstructor.Parameter parameter) { RelationalPersistentProperty property = this.entity.getRequiredPersistentProperty(parameter.getName()); diff --git a/src/main/java/org/springframework/data/r2dbc/core/BindParameterSource.java b/src/main/java/org/springframework/data/r2dbc/core/BindParameterSource.java index 5403c8dc..c4dfd26e 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/BindParameterSource.java +++ b/src/main/java/org/springframework/data/r2dbc/core/BindParameterSource.java @@ -29,7 +29,9 @@ * * @author Mark Paluch * @see MapBindParameterSource + * @deprecated since 1.2, without replacement. */ +@Deprecated public interface BindParameterSource { /** diff --git a/src/main/java/org/springframework/data/r2dbc/core/ConnectionAccessor.java b/src/main/java/org/springframework/data/r2dbc/core/ConnectionAccessor.java index 219670e0..fc7b77b6 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/ConnectionAccessor.java +++ b/src/main/java/org/springframework/data/r2dbc/core/ConnectionAccessor.java @@ -32,8 +32,9 @@ * long the allocated {@link Connection} is valid. Connections are released after the publisher terminates. * * @author Mark Paluch + * @deprecated since 1.2, use Spring R2DBC's {@link org.springframework.r2dbc.core.DatabaseClient} support instead. */ -public interface ConnectionAccessor { +public interface ConnectionAccessor extends org.springframework.r2dbc.core.ConnectionAccessor { /** * Execute a callback {@link Function} within a {@link Connection} scope. The function is responsible for creating a diff --git a/src/main/java/org/springframework/data/r2dbc/core/DatabaseClient.java b/src/main/java/org/springframework/data/r2dbc/core/DatabaseClient.java index 593e6c69..e1f0ae5e 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/DatabaseClient.java +++ b/src/main/java/org/springframework/data/r2dbc/core/DatabaseClient.java @@ -49,7 +49,9 @@ * * @author Mark Paluch * @author Bogdan Ilchyshyn + * @deprecated since 1.2, use Spring R2DBC's {@link org.springframework.r2dbc.core.DatabaseClient} support instead. */ +@Deprecated public interface DatabaseClient { /** diff --git a/src/main/java/org/springframework/data/r2dbc/core/DefaultDatabaseClient.java b/src/main/java/org/springframework/data/r2dbc/core/DefaultDatabaseClient.java index 194d9941..ebacda90 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/DefaultDatabaseClient.java +++ b/src/main/java/org/springframework/data/r2dbc/core/DefaultDatabaseClient.java @@ -44,6 +44,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.reactivestreams.Publisher; + import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Pageable; @@ -62,6 +63,8 @@ import org.springframework.data.relational.core.query.CriteriaDefinition; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.Parameter; +import org.springframework.r2dbc.core.PreparedOperation; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -71,7 +74,9 @@ * @author Mark Paluch * @author Mingyuan Wu * @author Bogdan Ilchyshyn + * @deprecated since 1.2. */ +@Deprecated class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor { private final Log logger = LogFactory.getLog(getClass()); @@ -1169,7 +1174,7 @@ private FetchSpec exchange(Object toInsert, BiFunction then() { private UpdatedRowsFetchSpec exchange(SqlIdentifier table) { StatementMapper mapper = dataAccessStrategy.getStatementMapper(); - Map columns = dataAccessStrategy.getOutboundRow(this.objectToUpdate); + Map columns = dataAccessStrategy.getOutboundRow(this.objectToUpdate); List ids = dataAccessStrategy.getIdentifierColumns(this.typeToUpdate); if (ids.isEmpty()) { diff --git a/src/main/java/org/springframework/data/r2dbc/core/DefaultReactiveDataAccessStrategy.java b/src/main/java/org/springframework/data/r2dbc/core/DefaultReactiveDataAccessStrategy.java index 75186ad4..b91978ee 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/DefaultReactiveDataAccessStrategy.java +++ b/src/main/java/org/springframework/data/r2dbc/core/DefaultReactiveDataAccessStrategy.java @@ -46,6 +46,7 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.Parameter; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -206,10 +207,10 @@ public OutboundRow getOutboundRow(Object object) { for (RelationalPersistentProperty property : entity) { - SettableValue value = row.get(property.getColumnName()); + Parameter value = row.get(property.getColumnName()); if (value != null && shouldConvertArrayValue(property, value)) { - SettableValue writeValue = getArrayValue(value, property); + Parameter writeValue = getArrayValue(value, property); row.put(property.getColumnName(), writeValue); } } @@ -217,7 +218,7 @@ public OutboundRow getOutboundRow(Object object) { return row; } - private boolean shouldConvertArrayValue(RelationalPersistentProperty property, SettableValue value) { + private boolean shouldConvertArrayValue(RelationalPersistentProperty property, Parameter value) { if (!property.isCollectionLike()) { return false; @@ -234,7 +235,7 @@ private boolean shouldConvertArrayValue(RelationalPersistentProperty property, S return false; } - private SettableValue getArrayValue(SettableValue value, RelationalPersistentProperty property) { + private Parameter getArrayValue(Parameter value, RelationalPersistentProperty property) { if (value.getType().equals(byte[].class)) { return value; @@ -249,8 +250,8 @@ private SettableValue getArrayValue(SettableValue value, RelationalPersistentPro } Class actualType = null; - if (value instanceof Collection) { - actualType = CollectionUtils.findCommonElementType((Collection) value); + if (value.getValue() instanceof Collection) { + actualType = CollectionUtils.findCommonElementType((Collection) value.getValue()); } else if (value.getClass().isArray()) { actualType = value.getClass().getComponentType(); } @@ -264,10 +265,10 @@ private SettableValue getArrayValue(SettableValue value, RelationalPersistentPro Class targetType = arrayColumns.getArrayType(actualType); int depth = actualType.isArray() ? ArrayUtils.getDimensionDepth(actualType) : 1; Class targetArrayType = ArrayUtils.getArrayClass(targetType, depth); - return SettableValue.empty(targetArrayType); + return Parameter.empty(targetArrayType); } - return SettableValue.fromOrEmpty(this.converter.getArrayValue(arrayColumns, property, value.getValue()), + return Parameter.fromOrEmpty(this.converter.getArrayValue(arrayColumns, property, value.getValue()), actualType); } @@ -280,6 +281,15 @@ public SettableValue getBindValue(SettableValue value) { return this.updateMapper.getBindValue(value); } + /* + * (non-Javadoc) + * @see org.springframework.data.r2dbc.function.ReactiveDataAccessStrategy#getBindValue(Parameter) + */ + @Override + public Parameter getBindValue(Parameter value) { + return this.updateMapper.getBindValue(value); + } + /* * (non-Javadoc) * @see org.springframework.data.r2dbc.function.ReactiveDataAccessStrategy#getRowMapper(java.lang.Class) diff --git a/src/main/java/org/springframework/data/r2dbc/core/DefaultSqlResult.java b/src/main/java/org/springframework/data/r2dbc/core/DefaultSqlResult.java index 986842c4..fabcd0f2 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/DefaultSqlResult.java +++ b/src/main/java/org/springframework/data/r2dbc/core/DefaultSqlResult.java @@ -31,13 +31,9 @@ * * @author Mark Paluch */ -class DefaultSqlResult implements SqlResult { +class DefaultSqlResult implements FetchSpec { - private final static SqlResult EMPTY = new SqlResult() { - @Override - public SqlResult map(BiFunction mappingFunction) { - return DefaultSqlResult.empty(); - } + private final static FetchSpec EMPTY = new FetchSpec() { @Override public Mono one() { @@ -104,15 +100,14 @@ public String getSql() { * @return a {@code SqlResult}. */ @SuppressWarnings("unchecked") - public static SqlResult empty() { - return (SqlResult) EMPTY; + public static FetchSpec empty() { + return (FetchSpec) EMPTY; } /* (non-Javadoc) * @see org.springframework.data.r2dbc.function.SqlResult#map(java.util.function.BiFunction) */ - @Override - public SqlResult map(BiFunction mappingFunction) { + public FetchSpec map(BiFunction mappingFunction) { return new DefaultSqlResult<>(connectionAccessor, sql, resultFunction, updatedRowsFunction, mappingFunction); } diff --git a/src/main/java/org/springframework/data/r2dbc/core/DefaultStatementMapper.java b/src/main/java/org/springframework/data/r2dbc/core/DefaultStatementMapper.java index fe481ed5..7c084fc0 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/DefaultStatementMapper.java +++ b/src/main/java/org/springframework/data/r2dbc/core/DefaultStatementMapper.java @@ -19,9 +19,7 @@ import java.util.List; import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.r2dbc.dialect.BindMarkers; import org.springframework.data.r2dbc.dialect.BindTarget; -import org.springframework.data.r2dbc.dialect.Bindings; import org.springframework.data.r2dbc.dialect.R2dbcDialect; import org.springframework.data.r2dbc.query.BoundAssignments; import org.springframework.data.r2dbc.query.BoundCondition; @@ -34,6 +32,8 @@ import org.springframework.data.relational.core.sql.render.RenderContext; import org.springframework.data.relational.core.sql.render.SqlRenderer; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.binding.BindMarkers; +import org.springframework.r2dbc.core.binding.Bindings; import org.springframework.util.Assert; /** @@ -336,6 +336,11 @@ public String toQuery() { public void bindTo(BindTarget to) { this.bindings.apply(to); } + + @Override + public void bindTo(org.springframework.r2dbc.core.binding.BindTarget to) { + this.bindings.apply(to); + } } class DefaultTypedStatementMapper implements TypedStatementMapper { diff --git a/src/main/java/org/springframework/data/r2dbc/core/ExecuteFunction.java b/src/main/java/org/springframework/data/r2dbc/core/ExecuteFunction.java index 773916da..a0447b2e 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/ExecuteFunction.java +++ b/src/main/java/org/springframework/data/r2dbc/core/ExecuteFunction.java @@ -32,9 +32,11 @@ * @author Mark Paluch * @since 1.1 * @see Statement#execute() + * @deprecated since 1.2, use Spring's {@link org.springframework.r2dbc.core} support instead. */ +@Deprecated @FunctionalInterface -public interface ExecuteFunction { +public interface ExecuteFunction extends org.springframework.r2dbc.core.ExecuteFunction { /** * Execute the given {@link Statement} for a stream of {@link Result}s. diff --git a/src/main/java/org/springframework/data/r2dbc/core/FetchSpec.java b/src/main/java/org/springframework/data/r2dbc/core/FetchSpec.java index b4ea1102..133bc790 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/FetchSpec.java +++ b/src/main/java/org/springframework/data/r2dbc/core/FetchSpec.java @@ -22,5 +22,7 @@ * @author Mark Paluch * @see RowsFetchSpec * @see UpdatedRowsFetchSpec + * @deprecated since 1.2, use Spring's {@link org.springframework.r2dbc.core} support instead. */ +@Deprecated public interface FetchSpec extends RowsFetchSpec, UpdatedRowsFetchSpec {} diff --git a/src/main/java/org/springframework/data/r2dbc/core/MapBindParameterSource.java b/src/main/java/org/springframework/data/r2dbc/core/MapBindParameterSource.java index 6b1e8412..fc36dbb7 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/MapBindParameterSource.java +++ b/src/main/java/org/springframework/data/r2dbc/core/MapBindParameterSource.java @@ -31,6 +31,7 @@ * * @author Mark Paluch */ +@Deprecated class MapBindParameterSource implements BindParameterSource { private final Map values; diff --git a/src/main/java/org/springframework/data/r2dbc/core/NamedParameterExpander.java b/src/main/java/org/springframework/data/r2dbc/core/NamedParameterExpander.java index 2137fb2b..5093c47d 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/NamedParameterExpander.java +++ b/src/main/java/org/springframework/data/r2dbc/core/NamedParameterExpander.java @@ -36,7 +36,9 @@ * NOTE: An instance of this class is thread-safe once configured. * * @author Mark Paluch + * @deprecated since 1.2, without replacement. */ +@Deprecated public class NamedParameterExpander { /** @@ -124,6 +126,11 @@ private ParsedSql getParsedSql(String sql) { */ public PreparedOperation expand(String sql, BindMarkersFactory bindMarkersFactory, BindParameterSource paramSource) { + return expand(sql, (org.springframework.r2dbc.core.binding.BindMarkersFactory) bindMarkersFactory, paramSource); + } + + PreparedOperation expand(String sql, + org.springframework.r2dbc.core.binding.BindMarkersFactory bindMarkersFactory, BindParameterSource paramSource) { ParsedSql parsedSql = getParsedSql(sql); diff --git a/src/main/java/org/springframework/data/r2dbc/core/NamedParameterUtils.java b/src/main/java/org/springframework/data/r2dbc/core/NamedParameterUtils.java index 301aecc4..083e2ef2 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/NamedParameterUtils.java +++ b/src/main/java/org/springframework/data/r2dbc/core/NamedParameterUtils.java @@ -26,10 +26,10 @@ import java.util.TreeMap; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.r2dbc.dialect.BindMarker; -import org.springframework.data.r2dbc.dialect.BindMarkers; -import org.springframework.data.r2dbc.dialect.BindMarkersFactory; import org.springframework.data.r2dbc.dialect.BindTarget; +import org.springframework.r2dbc.core.binding.BindMarker; +import org.springframework.r2dbc.core.binding.BindMarkers; +import org.springframework.r2dbc.core.binding.BindMarkersFactory; import org.springframework.util.Assert; /** @@ -47,6 +47,7 @@ * @author Juergen Hoeller * @author Mark Paluch */ +@Deprecated abstract class NamedParameterUtils { /** @@ -494,7 +495,7 @@ private static class ExpandedQuery implements PreparedOperation { } @SuppressWarnings("unchecked") - public void bind(BindTarget target, String identifier, Object value) { + public void bind(org.springframework.r2dbc.core.binding.BindTarget target, String identifier, Object value) { List bindMarkers = getBindMarkers(identifier); @@ -530,7 +531,8 @@ public void bind(BindTarget target, String identifier, Object value) { } } - private void bind(BindTarget target, Iterator markers, Object valueToBind) { + private void bind(org.springframework.r2dbc.core.binding.BindTarget target, Iterator markers, + Object valueToBind) { Assert.isTrue(markers.hasNext(), () -> String.format( @@ -540,7 +542,8 @@ private void bind(BindTarget target, Iterator markers, Object valueT markers.next().bind(target, valueToBind); } - public void bindNull(BindTarget target, String identifier, Class valueType) { + public void bindNull(org.springframework.r2dbc.core.binding.BindTarget target, String identifier, + Class valueType) { List bindMarkers = getBindMarkers(identifier); @@ -579,6 +582,11 @@ public String getSource() { @Override public void bindTo(BindTarget target) { + bindTo((org.springframework.r2dbc.core.binding.BindTarget) target); + } + + @Override + public void bindTo(org.springframework.r2dbc.core.binding.BindTarget target) { for (String namedParameter : this.parameterSource.getParameterNames()) { diff --git a/src/main/java/org/springframework/data/r2dbc/core/ParsedSql.java b/src/main/java/org/springframework/data/r2dbc/core/ParsedSql.java index efa5bb83..af3cc6ef 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/ParsedSql.java +++ b/src/main/java/org/springframework/data/r2dbc/core/ParsedSql.java @@ -26,6 +26,7 @@ * @author Thomas Risberg * @author Juergen Hoeller */ +@Deprecated class ParsedSql { private String originalSql; diff --git a/src/main/java/org/springframework/data/r2dbc/core/PreparedOperation.java b/src/main/java/org/springframework/data/r2dbc/core/PreparedOperation.java index 73945511..fede1379 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/PreparedOperation.java +++ b/src/main/java/org/springframework/data/r2dbc/core/PreparedOperation.java @@ -29,8 +29,10 @@ * @param underlying operation source. * @author Mark Paluch * @see org.springframework.data.r2dbc.core.DatabaseClient#execute(Supplier) + * @deprecated since 1.2, use Spring R2DBC's {@link org.springframework.r2dbc.core} support instead. */ -public interface PreparedOperation extends QueryOperation { +@Deprecated +public interface PreparedOperation extends QueryOperation, org.springframework.r2dbc.core.PreparedOperation { /** * @return the query source, such as a statement/criteria object. @@ -44,4 +46,9 @@ public interface PreparedOperation extends QueryOperation { */ void bindTo(BindTarget target); + @Override + default String get() { + return toQuery(); + } + } diff --git a/src/main/java/org/springframework/data/r2dbc/core/QueryOperation.java b/src/main/java/org/springframework/data/r2dbc/core/QueryOperation.java index b5313397..c7f08a31 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/QueryOperation.java +++ b/src/main/java/org/springframework/data/r2dbc/core/QueryOperation.java @@ -23,9 +23,11 @@ * * @author Mark Paluch * @see PreparedOperation + * @deprecated since 1.2, use Spring R2DBC's {@link org.springframework.r2dbc.core} support instead. */ @FunctionalInterface -public interface QueryOperation extends Supplier { +@Deprecated +public interface QueryOperation extends Supplier, org.springframework.r2dbc.core.QueryOperation { /** * Returns the string-representation of this operation to be used with {@link io.r2dbc.spi.Statement} creation. diff --git a/src/main/java/org/springframework/data/r2dbc/core/R2dbcEntityOperations.java b/src/main/java/org/springframework/data/r2dbc/core/R2dbcEntityOperations.java index e3ef2338..f0cb4505 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/R2dbcEntityOperations.java +++ b/src/main/java/org/springframework/data/r2dbc/core/R2dbcEntityOperations.java @@ -22,6 +22,7 @@ import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.data.relational.core.query.Query; import org.springframework.data.relational.core.query.Update; +import org.springframework.r2dbc.core.DatabaseClient; /** * Interface specifying a basic set of reactive R2DBC operations using entities. Implemented by diff --git a/src/main/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplate.java b/src/main/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplate.java index ce0663ce..fe68d1aa 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplate.java +++ b/src/main/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplate.java @@ -15,6 +15,7 @@ */ package org.springframework.data.r2dbc.core; +import io.r2dbc.spi.Connection; import io.r2dbc.spi.Row; import io.r2dbc.spi.RowMetadata; import reactor.core.publisher.Flux; @@ -27,6 +28,7 @@ import java.util.Optional; import java.util.function.BiFunction; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; import org.reactivestreams.Publisher; @@ -47,8 +49,8 @@ import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.projection.ProjectionInformation; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; +import org.springframework.data.r2dbc.dialect.R2dbcDialect; import org.springframework.data.r2dbc.mapping.OutboundRow; -import org.springframework.data.r2dbc.mapping.SettableValue; import org.springframework.data.r2dbc.mapping.event.AfterConvertCallback; import org.springframework.data.r2dbc.mapping.event.AfterSaveCallback; import org.springframework.data.r2dbc.mapping.event.BeforeConvertCallback; @@ -65,6 +67,12 @@ import org.springframework.data.relational.core.sql.Table; import org.springframework.data.util.ProxyUtils; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.DatabaseClient; +import org.springframework.r2dbc.core.FetchSpec; +import org.springframework.r2dbc.core.Parameter; +import org.springframework.r2dbc.core.PreparedOperation; +import org.springframework.r2dbc.core.RowsFetchSpec; +import org.springframework.r2dbc.core.StatementFilterFunction; import org.springframework.util.Assert; /** @@ -95,8 +103,21 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw * Create a new {@link R2dbcEntityTemplate} given {@link DatabaseClient}. * * @param databaseClient must not be {@literal null}. + * @param dialect the dialect to use, must not be {@literal null}. + * @since 1.2 + */ + public R2dbcEntityTemplate(org.springframework.r2dbc.core.DatabaseClient databaseClient, R2dbcDialect dialect) { + this(databaseClient, new DefaultReactiveDataAccessStrategy(dialect)); + } + + /** + * Create a new {@link R2dbcEntityTemplate} given {@link DatabaseClient}. + * + * @param databaseClient must not be {@literal null}. + * @deprecated since 1.2, use {@link #R2dbcEntityTemplate(DatabaseClient, R2dbcDialect)} instead. */ - public R2dbcEntityTemplate(DatabaseClient databaseClient) { + @Deprecated + public R2dbcEntityTemplate(org.springframework.data.r2dbc.core.DatabaseClient databaseClient) { this(databaseClient, getDataAccessStrategy(databaseClient)); } @@ -104,8 +125,10 @@ public R2dbcEntityTemplate(DatabaseClient databaseClient) { * Create a new {@link R2dbcEntityTemplate} given {@link DatabaseClient} and {@link ReactiveDataAccessStrategy}. * * @param databaseClient must not be {@literal null}. + * @since 1.2 */ - public R2dbcEntityTemplate(DatabaseClient databaseClient, ReactiveDataAccessStrategy strategy) { + public R2dbcEntityTemplate(org.springframework.r2dbc.core.DatabaseClient databaseClient, + ReactiveDataAccessStrategy strategy) { Assert.notNull(databaseClient, "DatabaseClient must not be null"); Assert.notNull(strategy, "ReactiveDataAccessStrategy must not be null"); @@ -116,6 +139,18 @@ public R2dbcEntityTemplate(DatabaseClient databaseClient, ReactiveDataAccessStra this.projectionFactory = new SpelAwareProxyProjectionFactory(); } + /** + * Create a new {@link R2dbcEntityTemplate} given {@link DatabaseClient} and {@link ReactiveDataAccessStrategy}. + * + * @param databaseClient must not be {@literal null}. + * @deprecated since 1.2, use {@link #R2dbcEntityTemplate(DatabaseClient, ReactiveDataAccessStrategy)} instead. + */ + @Deprecated + public R2dbcEntityTemplate(org.springframework.data.r2dbc.core.DatabaseClient databaseClient, + ReactiveDataAccessStrategy strategy) { + this(new DatabaseClientAdapter(databaseClient), strategy); + } + /* * (non-Javadoc) * @see org.springframework.data.r2dbc.core.R2dbcEntityOperations#getDatabaseClient() @@ -250,7 +285,7 @@ Mono doCount(Query query, Class entityClass, SqlIdentifier tableName) { PreparedOperation operation = statementMapper.getMappedObject(selectSpec); - return this.databaseClient.execute(operation) // + return this.databaseClient.sql(operation) // .map((r, md) -> r.get(0, Long.class)) // .first() // .defaultIfEmpty(0L); @@ -289,7 +324,7 @@ Mono doExists(Query query, Class entityClass, SqlIdentifier tableNam PreparedOperation operation = statementMapper.getMappedObject(selectSpec); - return this.databaseClient.execute(operation) // + return this.databaseClient.sql(operation) // .map((r, md) -> r) // .first() // .hasElement(); @@ -360,7 +395,7 @@ private RowsFetchSpec doSelect(Query query, Class entityClass, SqlIden rowMapper = dataAccessStrategy.getRowMapper(returnType); } - return this.databaseClient.execute(operation).map(rowMapper); + return this.databaseClient.sql(operation).map(rowMapper); } /* @@ -399,7 +434,7 @@ Mono doUpdate(Query query, Update update, Class entityClass, SqlIden } PreparedOperation operation = statementMapper.getMappedObject(selectSpec); - return this.databaseClient.execute(operation).fetch().rowsUpdated(); + return this.databaseClient.sql(operation).fetch().rowsUpdated(); } /* @@ -428,7 +463,7 @@ Mono doDelete(Query query, Class entityClass, SqlIdentifier tableNam } PreparedOperation operation = statementMapper.getMappedObject(selectSpec); - return this.databaseClient.execute(operation).fetch().rowsUpdated().defaultIfEmpty(0); + return this.databaseClient.sql(operation).fetch().rowsUpdated().defaultIfEmpty(0); } // ------------------------------------------------------------------------- @@ -453,14 +488,13 @@ Mono doInsert(T entity, SqlIdentifier tableName) { T entityWithVersion = setVersionIfNecessary(persistentEntity, entity); - return maybeCallBeforeConvert(entityWithVersion, tableName) - .flatMap(beforeConvert -> { + return maybeCallBeforeConvert(entityWithVersion, tableName).flatMap(beforeConvert -> { - OutboundRow outboundRow = dataAccessStrategy.getOutboundRow(beforeConvert); + OutboundRow outboundRow = dataAccessStrategy.getOutboundRow(beforeConvert); - return maybeCallBeforeSave(beforeConvert, outboundRow, tableName) // - .flatMap(entityToSave -> doInsert(entityToSave, tableName, outboundRow)); - }); + return maybeCallBeforeSave(beforeConvert, outboundRow, tableName) // + .flatMap(entityToSave -> doInsert(entityToSave, tableName, outboundRow)); + }); } private Mono doInsert(T entity, SqlIdentifier tableName, OutboundRow outboundRow) { @@ -469,7 +503,7 @@ private Mono doInsert(T entity, SqlIdentifier tableName, OutboundRow outb StatementMapper.InsertSpec insert = mapper.createInsert(tableName); for (SqlIdentifier column : outboundRow.keySet()) { - SettableValue settableValue = outboundRow.get(column); + Parameter settableValue = outboundRow.get(column); if (settableValue.hasValue()) { insert = insert.withColumn(column, settableValue); } @@ -477,7 +511,7 @@ private Mono doInsert(T entity, SqlIdentifier tableName, OutboundRow outb PreparedOperation operation = mapper.getMappedObject(insert); - return this.databaseClient.execute(operation) // + return this.databaseClient.sql(operation) // .filter(statement -> statement.returnGeneratedValues()) .map(this.dataAccessStrategy.getConverter().populateIdIfNecessary(entity)) // .first() // @@ -539,7 +573,7 @@ private Mono doUpdate(T entity, SqlIdentifier tableName) { .flatMap(entityToSave -> { SqlIdentifier idColumn = persistentEntity.getRequiredIdProperty().getColumnName(); - SettableValue id = outboundRow.remove(idColumn); + Parameter id = outboundRow.remove(idColumn); Criteria criteria = Criteria.where(dataAccessStrategy.toSql(idColumn)).is(id); if (matchingVersionCriteria != null) { @@ -562,7 +596,7 @@ private Mono doUpdate(T entity, SqlIdentifier tableName, RelationalPersis PreparedOperation operation = mapper.getMappedObject(updateSpec); - return this.databaseClient.execute(operation) // + return this.databaseClient.sql(operation) // .fetch() // .rowsUpdated() // .handle((rowsUpdated, sink) -> { @@ -719,7 +753,8 @@ private List getSelectProjection(Table table, Query query, Class return query.getColumns().stream().map(table::column).collect(Collectors.toList()); } - private static ReactiveDataAccessStrategy getDataAccessStrategy(DatabaseClient databaseClient) { + private static ReactiveDataAccessStrategy getDataAccessStrategy( + org.springframework.data.r2dbc.core.DatabaseClient databaseClient) { Assert.notNull(databaseClient, "DatabaseClient must not be null"); @@ -732,4 +767,127 @@ private static ReactiveDataAccessStrategy getDataAccessStrategy(DatabaseClient d throw new IllegalStateException("Cannot obtain ReactiveDataAccessStrategy"); } + /** + * Adapter to adapt our deprecated {@link org.springframework.data.r2dbc.core.DatabaseClient} into Spring R2DBC + * {@link DatabaseClient}. + */ + private static class DatabaseClientAdapter implements DatabaseClient { + + private final org.springframework.data.r2dbc.core.DatabaseClient delegate; + + private DatabaseClientAdapter(org.springframework.data.r2dbc.core.DatabaseClient delegate) { + + Assert.notNull(delegate, "DatabaseClient must not be null"); + + this.delegate = delegate; + } + + @Override + public GenericExecuteSpec sql(String sql) { + return new GenericExecuteSpecAdapter(delegate.execute(sql)); + } + + @Override + public GenericExecuteSpec sql(Supplier sqlSupplier) { + return new GenericExecuteSpecAdapter(delegate.execute(sqlSupplier)); + } + + @Override + public Mono inConnection(Function> action) throws DataAccessException { + return ((ConnectionAccessor) delegate).inConnection(action); + } + + @Override + public Flux inConnectionMany(Function> action) throws DataAccessException { + return ((ConnectionAccessor) delegate).inConnectionMany(action); + } + + static class GenericExecuteSpecAdapter implements GenericExecuteSpec { + + private final org.springframework.data.r2dbc.core.DatabaseClient.GenericExecuteSpec delegate; + + public GenericExecuteSpecAdapter(org.springframework.data.r2dbc.core.DatabaseClient.GenericExecuteSpec delegate) { + this.delegate = delegate; + } + + @Override + public GenericExecuteSpec bind(int index, Object value) { + return new GenericExecuteSpecAdapter(delegate.bind(index, value)); + } + + @Override + public GenericExecuteSpec bindNull(int index, Class type) { + return new GenericExecuteSpecAdapter(delegate.bindNull(index, type)); + } + + @Override + public GenericExecuteSpec bind(String name, Object value) { + return new GenericExecuteSpecAdapter(delegate.bind(name, value)); + } + + @Override + public GenericExecuteSpec bindNull(String name, Class type) { + return new GenericExecuteSpecAdapter(delegate.bindNull(name, type)); + } + + @Override + public GenericExecuteSpec filter(StatementFilterFunction filter) { + return new GenericExecuteSpecAdapter(delegate.filter(filter::filter)); + } + + @Override + public RowsFetchSpec map(BiFunction mappingFunction) { + return new RowFetchSpecAdapter<>(delegate.map(mappingFunction)); + } + + @Override + public FetchSpec> fetch() { + return new FetchSpecAdapter<>(delegate.fetch()); + } + + @Override + public Mono then() { + return delegate.then(); + } + } + + private static class RowFetchSpecAdapter implements RowsFetchSpec { + + private final org.springframework.data.r2dbc.core.RowsFetchSpec delegate; + + RowFetchSpecAdapter(org.springframework.data.r2dbc.core.RowsFetchSpec delegate) { + this.delegate = delegate; + } + + @Override + public Mono one() { + return delegate.one(); + } + + @Override + public Mono first() { + return delegate.first(); + } + + @Override + public Flux all() { + return delegate.all(); + } + } + + private static class FetchSpecAdapter extends RowFetchSpecAdapter implements FetchSpec { + + private final org.springframework.data.r2dbc.core.FetchSpec delegate; + + FetchSpecAdapter(org.springframework.data.r2dbc.core.FetchSpec delegate) { + super(delegate); + this.delegate = delegate; + } + + @Override + public Mono rowsUpdated() { + return delegate.rowsUpdated(); + } + } + } } diff --git a/src/main/java/org/springframework/data/r2dbc/core/ReactiveDataAccessStrategy.java b/src/main/java/org/springframework/data/r2dbc/core/ReactiveDataAccessStrategy.java index 8c65fa54..b35cac98 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/ReactiveDataAccessStrategy.java +++ b/src/main/java/org/springframework/data/r2dbc/core/ReactiveDataAccessStrategy.java @@ -27,6 +27,8 @@ import org.springframework.data.relational.core.sql.IdentifierProcessing; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.Parameter; +import org.springframework.r2dbc.core.PreparedOperation; /** * Data access strategy that generalizes convenience operations using mapped entities. Typically used internally by @@ -34,7 +36,7 @@ * primary keys. * * @author Mark Paluch - * @see PreparedOperation + * @see org.springframework.r2dbc.core.PreparedOperation */ public interface ReactiveDataAccessStrategy { @@ -51,7 +53,7 @@ public interface ReactiveDataAccessStrategy { List getIdentifierColumns(Class entityType); /** - * Returns a {@link OutboundRow} that maps column names to a {@link SettableValue} value. + * Returns a {@link OutboundRow} that maps column names to a {@link Parameter} value. * * @param object must not be {@literal null}. * @return @@ -64,9 +66,20 @@ public interface ReactiveDataAccessStrategy { * @param value must not be {@literal null}. * @return * @since 1.1 + * @deprecated since 1.2, use {@link #getBindValue(Parameter)} instead. */ + @Deprecated SettableValue getBindValue(SettableValue value); + /** + * Return a potentially converted {@link Parameter} for strategies that support type conversion. + * + * @param value must not be {@literal null}. + * @return + * @since 1.2 + */ + Parameter getBindValue(Parameter value); + /** * Returns a {@link BiFunction row mapping function} to map {@link Row rows} to {@code T}. * @@ -89,7 +102,10 @@ public interface ReactiveDataAccessStrategy { * @param parameterProvider indexed parameter bindings. * @return the {@link PreparedOperation} encapsulating expanded SQL and namedBindings. * @throws org.springframework.dao.InvalidDataAccessApiUsageException if a named parameter value cannot be resolved. + * @deprecated since 1.2. {@link org.springframework.r2dbc.core.DatabaseClient} encapsulates named parameter handling + * entirely. */ + @Deprecated PreparedOperation processNamedParameters(String query, NamedParameterProvider parameterProvider); /** diff --git a/src/main/java/org/springframework/data/r2dbc/core/ReactiveSelectOperationSupport.java b/src/main/java/org/springframework/data/r2dbc/core/ReactiveSelectOperationSupport.java index 1cfabb47..46be18f9 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/ReactiveSelectOperationSupport.java +++ b/src/main/java/org/springframework/data/r2dbc/core/ReactiveSelectOperationSupport.java @@ -21,6 +21,7 @@ import org.springframework.data.relational.core.query.Query; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.RowsFetchSpec; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/r2dbc/core/RowsFetchSpec.java b/src/main/java/org/springframework/data/r2dbc/core/RowsFetchSpec.java index e6f59a7b..3b76d4de 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/RowsFetchSpec.java +++ b/src/main/java/org/springframework/data/r2dbc/core/RowsFetchSpec.java @@ -23,7 +23,9 @@ * * @param row result type. * @author Mark Paluch + * @deprecated since 1.2, use Spring's {@link org.springframework.r2dbc.core} support instead. */ +@Deprecated public interface RowsFetchSpec { /** diff --git a/src/main/java/org/springframework/data/r2dbc/core/SqlProvider.java b/src/main/java/org/springframework/data/r2dbc/core/SqlProvider.java index 7b02b609..914e3408 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/SqlProvider.java +++ b/src/main/java/org/springframework/data/r2dbc/core/SqlProvider.java @@ -25,8 +25,10 @@ * * @author Juergen Hoeller * @author Mark Paluch + * @deprecated since 1.2, use Spring's {@link org.springframework.r2dbc.core} support instead. */ -public interface SqlProvider { +@Deprecated +public interface SqlProvider extends org.springframework.r2dbc.core.SqlProvider { /** * Return the SQL string for this object, i.e. typically the SQL used for creating statements. diff --git a/src/main/java/org/springframework/data/r2dbc/core/SqlResult.java b/src/main/java/org/springframework/data/r2dbc/core/SqlResult.java deleted file mode 100644 index 8cf624df..00000000 --- a/src/main/java/org/springframework/data/r2dbc/core/SqlResult.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2018-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.data.r2dbc.core; - -import io.r2dbc.spi.Row; -import io.r2dbc.spi.RowMetadata; - -import java.util.function.BiFunction; - -/** - * Mappable {@link FetchSpec} that accepts a {@link BiFunction mapping function} to map SQL {@link Row}s. - * - * @author Mark Paluch - */ -interface SqlResult extends FetchSpec { - - /** - * Apply a {@link BiFunction mapping function} to the result that emits {@link Row}s. - * - * @param mappingFunction must not be {@literal null}. - * @param the value type of the {@code SqlResult}. - * @return a new {@link SqlResult} with {@link BiFunction mapping function} applied. - */ - SqlResult map(BiFunction mappingFunction); -} diff --git a/src/main/java/org/springframework/data/r2dbc/core/StatementFilterFunction.java b/src/main/java/org/springframework/data/r2dbc/core/StatementFilterFunction.java index 520b7ab6..a7350f65 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/StatementFilterFunction.java +++ b/src/main/java/org/springframework/data/r2dbc/core/StatementFilterFunction.java @@ -31,7 +31,9 @@ * @author Mark Paluch * @since 1.1 * @see ExecuteFunction + * @deprecated since 1.2, use Spring's {@link org.springframework.r2dbc.core} support instead. */ +@Deprecated @FunctionalInterface public interface StatementFilterFunction { diff --git a/src/main/java/org/springframework/data/r2dbc/core/StatementFilterFunctions.java b/src/main/java/org/springframework/data/r2dbc/core/StatementFilterFunctions.java index e9788992..f98c8b36 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/StatementFilterFunctions.java +++ b/src/main/java/org/springframework/data/r2dbc/core/StatementFilterFunctions.java @@ -26,6 +26,7 @@ * @author Mark Paluch * @since 1.1 */ +@Deprecated enum StatementFilterFunctions implements StatementFilterFunction { EMPTY_FILTER; diff --git a/src/main/java/org/springframework/data/r2dbc/core/StatementMapper.java b/src/main/java/org/springframework/data/r2dbc/core/StatementMapper.java index 22399e7e..c68d8eab 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/StatementMapper.java +++ b/src/main/java/org/springframework/data/r2dbc/core/StatementMapper.java @@ -36,6 +36,8 @@ import org.springframework.data.relational.core.sql.Table; import org.springframework.data.relational.core.sql.render.RenderContext; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.Parameter; +import org.springframework.r2dbc.core.PreparedOperation; /** * Mapper for statement specifications to {@link PreparedOperation}. Statement mapping applies a @@ -424,9 +426,9 @@ public boolean isDistinct() { class InsertSpec { private final SqlIdentifier table; - private final Map assignments; + private final Map assignments; - protected InsertSpec(SqlIdentifier table, Map assignments) { + protected InsertSpec(SqlIdentifier table, Map assignments) { this.table = table; this.assignments = assignments; } @@ -458,21 +460,49 @@ public static InsertSpec create(SqlIdentifier table) { * @param column * @param value * @return the {@link InsertSpec}. + * @deprecated since 1.2, use {@link #withColumn(String, Parameter)} instead. */ + @Deprecated public InsertSpec withColumn(String column, SettableValue value) { return withColumn(SqlIdentifier.unquoted(column), value); } + /** + * Associate a column with a {@link Parameter} and create a new {@link InsertSpec}. + * + * @param column + * @param value + * @return the {@link InsertSpec}. + * @since 1.2 + */ + public InsertSpec withColumn(String column, Parameter value) { + return withColumn(SqlIdentifier.unquoted(column), value); + } + /** * Associate a column with a {@link SettableValue} and create a new {@link InsertSpec}. * * @param column * @param value * @return the {@link InsertSpec}. + * @deprecated since 1.2, use {@link #withColumn(SqlIdentifier, Parameter)} instead. */ + @Deprecated public InsertSpec withColumn(SqlIdentifier column, SettableValue value) { + return withColumn(column, value.toParameter()); + } + + /** + * Associate a column with a {@link Parameter} and create a new {@link InsertSpec}. + * + * @param column + * @param value + * @return the {@link InsertSpec}. + * @since 1.2 + */ + public InsertSpec withColumn(SqlIdentifier column, Parameter value) { - Map values = new LinkedHashMap<>(this.assignments); + Map values = new LinkedHashMap<>(this.assignments); values.put(column, value); return new InsertSpec(this.table, values); @@ -482,7 +512,7 @@ public SqlIdentifier getTable() { return this.table; } - public Map getAssignments() { + public Map getAssignments() { return Collections.unmodifiableMap(this.assignments); } } diff --git a/src/main/java/org/springframework/data/r2dbc/core/UpdatedRowsFetchSpec.java b/src/main/java/org/springframework/data/r2dbc/core/UpdatedRowsFetchSpec.java index 256d2598..69aee602 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/UpdatedRowsFetchSpec.java +++ b/src/main/java/org/springframework/data/r2dbc/core/UpdatedRowsFetchSpec.java @@ -21,7 +21,9 @@ * Contract for fetching the number of affected rows. * * @author Mark Paluch + * @deprecated since 1.2, use Spring's {@link org.springframework.r2dbc.core} support instead. */ +@Deprecated public interface UpdatedRowsFetchSpec { /** diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/AnonymousBindMarkers.java b/src/main/java/org/springframework/data/r2dbc/dialect/AnonymousBindMarkers.java deleted file mode 100644 index 205e1a4d..00000000 --- a/src/main/java/org/springframework/data/r2dbc/dialect/AnonymousBindMarkers.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2019-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.data.r2dbc.dialect; - -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; - -/** - * Anonymous, index-based bind marker using a static placeholder. Instances are bound by the ordinal position ordered by - * the appearance of the placeholder. This implementation creates indexed bind markers using an anonymous placeholder - * that correlates with an index. - *

- * Note: Anonymous bind markers are problematic because the have to appear in generated SQL in the same order they get generated. - * - * This might cause challenges in the future with complex generate statements. - * For example those containing subselects which limit the freedom of arranging bind markers. - *

- * - * @author Mark Paluch - */ -class AnonymousBindMarkers implements BindMarkers { - - private static final AtomicIntegerFieldUpdater COUNTER_INCREMENTER = AtomicIntegerFieldUpdater - .newUpdater(AnonymousBindMarkers.class, "counter"); - - // access via COUNTER_INCREMENTER - @SuppressWarnings("unused") private volatile int counter; - - private final String placeholder; - - /** - * Creates a new {@link AnonymousBindMarkers} instance given {@code placeholder}. - * - * @param placeholder parameter bind marker. - */ - AnonymousBindMarkers(String placeholder) { - this.counter = 0; - this.placeholder = placeholder; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.r2dbc.dialect.BindMarkers#next() - */ - @Override - public BindMarker next() { - - int index = COUNTER_INCREMENTER.getAndIncrement(this); - - return new IndexedBindMarker(placeholder, index); - } - -} diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/BindMarker.java b/src/main/java/org/springframework/data/r2dbc/dialect/BindMarker.java index 66240521..e574aaea 100644 --- a/src/main/java/org/springframework/data/r2dbc/dialect/BindMarker.java +++ b/src/main/java/org/springframework/data/r2dbc/dialect/BindMarker.java @@ -10,8 +10,10 @@ * @see Statement#bind * @see BindMarkers * @see BindMarkersFactory + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.core.binding} instead. */ -public interface BindMarker { +@Deprecated +public interface BindMarker extends org.springframework.r2dbc.core.binding.BindMarker { /** * Returns the database-specific placeholder for a given substitution. diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/BindMarkers.java b/src/main/java/org/springframework/data/r2dbc/dialect/BindMarkers.java index 3d56ed40..53296d33 100644 --- a/src/main/java/org/springframework/data/r2dbc/dialect/BindMarkers.java +++ b/src/main/java/org/springframework/data/r2dbc/dialect/BindMarkers.java @@ -12,9 +12,11 @@ * @see BindMarker * @see BindMarkersFactory * @see io.r2dbc.spi.Statement#bind + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.core.binding} instead. */ @FunctionalInterface -public interface BindMarkers { +@Deprecated +public interface BindMarkers extends org.springframework.r2dbc.core.binding.BindMarkers { /** * Creates a new {@link BindMarker}. diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/BindMarkersAdapter.java b/src/main/java/org/springframework/data/r2dbc/dialect/BindMarkersAdapter.java new file mode 100644 index 00000000..448ea223 --- /dev/null +++ b/src/main/java/org/springframework/data/r2dbc/dialect/BindMarkersAdapter.java @@ -0,0 +1,85 @@ +/* + * Copyright 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.data.r2dbc.dialect; + +import org.springframework.r2dbc.core.binding.BindMarker; +import org.springframework.r2dbc.core.binding.BindMarkers; +import org.springframework.r2dbc.core.binding.BindTarget; + +/** + * Adapter to use Spring R2DBC's {@link org.springframework.r2dbc.core.binding.BindMarkers} exposing it as + * {@link org.springframework.data.r2dbc.dialect.BindMarkers}. + * + * @author Mark Paluch + * @since 1.2 + */ +class BindMarkersAdapter implements org.springframework.data.r2dbc.dialect.BindMarkers { + + private final BindMarkers delegate; + + BindMarkersAdapter(BindMarkers delegate) { + this.delegate = delegate; + } + + @Override + public org.springframework.data.r2dbc.dialect.BindMarker next() { + return new BindMarkerAdapter(delegate.next()); + } + + @Override + public org.springframework.data.r2dbc.dialect.BindMarker next(String hint) { + return new BindMarkerAdapter(delegate.next()); + } + + static class BindMarkerAdapter implements org.springframework.data.r2dbc.dialect.BindMarker { + + private final BindMarker delegate; + + BindMarkerAdapter(BindMarker delegate) { + this.delegate = delegate; + } + + @Override + public String getPlaceholder() { + return delegate.getPlaceholder(); + } + + @Override + public void bind(org.springframework.data.r2dbc.dialect.BindTarget bindTarget, Object value) { + delegate.bind(bindTarget, value); + } + + @Override + public void bindNull(org.springframework.data.r2dbc.dialect.BindTarget bindTarget, Class valueType) { + delegate.bindNull(bindTarget, valueType); + } + + @Override + public void bind(BindTarget bindTarget, Object value) { + delegate.bind(bindTarget, value); + } + + @Override + public void bindNull(BindTarget bindTarget, Class valueType) { + delegate.bindNull(bindTarget, valueType); + } + + @Override + public String toString() { + return delegate.toString(); + } + } +} diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/BindMarkersFactory.java b/src/main/java/org/springframework/data/r2dbc/dialect/BindMarkersFactory.java index 15755ccc..55f3aee5 100644 --- a/src/main/java/org/springframework/data/r2dbc/dialect/BindMarkersFactory.java +++ b/src/main/java/org/springframework/data/r2dbc/dialect/BindMarkersFactory.java @@ -15,9 +15,11 @@ * @author Mark Paluch * @see BindMarkers * @see io.r2dbc.spi.Statement + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.core.binding} instead. */ @FunctionalInterface -public interface BindMarkersFactory { +@Deprecated +public interface BindMarkersFactory extends org.springframework.r2dbc.core.binding.BindMarkersFactory { /** * Create a new {@link BindMarkers} instance. @@ -52,7 +54,21 @@ static BindMarkersFactory indexed(String prefix, int beginWith) { Assert.notNull(prefix, "Prefix must not be null!"); - return () -> new IndexedBindMarkers(prefix, beginWith); + org.springframework.r2dbc.core.binding.BindMarkersFactory factory = org.springframework.r2dbc.core.binding.BindMarkersFactory + .indexed(prefix, beginWith); + + return new BindMarkersFactory() { + + @Override + public BindMarkers create() { + return new BindMarkersAdapter(factory.create()); + } + + @Override + public boolean identifiablePlaceholders() { + return factory.identifiablePlaceholders(); + } + }; } /** @@ -68,17 +84,19 @@ static BindMarkersFactory indexed(String prefix, int beginWith) { static BindMarkersFactory anonymous(String placeholder) { Assert.hasText(placeholder, "Placeholder must not be empty!"); + org.springframework.r2dbc.core.binding.BindMarkersFactory factory = org.springframework.r2dbc.core.binding.BindMarkersFactory + .anonymous(placeholder); return new BindMarkersFactory() { @Override public BindMarkers create() { - return new AnonymousBindMarkers(placeholder); + return new BindMarkersAdapter(factory.create()); } @Override public boolean identifiablePlaceholders() { - return false; + return factory.identifiablePlaceholders(); } }; } @@ -127,6 +145,20 @@ static BindMarkersFactory named(String prefix, String namePrefix, int maxLength, Assert.notNull(namePrefix, "Index prefix must not be null!"); Assert.notNull(hintFilterFunction, "Hint filter function must not be null!"); - return () -> new NamedBindMarkers(prefix, namePrefix, maxLength, hintFilterFunction); + org.springframework.r2dbc.core.binding.BindMarkersFactory factory = org.springframework.r2dbc.core.binding.BindMarkersFactory + .named(prefix, namePrefix, maxLength, hintFilterFunction); + + return new BindMarkersFactory() { + + @Override + public BindMarkers create() { + return new BindMarkersAdapter(factory.create()); + } + + @Override + public boolean identifiablePlaceholders() { + return factory.identifiablePlaceholders(); + } + }; } } diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/BindTarget.java b/src/main/java/org/springframework/data/r2dbc/dialect/BindTarget.java index a1098bd3..d7b95580 100644 --- a/src/main/java/org/springframework/data/r2dbc/dialect/BindTarget.java +++ b/src/main/java/org/springframework/data/r2dbc/dialect/BindTarget.java @@ -24,8 +24,10 @@ * @see PreparedOperation * @see io.r2dbc.spi.Statement#bind * @see io.r2dbc.spi.Statement#bindNull + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.core.binding} instead. */ -public interface BindTarget { +@Deprecated +public interface BindTarget extends org.springframework.r2dbc.core.binding.BindTarget { /** * Bind a value. diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/Bindings.java b/src/main/java/org/springframework/data/r2dbc/dialect/Bindings.java index e0e503cd..2e1bcb4d 100644 --- a/src/main/java/org/springframework/data/r2dbc/dialect/Bindings.java +++ b/src/main/java/org/springframework/data/r2dbc/dialect/Bindings.java @@ -29,6 +29,9 @@ import org.springframework.data.util.Streamable; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.binding.BindMarker; +import org.springframework.r2dbc.core.binding.BindMarkers; +import org.springframework.r2dbc.core.binding.BindTarget; import org.springframework.util.Assert; /** @@ -36,7 +39,9 @@ * Bindings are typically immutable. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.core.binding} instead. */ +@Deprecated public class Bindings implements Streamable { private static final Bindings EMPTY = new Bindings(); diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/IndexedBindMarker.java b/src/main/java/org/springframework/data/r2dbc/dialect/IndexedBindMarker.java deleted file mode 100644 index 613f4e1a5..00000000 --- a/src/main/java/org/springframework/data/r2dbc/dialect/IndexedBindMarker.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2019-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.data.r2dbc.dialect; - -/** - * A single indexed bind marker. - */ -class IndexedBindMarker implements BindMarker { - - private final String placeholder; - - private final int index; - - IndexedBindMarker(String placeholder, int index) { - this.placeholder = placeholder; - this.index = index; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.r2dbc.dialect.BindMarker#getPlaceholder() - */ - @Override - public String getPlaceholder() { - return placeholder; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.r2dbc.dialect.BindMarker#bindValue(org.springframework.data.r2dbc.dialect.BindTarget, java.lang.Object) - */ - @Override - public void bind(BindTarget target, Object value) { - target.bind(this.index, value); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.r2dbc.dialect.BindMarker#bindNull(org.springframework.data.r2dbc.dialect.BindTarget, java.lang.Class) - */ - @Override - public void bindNull(BindTarget target, Class valueType) { - target.bindNull(this.index, valueType); - } - - - public int getIndex() { - return index; - } - -} diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/IndexedBindMarkers.java b/src/main/java/org/springframework/data/r2dbc/dialect/IndexedBindMarkers.java deleted file mode 100644 index 50a80c05..00000000 --- a/src/main/java/org/springframework/data/r2dbc/dialect/IndexedBindMarkers.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.springframework.data.r2dbc.dialect; - -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 - */ -class IndexedBindMarkers implements BindMarkers { - - private static final AtomicIntegerFieldUpdater COUNTER_INCREMENTER = AtomicIntegerFieldUpdater - .newUpdater(org.springframework.data.r2dbc.dialect.IndexedBindMarkers.class, "counter"); - - // access via COUNTER_INCREMENTER - @SuppressWarnings("unused") private volatile int counter; - - private final int offset; - private final String prefix; - - /** - * Creates a new {@link IndexedBindMarker} instance given {@code prefix} and {@code beginWith}. - * - * @param prefix bind parameter prefix. - * @param beginWith the first index to use. - */ - IndexedBindMarkers(String prefix, int beginWith) { - this.counter = 0; - this.prefix = prefix; - this.offset = beginWith; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.r2dbc.dialect.BindMarkers#next() - */ - @Override - public BindMarker next() { - - int index = COUNTER_INCREMENTER.getAndIncrement(this); - - return new IndexedBindMarker(prefix + "" + (index + offset), index); - } -} diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/MutableBindings.java b/src/main/java/org/springframework/data/r2dbc/dialect/MutableBindings.java index 27aad5b5..0178c9eb 100644 --- a/src/main/java/org/springframework/data/r2dbc/dialect/MutableBindings.java +++ b/src/main/java/org/springframework/data/r2dbc/dialect/MutableBindings.java @@ -26,7 +26,9 @@ * {@link BindMarkers}. * * @author Mark Paluch + * @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.core.binding} instead. */ +@Deprecated public class MutableBindings extends Bindings { private final BindMarkers markers; diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/MySqlDialect.java b/src/main/java/org/springframework/data/r2dbc/dialect/MySqlDialect.java index ab977a81..3a38df95 100644 --- a/src/main/java/org/springframework/data/r2dbc/dialect/MySqlDialect.java +++ b/src/main/java/org/springframework/data/r2dbc/dialect/MySqlDialect.java @@ -27,6 +27,7 @@ import java.util.UUID; import org.springframework.core.convert.converter.Converter; +import org.springframework.r2dbc.core.binding.BindMarkersFactory; /** * An SQL dialect for MySQL. diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/NamedBindMarkers.java b/src/main/java/org/springframework/data/r2dbc/dialect/NamedBindMarkers.java deleted file mode 100644 index 7f1dd0f5..00000000 --- a/src/main/java/org/springframework/data/r2dbc/dialect/NamedBindMarkers.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.springframework.data.r2dbc.dialect; - -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import java.util.function.Function; - -import org.springframework.util.Assert; - -/** - * Name-based bind markers. - * - * @author Mark Paluch - */ -class NamedBindMarkers implements BindMarkers { - - private static final AtomicIntegerFieldUpdater COUNTER_INCREMENTER = AtomicIntegerFieldUpdater - .newUpdater(NamedBindMarkers.class, "counter"); - - // access via COUNTER_INCREMENTER - @SuppressWarnings("unused") private volatile int counter; - - private final String prefix; - - private final String namePrefix; - - private final int nameLimit; - - private final Function hintFilterFunction; - - NamedBindMarkers(String prefix, String namePrefix, int nameLimit, Function hintFilterFunction) { - - this.prefix = prefix; - this.namePrefix = namePrefix; - this.nameLimit = nameLimit; - this.hintFilterFunction = hintFilterFunction; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.r2dbc.dialect.BindMarkers#next() - */ - @Override - public BindMarker next() { - - String name = nextName(); - - return new NamedBindMarker(prefix + name, name); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.r2dbc.dialect.BindMarkers#next(java.lang.String) - */ - @Override - public BindMarker next(String hint) { - - Assert.notNull(hint, "Name hint must not be null"); - - String name = nextName() + hintFilterFunction.apply(hint); - - if (name.length() > nameLimit) { - name = name.substring(0, nameLimit); - } - - return new NamedBindMarker(prefix + name, name); - } - - private String nextName() { - - int index = COUNTER_INCREMENTER.getAndIncrement(this); - return namePrefix + index; - } - - /** - * A single named bind marker. - */ - static class NamedBindMarker implements BindMarker { - - private final String placeholder; - - private final String identifier; - - NamedBindMarker(String placeholder, String identifier) { - - this.placeholder = placeholder; - this.identifier = identifier; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.r2dbc.dialect.BindMarker#getPlaceholder() - */ - @Override - public String getPlaceholder() { - return this.placeholder; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.r2dbc.dialect.BindMarker#bindValue(org.springframework.data.r2dbc.dialect.BindTarget, java.lang.Object) - */ - @Override - public void bind(BindTarget target, Object value) { - target.bind(this.identifier, value); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.r2dbc.dialect.BindMarker#bindNull(org.springframework.data.r2dbc.dialect.BindTarget, java.lang.Class) - */ - @Override - public void bindNull(BindTarget target, Class valueType) { - target.bindNull(this.identifier, valueType); - } - } -} diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/PostgresDialect.java b/src/main/java/org/springframework/data/r2dbc/dialect/PostgresDialect.java index b26d6313..77f838ee 100644 --- a/src/main/java/org/springframework/data/r2dbc/dialect/PostgresDialect.java +++ b/src/main/java/org/springframework/data/r2dbc/dialect/PostgresDialect.java @@ -12,6 +12,7 @@ import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.relational.core.dialect.ArrayColumns; import org.springframework.data.util.Lazy; +import org.springframework.r2dbc.core.binding.BindMarkersFactory; import org.springframework.util.ClassUtils; /** diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/R2dbcDialect.java b/src/main/java/org/springframework/data/r2dbc/dialect/R2dbcDialect.java index 9a28b6c5..fe56872c 100644 --- a/src/main/java/org/springframework/data/r2dbc/dialect/R2dbcDialect.java +++ b/src/main/java/org/springframework/data/r2dbc/dialect/R2dbcDialect.java @@ -8,6 +8,7 @@ import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.r2dbc.mapping.R2dbcSimpleTypeHolder; import org.springframework.data.relational.core.dialect.Dialect; +import org.springframework.r2dbc.core.binding.BindMarkersFactory; /** * R2DBC-specific extension to {@link Dialect}. Represents a dialect that is implemented by a particular database. diff --git a/src/main/java/org/springframework/data/r2dbc/dialect/SqlServerDialect.java b/src/main/java/org/springframework/data/r2dbc/dialect/SqlServerDialect.java index 33ea66ca..2c0fb061 100644 --- a/src/main/java/org/springframework/data/r2dbc/dialect/SqlServerDialect.java +++ b/src/main/java/org/springframework/data/r2dbc/dialect/SqlServerDialect.java @@ -6,6 +6,8 @@ import java.util.Set; import java.util.UUID; +import org.springframework.r2dbc.core.binding.BindMarkersFactory; + /** * An SQL dialect for Microsoft SQL Server. * diff --git a/src/main/java/org/springframework/data/r2dbc/mapping/OutboundRow.java b/src/main/java/org/springframework/data/r2dbc/mapping/OutboundRow.java index fc1d7761..640a0521 100644 --- a/src/main/java/org/springframework/data/r2dbc/mapping/OutboundRow.java +++ b/src/main/java/org/springframework/data/r2dbc/mapping/OutboundRow.java @@ -24,6 +24,7 @@ import java.util.function.BiConsumer; import org.springframework.data.relational.core.sql.SqlIdentifier; +import org.springframework.r2dbc.core.Parameter; import org.springframework.util.Assert; /** @@ -33,11 +34,11 @@ * * @author Mark Paluch * @see SqlIdentifier - * @see SettableValue + * @see Parameter */ -public class OutboundRow implements Map { +public class OutboundRow implements Map { - private final Map rowAsMap; + private final Map rowAsMap; /** * Creates an empty {@link OutboundRow} instance. @@ -51,13 +52,13 @@ public OutboundRow() { * * @param map the map used to initialize the {@link OutboundRow}. */ - public OutboundRow(Map map) { + public OutboundRow(Map map) { Assert.notNull(map, "Map must not be null"); this.rowAsMap = new LinkedHashMap<>(map.size()); - map.forEach((s, settableValue) -> this.rowAsMap.put(SqlIdentifier.unquoted(s), settableValue)); + map.forEach((s, Parameter) -> this.rowAsMap.put(SqlIdentifier.unquoted(s), Parameter)); } /** @@ -67,7 +68,7 @@ public OutboundRow(Map map) { * @param value value. * @see SqlIdentifier#unquoted(String) */ - public OutboundRow(String key, SettableValue value) { + public OutboundRow(String key, Parameter value) { this(SqlIdentifier.unquoted(key), value); } @@ -78,7 +79,7 @@ public OutboundRow(String key, SettableValue value) { * @param value value. * @since 1.1 */ - public OutboundRow(SqlIdentifier key, SettableValue value) { + public OutboundRow(SqlIdentifier key, Parameter value) { this.rowAsMap = new LinkedHashMap<>(); this.rowAsMap.put(key, value); } @@ -96,7 +97,7 @@ public OutboundRow(SqlIdentifier key, SettableValue value) { * @return this * @see SqlIdentifier#unquoted(String) */ - public OutboundRow append(String key, SettableValue value) { + public OutboundRow append(String key, Parameter value) { return append(SqlIdentifier.unquoted(key), value); } @@ -113,7 +114,7 @@ public OutboundRow append(String key, SettableValue value) { * @return this * @since 1.1 */ - public OutboundRow append(SqlIdentifier key, SettableValue value) { + public OutboundRow append(SqlIdentifier key, Parameter value) { this.rowAsMap.put(key, value); return this; } @@ -159,7 +160,7 @@ public boolean containsValue(Object value) { * @see java.util.Map#get(java.lang.Object) */ @Override - public SettableValue get(Object key) { + public Parameter get(Object key) { return this.rowAsMap.get(convertKeyIfNecessary(key)); } @@ -167,7 +168,7 @@ public SettableValue get(Object key) { * (non-Javadoc) * @see java.util.Map#put(java.lang.Object, java.lang.Object) */ - public SettableValue put(String key, SettableValue value) { + public Parameter put(String key, Parameter value) { return put(SqlIdentifier.unquoted(key), value); } @@ -176,7 +177,7 @@ public SettableValue put(String key, SettableValue value) { * @see java.util.Map#put(java.lang.Object, java.lang.Object) */ @Override - public SettableValue put(SqlIdentifier key, SettableValue value) { + public Parameter put(SqlIdentifier key, Parameter value) { return this.rowAsMap.put(key, value); } @@ -185,7 +186,7 @@ public SettableValue put(SqlIdentifier key, SettableValue value) { * @see java.util.Map#remove(java.lang.Object) */ @Override - public SettableValue remove(Object key) { + public Parameter remove(Object key) { return this.rowAsMap.remove(key); } @@ -194,7 +195,7 @@ public SettableValue remove(Object key) { * @see java.util.Map#putAll(java.util.Map) */ @Override - public void putAll(Map m) { + public void putAll(Map m) { this.rowAsMap.putAll(m); } @@ -221,7 +222,7 @@ public Set keySet() { * @see java.util.Map#values() */ @Override - public Collection values() { + public Collection values() { return this.rowAsMap.values(); } @@ -230,7 +231,7 @@ public Collection values() { * @see java.util.Map#entrySet() */ @Override - public Set> entrySet() { + public Set> entrySet() { return this.rowAsMap.entrySet(); } @@ -273,7 +274,7 @@ public String toString() { } @Override - public void forEach(BiConsumer action) { + public void forEach(BiConsumer action) { this.rowAsMap.forEach(action); } diff --git a/src/main/java/org/springframework/data/r2dbc/mapping/SettableValue.java b/src/main/java/org/springframework/data/r2dbc/mapping/SettableValue.java index f6db5b8a..71587ac1 100644 --- a/src/main/java/org/springframework/data/r2dbc/mapping/SettableValue.java +++ b/src/main/java/org/springframework/data/r2dbc/mapping/SettableValue.java @@ -15,30 +15,24 @@ */ package org.springframework.data.r2dbc.mapping; -import java.util.Objects; - import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.Parameter; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; /** * A database value that can be set in a statement. * * @author Mark Paluch * @see OutboundRow + * @deprecated since 1.2, use Spring R2DBC's {@link Parameter} directly. */ +@Deprecated public class SettableValue { - private final @Nullable Object value; - private final Class type; - - private SettableValue(@Nullable Object value, Class type) { - - Assert.notNull(type, "Type must not be null"); + private final Parameter parameter; - this.value = value; - this.type = type; + private SettableValue(Parameter parameter) { + this.parameter = parameter; } /** @@ -51,7 +45,7 @@ public static SettableValue from(Object value) { Assert.notNull(value, "Value must not be null"); - return new SettableValue(value, ClassUtils.getUserClass(value)); + return new SettableValue(Parameter.from(value)); } /** @@ -62,7 +56,7 @@ public static SettableValue from(Object value) { * @return the {@link SettableValue} value for {@code value}. */ public static SettableValue fromOrEmpty(@Nullable Object value, Class type) { - return value == null ? empty(type) : new SettableValue(value, ClassUtils.getUserClass(value)); + return new SettableValue(Parameter.fromOrEmpty(value, type)); } /** @@ -74,7 +68,7 @@ public static SettableValue empty(Class type) { Assert.notNull(type, "Type must not be null"); - return new SettableValue(null, type); + return new SettableValue(Parameter.empty(type)); } /** @@ -85,7 +79,7 @@ public static SettableValue empty(Class type) { */ @Nullable public Object getValue() { - return this.value; + return this.parameter.getValue(); } /** @@ -94,7 +88,7 @@ public Object getValue() { * @return the column value type */ public Class getType() { - return this.type; + return this.parameter.getType(); } /** @@ -103,7 +97,7 @@ public Class getType() { * @return whether this {@link SettableValue} has a value. {@literal false} if {@link #getValue()} is {@literal null}. */ public boolean hasValue() { - return this.value != null; + return this.parameter.hasValue(); } /** @@ -112,7 +106,7 @@ public boolean hasValue() { * @return whether this {@link SettableValue} is empty. {@literal true} if {@link #getValue()} is {@literal null}. */ public boolean isEmpty() { - return this.value == null; + return this.parameter.isEmpty(); } @Override @@ -122,21 +116,24 @@ public boolean equals(Object o) { if (!(o instanceof SettableValue)) return false; SettableValue value1 = (SettableValue) o; - return ObjectUtils.nullSafeEquals(this.value, value1.value) && ObjectUtils.nullSafeEquals(this.type, value1.type); + return this.parameter.equals(value1.parameter); } @Override public int hashCode() { - return Objects.hash(this.value, this.type); + return this.parameter.hashCode(); } @Override public String toString() { - final StringBuffer sb = new StringBuffer(); - sb.append("SettableValue"); - sb.append("[value=").append(this.value); - sb.append(", type=").append(this.type); - sb.append(']'); - return sb.toString(); + return this.parameter.toString(); + } + + /** + * @return the {@link Parameter} representing this settable value. + * @since 1.2 + */ + public Parameter toParameter() { + return isEmpty() ? Parameter.empty(getType()) : Parameter.fromOrEmpty(getValue(), getType()); } } diff --git a/src/main/java/org/springframework/data/r2dbc/query/BoundAssignments.java b/src/main/java/org/springframework/data/r2dbc/query/BoundAssignments.java index a770e3eb..ac196116 100644 --- a/src/main/java/org/springframework/data/r2dbc/query/BoundAssignments.java +++ b/src/main/java/org/springframework/data/r2dbc/query/BoundAssignments.java @@ -17,8 +17,8 @@ import java.util.List; -import org.springframework.data.r2dbc.dialect.Bindings; import org.springframework.data.relational.core.sql.Assignment; +import org.springframework.r2dbc.core.binding.Bindings; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/r2dbc/query/BoundCondition.java b/src/main/java/org/springframework/data/r2dbc/query/BoundCondition.java index 4ec658ed..2f63022b 100644 --- a/src/main/java/org/springframework/data/r2dbc/query/BoundCondition.java +++ b/src/main/java/org/springframework/data/r2dbc/query/BoundCondition.java @@ -15,7 +15,7 @@ */ package org.springframework.data.r2dbc.query; -import org.springframework.data.r2dbc.dialect.Bindings; +import org.springframework.r2dbc.core.binding.Bindings; import org.springframework.data.relational.core.sql.Condition; import org.springframework.util.Assert; diff --git a/src/main/java/org/springframework/data/r2dbc/query/QueryMapper.java b/src/main/java/org/springframework/data/r2dbc/query/QueryMapper.java index ab8f7355..0fa732dc 100644 --- a/src/main/java/org/springframework/data/r2dbc/query/QueryMapper.java +++ b/src/main/java/org/springframework/data/r2dbc/query/QueryMapper.java @@ -29,10 +29,6 @@ import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.r2dbc.convert.R2dbcConverter; -import org.springframework.data.r2dbc.dialect.BindMarker; -import org.springframework.data.r2dbc.dialect.BindMarkers; -import org.springframework.data.r2dbc.dialect.Bindings; -import org.springframework.data.r2dbc.dialect.MutableBindings; import org.springframework.data.r2dbc.dialect.R2dbcDialect; import org.springframework.data.r2dbc.mapping.SettableValue; import org.springframework.data.relational.core.dialect.Escaper; @@ -46,6 +42,11 @@ import org.springframework.data.util.Pair; import org.springframework.data.util.TypeInformation; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.Parameter; +import org.springframework.r2dbc.core.binding.BindMarker; +import org.springframework.r2dbc.core.binding.BindMarkers; +import org.springframework.r2dbc.core.binding.Bindings; +import org.springframework.r2dbc.core.binding.MutableBindings; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -351,6 +352,12 @@ private Condition mapCondition(CriteriaDefinition criteria, MutableBindings bind mappedValue = convertValue(settableValue.getValue(), propertyField.getTypeHint()); typeHint = getTypeHint(mappedValue, actualType.getType(), settableValue); + } else if (criteria.getValue() instanceof Parameter) { + + Parameter parameter = (Parameter) criteria.getValue(); + + mappedValue = convertValue(parameter.getValue(), propertyField.getTypeHint()); + typeHint = getTypeHint(mappedValue, actualType.getType(), parameter); } else if (criteria.getValue() instanceof ValueFunction) { ValueFunction valueFunction = (ValueFunction) criteria.getValue(); @@ -391,6 +398,22 @@ public SettableValue getBindValue(SettableValue value) { return SettableValue.from(convertValue(value.getValue(), ClassTypeInformation.OBJECT)); } + /** + * Potentially convert the {@link SettableValue}. + * + * @param value + * @return + * @since 1.2 + */ + public Parameter getBindValue(Parameter value) { + + if (value.isEmpty()) { + return Parameter.empty(converter.getTargetType(value.getType())); + } + + return Parameter.from(convertValue(value.getValue(), ClassTypeInformation.OBJECT)); + } + @Nullable protected Object convertValue(@Nullable Object value, TypeInformation typeInformation) { @@ -572,6 +595,19 @@ Class getTypeHint(@Nullable Object mappedValue, Class propertyType, Settab return propertyType; } + Class getTypeHint(@Nullable Object mappedValue, Class propertyType, Parameter parameter) { + + if (mappedValue == null || propertyType.equals(Object.class)) { + return parameter.getType(); + } + + if (mappedValue.getClass().equals(parameter.getValue().getClass())) { + return parameter.getType(); + } + + return propertyType; + } + private Expression bind(@Nullable Object mappedValue, Class valueType, MutableBindings bindings, BindMarker bindMarker) { return bind(mappedValue, valueType, bindings, bindMarker, false); diff --git a/src/main/java/org/springframework/data/r2dbc/query/UpdateMapper.java b/src/main/java/org/springframework/data/r2dbc/query/UpdateMapper.java index 1504ec40..91861bba 100644 --- a/src/main/java/org/springframework/data/r2dbc/query/UpdateMapper.java +++ b/src/main/java/org/springframework/data/r2dbc/query/UpdateMapper.java @@ -20,10 +20,10 @@ import java.util.Map; import org.springframework.data.r2dbc.convert.R2dbcConverter; -import org.springframework.data.r2dbc.dialect.BindMarker; -import org.springframework.data.r2dbc.dialect.BindMarkers; -import org.springframework.data.r2dbc.dialect.Bindings; -import org.springframework.data.r2dbc.dialect.MutableBindings; +import org.springframework.r2dbc.core.Parameter; +import org.springframework.r2dbc.core.binding.BindMarkers; +import org.springframework.r2dbc.core.binding.Bindings; +import org.springframework.r2dbc.core.binding.MutableBindings; import org.springframework.data.r2dbc.dialect.R2dbcDialect; import org.springframework.data.r2dbc.mapping.SettableValue; import org.springframework.data.relational.core.dialect.Escaper; @@ -38,6 +38,7 @@ import org.springframework.data.relational.core.sql.Table; import org.springframework.data.util.TypeInformation; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.binding.BindMarker; import org.springframework.util.Assert; /** @@ -136,6 +137,13 @@ private Assignment getAssignment(SqlIdentifier columnName, Object value, Mutable mappedValue = convertValue(settableValue.getValue(), propertyField.getTypeHint()); typeHint = getTypeHint(mappedValue, actualType.getType(), settableValue); + } else if (value instanceof Parameter) { + + Parameter parameter = (Parameter) value; + + mappedValue = convertValue(parameter.getValue(), propertyField.getTypeHint()); + typeHint = getTypeHint(mappedValue, actualType.getType(), parameter); + } else if (value instanceof ValueFunction) { ValueFunction valueFunction = (ValueFunction) value; diff --git a/src/main/java/org/springframework/data/r2dbc/repository/query/AbstractR2dbcQuery.java b/src/main/java/org/springframework/data/r2dbc/repository/query/AbstractR2dbcQuery.java index 0483165d..b722dc0c 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/query/AbstractR2dbcQuery.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/query/AbstractR2dbcQuery.java @@ -21,10 +21,8 @@ import org.reactivestreams.Publisher; import org.springframework.data.mapping.model.EntityInstantiators; +import org.springframework.data.r2dbc.convert.EntityRowMapper; import org.springframework.data.r2dbc.convert.R2dbcConverter; -import org.springframework.data.r2dbc.core.DatabaseClient; -import org.springframework.data.r2dbc.core.DatabaseClient.GenericExecuteSpec; -import org.springframework.data.r2dbc.core.FetchSpec; import org.springframework.data.r2dbc.repository.query.R2dbcQueryExecution.ResultProcessingConverter; import org.springframework.data.r2dbc.repository.query.R2dbcQueryExecution.ResultProcessingExecution; import org.springframework.data.relational.core.sql.SqlIdentifier; @@ -34,6 +32,9 @@ import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ReturnedType; +import org.springframework.r2dbc.core.DatabaseClient; +import org.springframework.r2dbc.core.FetchSpec; +import org.springframework.r2dbc.core.RowsFetchSpec; import org.springframework.util.Assert; /** @@ -103,8 +104,15 @@ private Object execute(RelationalParameterAccessor parameterAccessor) { BindableQuery query = createQuery(parameterAccessor); ResultProcessor processor = method.getResultProcessor().withDynamicProjection(parameterAccessor); - GenericExecuteSpec boundQuery = query.bind(databaseClient.execute(query)); - FetchSpec fetchSpec = boundQuery.as(resolveResultType(processor)).fetch(); + DatabaseClient.GenericExecuteSpec boundQuery = query.bind(databaseClient.sql(query)); + + FetchSpec fetchSpec; + if (requiresMapping()) { + EntityRowMapper rowMapper = new EntityRowMapper<>(resolveResultType(processor), converter); + fetchSpec = new FetchSpecAdapter<>(boundQuery.map(rowMapper)); + } else { + fetchSpec = boundQuery.fetch(); + } SqlIdentifier tableName = method.getEntityInformation().getTableName(); @@ -114,6 +122,10 @@ private Object execute(RelationalParameterAccessor parameterAccessor) { return execution.execute(fetchSpec, processor.getReturnedType().getDomainType(), tableName); } + private boolean requiresMapping() { + return !isModifyingQuery(); + } + private Class resolveResultType(ResultProcessor resultProcessor) { ReturnedType returnedType = resultProcessor.getReturnedType(); @@ -152,7 +164,7 @@ private R2dbcQueryExecution getExecutionToWrap(ReturnedType returnedType) { /** * Returns whether this query is a modifying one. - * + * * @return * @since 1.1 */ @@ -165,4 +177,33 @@ private R2dbcQueryExecution getExecutionToWrap(ReturnedType returnedType) { * @return the {@link BindableQuery}. */ protected abstract BindableQuery createQuery(RelationalParameterAccessor accessor); + + private static class FetchSpecAdapter implements FetchSpec { + + private final RowsFetchSpec delegate; + + private FetchSpecAdapter(RowsFetchSpec delegate) { + this.delegate = delegate; + } + + @Override + public Mono one() { + return delegate.one(); + } + + @Override + public Mono first() { + return delegate.first(); + } + + @Override + public Flux all() { + return delegate.all(); + } + + @Override + public Mono rowsUpdated() { + throw new UnsupportedOperationException("Not supported after applying a row mapper"); + } + } } diff --git a/src/main/java/org/springframework/data/r2dbc/repository/query/BindableQuery.java b/src/main/java/org/springframework/data/r2dbc/repository/query/BindableQuery.java index 3f16340f..fefaa9ff 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/query/BindableQuery.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/query/BindableQuery.java @@ -17,20 +17,20 @@ import java.util.function.Supplier; -import org.springframework.data.r2dbc.core.DatabaseClient.BindSpec; +import org.springframework.r2dbc.core.DatabaseClient; /** - * Interface declaring a query that supplies SQL and can bind parameters to a {@link BindSpec}. + * Interface declaring a query that supplies SQL and can bind parameters to a {@link DatabaseClient.GenericExecuteSpec}. * * @author Mark Paluch */ public interface BindableQuery extends Supplier { /** - * Bind parameters to the {@link BindSpec query}. + * Bind parameters to the {@link DatabaseClient.GenericExecuteSpec query}. * * @param bindSpec must not be {@literal null}. * @return the bound query object. */ - > T bind(T bindSpec); + DatabaseClient.GenericExecuteSpec bind(DatabaseClient.GenericExecuteSpec bindSpec); } diff --git a/src/main/java/org/springframework/data/r2dbc/repository/query/ExpressionEvaluatingParameterBinder.java b/src/main/java/org/springframework/data/r2dbc/repository/query/ExpressionEvaluatingParameterBinder.java index 2306d4ca..9ac8c77f 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/query/ExpressionEvaluatingParameterBinder.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/query/ExpressionEvaluatingParameterBinder.java @@ -22,8 +22,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; -import org.springframework.data.r2dbc.core.DatabaseClient; -import org.springframework.data.r2dbc.mapping.SettableValue; import org.springframework.data.relational.repository.query.RelationalParameterAccessor; import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.Parameters; @@ -31,6 +29,7 @@ import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.util.Assert; /** @@ -76,25 +75,27 @@ class ExpressionEvaluatingParameterBinder { * @param bindSpec must not be {@literal null}. * @param parameterAccessor must not be {@literal null}. */ - public > T bind(T bindSpec, RelationalParameterAccessor parameterAccessor) { + public DatabaseClient.GenericExecuteSpec bind(DatabaseClient.GenericExecuteSpec bindSpec, + RelationalParameterAccessor parameterAccessor) { Object[] values = parameterAccessor.getValues(); Parameters bindableParameters = parameterAccessor.getBindableParameters(); - T bindSpecToUse = bindExpressions(bindSpec, values, bindableParameters); + DatabaseClient.GenericExecuteSpec bindSpecToUse = bindExpressions(bindSpec, values, bindableParameters); bindSpecToUse = bindParameters(bindSpecToUse, parameterAccessor.hasBindableNullValue(), values, bindableParameters); return bindSpecToUse; } - private > T bindExpressions(T bindSpec, Object[] values, + private DatabaseClient.GenericExecuteSpec bindExpressions(DatabaseClient.GenericExecuteSpec bindSpec, Object[] values, Parameters bindableParameters) { - T bindSpecToUse = bindSpec; + DatabaseClient.GenericExecuteSpec bindSpecToUse = bindSpec; for (ParameterBinding binding : expressionQuery.getBindings()) { - SettableValue valueForBinding = getParameterValueForBinding(bindableParameters, values, binding); + org.springframework.r2dbc.core.Parameter valueForBinding = getParameterValueForBinding(bindableParameters, values, + binding); if (valueForBinding.isEmpty()) { bindSpecToUse = bindSpecToUse.bindNull(binding.getParameterName(), valueForBinding.getType()); @@ -106,10 +107,11 @@ private > T bindExpressions(T bindSpec, Obj return bindSpecToUse; } - private > T bindParameters(T bindSpec, boolean bindableNull, Object[] values, + private DatabaseClient.GenericExecuteSpec bindParameters(DatabaseClient.GenericExecuteSpec bindSpec, + boolean bindableNull, Object[] values, Parameters bindableParameters) { - T bindSpecToUse = bindSpec; + DatabaseClient.GenericExecuteSpec bindSpecToUse = bindSpec; int bindingIndex = 0; @@ -166,7 +168,8 @@ private boolean isNamedParameterUsed(Optional name) { * @param binding must not be {@literal null}. * @return the value used for the given {@link ParameterBinding}. */ - private SettableValue getParameterValueForBinding(Parameters parameters, Object[] values, + private org.springframework.r2dbc.core.Parameter getParameterValueForBinding(Parameters parameters, + Object[] values, ParameterBinding binding) { return evaluateExpression(binding.getExpression(), parameters, values); } @@ -179,7 +182,8 @@ private SettableValue getParameterValueForBinding(Parameters parameters, O * @param parameterValues must not be {@literal null}. * @return the value of the {@code expressionString} evaluation. */ - private SettableValue evaluateExpression(String expressionString, Parameters parameters, + private org.springframework.r2dbc.core.Parameter evaluateExpression(String expressionString, + Parameters parameters, Object[] parameterValues) { EvaluationContext evaluationContext = evaluationContextProvider.getEvaluationContext(parameters, parameterValues); @@ -188,6 +192,6 @@ private SettableValue evaluateExpression(String expressionString, Parameters valueType = expression.getValueType(evaluationContext); - return SettableValue.fromOrEmpty(value, valueType != null ? valueType : Object.class); + return org.springframework.r2dbc.core.Parameter.fromOrEmpty(value, valueType != null ? valueType : Object.class); } } diff --git a/src/main/java/org/springframework/data/r2dbc/repository/query/PartTreeR2dbcQuery.java b/src/main/java/org/springframework/data/r2dbc/repository/query/PartTreeR2dbcQuery.java index 8c4476dc..3a6c6d15 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/query/PartTreeR2dbcQuery.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/query/PartTreeR2dbcQuery.java @@ -21,8 +21,6 @@ import org.springframework.data.domain.Sort; import org.springframework.data.r2dbc.convert.R2dbcConverter; -import org.springframework.data.r2dbc.core.DatabaseClient; -import org.springframework.data.r2dbc.core.PreparedOperation; import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy; import org.springframework.data.relational.repository.query.RelationalEntityMetadata; import org.springframework.data.relational.repository.query.RelationalParameterAccessor; @@ -30,6 +28,8 @@ import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ReturnedType; import org.springframework.data.repository.query.parser.PartTree; +import org.springframework.r2dbc.core.DatabaseClient; +import org.springframework.r2dbc.core.PreparedOperation; /** * An {@link AbstractR2dbcQuery} implementation based on a {@link PartTree}. @@ -71,7 +71,7 @@ public PartTreeR2dbcQuery(R2dbcQueryMethod method, DatabaseClient databaseClient } } - /* + /* * (non-Javadoc) * @see org.springframework.data.r2dbc.repository.query.AbstractR2dbcQuery#isModifyingQuery() */ @@ -80,7 +80,7 @@ protected boolean isModifyingQuery() { return this.tree.isDelete(); } - /* + /* * (non-Javadoc) * @see org.springframework.data.r2dbc.repository.query.AbstractR2dbcQuery#createQuery(org.springframework.data.relational.repository.query.RelationalParameterAccessor) */ diff --git a/src/main/java/org/springframework/data/r2dbc/repository/query/PreparedOperationBindableQuery.java b/src/main/java/org/springframework/data/r2dbc/repository/query/PreparedOperationBindableQuery.java index 2a4c9072..0d5b2b98 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/query/PreparedOperationBindableQuery.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/query/PreparedOperationBindableQuery.java @@ -15,15 +15,16 @@ */ package org.springframework.data.r2dbc.repository.query; -import org.springframework.data.r2dbc.core.DatabaseClient; -import org.springframework.data.r2dbc.core.PreparedOperation; -import org.springframework.data.r2dbc.dialect.BindTarget; +import org.springframework.r2dbc.core.DatabaseClient; +import org.springframework.r2dbc.core.PreparedOperation; +import org.springframework.r2dbc.core.binding.BindTarget; import org.springframework.util.Assert; /** * A {@link BindableQuery} implementation based on a {@link PreparedOperation}. * * @author Roman Chigvintsev + * @author Mark Paluch */ class PreparedOperationBindableQuery implements BindableQuery { @@ -41,12 +42,11 @@ class PreparedOperationBindableQuery implements BindableQuery { this.preparedQuery = preparedQuery; } - @SuppressWarnings("unchecked") @Override - public > T bind(T bindSpec) { - BindSpecBindTargetAdapter bindTargetAdapter = new BindSpecBindTargetAdapter<>(bindSpec); + public DatabaseClient.GenericExecuteSpec bind(DatabaseClient.GenericExecuteSpec bindSpec) { + BindSpecBindTargetAdapter bindTargetAdapter = new BindSpecBindTargetAdapter(bindSpec); preparedQuery.bindTo(bindTargetAdapter); - return (T) bindTargetAdapter.bindSpec; + return bindTargetAdapter.bindSpec; } @Override @@ -55,13 +55,14 @@ public String get() { } /** - * This class adapts {@link org.springframework.data.r2dbc.core.DatabaseClient.BindSpec} to {@link BindTarget} - * allowing easy binding of query parameters using {@link PreparedOperation}. + * This class adapts {@link DatabaseClient.GenericExecuteSpec} to {@link BindTarget} allowing easy binding of query + * parameters using {@link PreparedOperation}. */ - private static class BindSpecBindTargetAdapter> implements BindTarget { - DatabaseClient.BindSpec bindSpec; + private static class BindSpecBindTargetAdapter implements BindTarget { - private BindSpecBindTargetAdapter(DatabaseClient.BindSpec bindSpec) { + DatabaseClient.GenericExecuteSpec bindSpec; + + private BindSpecBindTargetAdapter(DatabaseClient.GenericExecuteSpec bindSpec) { this.bindSpec = bindSpec; } diff --git a/src/main/java/org/springframework/data/r2dbc/repository/query/R2dbcQueryCreator.java b/src/main/java/org/springframework/data/r2dbc/repository/query/R2dbcQueryCreator.java index 397fc9c6..9162908c 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/query/R2dbcQueryCreator.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/query/R2dbcQueryCreator.java @@ -22,19 +22,23 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import org.springframework.data.r2dbc.core.PreparedOperation; import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy; import org.springframework.data.r2dbc.core.StatementMapper; import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; import org.springframework.data.relational.core.query.Criteria; -import org.springframework.data.relational.core.sql.*; +import org.springframework.data.relational.core.sql.Column; +import org.springframework.data.relational.core.sql.Expression; +import org.springframework.data.relational.core.sql.Functions; +import org.springframework.data.relational.core.sql.SqlIdentifier; +import org.springframework.data.relational.core.sql.Table; import org.springframework.data.relational.repository.query.RelationalEntityMetadata; import org.springframework.data.relational.repository.query.RelationalParameterAccessor; import org.springframework.data.relational.repository.query.RelationalQueryCreator; import org.springframework.data.repository.query.parser.AbstractQueryCreator; import org.springframework.data.repository.query.parser.PartTree; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.PreparedOperation; /** * Implementation of {@link AbstractQueryCreator} that creates {@link PreparedOperation} from a {@link PartTree}. @@ -56,7 +60,7 @@ class R2dbcQueryCreator extends RelationalQueryCreator> { /** * Creates new instance of this class with the given {@link PartTree}, {@link ReactiveDataAccessStrategy}, * {@link RelationalEntityMetadata} and {@link RelationalParameterAccessor}. - * + * * @param tree part tree, must not be {@literal null}. * @param dataAccessStrategy data access strategy, must not be {@literal null}. * @param entityMetadata relational entity metadata, must not be {@literal null}. diff --git a/src/main/java/org/springframework/data/r2dbc/repository/query/R2dbcQueryExecution.java b/src/main/java/org/springframework/data/r2dbc/repository/query/R2dbcQueryExecution.java index 6392d95d..7b82e5d5 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/query/R2dbcQueryExecution.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/query/R2dbcQueryExecution.java @@ -23,13 +23,13 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.EntityInstantiators; -import org.springframework.data.r2dbc.core.FetchSpec; import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.data.relational.repository.query.DtoInstantiatingConverter; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ReturnedType; +import org.springframework.r2dbc.core.FetchSpec; import org.springframework.util.ClassUtils; /** diff --git a/src/main/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQuery.java b/src/main/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQuery.java index eb0d00f2..ded9bfef 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQuery.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQuery.java @@ -16,12 +16,11 @@ package org.springframework.data.r2dbc.repository.query; import org.springframework.data.r2dbc.convert.R2dbcConverter; -import org.springframework.data.r2dbc.core.DatabaseClient; -import org.springframework.data.r2dbc.core.DatabaseClient.BindSpec; import org.springframework.data.r2dbc.repository.Query; import org.springframework.data.relational.repository.query.RelationalParameterAccessor; import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.util.Assert; /** @@ -76,7 +75,7 @@ public StringBasedR2dbcQuery(String query, R2dbcQueryMethod method, DatabaseClie this.binder = new ExpressionEvaluatingParameterBinder(expressionParser, evaluationContextProvider, expressionQuery); } - /* + /* * (non-Javadoc) * @see org.springframework.data.r2dbc.repository.query.AbstractR2dbcQuery#isModifyingQuery() */ @@ -85,7 +84,7 @@ protected boolean isModifyingQuery() { return getQueryMethod().isModifyingQuery(); } - /* + /* * (non-Javadoc) * @see org.springframework.data.r2dbc.repository.query.AbstractR2dbcQuery#createQuery(org.springframework.data.relational.repository.query.RelationalParameterAccessor) */ @@ -95,7 +94,7 @@ protected BindableQuery createQuery(RelationalParameterAccessor accessor) { return new BindableQuery() { @Override - public > T bind(T bindSpec) { + public DatabaseClient.GenericExecuteSpec bind(DatabaseClient.GenericExecuteSpec bindSpec) { return binder.bind(bindSpec, accessor); } diff --git a/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactory.java b/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactory.java index fba62156..4c71dc8b 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactory.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactory.java @@ -21,7 +21,6 @@ import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.r2dbc.convert.R2dbcConverter; -import org.springframework.data.r2dbc.core.DatabaseClient; import org.springframework.data.r2dbc.core.R2dbcEntityOperations; import org.springframework.data.r2dbc.core.R2dbcEntityTemplate; import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy; @@ -43,6 +42,7 @@ import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.util.Assert; /** @@ -184,8 +184,7 @@ public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, return new StringBasedR2dbcQuery(queryMethod, this.databaseClient, this.converter, EXPRESSION_PARSER, this.evaluationContextProvider); } else { - return new PartTreeR2dbcQuery(queryMethod, this.databaseClient, this.converter, - this.dataAccessStrategy); + return new PartTreeR2dbcQuery(queryMethod, this.databaseClient, this.converter, this.dataAccessStrategy); } } } diff --git a/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryBean.java b/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryBean.java index 2c01b5a3..b4042512 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryBean.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryBean.java @@ -18,13 +18,13 @@ import java.io.Serializable; import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.r2dbc.core.DatabaseClient; import org.springframework.data.r2dbc.core.R2dbcEntityOperations; import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.data.repository.core.support.RepositoryFactorySupport; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/r2dbc/repository/support/SimpleR2dbcRepository.java b/src/main/java/org/springframework/data/r2dbc/repository/support/SimpleR2dbcRepository.java index 95bfb886..16fde99e 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/support/SimpleR2dbcRepository.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/support/SimpleR2dbcRepository.java @@ -22,16 +22,16 @@ import org.springframework.data.domain.Sort; import org.springframework.data.r2dbc.convert.R2dbcConverter; -import org.springframework.data.r2dbc.core.DatabaseClient; import org.springframework.data.r2dbc.core.R2dbcEntityOperations; import org.springframework.data.r2dbc.core.R2dbcEntityTemplate; import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy; -import org.springframework.data.relational.core.query.Criteria; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; +import org.springframework.data.relational.core.query.Criteria; import org.springframework.data.relational.core.query.Query; import org.springframework.data.relational.repository.query.RelationalEntityInformation; import org.springframework.data.repository.reactive.ReactiveSortingRepository; import org.springframework.data.util.Lazy; +import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; @@ -76,6 +76,7 @@ public class SimpleR2dbcRepository implements ReactiveSortingRepository entity, DatabaseClient databaseClient, R2dbcConverter converter, ReactiveDataAccessStrategy accessStrategy) { @@ -88,6 +89,28 @@ public SimpleR2dbcRepository(RelationalEntityInformation entity, Database .getRequiredIdProperty()); } + /** + * Create a new {@link SimpleR2dbcRepository}. + * + * @param entity + * @param databaseClient + * @param converter + * @param accessStrategy + * @deprecated since 1.2. + */ + @Deprecated + public SimpleR2dbcRepository(RelationalEntityInformation entity, + org.springframework.data.r2dbc.core.DatabaseClient databaseClient, R2dbcConverter converter, + ReactiveDataAccessStrategy accessStrategy) { + + this.entity = entity; + this.entityOperations = new R2dbcEntityTemplate(databaseClient, accessStrategy); + this.idProperty = Lazy.of(() -> converter // + .getMappingContext() // + .getRequiredPersistentEntity(this.entity.getJavaType()) // + .getRequiredIdProperty()); + } + /* (non-Javadoc) * @see org.springframework.data.repository.reactive.ReactiveCrudRepository#save(S) */ diff --git a/src/main/java/org/springframework/data/r2dbc/support/AbstractFallbackR2dbcExceptionTranslator.java b/src/main/java/org/springframework/data/r2dbc/support/AbstractFallbackR2dbcExceptionTranslator.java index 33bf6778..7d7ce64b 100644 --- a/src/main/java/org/springframework/data/r2dbc/support/AbstractFallbackR2dbcExceptionTranslator.java +++ b/src/main/java/org/springframework/data/r2dbc/support/AbstractFallbackR2dbcExceptionTranslator.java @@ -31,7 +31,11 @@ * {@link R2dbcExceptionTranslator}. * * @author Mark Paluch + * @deprecated since 1.2. Use Spring R2DBC's + * {@link org.springframework.r2dbc.connection.ConnectionFactoryUtils#convertR2dbcException(String, String, R2dbcException)} + * instead. */ +@Deprecated public abstract class AbstractFallbackR2dbcExceptionTranslator implements R2dbcExceptionTranslator { /** Logger available to subclasses */ diff --git a/src/main/java/org/springframework/data/r2dbc/support/R2dbcExceptionSubclassTranslator.java b/src/main/java/org/springframework/data/r2dbc/support/R2dbcExceptionSubclassTranslator.java index 8289fa69..540af8c5 100644 --- a/src/main/java/org/springframework/data/r2dbc/support/R2dbcExceptionSubclassTranslator.java +++ b/src/main/java/org/springframework/data/r2dbc/support/R2dbcExceptionSubclassTranslator.java @@ -43,7 +43,11 @@ * Falls back to a standard {@link SqlStateR2dbcExceptionTranslator}. * * @author Mark Paluch + * @deprecated since 1.2. Use Spring R2DBC's + * {@link org.springframework.r2dbc.connection.ConnectionFactoryUtils#convertR2dbcException(String, String, R2dbcException)} + * instead. */ +@Deprecated public class R2dbcExceptionSubclassTranslator extends AbstractFallbackR2dbcExceptionTranslator { public R2dbcExceptionSubclassTranslator() { diff --git a/src/main/java/org/springframework/data/r2dbc/support/R2dbcExceptionTranslator.java b/src/main/java/org/springframework/data/r2dbc/support/R2dbcExceptionTranslator.java index dd42f4d8..1ab81d11 100644 --- a/src/main/java/org/springframework/data/r2dbc/support/R2dbcExceptionTranslator.java +++ b/src/main/java/org/springframework/data/r2dbc/support/R2dbcExceptionTranslator.java @@ -31,8 +31,12 @@ * @see org.springframework.dao.DataAccessException * @see SqlStateR2dbcExceptionTranslator * @see SqlErrorCodeR2dbcExceptionTranslator + * @deprecated since 1.2. Use Spring R2DBC's + * {@link org.springframework.r2dbc.connection.ConnectionFactoryUtils#convertR2dbcException(String, String, R2dbcException)} + * instead. */ @FunctionalInterface +@Deprecated public interface R2dbcExceptionTranslator { /** diff --git a/src/main/java/org/springframework/data/r2dbc/support/SqlErrorCodeR2dbcExceptionTranslator.java b/src/main/java/org/springframework/data/r2dbc/support/SqlErrorCodeR2dbcExceptionTranslator.java index b43c1d60..f818cc9a 100644 --- a/src/main/java/org/springframework/data/r2dbc/support/SqlErrorCodeR2dbcExceptionTranslator.java +++ b/src/main/java/org/springframework/data/r2dbc/support/SqlErrorCodeR2dbcExceptionTranslator.java @@ -60,7 +60,11 @@ * @author Mark Paluch * @see SQLErrorCodesFactory * @see SqlStateR2dbcExceptionTranslator + * @deprecated since 1.2. Use Spring R2DBC's + * {@link org.springframework.r2dbc.connection.ConnectionFactoryUtils#convertR2dbcException(String, String, R2dbcException)} + * instead. */ +@Deprecated public class SqlErrorCodeR2dbcExceptionTranslator extends AbstractFallbackR2dbcExceptionTranslator { /** Error codes used by this translator */ diff --git a/src/main/java/org/springframework/data/r2dbc/support/SqlStateR2dbcExceptionTranslator.java b/src/main/java/org/springframework/data/r2dbc/support/SqlStateR2dbcExceptionTranslator.java index ec73fdbc..cfa30f7e 100644 --- a/src/main/java/org/springframework/data/r2dbc/support/SqlStateR2dbcExceptionTranslator.java +++ b/src/main/java/org/springframework/data/r2dbc/support/SqlStateR2dbcExceptionTranslator.java @@ -40,7 +40,11 @@ * @author Mark Paluch * @see io.r2dbc.spi.R2dbcException#getSqlState() * @see SqlErrorCodeR2dbcExceptionTranslator + * @deprecated since 1.2. Use Spring R2DBC's + * {@link org.springframework.r2dbc.connection.ConnectionFactoryUtils#convertR2dbcException(String, String, R2dbcException)} + * instead. */ +@Deprecated public class SqlStateR2dbcExceptionTranslator extends AbstractFallbackR2dbcExceptionTranslator { private static final Set BAD_SQL_GRAMMAR_CODES = new HashSet<>(8); diff --git a/src/main/kotlin/org/springframework/data/r2dbc/core/DatabaseClientExtensions.kt b/src/main/kotlin/org/springframework/data/r2dbc/core/DatabaseClientExtensions.kt index e85d25a5..cecd89f6 100644 --- a/src/main/kotlin/org/springframework/data/r2dbc/core/DatabaseClientExtensions.kt +++ b/src/main/kotlin/org/springframework/data/r2dbc/core/DatabaseClientExtensions.kt @@ -23,6 +23,7 @@ import org.springframework.data.r2dbc.mapping.SettableValue * * @author Sebastien Deleuze */ +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") suspend fun DatabaseClient.GenericExecuteSpec.await() { then().awaitFirstOrNull() } @@ -34,6 +35,7 @@ suspend fun DatabaseClient.GenericExecuteSpec.await() { * @author Ibanga Enoobong Ime */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") inline fun DatabaseClient.TypedExecuteSpec<*>.bind(index: Int, value: T?) = bind(index, SettableValue.fromOrEmpty(value, T::class.java)) /** @@ -43,6 +45,7 @@ inline fun DatabaseClient.TypedExecuteSpec<*>.bind(index: Int, * @author Ibanga Enoobong Ime */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") inline fun DatabaseClient.GenericExecuteSpec.bind(index: Int, value: T?) = bind(index, SettableValue.fromOrEmpty(value, T::class.java)) /** @@ -52,6 +55,7 @@ inline fun DatabaseClient.GenericExecuteSpec.bind(index: Int, * @author Ibanga Enoobong Ime */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") inline fun DatabaseClient.TypedExecuteSpec<*>.bind(name: String, value: T?) = bind(name, SettableValue.fromOrEmpty(value, T::class.java)) /** @@ -61,6 +65,7 @@ inline fun DatabaseClient.TypedExecuteSpec<*>.bind(name: Strin * @author Ibanga Enoobong Ime */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") inline fun DatabaseClient.GenericExecuteSpec.bind(name: String, value: T?) = bind(name, SettableValue.fromOrEmpty(value, T::class.java)) /** @@ -69,6 +74,7 @@ inline fun DatabaseClient.GenericExecuteSpec.bind(name: String * * @author Sebastien Deleuze */ +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") inline fun DatabaseClient.GenericExecuteSpec.asType(): DatabaseClient.TypedExecuteSpec = `as`(T::class.java) @@ -78,6 +84,7 @@ inline fun DatabaseClient.GenericExecuteSpec.asType(): Databas * * @author Sebastien Deleuze */ +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") inline fun DatabaseClient.GenericSelectSpec.asType(): DatabaseClient.TypedSelectSpec = `as`(T::class.java) @@ -86,6 +93,7 @@ inline fun DatabaseClient.GenericSelectSpec.asType(): Database * * @author Sebastien Deleuze */ +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") suspend fun DatabaseClient.TypedExecuteSpec.await() { then().awaitFirstOrNull() } @@ -96,6 +104,7 @@ suspend fun DatabaseClient.TypedExecuteSpec.await() { * * @author Sebastien Deleuze */ +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") inline fun DatabaseClient.TypedExecuteSpec.asType(): DatabaseClient.TypedExecuteSpec = `as`(T::class.java) @@ -104,6 +113,7 @@ inline fun DatabaseClient.TypedExecuteSpec.asType(): Databa * * @author Sebastien Deleuze */ +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") suspend fun DatabaseClient.InsertSpec.await() { then().awaitFirstOrNull() } @@ -114,6 +124,7 @@ suspend fun DatabaseClient.InsertSpec.await() { * * @author Sebastien Deleuze */ +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") inline fun DatabaseClient.InsertIntoSpec.into(): DatabaseClient.TypedInsertSpec = into(T::class.java) @@ -123,6 +134,7 @@ inline fun DatabaseClient.InsertIntoSpec.into(): DatabaseClien * @author Mark Paluch */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") inline fun DatabaseClient.GenericInsertSpec<*>.value(name: String, value: T?) = value(name, SettableValue.fromOrEmpty(value, T::class.java)) @@ -132,6 +144,7 @@ inline fun DatabaseClient.GenericInsertSpec<*>.value(name: Str * * @author Jonas Bark */ +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") inline fun DatabaseClient.SelectFromSpec.from(): DatabaseClient.TypedSelectSpec = from(T::class.java) @@ -141,6 +154,7 @@ inline fun DatabaseClient.SelectFromSpec.from(): DatabaseClien * * @author Mark Paluch */ +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") inline fun DatabaseClient.UpdateTableSpec.table(): DatabaseClient.TypedUpdateSpec = table(T::class.java) @@ -150,5 +164,6 @@ inline fun DatabaseClient.UpdateTableSpec.table(): DatabaseCli * * @author Jonas Bark */ +@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient") inline fun DatabaseClient.DeleteFromSpec.from(): DatabaseClient.TypedDeleteSpec = from(T::class.java) diff --git a/src/test/java/org/springframework/data/r2dbc/config/H2IntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/config/H2IntegrationTests.java index 18d611cd..1ded23e7 100644 --- a/src/test/java/org/springframework/data/r2dbc/config/H2IntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/config/H2IntegrationTests.java @@ -32,13 +32,13 @@ import org.springframework.context.annotation.FilterType; import org.springframework.dao.DataAccessException; import org.springframework.data.annotation.Id; -import org.springframework.data.r2dbc.core.DatabaseClient; import org.springframework.data.r2dbc.repository.Query; import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories; import org.springframework.data.r2dbc.testing.H2TestSupport; import org.springframework.data.relational.core.mapping.Table; import org.springframework.data.repository.reactive.ReactiveCrudRepository; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @@ -70,9 +70,8 @@ public void shouldSelectCountWithDatabaseClient() { jdbc.execute("INSERT INTO legoset (id, name, manual) VALUES(42055, 'SCHAUFELRADBAGGER', 12)"); - databaseClient.execute("SELECT COUNT(*) FROM legoset") // - .as(Long.class) // - .fetch() // + databaseClient.sql("SELECT COUNT(*) FROM legoset") // + .map(it -> it.get(0, Long.class)) // .all() // .as(StepVerifier::create) // .expectNext(1L) // diff --git a/src/test/java/org/springframework/data/r2dbc/config/R2dbcConfigurationIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/config/R2dbcConfigurationIntegrationTests.java index 528bb172..30b075e7 100644 --- a/src/test/java/org/springframework/data/r2dbc/config/R2dbcConfigurationIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/config/R2dbcConfigurationIntegrationTests.java @@ -27,7 +27,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.r2dbc.core.DatabaseClient; +import org.springframework.r2dbc.core.DatabaseClient; /** * Tests for {@link AbstractR2dbcConfiguration}. diff --git a/src/test/java/org/springframework/data/r2dbc/connectionfactory/R2dbcTransactionManagerUnitTests.java b/src/test/java/org/springframework/data/r2dbc/connectionfactory/R2dbcTransactionManagerUnitTests.java deleted file mode 100644 index ff45ef40..00000000 --- a/src/test/java/org/springframework/data/r2dbc/connectionfactory/R2dbcTransactionManagerUnitTests.java +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Copyright 2019-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.data.r2dbc.connectionfactory; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.*; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.*; - -import io.r2dbc.spi.Connection; -import io.r2dbc.spi.ConnectionFactory; -import io.r2dbc.spi.IsolationLevel; -import io.r2dbc.spi.R2dbcBadGrammarException; -import io.r2dbc.spi.Statement; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.data.r2dbc.BadSqlGrammarException; -import org.springframework.transaction.CannotCreateTransactionException; -import org.springframework.transaction.IllegalTransactionStateException; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.reactive.TransactionSynchronization; -import org.springframework.transaction.reactive.TransactionSynchronizationManager; -import org.springframework.transaction.reactive.TransactionalOperator; -import org.springframework.transaction.support.DefaultTransactionDefinition; - -/** - * Unit tests for {@link R2dbcTransactionManager}. - * - * @author Mark Paluch - */ -public class R2dbcTransactionManagerUnitTests { - - ConnectionFactory connectionFactoryMock = mock(ConnectionFactory.class); - Connection connectionMock = mock(Connection.class); - - private R2dbcTransactionManager tm; - - @Before - public void before() { - - when(connectionFactoryMock.create()).thenReturn((Mono) Mono.just(connectionMock)); - when(connectionMock.beginTransaction()).thenReturn(Mono.empty()); - when(connectionMock.close()).thenReturn(Mono.empty()); - tm = new R2dbcTransactionManager(connectionFactoryMock); - } - - @Test // gh-107 - public void testSimpleTransaction() { - - TestTransactionSynchronization sync = new TestTransactionSynchronization( - TransactionSynchronization.STATUS_COMMITTED); - AtomicInteger commits = new AtomicInteger(); - when(connectionMock.commitTransaction()).thenReturn(Mono.fromRunnable(commits::incrementAndGet)); - - TransactionalOperator operator = TransactionalOperator.create(tm); - - ConnectionFactoryUtils.getConnection(connectionFactoryMock).flatMap(it -> { - - return TransactionSynchronizationManager.forCurrentTransaction() - .doOnNext(synchronizationManager -> synchronizationManager.registerSynchronization(sync)); - - }) // - .as(operator::transactional) // - .as(StepVerifier::create) // - .expectNextCount(1) // - .verifyComplete(); - - assertThat(commits).hasValue(1); - verify(connectionMock).isAutoCommit(); - verify(connectionMock).beginTransaction(); - verify(connectionMock).commitTransaction(); - verify(connectionMock).close(); - verifyNoMoreInteractions(connectionMock); - - assertThat(sync.beforeCommitCalled).isTrue(); - assertThat(sync.afterCommitCalled).isTrue(); - assertThat(sync.beforeCompletionCalled).isTrue(); - assertThat(sync.afterCompletionCalled).isTrue(); - } - - @Test // gh-329 - public void testBeginFails() { - - reset(connectionFactoryMock); - when(connectionFactoryMock.create()).thenReturn(Mono.error(new R2dbcBadGrammarException("fail"))); - - when(connectionMock.rollbackTransaction()).thenReturn(Mono.empty()); - - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - - TransactionalOperator operator = TransactionalOperator.create(tm, definition); - - ConnectionFactoryUtils.getConnection(connectionFactoryMock).as(operator::transactional) // - .as(StepVerifier::create) // - .expectErrorSatisfies(actual -> { - - assertThat(actual).isInstanceOf(CannotCreateTransactionException.class) - .hasCauseInstanceOf(BadSqlGrammarException.class); - - }).verify(); - } - - @Test // gh-107 - public void appliesIsolationLevel() { - - when(connectionMock.commitTransaction()).thenReturn(Mono.empty()); - when(connectionMock.getTransactionIsolationLevel()).thenReturn(IsolationLevel.READ_COMMITTED); - when(connectionMock.setTransactionIsolationLevel(any())).thenReturn(Mono.empty()); - - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); - - TransactionalOperator operator = TransactionalOperator.create(tm, definition); - - ConnectionFactoryUtils.getConnection(connectionFactoryMock).as(operator::transactional) // - .as(StepVerifier::create) // - .expectNextCount(1) // - .verifyComplete(); - - verify(connectionMock).beginTransaction(); - verify(connectionMock).setTransactionIsolationLevel(IsolationLevel.READ_COMMITTED); - verify(connectionMock).setTransactionIsolationLevel(IsolationLevel.SERIALIZABLE); - verify(connectionMock).commitTransaction(); - verify(connectionMock).close(); - } - - @Test // gh-184 - public void doesNotSetIsolationLevelIfMatch() { - - when(connectionMock.getTransactionIsolationLevel()).thenReturn(IsolationLevel.READ_COMMITTED); - when(connectionMock.commitTransaction()).thenReturn(Mono.empty()); - - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); - - TransactionalOperator operator = TransactionalOperator.create(tm, definition); - - ConnectionFactoryUtils.getConnection(connectionFactoryMock).as(operator::transactional) // - .as(StepVerifier::create) // - .expectNextCount(1) // - .verifyComplete(); - - verify(connectionMock).beginTransaction(); - verify(connectionMock, never()).setTransactionIsolationLevel(any()); - verify(connectionMock).commitTransaction(); - } - - @Test // gh-184 - public void doesNotSetAutoCommitDisabled() { - - when(connectionMock.isAutoCommit()).thenReturn(false); - when(connectionMock.commitTransaction()).thenReturn(Mono.empty()); - - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - - TransactionalOperator operator = TransactionalOperator.create(tm, definition); - - ConnectionFactoryUtils.getConnection(connectionFactoryMock).as(operator::transactional) // - .as(StepVerifier::create) // - .expectNextCount(1) // - .verifyComplete(); - - verify(connectionMock).beginTransaction(); - verify(connectionMock, never()).setAutoCommit(anyBoolean()); - verify(connectionMock).commitTransaction(); - } - - @Test // gh-184 - public void restoresAutoCommit() { - - when(connectionMock.isAutoCommit()).thenReturn(true); - when(connectionMock.setAutoCommit(anyBoolean())).thenReturn(Mono.empty()); - when(connectionMock.commitTransaction()).thenReturn(Mono.empty()); - - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - - TransactionalOperator operator = TransactionalOperator.create(tm, definition); - - ConnectionFactoryUtils.getConnection(connectionFactoryMock).as(operator::transactional) // - .as(StepVerifier::create) // - .expectNextCount(1) // - .verifyComplete(); - - verify(connectionMock).beginTransaction(); - verify(connectionMock).setAutoCommit(false); - verify(connectionMock).setAutoCommit(true); - verify(connectionMock).commitTransaction(); - verify(connectionMock).close(); - } - - @Test // gh-107 - public void appliesReadOnly() { - - when(connectionMock.commitTransaction()).thenReturn(Mono.empty()); - when(connectionMock.setTransactionIsolationLevel(any())).thenReturn(Mono.empty()); - Statement statement = mock(Statement.class); - when(connectionMock.createStatement(anyString())).thenReturn(statement); - when(statement.execute()).thenReturn(Mono.empty()); - tm.setEnforceReadOnly(true); - - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setReadOnly(true); - - TransactionalOperator operator = TransactionalOperator.create(tm, definition); - - ConnectionFactoryUtils.getConnection(connectionFactoryMock).as(operator::transactional) // - .as(StepVerifier::create) // - .expectNextCount(1) // - .verifyComplete(); - - verify(connectionMock).isAutoCommit(); - verify(connectionMock).beginTransaction(); - verify(connectionMock).createStatement("SET TRANSACTION READ ONLY"); - verify(connectionMock).commitTransaction(); - verify(connectionMock).close(); - verifyNoMoreInteractions(connectionMock); - } - - @Test // gh-107 - public void testCommitFails() { - - when(connectionMock.commitTransaction()).thenReturn(Mono.defer(() -> { - return Mono.error(new R2dbcBadGrammarException("Commit should fail")); - })); - - when(connectionMock.rollbackTransaction()).thenReturn(Mono.empty()); - - TransactionalOperator operator = TransactionalOperator.create(tm); - - ConnectionFactoryUtils.getConnection(connectionFactoryMock) // - .doOnNext(it -> { - it.createStatement("foo"); - }).then() // - .as(operator::transactional) // - .as(StepVerifier::create) // - .verifyError(IllegalTransactionStateException.class); - - verify(connectionMock).isAutoCommit(); - verify(connectionMock).beginTransaction(); - verify(connectionMock).createStatement("foo"); - verify(connectionMock).commitTransaction(); - verify(connectionMock).close(); - verifyNoMoreInteractions(connectionMock); - } - - @Test // gh-107 - public void testRollback() { - - AtomicInteger commits = new AtomicInteger(); - when(connectionMock.commitTransaction()).thenReturn(Mono.fromRunnable(commits::incrementAndGet)); - - AtomicInteger rollbacks = new AtomicInteger(); - when(connectionMock.rollbackTransaction()).thenReturn(Mono.fromRunnable(rollbacks::incrementAndGet)); - - TransactionalOperator operator = TransactionalOperator.create(tm); - - ConnectionFactoryUtils.getConnection(connectionFactoryMock).doOnNext(it -> { - - throw new IllegalStateException(); - - }).as(operator::transactional) // - .as(StepVerifier::create) // - .verifyError(IllegalStateException.class); - - assertThat(commits).hasValue(0); - assertThat(rollbacks).hasValue(1); - verify(connectionMock).isAutoCommit(); - verify(connectionMock).beginTransaction(); - verify(connectionMock).rollbackTransaction(); - verify(connectionMock).close(); - verifyNoMoreInteractions(connectionMock); - } - - @Test // gh-329 - public void testRollbackFails() { - - when(connectionMock.rollbackTransaction()).thenReturn(Mono.defer(() -> { - return Mono.error(new R2dbcBadGrammarException("Commit should fail")); - }), Mono.empty()); - - TransactionalOperator operator = TransactionalOperator.create(tm); - - operator.execute(reactiveTransaction -> { - - reactiveTransaction.setRollbackOnly(); - - return ConnectionFactoryUtils.getConnection(connectionFactoryMock) // - .doOnNext(it -> { - it.createStatement("foo"); - }).then(); - }).as(StepVerifier::create) // - .verifyError(IllegalTransactionStateException.class); - - verify(connectionMock).isAutoCommit(); - verify(connectionMock).beginTransaction(); - verify(connectionMock).createStatement("foo"); - verify(connectionMock, never()).commitTransaction(); - verify(connectionMock).rollbackTransaction(); - verify(connectionMock).close(); - verifyNoMoreInteractions(connectionMock); - } - - @Test // gh-107 - public void testTransactionSetRollbackOnly() { - - when(connectionMock.rollbackTransaction()).thenReturn(Mono.empty()); - TestTransactionSynchronization sync = new TestTransactionSynchronization( - TransactionSynchronization.STATUS_ROLLED_BACK); - - TransactionalOperator operator = TransactionalOperator.create(tm); - - operator.execute(tx -> { - - tx.setRollbackOnly(); - assertThat(tx.isNewTransaction()).isTrue(); - - return TransactionSynchronizationManager.forCurrentTransaction().doOnNext(it -> { - - assertThat(it.hasResource(connectionFactoryMock)).isTrue(); - it.registerSynchronization(sync); - - }).then(); - }).as(StepVerifier::create) // - .verifyComplete(); - - verify(connectionMock).isAutoCommit(); - verify(connectionMock).beginTransaction(); - verify(connectionMock).rollbackTransaction(); - verify(connectionMock).close(); - verifyNoMoreInteractions(connectionMock); - - assertThat(sync.beforeCommitCalled).isFalse(); - assertThat(sync.afterCommitCalled).isFalse(); - assertThat(sync.beforeCompletionCalled).isTrue(); - assertThat(sync.afterCompletionCalled).isTrue(); - } - - @Test // gh-107 - public void testPropagationNeverWithExistingTransaction() { - - when(connectionMock.rollbackTransaction()).thenReturn(Mono.empty()); - - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - TransactionalOperator operator = TransactionalOperator.create(tm, definition); - - operator.execute(tx1 -> { - - assertThat(tx1.isNewTransaction()).isTrue(); - - definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NEVER); - return operator.execute(tx2 -> { - - fail("Should have thrown IllegalTransactionStateException"); - return Mono.empty(); - }); - }).as(StepVerifier::create) // - .verifyError(IllegalTransactionStateException.class); - - verify(connectionMock).rollbackTransaction(); - verify(connectionMock).close(); - } - - @Test // gh-107 - public void testPropagationSupportsAndRequiresNew() { - - when(connectionMock.commitTransaction()).thenReturn(Mono.empty()); - - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); - TransactionalOperator operator = TransactionalOperator.create(tm, definition); - - operator.execute(tx1 -> { - - assertThat(tx1.isNewTransaction()).isFalse(); - - DefaultTransactionDefinition innerDef = new DefaultTransactionDefinition(); - innerDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - TransactionalOperator inner = TransactionalOperator.create(tm, innerDef); - - return inner.execute(tx2 -> { - - assertThat(tx2.isNewTransaction()).isTrue(); - return Mono.empty(); - }); - }).as(StepVerifier::create) // - .verifyComplete(); - - verify(connectionMock).commitTransaction(); - verify(connectionMock).close(); - } - - private static class TestTransactionSynchronization implements TransactionSynchronization { - - private int status; - - public boolean beforeCommitCalled; - - public boolean beforeCompletionCalled; - - public boolean afterCommitCalled; - - public boolean afterCompletionCalled; - - public Throwable afterCompletionException; - - public TestTransactionSynchronization(int status) { - this.status = status; - } - - @Override - public Mono suspend() { - return Mono.empty(); - } - - @Override - public Mono resume() { - return Mono.empty(); - } - - @Override - public Mono beforeCommit(boolean readOnly) { - if (this.status != TransactionSynchronization.STATUS_COMMITTED) { - fail("Should never be called"); - } - return Mono.fromRunnable(() -> { - assertFalse(this.beforeCommitCalled); - this.beforeCommitCalled = true; - }); - } - - @Override - public Mono beforeCompletion() { - return Mono.fromRunnable(() -> { - assertFalse(this.beforeCompletionCalled); - this.beforeCompletionCalled = true; - }); - } - - @Override - public Mono afterCommit() { - if (this.status != TransactionSynchronization.STATUS_COMMITTED) { - fail("Should never be called"); - } - return Mono.fromRunnable(() -> { - assertFalse(this.afterCommitCalled); - this.afterCommitCalled = true; - }); - } - - @Override - public Mono afterCompletion(int status) { - try { - return Mono.fromRunnable(() -> doAfterCompletion(status)); - } catch (Throwable ex) { - this.afterCompletionException = ex; - } - - return Mono.empty(); - } - - protected void doAfterCompletion(int status) { - assertFalse(this.afterCompletionCalled); - this.afterCompletionCalled = true; - assertTrue(status == this.status); - } - } -} diff --git a/src/test/java/org/springframework/data/r2dbc/connectionfactory/SingleConnectionConnectionFactoryUnitTests.java b/src/test/java/org/springframework/data/r2dbc/connectionfactory/SingleConnectionConnectionFactoryUnitTests.java index 09089aac..e3af59eb 100644 --- a/src/test/java/org/springframework/data/r2dbc/connectionfactory/SingleConnectionConnectionFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/connectionfactory/SingleConnectionConnectionFactoryUnitTests.java @@ -100,23 +100,6 @@ public void shouldNotSuppressClose() { factory.destroy(); } - @Test // gh-204 - public void releaseConnectionShouldNotCloseConnection() { - - Connection connectionMock = mock(Connection.class); - ConnectionFactoryMetadata metadata = mock(ConnectionFactoryMetadata.class); - - SingleConnectionConnectionFactory factory = new SingleConnectionConnectionFactory(connectionMock, metadata, false); - - Connection connection = factory.create().block(); - - ConnectionFactoryUtils.releaseConnection(connection, factory) // - .as(StepVerifier::create) // - .verifyComplete(); - - verify(connectionMock, never()).close(); - } - @Test // gh-204 public void releaseConnectionShouldCloseUnrelatedConnection() { diff --git a/src/test/java/org/springframework/data/r2dbc/convert/MappingR2dbcConverterUnitTests.java b/src/test/java/org/springframework/data/r2dbc/convert/MappingR2dbcConverterUnitTests.java index 63496b52..61a9244a 100644 --- a/src/test/java/org/springframework/data/r2dbc/convert/MappingR2dbcConverterUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/convert/MappingR2dbcConverterUnitTests.java @@ -37,9 +37,9 @@ import org.springframework.data.convert.WritingConverter; import org.springframework.data.r2dbc.mapping.OutboundRow; import org.springframework.data.r2dbc.mapping.R2dbcMappingContext; -import org.springframework.data.r2dbc.mapping.SettableValue; import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.sql.SqlIdentifier; +import org.springframework.r2dbc.core.Parameter; /** * Unit tests for {@link MappingR2dbcConverter}. @@ -72,12 +72,12 @@ public void shouldIncludeAllPropertiesInOutboundRow() { LocalDateTime localDateTime = LocalDateTime.now(); converter.write(new Person("id", "Walter", "White", instant, localDateTime), row); - assertThat(row).containsEntry(SqlIdentifier.unquoted("id"), SettableValue.fromOrEmpty("id", String.class)); + assertThat(row).containsEntry(SqlIdentifier.unquoted("id"), Parameter.fromOrEmpty("id", String.class)); assertThat(row).containsEntry(SqlIdentifier.unquoted("firstname"), - SettableValue.fromOrEmpty("Walter", String.class)); - assertThat(row).containsEntry(SqlIdentifier.unquoted("lastname"), SettableValue.fromOrEmpty("White", String.class)); - assertThat(row).containsEntry(SqlIdentifier.unquoted("instant"), SettableValue.from(instant)); - assertThat(row).containsEntry(SqlIdentifier.unquoted("local_date_time"), SettableValue.from(localDateTime)); + Parameter.fromOrEmpty("Walter", String.class)); + assertThat(row).containsEntry(SqlIdentifier.unquoted("lastname"), Parameter.fromOrEmpty("White", String.class)); + assertThat(row).containsEntry(SqlIdentifier.unquoted("instant"), Parameter.from(instant)); + assertThat(row).containsEntry(SqlIdentifier.unquoted("local_date_time"), Parameter.from(localDateTime)); } @Test // gh-41 @@ -117,7 +117,7 @@ public void shouldConvertMapToString() { OutboundRow row = new OutboundRow(); converter.write(withMap, row); - assertThat(row).containsEntry(SqlIdentifier.unquoted("nested"), SettableValue.from("map")); + assertThat(row).containsEntry(SqlIdentifier.unquoted("nested"), Parameter.from("map")); } @Test // gh-59 @@ -138,7 +138,7 @@ public void shouldConvertEnum() { OutboundRow row = new OutboundRow(); converter.write(withMap, row); - assertThat(row).containsEntry(SqlIdentifier.unquoted("condition"), SettableValue.from("Mint")); + assertThat(row).containsEntry(SqlIdentifier.unquoted("condition"), Parameter.from("Mint")); } @Test // gh-59 @@ -148,7 +148,7 @@ public void shouldConvertNullEnum() { OutboundRow row = new OutboundRow(); converter.write(withMap, row); - assertThat(row).containsEntry(SqlIdentifier.unquoted("condition"), SettableValue.fromOrEmpty(null, String.class)); + assertThat(row).containsEntry(SqlIdentifier.unquoted("condition"), Parameter.fromOrEmpty(null, String.class)); } @Test // gh-59 @@ -172,8 +172,8 @@ public void shouldWriteTopLevelEntity() { OutboundRow row = new OutboundRow(); converter.write(person, row); - assertThat(row).containsEntry(SqlIdentifier.unquoted("foo_column"), SettableValue.from("bar")) - .containsEntry(SqlIdentifier.unquoted("entity"), SettableValue.from("nested_entity")); + assertThat(row).containsEntry(SqlIdentifier.unquoted("foo_column"), Parameter.from("bar")) + .containsEntry(SqlIdentifier.unquoted("entity"), Parameter.from("nested_entity")); } @Test // gh-59 @@ -263,8 +263,8 @@ enum CustomConversionPersonToOutboundRowConverter implements Converter prepareForTransaction(DatabaseClient client) { public void executeInsertInManagedTransaction() { Flux integerFlux = databaseClient // - .execute(getInsertIntoLegosetStatement()) // + .sql(getInsertIntoLegosetStatement()) // .bind(0, 42055) // .bind(1, "SCHAUFELRADBAGGER") // .bindNull(2, Integer.class) // @@ -162,7 +163,7 @@ public void executeInsertInManagedTransaction() { @Test // gh-2 public void executeInsertInAutoCommitTransaction() { - Flux integerFlux = databaseClient.execute(getInsertIntoLegosetStatement()) // + Flux integerFlux = databaseClient.sql(getInsertIntoLegosetStatement()) // .bind(0, 42055) // .bind(1, "SCHAUFELRADBAGGER") // .bindNull(2, Integer.class) // @@ -178,7 +179,7 @@ public void executeInsertInAutoCommitTransaction() { @Test // gh-2 public void shouldRollbackTransaction() { - Mono integerFlux = databaseClient.execute(getInsertIntoLegosetStatement()) // + Mono integerFlux = databaseClient.sql(getInsertIntoLegosetStatement()) // .bind(0, 42055) // .bind(1, "SCHAUFELRADBAGGER") // .bindNull(2, Integer.class) // @@ -196,7 +197,7 @@ public void shouldRollbackTransaction() { @Test // gh-2, gh-75, gh-107 public void emitTransactionIds() { - Flux txId = databaseClient.execute(getCurrentTransactionIdStatement()) // + Flux txId = databaseClient.sql(getCurrentTransactionIdStatement()) // .map((row, md) -> row.get(0)) // .all(); @@ -220,7 +221,7 @@ public void shouldRollbackTransactionUsingTransactionalOperator() { TransactionalOperator transactionalOperator = TransactionalOperator .create(new R2dbcTransactionManager(connectionFactory), new DefaultTransactionDefinition()); - Flux integerFlux = databaseClient.execute(getInsertIntoLegosetStatement()) // + Flux integerFlux = databaseClient.sql(getInsertIntoLegosetStatement()) // .bind(0, 42055) // .bind(1, "SCHAUFELRADBAGGER") // .bindNull(2, Integer.class) // @@ -301,7 +302,7 @@ public TransactionalService(DatabaseClient databaseClient) { @Transactional public Flux emitTransactionIds(Mono prepareTransaction, String idStatement) { - Flux txId = databaseClient.execute(idStatement) // + Flux txId = databaseClient.sql(idStatement) // .map((row, md) -> row.get(0)) // .all(); @@ -311,7 +312,7 @@ public Flux emitTransactionIds(Mono prepareTransaction, String idS @Transactional public Flux shouldRollbackTransactionUsingTransactionalOperator(String insertStatement) { - return databaseClient.execute(insertStatement) // + return databaseClient.sql(insertStatement) // .bind(0, 42055) // .bind(1, "SCHAUFELRADBAGGER") // .bindNull(2, Integer.class) // diff --git a/src/test/java/org/springframework/data/r2dbc/core/JasyncMySqlTransactionalDatabaseClientIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/core/JasyncMySqlTransactionalDatabaseClientIntegrationTests.java index ec6117ab..3a4ddfde 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/JasyncMySqlTransactionalDatabaseClientIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/core/JasyncMySqlTransactionalDatabaseClientIntegrationTests.java @@ -26,6 +26,7 @@ import org.springframework.data.r2dbc.testing.ExternalDatabase; import org.springframework.data.r2dbc.testing.MySqlTestSupport; +import org.springframework.r2dbc.core.DatabaseClient; /** * Transactional integration tests for {@link DatabaseClient} against MySQL using Jasync MySQL. @@ -62,7 +63,7 @@ protected Mono prepareForTransaction(DatabaseClient client) { * batches every now and then. * @see: https://dev.mysql.com/doc/refman/5.7/en/innodb-information-schema-internal-data.html */ - return client.execute(getInsertIntoLegosetStatement()) // + return client.sql(getInsertIntoLegosetStatement()) // .bind(0, 42055) // .bind(1, "SCHAUFELRADBAGGER") // .bindNull(2, Integer.class) // diff --git a/src/test/java/org/springframework/data/r2dbc/core/MariaDbTransactionalDatabaseClientIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/core/MariaDbTransactionalDatabaseClientIntegrationTests.java index 28dcbed7..7fea1cc3 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/MariaDbTransactionalDatabaseClientIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/core/MariaDbTransactionalDatabaseClientIntegrationTests.java @@ -26,6 +26,7 @@ import org.springframework.data.r2dbc.testing.ExternalDatabase; import org.springframework.data.r2dbc.testing.MariaDbTestSupport; +import org.springframework.r2dbc.core.DatabaseClient; /** * Transactional integration tests for {@link DatabaseClient} against MariaDb. @@ -61,7 +62,7 @@ protected Mono prepareForTransaction(DatabaseClient client) { * And we need to delay emitting the result so that Mariadb has time to write the transaction id, which is done in * batches every now and then. */ - return client.execute(getInsertIntoLegosetStatement()) // + return client.sql(getInsertIntoLegosetStatement()) // .bind(0, 42055) // .bind(1, "SCHAUFELRADBAGGER") // .bindNull(2, Integer.class) // diff --git a/src/test/java/org/springframework/data/r2dbc/core/MySqlTransactionalDatabaseClientIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/core/MySqlTransactionalDatabaseClientIntegrationTests.java index baed70f9..e18cc567 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/MySqlTransactionalDatabaseClientIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/core/MySqlTransactionalDatabaseClientIntegrationTests.java @@ -26,6 +26,7 @@ import org.springframework.data.r2dbc.testing.ExternalDatabase; import org.springframework.data.r2dbc.testing.MySqlTestSupport; +import org.springframework.r2dbc.core.DatabaseClient; /** * Transactional integration tests for {@link DatabaseClient} against MySQL. @@ -62,7 +63,7 @@ protected Mono prepareForTransaction(DatabaseClient client) { * batches every now and then. * @see: https://dev.mysql.com/doc/refman/5.7/en/innodb-information-schema-internal-data.html */ - return client.execute(getInsertIntoLegosetStatement()) // + return client.sql(getInsertIntoLegosetStatement()) // .bind(0, 42055) // .bind(1, "SCHAUFELRADBAGGER") // .bindNull(2, Integer.class) // diff --git a/src/test/java/org/springframework/data/r2dbc/core/NamedParameterUtilsUnitTests.java b/src/test/java/org/springframework/data/r2dbc/core/NamedParameterUtilsUnitTests.java index 84ddb94a..6f99a8e8 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/NamedParameterUtilsUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/core/NamedParameterUtilsUnitTests.java @@ -26,11 +26,11 @@ import org.junit.Test; -import org.springframework.data.r2dbc.dialect.BindMarkersFactory; import org.springframework.data.r2dbc.dialect.BindTarget; import org.springframework.data.r2dbc.dialect.PostgresDialect; import org.springframework.data.r2dbc.dialect.SqlServerDialect; import org.springframework.data.r2dbc.mapping.SettableValue; +import org.springframework.r2dbc.core.binding.BindMarkersFactory; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; diff --git a/src/test/java/org/springframework/data/r2dbc/core/PostgresReactiveDataAccessStrategyTests.java b/src/test/java/org/springframework/data/r2dbc/core/PostgresReactiveDataAccessStrategyTests.java index 6205866e..5356051e 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/PostgresReactiveDataAccessStrategyTests.java +++ b/src/test/java/org/springframework/data/r2dbc/core/PostgresReactiveDataAccessStrategyTests.java @@ -33,6 +33,7 @@ import org.springframework.data.r2dbc.mapping.OutboundRow; import org.springframework.data.r2dbc.mapping.SettableValue; import org.springframework.data.relational.core.sql.SqlIdentifier; +import org.springframework.r2dbc.core.Parameter; /** * {@link PostgresDialect} specific tests for {@link ReactiveDataAccessStrategy}. @@ -88,8 +89,8 @@ public void shouldConvertToArray() { OutboundRow outboundRow = strategy.getOutboundRow(withArray); assertThat(outboundRow) // - .containsEntry(SqlIdentifier.unquoted("string_array"), SettableValue.from(new String[] { "hello", "world" })) - .containsEntry(SqlIdentifier.unquoted("string_list"), SettableValue.from(new String[] { "hello", "world" })); + .containsEntry(SqlIdentifier.unquoted("string_array"), Parameter.from(new String[] { "hello", "world" })) + .containsEntry(SqlIdentifier.unquoted("string_list"), Parameter.from(new String[] { "hello", "world" })); } @Test // gh-139 @@ -104,7 +105,7 @@ public void shouldApplyCustomConversion() { OutboundRow outboundRow = strategy.getOutboundRow(withConversion); assertThat(outboundRow) // - .containsEntry(SqlIdentifier.unquoted("my_objects"), SettableValue.from("[one, two]")); + .containsEntry(SqlIdentifier.unquoted("my_objects"), Parameter.from("[one, two]")); } @Test // gh-139 @@ -121,7 +122,7 @@ public void shouldApplyCustomConversionForNull() { assertThat(outboundRow) // .containsKey(SqlIdentifier.unquoted("my_objects")); - SettableValue value = outboundRow.get("my_objects"); + Parameter value = outboundRow.get("my_objects"); assertThat(value.isEmpty()).isTrue(); assertThat(value.getType()).isEqualTo(String.class); } @@ -139,7 +140,7 @@ public void shouldConvertSetOfEnumToString() { assertThat(outboundRow).containsKey(SqlIdentifier.unquoted("enum_set")); - SettableValue value = outboundRow.get(SqlIdentifier.unquoted("enum_set")); + Parameter value = outboundRow.get(SqlIdentifier.unquoted("enum_set")); assertThat(value.getValue()).isEqualTo(new String[] { "ONE", "TWO" }); } @@ -156,7 +157,7 @@ public void shouldConvertArrayOfEnumToString() { assertThat(outboundRow).containsKey(SqlIdentifier.unquoted("enum_array")); - SettableValue value = outboundRow.get(SqlIdentifier.unquoted("enum_array")); + Parameter value = outboundRow.get(SqlIdentifier.unquoted("enum_array")); assertThat(value.getValue()).isEqualTo(new String[] { "ONE", "TWO" }); } diff --git a/src/test/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplateUnitTests.java b/src/test/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplateUnitTests.java index 0dfc007e..d749c3c1 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplateUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplateUnitTests.java @@ -40,7 +40,6 @@ import org.springframework.data.mapping.callback.ReactiveEntityCallbacks; import org.springframework.data.r2dbc.dialect.PostgresDialect; import org.springframework.data.r2dbc.mapping.OutboundRow; -import org.springframework.data.r2dbc.mapping.SettableValue; import org.springframework.data.r2dbc.mapping.event.AfterConvertCallback; import org.springframework.data.r2dbc.mapping.event.AfterSaveCallback; import org.springframework.data.r2dbc.mapping.event.BeforeConvertCallback; @@ -52,6 +51,8 @@ import org.springframework.data.relational.core.query.Update; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.lang.Nullable; +import org.springframework.r2dbc.core.DatabaseClient; +import org.springframework.r2dbc.core.Parameter; import org.springframework.util.CollectionUtils; /** @@ -61,7 +62,7 @@ */ public class R2dbcEntityTemplateUnitTests { - DatabaseClient client; + org.springframework.r2dbc.core.DatabaseClient client; R2dbcEntityTemplate entityTemplate; StatementRecorder recorder; @@ -70,8 +71,8 @@ public void before() { recorder = StatementRecorder.newInstance(); client = DatabaseClient.builder().connectionFactory(recorder) - .dataAccessStrategy(new DefaultReactiveDataAccessStrategy(PostgresDialect.INSTANCE)).build(); - entityTemplate = new R2dbcEntityTemplate(client); + .bindMarkers(PostgresDialect.INSTANCE.getBindMarkersFactory()).build(); + entityTemplate = new R2dbcEntityTemplate(client, PostgresDialect.INSTANCE); } @Test // gh-220 @@ -92,7 +93,7 @@ public void shouldCountBy() { StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("SELECT")); assertThat(statement.getSql()).isEqualTo("SELECT COUNT(person.id) FROM person WHERE person.THE_NAME = $1"); - assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Walter")); + assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter")); } @Test // gh-220 @@ -113,7 +114,7 @@ public void shouldExistsByCriteria() { StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("SELECT")); assertThat(statement.getSql()).isEqualTo("SELECT person.id FROM person WHERE person.THE_NAME = $1 LIMIT 1"); - assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Walter")); + assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter")); } @Test // gh-220 @@ -129,7 +130,7 @@ public void shouldSelectByCriteria() { assertThat(statement.getSql()) .isEqualTo("SELECT person.* FROM person WHERE person.THE_NAME = $1 ORDER BY THE_NAME ASC"); - assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Walter")); + assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter")); } @Test // gh-215 @@ -170,7 +171,7 @@ public void shouldSelectOne() { assertThat(statement.getSql()) .isEqualTo("SELECT person.* FROM person WHERE person.THE_NAME = $1 ORDER BY THE_NAME ASC LIMIT 2"); - assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Walter")); + assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter")); } @Test // gh-220 @@ -191,8 +192,8 @@ public void shouldUpdateByQuery() { StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("UPDATE")); assertThat(statement.getSql()).isEqualTo("UPDATE person SET THE_NAME = $1 WHERE person.THE_NAME = $2"); - assertThat(statement.getBindings()).hasSize(2).containsEntry(0, SettableValue.from("Heisenberg")).containsEntry(1, - SettableValue.from("Walter")); + assertThat(statement.getBindings()).hasSize(2).containsEntry(0, Parameter.from("Heisenberg")).containsEntry(1, + Parameter.from("Walter")); } @Test // gh-220 @@ -212,7 +213,7 @@ public void shouldDeleteByQuery() { StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("DELETE")); assertThat(statement.getSql()).isEqualTo("DELETE FROM person WHERE person.THE_NAME = $1"); - assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Walter")); + assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter")); } @Test // gh-220 @@ -229,7 +230,7 @@ public void shouldDeleteEntity() { StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("DELETE")); assertThat(statement.getSql()).isEqualTo("DELETE FROM person WHERE person.id = $1"); - assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Walter")); + assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter")); } @Test // gh-365 @@ -249,8 +250,8 @@ public void shouldInsertVersioned() { StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("INSERT")); assertThat(statement.getSql()).isEqualTo("INSERT INTO versioned_person (id, version, name) VALUES ($1, $2, $3)"); - assertThat(statement.getBindings()).hasSize(3).containsEntry(0, SettableValue.from("id")).containsEntry(1, - SettableValue.from(1L)); + assertThat(statement.getBindings()).hasSize(3).containsEntry(0, Parameter.from("id")).containsEntry(1, + Parameter.from(1L)); } @Test // gh-215 @@ -277,8 +278,8 @@ public void insertShouldInvokeCallback() { StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("INSERT")); assertThat(statement.getSql()).isEqualTo("INSERT INTO person (THE_NAME, description) VALUES ($1, $2)"); - assertThat(statement.getBindings()).hasSize(2).containsEntry(0, SettableValue.from("before-convert")) - .containsEntry(1, SettableValue.from("before-save")); + assertThat(statement.getBindings()).hasSize(2).containsEntry(0, Parameter.from("before-convert")).containsEntry(1, + Parameter.from("before-save")); } @Test // gh-365 @@ -299,8 +300,8 @@ public void shouldUpdateVersioned() { assertThat(statement.getSql()).isEqualTo( "UPDATE versioned_person SET version = $1, name = $2 WHERE versioned_person.id = $3 AND (versioned_person.version = $4)"); - assertThat(statement.getBindings()).hasSize(4).containsEntry(0, SettableValue.from(2L)).containsEntry(3, - SettableValue.from(1L)); + assertThat(statement.getBindings()).hasSize(4).containsEntry(0, Parameter.from(2L)).containsEntry(3, + Parameter.from(1L)); } @Test // gh-215 @@ -332,8 +333,8 @@ public void updateShouldInvokeCallback() { StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("UPDATE")); assertThat(statement.getSql()).isEqualTo("UPDATE person SET THE_NAME = $1, description = $2 WHERE person.id = $3"); - assertThat(statement.getBindings()).hasSize(3).containsEntry(0, SettableValue.from("before-convert")) - .containsEntry(1, SettableValue.from("before-save")); + assertThat(statement.getBindings()).hasSize(3).containsEntry(0, Parameter.from("before-convert")).containsEntry(1, + Parameter.from("before-save")); } @ToString @@ -402,7 +403,7 @@ static class ValueCapturingBeforeSaveCallback extends ValueCapturingEntityCallba public Mono onBeforeSave(Person entity, OutboundRow outboundRow, SqlIdentifier table) { capture(entity); - outboundRow.put(SqlIdentifier.unquoted("description"), SettableValue.from("before-save")); + outboundRow.put(SqlIdentifier.unquoted("description"), Parameter.from("before-save")); return Mono.just(entity); } } diff --git a/src/test/java/org/springframework/data/r2dbc/core/ReactiveDataAccessStrategyTestSupport.java b/src/test/java/org/springframework/data/r2dbc/core/ReactiveDataAccessStrategyTestSupport.java index a91ab91d..db3dcb7f 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/ReactiveDataAccessStrategyTestSupport.java +++ b/src/test/java/org/springframework/data/r2dbc/core/ReactiveDataAccessStrategyTestSupport.java @@ -38,8 +38,8 @@ import org.springframework.data.annotation.ReadOnlyProperty; import org.springframework.data.r2dbc.dialect.R2dbcDialect; -import org.springframework.data.r2dbc.mapping.SettableValue; import org.springframework.data.relational.core.sql.SqlIdentifier; +import org.springframework.r2dbc.core.Parameter; /** * Abstract base class for {@link R2dbcDialect}-aware {@link DefaultReactiveDataAccessStrategy} tests. @@ -205,7 +205,7 @@ private void testType(BiConsumer setter, Function s.startsWith("DELETE")); assertThat(statement.getSql()).isEqualTo("DELETE FROM person WHERE person.THE_NAME = $1"); - assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Walter")); + assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter")); } @Test // gh-220 diff --git a/src/test/java/org/springframework/data/r2dbc/core/ReactiveInsertOperationUnitTests.java b/src/test/java/org/springframework/data/r2dbc/core/ReactiveInsertOperationUnitTests.java index f5b98f8d..1e05bb7e 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/ReactiveInsertOperationUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/core/ReactiveInsertOperationUnitTests.java @@ -31,6 +31,7 @@ import org.springframework.data.r2dbc.mapping.SettableValue; import org.springframework.data.r2dbc.testing.StatementRecorder; import org.springframework.data.relational.core.mapping.Column; +import org.springframework.r2dbc.core.Parameter; /** * Unit test for {@link ReactiveInsertOperation}. @@ -77,7 +78,7 @@ public void shouldInsert() { StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("INSERT")); assertThat(statement.getSql()).isEqualTo("INSERT INTO person (THE_NAME) VALUES ($1)"); - assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Walter")); + assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Walter")); } @Test // gh-220 diff --git a/src/test/java/org/springframework/data/r2dbc/core/ReactiveUpdateOperationUnitTests.java b/src/test/java/org/springframework/data/r2dbc/core/ReactiveUpdateOperationUnitTests.java index f29797b4..b35af0dc 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/ReactiveUpdateOperationUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/core/ReactiveUpdateOperationUnitTests.java @@ -31,6 +31,7 @@ import org.springframework.data.r2dbc.testing.StatementRecorder; import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.core.query.Update; +import org.springframework.r2dbc.core.Parameter; /** * Unit test for {@link ReactiveUpdateOperation}. @@ -68,7 +69,7 @@ public void shouldUpdate() { StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("UPDATE")); assertThat(statement.getSql()).isEqualTo("UPDATE person SET THE_NAME = $1"); - assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Heisenberg")); + assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Heisenberg")); } @Test // gh-410 @@ -87,7 +88,7 @@ public void shouldUpdateWithTable() { StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("UPDATE")); assertThat(statement.getSql()).isEqualTo("UPDATE table SET THE_NAME = $1"); - assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Heisenberg")); + assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Heisenberg")); } @Test // gh-220 @@ -107,8 +108,8 @@ public void shouldUpdateWithQuery() { StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("UPDATE")); assertThat(statement.getSql()).isEqualTo("UPDATE person SET THE_NAME = $1 WHERE person.THE_NAME = $2"); - assertThat(statement.getBindings()).hasSize(2).containsEntry(0, SettableValue.from("Heisenberg")).containsEntry(1, - SettableValue.from("Walter")); + assertThat(statement.getBindings()).hasSize(2).containsEntry(0, Parameter.from("Heisenberg")).containsEntry(1, + Parameter.from("Walter")); } @Test // gh-220 diff --git a/src/test/java/org/springframework/data/r2dbc/core/StatementMapperUnitTests.java b/src/test/java/org/springframework/data/r2dbc/core/StatementMapperUnitTests.java index 0aa08f9e..b9f14163 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/StatementMapperUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/core/StatementMapperUnitTests.java @@ -27,6 +27,7 @@ import org.springframework.data.r2dbc.dialect.PostgresDialect; import org.springframework.data.relational.core.query.Criteria; import org.springframework.data.relational.core.query.Update; +import org.springframework.r2dbc.core.PreparedOperation; /** * Unit tests for {@link DefaultStatementMapper}. diff --git a/src/test/java/org/springframework/data/r2dbc/dialect/AnonymousBindMarkersUnitTests.java b/src/test/java/org/springframework/data/r2dbc/dialect/AnonymousBindMarkersUnitTests.java deleted file mode 100644 index af0d8921..00000000 --- a/src/test/java/org/springframework/data/r2dbc/dialect/AnonymousBindMarkersUnitTests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2019-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.data.r2dbc.dialect; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import org.junit.Test; - -/** - * Unit tests for {@link AnonymousBindMarkers}. - * - * @author Mark Paluch - */ -public class AnonymousBindMarkersUnitTests { - - @Test // gh-75 - public void shouldCreateNewBindMarkers() { - - BindMarkersFactory factory = BindMarkersFactory.anonymous("?"); - - BindMarkers bindMarkers1 = factory.create(); - BindMarkers bindMarkers2 = factory.create(); - - assertThat(bindMarkers1.next().getPlaceholder()).isEqualTo("?"); - assertThat(bindMarkers2.next().getPlaceholder()).isEqualTo("?"); - } - - @Test // gh-75 - public void shouldBindByIndex() { - - BindTarget bindTarget = mock(BindTarget.class); - - BindMarkers bindMarkers = BindMarkersFactory.anonymous("?").create(); - - BindMarker first = bindMarkers.next(); - BindMarker second = bindMarkers.next(); - - second.bind(bindTarget, "foo"); - first.bindNull(bindTarget, Object.class); - - verify(bindTarget).bindNull(0, Object.class); - verify(bindTarget).bind(1, "foo"); - } -} diff --git a/src/test/java/org/springframework/data/r2dbc/dialect/IndexedBindMarkersUnitTests.java b/src/test/java/org/springframework/data/r2dbc/dialect/IndexedBindMarkersUnitTests.java deleted file mode 100644 index 924f3d53..00000000 --- a/src/test/java/org/springframework/data/r2dbc/dialect/IndexedBindMarkersUnitTests.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.springframework.data.r2dbc.dialect; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import org.junit.Test; - -/** - * Unit tests for {@link IndexedBindMarkers}. - * - * @author Mark Paluch - */ -public class IndexedBindMarkersUnitTests { - - @Test // gh-15 - public void shouldCreateNewBindMarkers() { - - BindMarkersFactory factory = BindMarkersFactory.indexed("$", 0); - - BindMarkers bindMarkers1 = factory.create(); - BindMarkers bindMarkers2 = factory.create(); - - assertThat(bindMarkers1.next().getPlaceholder()).isEqualTo("$0"); - assertThat(bindMarkers2.next().getPlaceholder()).isEqualTo("$0"); - } - - @Test // gh-15 - public void shouldCreateNewBindMarkersWithOffset() { - - BindTarget bindTarget = mock(BindTarget.class); - - BindMarkers bindMarkers = BindMarkersFactory.indexed("$", 1).create(); - - BindMarker first = bindMarkers.next(); - first.bind(bindTarget, "foo"); - - BindMarker second = bindMarkers.next(); - second.bind(bindTarget, "bar"); - - assertThat(first.getPlaceholder()).isEqualTo("$1"); - assertThat(second.getPlaceholder()).isEqualTo("$2"); - verify(bindTarget).bind(0, "foo"); - verify(bindTarget).bind(1, "bar"); - } - - @Test // gh-15 - public void nextShouldIncrementBindMarker() { - - String[] prefixes = { "$", "?" }; - - for (String prefix : prefixes) { - - BindMarkers bindMarkers = BindMarkersFactory.indexed(prefix, 0).create(); - - BindMarker marker1 = bindMarkers.next(); - BindMarker marker2 = bindMarkers.next(); - - assertThat(marker1.getPlaceholder()).isEqualTo(prefix + "0"); - assertThat(marker2.getPlaceholder()).isEqualTo(prefix + "1"); - } - } - - @Test // gh-15 - public void bindValueShouldBindByIndex() { - - BindTarget bindTarget = mock(BindTarget.class); - - BindMarkers bindMarkers = BindMarkersFactory.indexed("$", 0).create(); - - bindMarkers.next().bind(bindTarget, "foo"); - bindMarkers.next().bind(bindTarget, "bar"); - - verify(bindTarget).bind(0, "foo"); - verify(bindTarget).bind(1, "bar"); - } - - @Test // gh-15 - public void bindNullShouldBindByIndex() { - - BindTarget bindTarget = mock(BindTarget.class); - - BindMarkers bindMarkers = BindMarkersFactory.indexed("$", 0).create(); - - bindMarkers.next(); // ignore - - bindMarkers.next().bindNull(bindTarget, Integer.class); - - verify(bindTarget).bindNull(1, Integer.class); - } -} diff --git a/src/test/java/org/springframework/data/r2dbc/dialect/NamedBindMarkersUnitTests.java b/src/test/java/org/springframework/data/r2dbc/dialect/NamedBindMarkersUnitTests.java deleted file mode 100644 index 52729fad..00000000 --- a/src/test/java/org/springframework/data/r2dbc/dialect/NamedBindMarkersUnitTests.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.springframework.data.r2dbc.dialect; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import org.junit.Test; - -/** - * Unit tests for {@link NamedBindMarkers}. - * - * @author Mark Paluch - */ -public class NamedBindMarkersUnitTests { - - @Test // gh-15 - public void shouldCreateNewBindMarkers() { - - BindMarkersFactory factory = BindMarkersFactory.named("@", "p", 32); - - BindMarkers bindMarkers1 = factory.create(); - BindMarkers bindMarkers2 = factory.create(); - - assertThat(bindMarkers1.next().getPlaceholder()).isEqualTo("@p0"); - assertThat(bindMarkers2.next().getPlaceholder()).isEqualTo("@p0"); - } - - @Test // gh-15 - public void nextShouldIncrementBindMarker() { - - String[] prefixes = { "$", "?" }; - - for (String prefix : prefixes) { - - BindMarkers bindMarkers = BindMarkersFactory.named(prefix, "p", 32).create(); - - BindMarker marker1 = bindMarkers.next(); - BindMarker marker2 = bindMarkers.next(); - - assertThat(marker1.getPlaceholder()).isEqualTo(prefix + "p0"); - assertThat(marker2.getPlaceholder()).isEqualTo(prefix + "p1"); - } - } - - @Test // gh-15 - public void nextShouldConsiderNameHint() { - - BindMarkers bindMarkers = BindMarkersFactory.named("@", "x", 32).create(); - - BindMarker marker1 = bindMarkers.next("foo1bar"); - BindMarker marker2 = bindMarkers.next(); - - assertThat(marker1.getPlaceholder()).isEqualTo("@x0foo1bar"); - assertThat(marker2.getPlaceholder()).isEqualTo("@x1"); - } - - @Test // gh-15 - public void nextShouldConsiderFilteredNameHint() { - - BindMarkers bindMarkers = BindMarkersFactory.named("@", "p", 32, s -> { - - return s.chars().filter(Character::isAlphabetic) - .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString(); - - }).create(); - - BindMarker marker1 = bindMarkers.next("foo1.bar?"); - BindMarker marker2 = bindMarkers.next(); - - assertThat(marker1.getPlaceholder()).isEqualTo("@p0foobar"); - assertThat(marker2.getPlaceholder()).isEqualTo("@p1"); - } - - @Test // gh-15 - public void nextShouldConsiderNameLimit() { - - BindMarkers bindMarkers = BindMarkersFactory.named("@", "p", 10).create(); - - BindMarker marker1 = bindMarkers.next("123456789"); - - assertThat(marker1.getPlaceholder()).isEqualTo("@p012345678"); - } - - @Test // gh-15 - public void bindValueShouldBindByName() { - - BindTarget bindTarget = mock(BindTarget.class); - - BindMarkers bindMarkers = BindMarkersFactory.named("@", "p", 32).create(); - - bindMarkers.next().bind(bindTarget, "foo"); - bindMarkers.next().bind(bindTarget, "bar"); - - verify(bindTarget).bind("p0", "foo"); - verify(bindTarget).bind("p1", "bar"); - } - - @Test // gh-15 - public void bindNullShouldBindByName() { - - BindTarget bindTarget = mock(BindTarget.class); - - BindMarkers bindMarkers = BindMarkersFactory.named("@", "p", 32).create(); - - bindMarkers.next(); // ignore - bindMarkers.next().bindNull(bindTarget, Integer.class); - - verify(bindTarget).bindNull("p1", Integer.class); - } -} diff --git a/src/test/java/org/springframework/data/r2dbc/dialect/PostgresDialectUnitTests.java b/src/test/java/org/springframework/data/r2dbc/dialect/PostgresDialectUnitTests.java index a079bfc7..afaba8d6 100644 --- a/src/test/java/org/springframework/data/r2dbc/dialect/PostgresDialectUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/dialect/PostgresDialectUnitTests.java @@ -6,8 +6,11 @@ import java.util.List; import org.junit.Test; + import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.relational.core.dialect.ArrayColumns; +import org.springframework.r2dbc.core.binding.BindMarker; +import org.springframework.r2dbc.core.binding.BindMarkers; /** * Unit tests for {@link PostgresDialect}. diff --git a/src/test/java/org/springframework/data/r2dbc/dialect/SqlServerDialectUnitTests.java b/src/test/java/org/springframework/data/r2dbc/dialect/SqlServerDialectUnitTests.java index 502083e2..01e091a3 100644 --- a/src/test/java/org/springframework/data/r2dbc/dialect/SqlServerDialectUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/dialect/SqlServerDialectUnitTests.java @@ -7,6 +7,8 @@ import org.junit.Test; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.relational.core.dialect.ArrayColumns; +import org.springframework.r2dbc.core.binding.BindMarker; +import org.springframework.r2dbc.core.binding.BindMarkers; /** * Unit tests for {@link SqlServerDialect}. diff --git a/src/test/java/org/springframework/data/r2dbc/repository/ConvertingR2dbcRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/repository/ConvertingR2dbcRepositoryIntegrationTests.java index a232fe92..c2b8a603 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/ConvertingR2dbcRepositoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/ConvertingR2dbcRepositoryIntegrationTests.java @@ -49,6 +49,7 @@ import org.springframework.data.r2dbc.testing.H2TestSupport; import org.springframework.data.repository.reactive.ReactiveCrudRepository; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.r2dbc.core.Parameter; import org.springframework.test.context.junit4.SpringRunner; /** @@ -149,10 +150,10 @@ public OutboundRow convert(ConvertedEntity convertedEntity) { OutboundRow outboundRow = new OutboundRow(); if (convertedEntity.getId() != null) { - outboundRow.put("id", SettableValue.from(convertedEntity.getId())); + outboundRow.put("id", Parameter.from(convertedEntity.getId())); } - outboundRow.put("name", SettableValue.from("prefixed: " + convertedEntity.getName())); + outboundRow.put("name", Parameter.from("prefixed: " + convertedEntity.getName())); return outboundRow; } diff --git a/src/test/java/org/springframework/data/r2dbc/repository/config/R2dbcRepositoriesRegistrarTests.java b/src/test/java/org/springframework/data/r2dbc/repository/config/R2dbcRepositoriesRegistrarTests.java index e7c21af7..82ef0bd4 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/config/R2dbcRepositoriesRegistrarTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/config/R2dbcRepositoriesRegistrarTests.java @@ -26,7 +26,6 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.r2dbc.core.DatabaseClient; import org.springframework.data.r2dbc.core.DefaultReactiveDataAccessStrategy; import org.springframework.data.r2dbc.core.R2dbcEntityOperations; import org.springframework.data.r2dbc.core.R2dbcEntityTemplate; @@ -36,6 +35,8 @@ import org.springframework.data.r2dbc.dialect.SqlServerDialect; import org.springframework.data.r2dbc.repository.config.mysql.MySqlPersonRepository; import org.springframework.data.r2dbc.repository.config.sqlserver.SqlServerPersonRepository; +import org.springframework.r2dbc.core.DatabaseClient; +import org.springframework.r2dbc.core.binding.BindMarkersFactory; /** * Integration tests for {@link R2dbcRepositoriesRegistrar}. @@ -86,8 +87,8 @@ public ConnectionFactory mysqlConnectionFactory() { public R2dbcEntityOperations mysqlR2dbcEntityOperations(@Qualifier("mysql") ConnectionFactory connectionFactory) { DefaultReactiveDataAccessStrategy strategy = new DefaultReactiveDataAccessStrategy(MySqlDialect.INSTANCE); - DatabaseClient databaseClient = DatabaseClient.builder().connectionFactory(connectionFactory) - .dataAccessStrategy(strategy).build(); + DatabaseClient databaseClient = DatabaseClient.builder().bindMarkers(BindMarkersFactory.anonymous("?")) + .connectionFactory(connectionFactory).build(); return new R2dbcEntityTemplate(databaseClient, strategy); } @@ -107,8 +108,8 @@ public ConnectionFactory sqlserverConnectionFactory() { public DatabaseClient sqlserverDatabaseClient( @Qualifier("sqlserverConnectionFactory") ConnectionFactory connectionFactory, @Qualifier("sqlserverDataAccessStrategy") ReactiveDataAccessStrategy mysqlDataAccessStrategy) { - return DatabaseClient.builder().connectionFactory(connectionFactory).dataAccessStrategy(mysqlDataAccessStrategy) - .build(); + return DatabaseClient.builder().connectionFactory(connectionFactory) + .bindMarkers(BindMarkersFactory.anonymous("?")).build(); } @Bean diff --git a/src/test/java/org/springframework/data/r2dbc/repository/query/PartTreeR2dbcQueryUnitTests.java b/src/test/java/org/springframework/data/r2dbc/repository/query/PartTreeR2dbcQueryUnitTests.java index 3159d349..986fa4d0 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/query/PartTreeR2dbcQueryUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/query/PartTreeR2dbcQueryUnitTests.java @@ -38,7 +38,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.r2dbc.convert.R2dbcConverter; -import org.springframework.data.r2dbc.core.DatabaseClient; +import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.data.r2dbc.core.DefaultReactiveDataAccessStrategy; import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy; import org.springframework.data.r2dbc.dialect.DialectResolver; @@ -88,8 +88,7 @@ public void setUp() { R2dbcDialect dialect = DialectResolver.getDialect(connectionFactory); dataAccessStrategy = new DefaultReactiveDataAccessStrategy(dialect, r2dbcConverter); - databaseClient = DatabaseClient.builder().connectionFactory(connectionFactory) - .dataAccessStrategy(dataAccessStrategy).build(); + databaseClient = DatabaseClient.builder().connectionFactory(connectionFactory).build(); } @Test // gh-282 @@ -166,7 +165,7 @@ public void createsQueryToFindAllEntitiesByDateAttributeBetween() throws Excepti assertThat(bindableQuery.get()) .isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".date_of_birth BETWEEN $1 AND $2"); - DatabaseClient.BindSpec bindSpecMock = mock(DatabaseClient.BindSpec.class); + DatabaseClient.GenericExecuteSpec bindSpecMock = mock(DatabaseClient.GenericExecuteSpec.class); when(bindSpecMock.bind(anyInt(), any())).thenReturn(bindSpecMock); bindableQuery.bind(bindSpecMock); @@ -325,7 +324,7 @@ public void appendsLikeOperatorParameterWithPercentSymbolForStartingWithQuery() dataAccessStrategy); RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "Jo" }); BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor); - DatabaseClient.BindSpec bindSpecMock = mock(DatabaseClient.BindSpec.class); + DatabaseClient.GenericExecuteSpec bindSpecMock = mock(DatabaseClient.GenericExecuteSpec.class); bindableQuery.bind(bindSpecMock); verify(bindSpecMock, times(1)).bind(0, "Jo%"); @@ -353,7 +352,7 @@ public void prependsLikeOperatorParameterWithPercentSymbolForEndingWithQuery() t dataAccessStrategy); RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "hn" }); BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor); - DatabaseClient.BindSpec bindSpecMock = mock(DatabaseClient.BindSpec.class); + DatabaseClient.GenericExecuteSpec bindSpecMock = mock(DatabaseClient.GenericExecuteSpec.class); bindableQuery.bind(bindSpecMock); verify(bindSpecMock, times(1)).bind(0, "%hn"); @@ -381,7 +380,7 @@ public void wrapsLikeOperatorParameterWithPercentSymbolsForContainingQuery() thr dataAccessStrategy); RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "oh" }); BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor); - DatabaseClient.BindSpec bindSpecMock = mock(DatabaseClient.BindSpec.class); + DatabaseClient.GenericExecuteSpec bindSpecMock = mock(DatabaseClient.GenericExecuteSpec.class); bindableQuery.bind(bindSpecMock); verify(bindSpecMock, times(1)).bind(0, "%oh%"); @@ -409,7 +408,7 @@ public void wrapsLikeOperatorParameterWithPercentSymbolsForNotContainingQuery() dataAccessStrategy); RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "oh" }); BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor); - DatabaseClient.BindSpec bindSpecMock = mock(DatabaseClient.BindSpec.class); + DatabaseClient.GenericExecuteSpec bindSpecMock = mock(DatabaseClient.GenericExecuteSpec.class); bindableQuery.bind(bindSpecMock); verify(bindSpecMock, times(1)).bind(0, "%oh%"); diff --git a/src/test/java/org/springframework/data/r2dbc/repository/query/PreparedOperationBindableQueryUnitTests.java b/src/test/java/org/springframework/data/r2dbc/repository/query/PreparedOperationBindableQueryUnitTests.java index 3ad79dbb..ad585e14 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/query/PreparedOperationBindableQueryUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/query/PreparedOperationBindableQueryUnitTests.java @@ -23,11 +23,14 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; -import org.springframework.data.r2dbc.core.DatabaseClient; -import org.springframework.data.r2dbc.core.PreparedOperation; +import org.springframework.r2dbc.core.DatabaseClient; +import org.springframework.r2dbc.core.PreparedOperation; /** + * Unit tests for {@link PreparedOperationBindableQuery}. + * * @author Roman Chigvintsev + * @author Marl Paluch */ @RunWith(MockitoJUnitRunner.class) @Ignore @@ -35,11 +38,10 @@ public class PreparedOperationBindableQueryUnitTests { @Mock PreparedOperation preparedOperation; - @SuppressWarnings({ "rawtypes", "unchecked" }) @Test // gh-282 public void bindsQueryParameterValues() { - DatabaseClient.BindSpec bindSpecMock = mock(DatabaseClient.BindSpec.class); + DatabaseClient.GenericExecuteSpec bindSpecMock = mock(DatabaseClient.GenericExecuteSpec.class); PreparedOperationBindableQuery query = new PreparedOperationBindableQuery(preparedOperation); query.bind(bindSpecMock); diff --git a/src/test/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQueryUnitTests.java b/src/test/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQueryUnitTests.java index 9fdc9b83..66b68f2f 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQueryUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQueryUnitTests.java @@ -32,8 +32,8 @@ import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.r2dbc.convert.MappingR2dbcConverter; -import org.springframework.data.r2dbc.core.DatabaseClient; -import org.springframework.data.r2dbc.core.DatabaseClient.GenericExecuteSpec; +import org.springframework.r2dbc.core.DatabaseClient; +import org.springframework.r2dbc.core.DatabaseClient.GenericExecuteSpec; import org.springframework.data.r2dbc.mapping.R2dbcMappingContext; import org.springframework.data.r2dbc.repository.Query; import org.springframework.data.relational.core.mapping.RelationalMappingContext; diff --git a/src/test/java/org/springframework/data/r2dbc/repository/support/AbstractSimpleR2dbcRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/repository/support/AbstractSimpleR2dbcRepositoryIntegrationTests.java index 0c4329b4..156c333c 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/support/AbstractSimpleR2dbcRepositoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/support/AbstractSimpleR2dbcRepositoryIntegrationTests.java @@ -41,7 +41,6 @@ import org.springframework.data.domain.Persistable; import org.springframework.data.domain.Sort; import org.springframework.data.r2dbc.convert.MappingR2dbcConverter; -import org.springframework.data.r2dbc.core.DatabaseClient; import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy; import org.springframework.data.r2dbc.testing.R2dbcIntegrationTestSupport; import org.springframework.data.relational.core.mapping.RelationalMappingContext; @@ -50,6 +49,7 @@ import org.springframework.data.relational.repository.query.RelationalEntityInformation; import org.springframework.data.relational.repository.support.MappingRelationalEntityInformation; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.r2dbc.core.DatabaseClient; /** * Abstract integration tests for {@link SimpleR2dbcRepository} to be ran against various databases. diff --git a/src/test/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryUnitTests.java b/src/test/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryUnitTests.java index dea67ea1..0860adf0 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryUnitTests.java @@ -27,12 +27,12 @@ import org.springframework.data.annotation.Id; import org.springframework.data.r2dbc.convert.MappingR2dbcConverter; import org.springframework.data.r2dbc.convert.R2dbcConverter; -import org.springframework.data.r2dbc.core.DatabaseClient; import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy; import org.springframework.data.r2dbc.mapping.R2dbcMappingContext; import org.springframework.data.relational.repository.query.RelationalEntityInformation; import org.springframework.data.relational.repository.support.MappingRelationalEntityInformation; import org.springframework.data.repository.Repository; +import org.springframework.r2dbc.core.DatabaseClient; /** * Unit test for {@link R2dbcRepositoryFactory}. diff --git a/src/test/java/org/springframework/data/r2dbc/testing/StatementRecorder.java b/src/test/java/org/springframework/data/r2dbc/testing/StatementRecorder.java index d8dbd088..589ec484 100644 --- a/src/test/java/org/springframework/data/r2dbc/testing/StatementRecorder.java +++ b/src/test/java/org/springframework/data/r2dbc/testing/StatementRecorder.java @@ -40,7 +40,7 @@ import org.reactivestreams.Publisher; -import org.springframework.data.r2dbc.mapping.SettableValue; +import org.springframework.r2dbc.core.Parameter; /** * Recorder utility for R2DBC {@link Statement}s. Allows stubbing and introspection. @@ -255,7 +255,7 @@ public class RecordedStatement implements Statement { private final List results; - private final Map bindings = new LinkedHashMap<>(); + private final Map bindings = new LinkedHashMap<>(); public RecordedStatement(String sql, Result result) { this(sql, Collections.singletonList(result)); @@ -266,7 +266,7 @@ public RecordedStatement(String sql, List results) { this.results = results; } - public Map getBindings() { + public Map getBindings() { return bindings; } @@ -281,25 +281,25 @@ public Statement add() { @Override public Statement bind(int index, Object o) { - this.bindings.put(index, SettableValue.from(o)); + this.bindings.put(index, Parameter.from(o)); return this; } @Override public Statement bind(String identifier, Object o) { - this.bindings.put(identifier, SettableValue.from(o)); + this.bindings.put(identifier, Parameter.from(o)); return this; } @Override public Statement bindNull(int index, Class type) { - this.bindings.put(index, SettableValue.empty(type)); + this.bindings.put(index, Parameter.empty(type)); return this; } @Override public Statement bindNull(String identifier, Class type) { - this.bindings.put(identifier, SettableValue.empty(type)); + this.bindings.put(identifier, Parameter.empty(type)); return this; }