#368 - Deprecate API provided by Spring R2DBC.

This commit deprecates API that has been moved to Spring R2DBC.

Original pull request: #412.
This commit is contained in:
Mark Paluch
2020-07-20 15:05:39 +02:00
parent 266cc7f80d
commit f331572167
99 changed files with 487 additions and 793 deletions

View File

@@ -107,6 +107,11 @@
<version>${springdata.relational}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>

View File

@@ -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]

View File

@@ -0,0 +1,48 @@
[appendix]
= 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` 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.
[[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 affected:
* `R2dbcEntityTemplate`
* `R2dbcDialect`
* Types in `org.springframework.data.r2dbc.query`
We recommend that you review your imports if you work with these types directly.
[[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`

View File

@@ -17,8 +17,6 @@ package org.springframework.data.r2dbc;
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 @@ import org.springframework.dao.InvalidDataAccessResourceUsageException;
* 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 class BadSqlGrammarException extends InvalidDataAccessResourceUsageExcept
* Return the SQL that caused the problem.
*/
public String getSql() {
return this.sql;
return super.getSql();
}
}

View File

@@ -24,13 +24,15 @@ import org.springframework.lang.Nullable;
* 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.
* <p>
* 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;

View File

@@ -17,23 +17,19 @@ package org.springframework.data.r2dbc;
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 class UncategorizedR2dbcException extends UncategorizedDataAccessExceptio
*/
@Nullable
public String getSql() {
return this.sql;
return super.getSql();
}
}

View File

@@ -40,8 +40,6 @@ 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;
@@ -100,11 +98,9 @@ public abstract class AbstractR2dbcConfiguration implements ApplicationContextAw
* @throws IllegalArgumentException if any of the required args is {@literal null}.
*/
@Bean({ "r2dbcDatabaseClient", "databaseClient" })
public DatabaseClient databaseClient(ReactiveDataAccessStrategy dataAccessStrategy,
R2dbcExceptionTranslator exceptionTranslator) {
public DatabaseClient databaseClient(ReactiveDataAccessStrategy dataAccessStrategy) {
Assert.notNull(dataAccessStrategy, "DataAccessStrategy must not be null!");
Assert.notNull(exceptionTranslator, "ExceptionTranslator must not be null!");
SpelAwareProxyProjectionFactory projectionFactory = new SpelAwareProxyProjectionFactory();
if (context != null) {
@@ -115,7 +111,7 @@ public abstract class AbstractR2dbcConfiguration implements ApplicationContextAw
return DatabaseClient.builder() //
.connectionFactory(lookupConnectionFactory()) //
.dataAccessStrategy(dataAccessStrategy) //
.exceptionTranslator(exceptionTranslator) //
.exceptionTranslator(new R2dbcExceptionSubclassTranslator()) //
.projectionFactory(projectionFactory) //
.build();
}
@@ -200,19 +196,6 @@ public abstract class AbstractR2dbcConfiguration implements ApplicationContextAw
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;

View File

@@ -39,7 +39,9 @@ import org.springframework.util.Assert;
*
* @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 {
/**

View File

@@ -23,8 +23,10 @@ import io.r2dbc.spi.Connection;
* @author Mark Paluch
* @see SimpleConnectionHandle
* @see ConnectionHolder
* @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection} instead.
*/
@FunctionalInterface
@Deprecated
public interface ConnectionHandle {
/**

View File

@@ -22,8 +22,8 @@ import org.springframework.transaction.support.ResourceHolderSupport;
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}.
* <p>
* Inherits rollback-only support for nested R2DBC transactions and reference count functionality from the base class.
* <p>
@@ -33,7 +33,9 @@ import org.springframework.util.Assert;
* @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;

View File

@@ -26,7 +26,9 @@ import io.r2dbc.spi.Wrapped;
*
* @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<Connection> {
/**

View File

@@ -32,7 +32,9 @@ import org.springframework.util.Assert;
*
* @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<ConnectionFactory> {
private final ConnectionFactory targetConnectionFactory;

View File

@@ -73,7 +73,9 @@ import org.springframework.util.Assert;
* @see ConnectionFactoryUtils#releaseConnection
* @see TransactionAwareConnectionFactoryProxy
* @see DatabaseClient
* @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection} instead.
*/
@Deprecated
public class R2dbcTransactionManager extends AbstractReactiveTransactionManager implements InitializingBean {
private ConnectionFactory connectionFactory;
@@ -135,7 +137,7 @@ public class R2dbcTransactionManager extends AbstractReactiveTransactionManager
* <p>
* 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
*/
@@ -526,7 +528,7 @@ public class R2dbcTransactionManager extends AbstractReactiveTransactionManager
* <p>
* 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

View File

@@ -24,7 +24,9 @@ import org.springframework.util.Assert;
*
* @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;

View File

@@ -53,7 +53,9 @@ import org.springframework.util.Assert;
* @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 {

View File

@@ -27,7 +27,9 @@ import io.r2dbc.spi.ConnectionFactory;
*
* @author Mark Paluch
* @see ConnectionFactoryUtils#closeConnection
* @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection} instead.
*/
@Deprecated
public interface SmartConnectionFactory extends ConnectionFactory {
/**

View File

@@ -60,7 +60,9 @@ import org.springframework.util.ReflectionUtils;
* @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 {
/**

View File

@@ -21,7 +21,9 @@ import org.springframework.core.io.support.EncodedResource;
* 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;

View File

@@ -31,7 +31,9 @@ import org.springframework.util.Assert;
* 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<DatabasePopulator> populators = new ArrayList<>(4);

View File

@@ -28,7 +28,9 @@ import org.springframework.util.Assert;
*
* @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;

View File

@@ -25,8 +25,10 @@ import reactor.core.publisher.Mono;
* @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 {
/**

View File

@@ -27,7 +27,9 @@ import org.springframework.util.Assert;
* 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} instead.
*/
@Deprecated
public abstract class DatabasePopulatorUtils {
// utility constructor

View File

@@ -45,7 +45,9 @@ import org.springframework.util.StringUtils;
* @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<Resource> scripts = new ArrayList<>();

View File

@@ -22,7 +22,9 @@ import org.springframework.lang.Nullable;
* 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 {
/**

View File

@@ -22,7 +22,9 @@ import org.springframework.lang.Nullable;
* 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;

View File

@@ -21,7 +21,9 @@ import org.springframework.core.io.support.EncodedResource;
* 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;

View File

@@ -48,7 +48,9 @@ import org.springframework.util.StringUtils;
* 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 {
/**

View File

@@ -20,7 +20,9 @@ package org.springframework.data.r2dbc.connectionfactory.init;
* 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;

View File

@@ -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

View File

@@ -42,7 +42,9 @@ import org.springframework.util.Assert;
* @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();

View File

@@ -30,7 +30,9 @@ import org.springframework.util.Assert;
*
* @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;

View File

@@ -21,8 +21,10 @@ import io.r2dbc.spi.ConnectionFactory;
* 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 {
/**

View File

@@ -22,8 +22,10 @@ import org.springframework.dao.NonTransientDataAccessException;
* {@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 {
/**

View File

@@ -31,7 +31,9 @@ import org.springframework.util.Assert;
*
* @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<String, ConnectionFactory> connectionFactories = new HashMap<>();

View File

@@ -24,7 +24,9 @@ import org.springframework.util.Assert;
* 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 class SingleConnectionFactoryLookup implements ConnectionFactoryLookup {
this.connectionFactory = connectionFactory;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.r2dbc.connectionfactory.lookup.ConnectionFactoryLookup#getConnectionFactory(java.lang.String)
*/

View File

@@ -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

View File

@@ -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

View File

@@ -19,7 +19,6 @@ import io.r2dbc.spi.ColumnMetadata;
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 @@ import org.springframework.util.LinkedCaseInsensitiveMap;
* 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<Row, RowMetadata, Map<String, Object>> {
public class ColumnMapRowMapper extends org.springframework.r2dbc.core.ColumnMapRowMapper {
public final static ColumnMapRowMapper INSTANCE = new ColumnMapRowMapper();
@Override
public Map<String, Object> apply(Row row, RowMetadata rowMetadata) {
Collection<? extends ColumnMetadata> columns = IterableUtils.toCollection(rowMetadata.getColumnMetadatas());
int columnCount = columns.size();
Map<String, Object> 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 class ColumnMapRowMapper implements BiFunction<Row, RowMetadata, Map<Stri
* @see LinkedCaseInsensitiveMap
*/
protected Map<String, Object> createColumnMap(int columnCount) {
return new LinkedCaseInsensitiveMap<>(columnCount);
return super.createColumnMap(columnCount);
}
/**
@@ -83,7 +71,7 @@ public class ColumnMapRowMapper implements BiFunction<Row, RowMetadata, Map<Stri
* @see ColumnMetadata#getName()
*/
protected String getColumnKey(String columnName) {
return columnName;
return super.getColumnKey(columnName);
}
/**
@@ -97,6 +85,6 @@ public class ColumnMapRowMapper implements BiFunction<Row, RowMetadata, Map<Stri
*/
@Nullable
protected Object getColumnValue(Row row, int index) {
return row.get(index);
return super.getColumnValue(row, index);
}
}

View File

@@ -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 <T> Collection<T> toCollection(Iterable<T> iterable) {
Assert.notNull(iterable, "Iterable must not be null!");
if (iterable instanceof Collection) {
return (Collection<T>) iterable;
}
List<T> result = new ArrayList<>();
for (T element : iterable) {
result.add(element);
}
return result;
}
static <T> List<T> toList(Iterable<T> iterable) {
Assert.notNull(iterable, "Iterable must not be null!");
if (iterable instanceof List) {
return (List<T>) iterable;
}
List<T> result = new ArrayList<>();
for (T element : iterable) {
result.add(element);
}
return result;
}
}

View File

@@ -29,7 +29,9 @@ import org.springframework.lang.Nullable;
*
* @author Mark Paluch
* @see MapBindParameterSource
* @deprecated since 1.2, without replacement.
*/
@Deprecated
public interface BindParameterSource {
/**

View File

@@ -32,8 +32,9 @@ import org.springframework.dao.DataAccessException;
* 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

View File

@@ -49,7 +49,9 @@ import org.springframework.util.Assert;
*
* @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 {
/**

View File

@@ -44,6 +44,7 @@ import java.util.stream.Collectors;
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,7 @@ import org.springframework.data.relational.core.query.Criteria;
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.PreparedOperation;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

View File

@@ -46,6 +46,7 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentEnti
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;
@@ -280,6 +281,15 @@ public class DefaultReactiveDataAccessStrategy implements ReactiveDataAccessStra
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)

View File

@@ -31,13 +31,9 @@ import java.util.function.Function;
*
* @author Mark Paluch
*/
class DefaultSqlResult<T> implements SqlResult<T> {
class DefaultSqlResult<T> implements FetchSpec<T> {
private final static SqlResult<?> EMPTY = new SqlResult<Object>() {
@Override
public <R> SqlResult<R> map(BiFunction<Row, RowMetadata, R> mappingFunction) {
return DefaultSqlResult.empty();
}
private final static FetchSpec<?> EMPTY = new FetchSpec<Object>() {
@Override
public Mono<Object> one() {
@@ -104,15 +100,14 @@ class DefaultSqlResult<T> implements SqlResult<T> {
* @return a {@code SqlResult}.
*/
@SuppressWarnings("unchecked")
public static <R> SqlResult<R> empty() {
return (SqlResult<R>) EMPTY;
public static <R> FetchSpec<R> empty() {
return (FetchSpec<R>) EMPTY;
}
/* (non-Javadoc)
* @see org.springframework.data.r2dbc.function.SqlResult#map(java.util.function.BiFunction)
*/
@Override
public <R> SqlResult<R> map(BiFunction<Row, RowMetadata, R> mappingFunction) {
public <R> FetchSpec<R> map(BiFunction<Row, RowMetadata, R> mappingFunction) {
return new DefaultSqlResult<>(connectionAccessor, sql, resultFunction, updatedRowsFunction, mappingFunction);
}

View File

@@ -19,9 +19,7 @@ import java.util.ArrayList;
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.InsertBuilder.InsertValuesWi
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 @@ class DefaultStatementMapper implements StatementMapper {
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<T> implements TypedStatementMapper<T> {

View File

@@ -32,9 +32,11 @@ import org.reactivestreams.Publisher;
* @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.

View File

@@ -22,5 +22,7 @@ package org.springframework.data.r2dbc.core;
* @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<T> extends RowsFetchSpec<T>, UpdatedRowsFetchSpec {}

View File

@@ -31,6 +31,7 @@ import org.springframework.util.Assert;
*
* @author Mark Paluch
*/
@Deprecated
class MapBindParameterSource implements BindParameterSource {
private final Map<String, SettableValue> values;

View File

@@ -36,7 +36,9 @@ import org.springframework.data.r2dbc.dialect.BindMarkersFactory;
* <b>NOTE: An instance of this class is thread-safe once configured.</b>
*
* @author Mark Paluch
* @deprecated since 1.2, without replacement.
*/
@Deprecated
public class NamedParameterExpander {
/**
@@ -124,6 +126,11 @@ public class NamedParameterExpander {
*/
public PreparedOperation<String> expand(String sql, BindMarkersFactory bindMarkersFactory,
BindParameterSource paramSource) {
return expand(sql, (org.springframework.r2dbc.core.binding.BindMarkersFactory) bindMarkersFactory, paramSource);
}
PreparedOperation<String> expand(String sql,
org.springframework.r2dbc.core.binding.BindMarkersFactory bindMarkersFactory, BindParameterSource paramSource) {
ParsedSql parsedSql = getParsedSql(sql);

View File

@@ -26,10 +26,10 @@ import java.util.Set;
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 @@ import org.springframework.util.Assert;
* @author Juergen Hoeller
* @author Mark Paluch
*/
@Deprecated
abstract class NamedParameterUtils {
/**
@@ -494,7 +495,7 @@ abstract class NamedParameterUtils {
}
@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<BindMarker> bindMarkers = getBindMarkers(identifier);
@@ -530,7 +531,8 @@ abstract class NamedParameterUtils {
}
}
private void bind(BindTarget target, Iterator<BindMarker> markers, Object valueToBind) {
private void bind(org.springframework.r2dbc.core.binding.BindTarget target, Iterator<BindMarker> markers,
Object valueToBind) {
Assert.isTrue(markers.hasNext(),
() -> String.format(
@@ -540,7 +542,8 @@ abstract class NamedParameterUtils {
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<BindMarker> bindMarkers = getBindMarkers(identifier);
@@ -579,6 +582,11 @@ abstract class NamedParameterUtils {
@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()) {

View File

@@ -26,6 +26,7 @@ import java.util.List;
* @author Thomas Risberg
* @author Juergen Hoeller
*/
@Deprecated
class ParsedSql {
private String originalSql;

View File

@@ -29,8 +29,10 @@ import org.springframework.data.r2dbc.dialect.BindTarget;
* @param <T> 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<T> extends QueryOperation {
@Deprecated
public interface PreparedOperation<T> extends QueryOperation, org.springframework.r2dbc.core.PreparedOperation<T> {
/**
* @return the query source, such as a statement/criteria object.
@@ -44,4 +46,9 @@ public interface PreparedOperation<T> extends QueryOperation {
*/
void bindTo(BindTarget target);
@Override
default String get() {
return toQuery();
}
}

View File

@@ -23,9 +23,11 @@ import java.util.function.Supplier;
*
* @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<String> {
@Deprecated
public interface QueryOperation extends Supplier<String>, org.springframework.r2dbc.core.QueryOperation {
/**
* Returns the string-representation of this operation to be used with {@link io.r2dbc.spi.Statement} creation.

View File

@@ -64,6 +64,7 @@ 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.util.ProxyUtils;
import org.springframework.r2dbc.core.PreparedOperation;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

View File

@@ -27,6 +27,8 @@ import org.springframework.data.r2dbc.mapping.SettableValue;
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 @@ import org.springframework.lang.Nullable;
* primary keys.
*
* @author Mark Paluch
* @see PreparedOperation
* @see org.springframework.r2dbc.core.PreparedOperation
*/
public interface ReactiveDataAccessStrategy {
@@ -64,9 +66,19 @@ public interface ReactiveDataAccessStrategy {
* @param value must not be {@literal null}.
* @return
* @since 1.1
* @deprecated since 1.2, use {@link #getBindValue(Parameter)} instead.
*/
SettableValue getBindValue(SettableValue value);
/**
* Return a potentially converted {@link SettableValue} 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}.
*

View File

@@ -23,7 +23,9 @@ import reactor.core.publisher.Mono;
*
* @param <T> row result type.
* @author Mark Paluch
* @deprecated since 1.2, use Spring's {@link org.springframework.r2dbc.core} support instead.
*/
@Deprecated
public interface RowsFetchSpec<T> {
/**

View File

@@ -25,8 +25,10 @@ import org.springframework.lang.Nullable;
*
* @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.

View File

@@ -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<T> extends FetchSpec<T> {
/**
* Apply a {@link BiFunction mapping function} to the result that emits {@link Row}s.
*
* @param mappingFunction must not be {@literal null}.
* @param <R> the value type of the {@code SqlResult}.
* @return a new {@link SqlResult} with {@link BiFunction mapping function} applied.
*/
<R> SqlResult<R> map(BiFunction<Row, RowMetadata, R> mappingFunction);
}

View File

@@ -31,7 +31,9 @@ import org.springframework.util.Assert;
* @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 {

View File

@@ -26,6 +26,7 @@ import org.reactivestreams.Publisher;
* @author Mark Paluch
* @since 1.1
*/
@Deprecated
enum StatementFilterFunctions implements StatementFilterFunction {
EMPTY_FILTER;

View File

@@ -36,6 +36,7 @@ import org.springframework.data.relational.core.sql.SqlIdentifier;
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.PreparedOperation;
/**
* Mapper for statement specifications to {@link PreparedOperation}. Statement mapping applies a

View File

@@ -21,7 +21,9 @@ import reactor.core.publisher.Mono;
* 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 {
/**

View File

@@ -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.
* <p>
* 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.
* </p>
*
* @author Mark Paluch
*/
class AnonymousBindMarkers implements BindMarkers {
private static final AtomicIntegerFieldUpdater<AnonymousBindMarkers> 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);
}
}

View File

@@ -10,8 +10,10 @@ import io.r2dbc.spi.Statement;
* @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.

View File

@@ -12,9 +12,11 @@ package org.springframework.data.r2dbc.dialect;
* @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}.

View File

@@ -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();
}
}
}

View File

@@ -15,9 +15,11 @@ import org.springframework.util.Assert;
* @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 @@ public interface BindMarkersFactory {
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 @@ public interface BindMarkersFactory {
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 @@ public interface BindMarkersFactory {
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();
}
};
}
}

View File

@@ -24,8 +24,10 @@ import org.springframework.data.r2dbc.core.PreparedOperation;
* @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.

View File

@@ -29,6 +29,9 @@ import java.util.function.Consumer;
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 @@ import org.springframework.util.Assert;
* 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<Bindings.Binding> {
private static final Bindings EMPTY = new Bindings();

View File

@@ -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;
}
}

View File

@@ -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<org.springframework.data.r2dbc.dialect.IndexedBindMarkers> 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);
}
}

View File

@@ -26,7 +26,9 @@ import org.springframework.util.Assert;
* {@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;

View File

@@ -27,6 +27,7 @@ import java.util.Set;
import java.util.UUID;
import org.springframework.core.convert.converter.Converter;
import org.springframework.r2dbc.core.binding.BindMarkersFactory;
/**
* An SQL dialect for MySQL.

View File

@@ -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<NamedBindMarkers> 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<String, String> hintFilterFunction;
NamedBindMarkers(String prefix, String namePrefix, int nameLimit, Function<String, String> 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);
}
}
}

View File

@@ -12,6 +12,7 @@ import java.util.UUID;
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;
/**

View File

@@ -8,6 +8,7 @@ import java.util.Set;
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.

View File

@@ -6,6 +6,8 @@ import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.springframework.r2dbc.core.binding.BindMarkersFactory;
/**
* An SQL dialect for Microsoft SQL Server.
*

View File

@@ -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 final Parameter parameter;
private SettableValue(@Nullable Object value, Class<?> type) {
Assert.notNull(type, "Type must not be null");
this.value = value;
this.type = type;
private SettableValue(Parameter parameter) {
this.parameter = parameter;
}
/**
@@ -51,7 +45,7 @@ public class SettableValue {
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 class SettableValue {
* @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 class SettableValue {
Assert.notNull(type, "Type must not be null");
return new SettableValue(null, type);
return new SettableValue(Parameter.empty(type));
}
/**
@@ -85,7 +79,7 @@ public class SettableValue {
*/
@Nullable
public Object getValue() {
return this.value;
return this.parameter.getValue();
}
/**
@@ -94,7 +88,7 @@ public class SettableValue {
* @return the column value type
*/
public Class<?> getType() {
return this.type;
return this.parameter.getType();
}
/**
@@ -103,7 +97,7 @@ public class SettableValue {
* @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 class SettableValue {
* @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,16 @@ public class SettableValue {
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();
}
}

View File

@@ -17,8 +17,8 @@ package org.springframework.data.r2dbc.query;
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;
/**

View File

@@ -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;

View File

@@ -29,10 +29,6 @@ import org.springframework.data.mapping.PropertyPath;
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.ClassTypeInformation;
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 @@ public class QueryMapper {
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<Object> valueFunction = (ValueFunction<Object>) criteria.getValue();
@@ -391,6 +398,22 @@ public class QueryMapper {
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 @@ public class QueryMapper {
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);

View File

@@ -20,10 +20,10 @@ import java.util.List;
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.SqlIdentifier;
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 @@ public class UpdateMapper extends QueryMapper {
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<Object> valueFunction = (ValueFunction<Object>) value;

View File

@@ -22,7 +22,6 @@ import java.util.List;
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 +29,7 @@ import org.springframework.data.relational.repository.query.RelationalParameters
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.PreparedOperation;
/**
* An {@link AbstractR2dbcQuery} implementation based on a {@link PartTree}.
@@ -71,7 +71,7 @@ public class PartTreeR2dbcQuery extends AbstractR2dbcQuery {
}
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.r2dbc.repository.query.AbstractR2dbcQuery#isModifyingQuery()
*/
@@ -80,7 +80,7 @@ public class PartTreeR2dbcQuery extends AbstractR2dbcQuery {
return this.tree.isDelete();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.r2dbc.repository.query.AbstractR2dbcQuery#createQuery(org.springframework.data.relational.repository.query.RelationalParameterAccessor)
*/

View File

@@ -16,8 +16,8 @@
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.PreparedOperation;
import org.springframework.util.Assert;
/**

View File

@@ -22,19 +22,23 @@ import java.util.stream.Collectors;
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<PreparedOperation<?>> {
/**
* 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}.

View File

@@ -31,7 +31,11 @@ import org.springframework.util.Assert;
* {@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 */

View File

@@ -43,7 +43,11 @@ import org.springframework.lang.Nullable;
* 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() {

View File

@@ -31,8 +31,12 @@ import org.springframework.lang.Nullable;
* @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 {
/**

View File

@@ -60,7 +60,11 @@ import org.springframework.lang.Nullable;
* @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 */

View File

@@ -40,7 +40,11 @@ import org.springframework.lang.Nullable;
* @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<String> BAD_SQL_GRAMMAR_CODES = new HashSet<>(8);

View File

@@ -26,11 +26,11 @@ import java.util.Map;
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;

View File

@@ -31,6 +31,7 @@ import org.springframework.data.r2dbc.dialect.MySqlDialect;
import org.springframework.data.r2dbc.mapping.SettableValue;
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 ReactiveDataAccessStrategy}.

View File

@@ -27,6 +27,7 @@ import org.springframework.data.r2dbc.dialect.BindTarget;
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}.

View File

@@ -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");
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -6,8 +6,11 @@ import static org.assertj.core.api.SoftAssertions.*;
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}.

View File

@@ -7,6 +7,8 @@ import java.util.UUID;
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}.