#414 - Adopt SpEL support to use ReactiveEvaluationContextProvider.
We now defer query creation to obtain and resolve SpEL expression dependencies using reactive SpEL context extensions.
This commit is contained in:
@@ -15,13 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.r2dbc.repository.query;
|
||||
|
||||
import kotlin.Unit;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.core.KotlinDetector;
|
||||
|
||||
import org.springframework.data.mapping.model.EntityInstantiators;
|
||||
import org.springframework.data.r2dbc.convert.EntityRowMapper;
|
||||
import org.springframework.data.r2dbc.convert.R2dbcConverter;
|
||||
@@ -34,10 +32,10 @@ import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.ResultProcessor;
|
||||
import org.springframework.data.repository.query.ReturnedType;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.r2dbc.core.DatabaseClient;
|
||||
import org.springframework.r2dbc.core.FetchSpec;
|
||||
import org.springframework.r2dbc.core.RowsFetchSpec;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -86,29 +84,15 @@ public abstract class AbstractR2dbcQuery implements RepositoryQuery {
|
||||
*/
|
||||
public Object execute(Object[] parameters) {
|
||||
|
||||
return method.hasReactiveWrapperParameter() ? executeDeferred(parameters)
|
||||
: execute(new RelationalParametersParameterAccessor(method, parameters));
|
||||
RelationalParameterAccessor parameterAccessor = new RelationalParametersParameterAccessor(method, parameters);
|
||||
|
||||
return createQuery(parameterAccessor).flatMapMany(it -> executeQuery(parameterAccessor, it));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object executeDeferred(Object[] parameters) {
|
||||
|
||||
R2dbcParameterAccessor parameterAccessor = new R2dbcParameterAccessor(method, parameters);
|
||||
|
||||
if (getQueryMethod().isCollectionQuery()) {
|
||||
return Flux.defer(() -> (Publisher<Object>) execute(parameterAccessor));
|
||||
}
|
||||
|
||||
return Mono.defer(() -> (Mono<Object>) execute(parameterAccessor));
|
||||
}
|
||||
|
||||
private Object execute(RelationalParameterAccessor parameterAccessor) {
|
||||
|
||||
// TODO: ConvertingParameterAccessor
|
||||
BindableQuery query = createQuery(parameterAccessor);
|
||||
private Publisher<?> executeQuery(RelationalParameterAccessor parameterAccessor, BindableQuery it) {
|
||||
|
||||
ResultProcessor processor = method.getResultProcessor().withDynamicProjection(parameterAccessor);
|
||||
DatabaseClient.GenericExecuteSpec boundQuery = query.bind(databaseClient.sql(query));
|
||||
DatabaseClient.GenericExecuteSpec boundQuery = it.bind(databaseClient.sql(it));
|
||||
|
||||
FetchSpec<?> fetchSpec;
|
||||
if (requiresMapping()) {
|
||||
@@ -178,9 +162,9 @@ public abstract class AbstractR2dbcQuery implements RepositoryQuery {
|
||||
* Creates a {@link BindableQuery} instance using the given {@link ParameterAccessor}
|
||||
*
|
||||
* @param accessor must not be {@literal null}.
|
||||
* @return the {@link BindableQuery}.
|
||||
* @return a mono emitting a {@link BindableQuery}.
|
||||
*/
|
||||
protected abstract BindableQuery createQuery(RelationalParameterAccessor accessor);
|
||||
protected abstract Mono<BindableQuery> createQuery(RelationalParameterAccessor accessor);
|
||||
|
||||
private static class FetchSpecAdapter<T> implements FetchSpec<T> {
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.repository.query;
|
||||
|
||||
import org.springframework.data.mapping.model.SpELExpressionEvaluator;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.r2dbc.core.Parameter;
|
||||
|
||||
/**
|
||||
* Simple {@link R2dbcSpELExpressionEvaluator} implementation using {@link ExpressionParser} and
|
||||
* {@link EvaluationContext}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 1.2
|
||||
*/
|
||||
class DefaultR2dbcSpELExpressionEvaluator implements R2dbcSpELExpressionEvaluator {
|
||||
|
||||
private final ExpressionParser parser;
|
||||
|
||||
private final EvaluationContext context;
|
||||
|
||||
DefaultR2dbcSpELExpressionEvaluator(ExpressionParser parser, EvaluationContext context) {
|
||||
this.parser = parser;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link SpELExpressionEvaluator} that does not support expression evaluation.
|
||||
*
|
||||
* @return a {@link SpELExpressionEvaluator} that does not support expression evaluation.
|
||||
*/
|
||||
public static R2dbcSpELExpressionEvaluator unsupported() {
|
||||
return NoOpExpressionEvaluator.INSTANCE;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.model.R2dbcSpELExpressionEvaluator#evaluate(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Parameter evaluate(String expression) {
|
||||
|
||||
Expression expr = parser.parseExpression(expression);
|
||||
|
||||
Object value = expr.getValue(context, Object.class);
|
||||
Class<?> valueType = expr.getValueType(context);
|
||||
|
||||
return org.springframework.r2dbc.core.Parameter.fromOrEmpty(value, valueType != null ? valueType : Object.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link SpELExpressionEvaluator} that does not support SpEL evaluation.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
enum NoOpExpressionEvaluator implements R2dbcSpELExpressionEvaluator {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Parameter evaluate(String expression) {
|
||||
throw new UnsupportedOperationException("Expression evaluation not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,12 +25,7 @@ import java.util.regex.Pattern;
|
||||
import org.springframework.data.relational.repository.query.RelationalParameterAccessor;
|
||||
import org.springframework.data.repository.query.Parameter;
|
||||
import org.springframework.data.repository.query.Parameters;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
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;
|
||||
|
||||
/**
|
||||
* {@link ExpressionEvaluatingParameterBinder} allows to evaluate, convert and bind parameters to placeholders within a
|
||||
@@ -41,10 +36,6 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
class ExpressionEvaluatingParameterBinder {
|
||||
|
||||
private final SpelExpressionParser expressionParser;
|
||||
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
|
||||
private final ExpressionQuery expressionQuery;
|
||||
|
||||
private final Map<String, Boolean> namedParameters = new ConcurrentHashMap<>();
|
||||
@@ -52,19 +43,9 @@ class ExpressionEvaluatingParameterBinder {
|
||||
/**
|
||||
* Creates new {@link ExpressionEvaluatingParameterBinder}
|
||||
*
|
||||
* @param expressionParser must not be {@literal null}.
|
||||
* @param evaluationContextProvider must not be {@literal null}.
|
||||
* @param expressionQuery must not be {@literal null}.
|
||||
*/
|
||||
ExpressionEvaluatingParameterBinder(SpelExpressionParser expressionParser,
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider, ExpressionQuery expressionQuery) {
|
||||
|
||||
Assert.notNull(expressionParser, "ExpressionParser must not be null");
|
||||
Assert.notNull(evaluationContextProvider, "EvaluationContextProvider must not be null");
|
||||
Assert.notNull(expressionQuery, "ExpressionQuery must not be null");
|
||||
|
||||
this.expressionParser = expressionParser;
|
||||
this.evaluationContextProvider = evaluationContextProvider;
|
||||
ExpressionEvaluatingParameterBinder(ExpressionQuery expressionQuery) {
|
||||
this.expressionQuery = expressionQuery;
|
||||
}
|
||||
|
||||
@@ -74,28 +55,28 @@ class ExpressionEvaluatingParameterBinder {
|
||||
*
|
||||
* @param bindSpec must not be {@literal null}.
|
||||
* @param parameterAccessor must not be {@literal null}.
|
||||
* @param evaluator must not be {@literal null}.
|
||||
*/
|
||||
public DatabaseClient.GenericExecuteSpec bind(DatabaseClient.GenericExecuteSpec bindSpec,
|
||||
RelationalParameterAccessor parameterAccessor) {
|
||||
DatabaseClient.GenericExecuteSpec bind(DatabaseClient.GenericExecuteSpec bindSpec,
|
||||
RelationalParameterAccessor parameterAccessor, R2dbcSpELExpressionEvaluator evaluator) {
|
||||
|
||||
Object[] values = parameterAccessor.getValues();
|
||||
Parameters<?, ?> bindableParameters = parameterAccessor.getBindableParameters();
|
||||
|
||||
DatabaseClient.GenericExecuteSpec bindSpecToUse = bindExpressions(bindSpec, values, bindableParameters);
|
||||
DatabaseClient.GenericExecuteSpec bindSpecToUse = bindExpressions(bindSpec, evaluator);
|
||||
bindSpecToUse = bindParameters(bindSpecToUse, parameterAccessor.hasBindableNullValue(), values, bindableParameters);
|
||||
|
||||
return bindSpecToUse;
|
||||
}
|
||||
|
||||
private DatabaseClient.GenericExecuteSpec bindExpressions(DatabaseClient.GenericExecuteSpec bindSpec, Object[] values,
|
||||
Parameters<?, ?> bindableParameters) {
|
||||
private DatabaseClient.GenericExecuteSpec bindExpressions(DatabaseClient.GenericExecuteSpec bindSpec,
|
||||
R2dbcSpELExpressionEvaluator evaluator) {
|
||||
|
||||
DatabaseClient.GenericExecuteSpec bindSpecToUse = bindSpec;
|
||||
|
||||
for (ParameterBinding binding : expressionQuery.getBindings()) {
|
||||
|
||||
org.springframework.r2dbc.core.Parameter valueForBinding = getParameterValueForBinding(bindableParameters, values,
|
||||
binding);
|
||||
org.springframework.r2dbc.core.Parameter valueForBinding = evaluator.evaluate(binding.getExpression());
|
||||
|
||||
if (valueForBinding.isEmpty()) {
|
||||
bindSpecToUse = bindSpecToUse.bindNull(binding.getParameterName(), valueForBinding.getType());
|
||||
@@ -108,13 +89,11 @@ class ExpressionEvaluatingParameterBinder {
|
||||
}
|
||||
|
||||
private DatabaseClient.GenericExecuteSpec bindParameters(DatabaseClient.GenericExecuteSpec bindSpec,
|
||||
boolean bindableNull, Object[] values,
|
||||
Parameters<?, ?> bindableParameters) {
|
||||
boolean bindableNull, Object[] values, Parameters<?, ?> bindableParameters) {
|
||||
|
||||
DatabaseClient.GenericExecuteSpec bindSpecToUse = bindSpec;
|
||||
int bindingIndex = 0;
|
||||
|
||||
|
||||
for (Parameter bindableParameter : bindableParameters) {
|
||||
|
||||
Object value = values[bindableParameter.getIndex()];
|
||||
@@ -161,37 +140,4 @@ class ExpressionEvaluatingParameterBinder {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value to be used for the given {@link ParameterBinding}.
|
||||
*
|
||||
* @param parameters must not be {@literal null}.
|
||||
* @param binding must not be {@literal null}.
|
||||
* @return the value used for the given {@link ParameterBinding}.
|
||||
*/
|
||||
private org.springframework.r2dbc.core.Parameter getParameterValueForBinding(Parameters<?, ?> parameters,
|
||||
Object[] values,
|
||||
ParameterBinding binding) {
|
||||
return evaluateExpression(binding.getExpression(), parameters, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the given {@code expressionString}.
|
||||
*
|
||||
* @param expressionString must not be {@literal null} or empty.
|
||||
* @param parameters must not be {@literal null}.
|
||||
* @param parameterValues must not be {@literal null}.
|
||||
* @return the value of the {@code expressionString} evaluation.
|
||||
*/
|
||||
private org.springframework.r2dbc.core.Parameter evaluateExpression(String expressionString,
|
||||
Parameters<?, ?> parameters,
|
||||
Object[] parameterValues) {
|
||||
|
||||
EvaluationContext evaluationContext = evaluationContextProvider.getEvaluationContext(parameters, parameterValues);
|
||||
Expression expression = expressionParser.parseExpression(expressionString);
|
||||
|
||||
Object value = expression.getValue(evaluationContext, Object.class);
|
||||
Class<?> valueType = expression.getValueType(evaluationContext);
|
||||
|
||||
return org.springframework.r2dbc.core.Parameter.fromOrEmpty(value, valueType != null ? valueType : Object.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.repository.query.SpelQueryContext;
|
||||
import org.springframework.data.spel.ExpressionDependencies;
|
||||
|
||||
/**
|
||||
* Query using Spring Expression Language to indicate parameter bindings. Queries using SpEL use {@code :#{…}} to
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.r2dbc.repository.query;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -85,21 +87,24 @@ public class PartTreeR2dbcQuery extends AbstractR2dbcQuery {
|
||||
* @see org.springframework.data.r2dbc.repository.query.AbstractR2dbcQuery#createQuery(org.springframework.data.relational.repository.query.RelationalParameterAccessor)
|
||||
*/
|
||||
@Override
|
||||
protected BindableQuery createQuery(RelationalParameterAccessor accessor) {
|
||||
protected Mono<BindableQuery> createQuery(RelationalParameterAccessor accessor) {
|
||||
|
||||
ReturnedType returnedType = processor.withDynamicProjection(accessor).getReturnedType();
|
||||
List<String> projectedProperties = Collections.emptyList();
|
||||
return Mono.fromSupplier(() -> {
|
||||
|
||||
if (returnedType.needsCustomConstruction()) {
|
||||
projectedProperties = new ArrayList<>(returnedType.getInputProperties());
|
||||
}
|
||||
ReturnedType returnedType = processor.withDynamicProjection(accessor).getReturnedType();
|
||||
List<String> projectedProperties = Collections.emptyList();
|
||||
|
||||
RelationalEntityMetadata<?> entityMetadata = getQueryMethod().getEntityInformation();
|
||||
R2dbcQueryCreator queryCreator = new R2dbcQueryCreator(tree, dataAccessStrategy, entityMetadata, accessor,
|
||||
projectedProperties);
|
||||
PreparedOperation<?> preparedQuery = queryCreator.createQuery(getDynamicSort(accessor));
|
||||
if (returnedType.needsCustomConstruction()) {
|
||||
projectedProperties = new ArrayList<>(returnedType.getInputProperties());
|
||||
}
|
||||
|
||||
return new PreparedOperationBindableQuery(preparedQuery);
|
||||
RelationalEntityMetadata<?> entityMetadata = getQueryMethod().getEntityInformation();
|
||||
R2dbcQueryCreator queryCreator = new R2dbcQueryCreator(tree, dataAccessStrategy, entityMetadata, accessor,
|
||||
projectedProperties);
|
||||
PreparedOperation<?> preparedQuery = queryCreator.createQuery(getDynamicSort(accessor));
|
||||
|
||||
return new PreparedOperationBindableQuery(preparedQuery);
|
||||
});
|
||||
}
|
||||
|
||||
private Sort getDynamicSort(RelationalParameterAccessor accessor) {
|
||||
|
||||
@@ -41,7 +41,7 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
interface R2dbcQueryExecution {
|
||||
|
||||
Object execute(FetchSpec<?> query, Class<?> type, SqlIdentifier tableName);
|
||||
Publisher<?> execute(FetchSpec<?> query, Class<?> type, SqlIdentifier tableName);
|
||||
|
||||
/**
|
||||
* An {@link R2dbcQueryExecution} that wraps the results of the given delegate with the given result processing.
|
||||
@@ -60,8 +60,8 @@ interface R2dbcQueryExecution {
|
||||
* @see org.springframework.data.r2dbc.repository.query.R2dbcQueryExecution#execute(org.springframework.data.r2dbc.function.FetchSpec, java.lang.Class, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object execute(FetchSpec<?> query, Class<?> type, SqlIdentifier tableName) {
|
||||
return this.converter.convert(this.delegate.execute(query, type, tableName));
|
||||
public Publisher<?> execute(FetchSpec<?> query, Class<?> type, SqlIdentifier tableName) {
|
||||
return (Publisher<?>) this.converter.convert(this.delegate.execute(query, type, tableName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.repository.query;
|
||||
|
||||
import org.springframework.r2dbc.core.Parameter;
|
||||
|
||||
/**
|
||||
* SPI for components that can evaluate Spring EL expressions and return {@link Parameter}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 1.2
|
||||
*/
|
||||
interface R2dbcSpELExpressionEvaluator {
|
||||
|
||||
/**
|
||||
* Evaluates the given expression.
|
||||
*
|
||||
* @param expression
|
||||
* @return
|
||||
*/
|
||||
Parameter evaluate(String expression);
|
||||
}
|
||||
@@ -15,10 +15,18 @@
|
||||
*/
|
||||
package org.springframework.data.r2dbc.repository.query;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.r2dbc.convert.R2dbcConverter;
|
||||
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.data.repository.query.ReactiveQueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.spel.ExpressionDependencies;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.r2dbc.core.DatabaseClient;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -35,6 +43,9 @@ public class StringBasedR2dbcQuery extends AbstractR2dbcQuery {
|
||||
|
||||
private final ExpressionQuery expressionQuery;
|
||||
private final ExpressionEvaluatingParameterBinder binder;
|
||||
private final ExpressionParser expressionParser;
|
||||
private final ReactiveQueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ExpressionDependencies expressionDependencies;
|
||||
|
||||
/**
|
||||
* Creates a new {@link StringBasedR2dbcQuery} for the given {@link StringBasedR2dbcQuery}, {@link DatabaseClient},
|
||||
@@ -47,8 +58,7 @@ public class StringBasedR2dbcQuery extends AbstractR2dbcQuery {
|
||||
* @param evaluationContextProvider must not be {@literal null}.
|
||||
*/
|
||||
public StringBasedR2dbcQuery(R2dbcQueryMethod queryMethod, DatabaseClient databaseClient, R2dbcConverter converter,
|
||||
SpelExpressionParser expressionParser, QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
|
||||
ExpressionParser expressionParser, ReactiveQueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
this(queryMethod.getRequiredAnnotatedQuery(), queryMethod, databaseClient, converter, expressionParser,
|
||||
evaluationContextProvider);
|
||||
}
|
||||
@@ -64,15 +74,33 @@ public class StringBasedR2dbcQuery extends AbstractR2dbcQuery {
|
||||
* @param evaluationContextProvider must not be {@literal null}.
|
||||
*/
|
||||
public StringBasedR2dbcQuery(String query, R2dbcQueryMethod method, DatabaseClient databaseClient,
|
||||
R2dbcConverter converter, SpelExpressionParser expressionParser,
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
R2dbcConverter converter, ExpressionParser expressionParser,
|
||||
ReactiveQueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
|
||||
super(method, databaseClient, converter);
|
||||
this.expressionParser = expressionParser;
|
||||
this.evaluationContextProvider = evaluationContextProvider;
|
||||
|
||||
Assert.hasText(query, "Query must not be empty");
|
||||
|
||||
this.expressionQuery = ExpressionQuery.create(query);
|
||||
this.binder = new ExpressionEvaluatingParameterBinder(expressionParser, evaluationContextProvider, expressionQuery);
|
||||
this.binder = new ExpressionEvaluatingParameterBinder(expressionQuery);
|
||||
this.expressionDependencies = createExpressionDependencies();
|
||||
}
|
||||
|
||||
private ExpressionDependencies createExpressionDependencies() {
|
||||
|
||||
if (expressionQuery.getBindings().isEmpty()) {
|
||||
return ExpressionDependencies.none();
|
||||
}
|
||||
|
||||
List<ExpressionDependencies> dependencies = new ArrayList<>();
|
||||
|
||||
for (ExpressionQuery.ParameterBinding binding : expressionQuery.getBindings()) {
|
||||
dependencies.add(ExpressionDependencies.discover(expressionParser.parseExpression(binding.getExpression())));
|
||||
}
|
||||
|
||||
return ExpressionDependencies.merged(dependencies);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -89,19 +117,28 @@ public class StringBasedR2dbcQuery extends AbstractR2dbcQuery {
|
||||
* @see org.springframework.data.r2dbc.repository.query.AbstractR2dbcQuery#createQuery(org.springframework.data.relational.repository.query.RelationalParameterAccessor)
|
||||
*/
|
||||
@Override
|
||||
protected BindableQuery createQuery(RelationalParameterAccessor accessor) {
|
||||
protected Mono<BindableQuery> createQuery(RelationalParameterAccessor accessor) {
|
||||
|
||||
return new BindableQuery() {
|
||||
return getSpelEvaluator(accessor).map(evaluator -> new BindableQuery() {
|
||||
|
||||
@Override
|
||||
public DatabaseClient.GenericExecuteSpec bind(DatabaseClient.GenericExecuteSpec bindSpec) {
|
||||
return binder.bind(bindSpec, accessor);
|
||||
return binder.bind(bindSpec, accessor, evaluator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
return expressionQuery.getQuery();
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private Mono<R2dbcSpELExpressionEvaluator> getSpelEvaluator(RelationalParameterAccessor accessor) {
|
||||
|
||||
return evaluationContextProvider
|
||||
.getEvaluationContextLater(getQueryMethod().getParameters(), accessor.getValues(), expressionDependencies)
|
||||
.<R2dbcSpELExpressionEvaluator> map(
|
||||
context -> new DefaultR2dbcSpELExpressionEvaluator(expressionParser, context))
|
||||
.defaultIfEmpty(DefaultR2dbcSpELExpressionEvaluator.unsupported());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.repository.support;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.ParserContext;
|
||||
|
||||
/**
|
||||
* Caching variant of {@link ExpressionParser}. This implementation does not support
|
||||
* {@link #parseExpression(String, ParserContext) parsing with ParseContext}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 1.2
|
||||
*/
|
||||
class CachingExpressionParser implements ExpressionParser {
|
||||
|
||||
private final ExpressionParser delegate;
|
||||
private final Map<String, Expression> cache = new ConcurrentHashMap<>();
|
||||
|
||||
CachingExpressionParser(ExpressionParser delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.expression.ExpressionParser#parseExpression(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Expression parseExpression(String expressionString) throws ParseException {
|
||||
return cache.computeIfAbsent(expressionString, delegate::parseExpression);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.expression.ExpressionParser#parseExpression(java.lang.String, org.springframework.expression.ParserContext)
|
||||
*/
|
||||
@Override
|
||||
public Expression parseExpression(String expressionString, ParserContext context) throws ParseException {
|
||||
throw new UnsupportedOperationException("Parsing using ParserContext is not supported");
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,9 @@ import org.springframework.data.repository.core.support.ReactiveRepositoryFactor
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.r2dbc.core.DatabaseClient;
|
||||
@@ -74,6 +76,7 @@ public class R2dbcRepositoryFactory extends ReactiveRepositoryFactorySupport {
|
||||
this.dataAccessStrategy = dataAccessStrategy;
|
||||
this.converter = dataAccessStrategy.getConverter();
|
||||
this.mappingContext = this.converter.getMappingContext();
|
||||
setEvaluationContextProvider(ReactiveQueryMethodEvaluationContextProvider.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,6 +93,7 @@ public class R2dbcRepositoryFactory extends ReactiveRepositoryFactorySupport {
|
||||
this.dataAccessStrategy = operations.getDataAccessStrategy();
|
||||
this.converter = dataAccessStrategy.getConverter();
|
||||
this.mappingContext = this.converter.getMappingContext();
|
||||
setEvaluationContextProvider(ReactiveQueryMethodEvaluationContextProvider.DEFAULT);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -122,7 +126,8 @@ public class R2dbcRepositoryFactory extends ReactiveRepositoryFactorySupport {
|
||||
@Override
|
||||
protected Optional<QueryLookupStrategy> getQueryLookupStrategy(@Nullable Key key,
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
return Optional.of(new R2dbcQueryLookupStrategy(this.databaseClient, evaluationContextProvider, this.converter,
|
||||
return Optional.of(new R2dbcQueryLookupStrategy(this.databaseClient,
|
||||
(ReactiveQueryMethodEvaluationContextProvider) evaluationContextProvider, this.converter,
|
||||
this.dataAccessStrategy));
|
||||
}
|
||||
|
||||
@@ -151,17 +156,19 @@ public class R2dbcRepositoryFactory extends ReactiveRepositoryFactorySupport {
|
||||
private static class R2dbcQueryLookupStrategy implements QueryLookupStrategy {
|
||||
|
||||
private final DatabaseClient databaseClient;
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final ReactiveQueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
private final R2dbcConverter converter;
|
||||
private final ReactiveDataAccessStrategy dataAccessStrategy;
|
||||
private final ExpressionParser parser = new CachingExpressionParser(EXPRESSION_PARSER);
|
||||
|
||||
R2dbcQueryLookupStrategy(DatabaseClient databaseClient,
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider, R2dbcConverter converter,
|
||||
ReactiveQueryMethodEvaluationContextProvider evaluationContextProvider, R2dbcConverter converter,
|
||||
ReactiveDataAccessStrategy dataAccessStrategy) {
|
||||
this.databaseClient = databaseClient;
|
||||
this.evaluationContextProvider = evaluationContextProvider;
|
||||
this.converter = converter;
|
||||
this.dataAccessStrategy = dataAccessStrategy;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -179,9 +186,9 @@ public class R2dbcRepositoryFactory extends ReactiveRepositoryFactorySupport {
|
||||
if (namedQueries.hasQuery(namedQueryName)) {
|
||||
String namedQuery = namedQueries.getQuery(namedQueryName);
|
||||
return new StringBasedR2dbcQuery(namedQuery, queryMethod, this.databaseClient, this.converter,
|
||||
EXPRESSION_PARSER, this.evaluationContextProvider);
|
||||
parser, this.evaluationContextProvider);
|
||||
} else if (queryMethod.hasAnnotatedQuery()) {
|
||||
return new StringBasedR2dbcQuery(queryMethod, this.databaseClient, this.converter, EXPRESSION_PARSER,
|
||||
return new StringBasedR2dbcQuery(queryMethod, this.databaseClient, this.converter, parser,
|
||||
this.evaluationContextProvider);
|
||||
} else {
|
||||
return new PartTreeR2dbcQuery(queryMethod, this.databaseClient, this.converter, this.dataAccessStrategy);
|
||||
|
||||
@@ -23,6 +23,7 @@ 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.data.repository.query.ReactiveQueryMethodEvaluationContextProvider;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.r2dbc.core.DatabaseClient;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -52,6 +53,7 @@ public class R2dbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
|
||||
*/
|
||||
public R2dbcRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
|
||||
super(repositoryInterface);
|
||||
setEvaluationContextProvider(ReactiveQueryMethodEvaluationContextProvider.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,7 +38,6 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.r2dbc.convert.R2dbcConverter;
|
||||
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;
|
||||
@@ -49,6 +48,7 @@ import org.springframework.data.relational.core.mapping.Table;
|
||||
import org.springframework.data.relational.repository.query.RelationalParametersParameterAccessor;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||
import org.springframework.r2dbc.core.DatabaseClient;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link PartTreeR2dbcQuery}.
|
||||
@@ -97,7 +97,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
R2dbcQueryMethod queryMethod = getQueryMethod("findAllByFirstName", String.class);
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(getAccessor(queryMethod, new Object[] { "John" }));
|
||||
BindableQuery bindableQuery = createQuery(queryMethod, r2dbcQuery, "John");
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".first_name = $1");
|
||||
@@ -109,7 +109,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
R2dbcQueryMethod queryMethod = getQueryMethod("findAllByFirstName", String.class);
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery((getAccessor(queryMethod, new Object[] { null })));
|
||||
BindableQuery bindableQuery = createQuery(queryMethod, r2dbcQuery, new Object[] { null });
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".first_name IS NULL");
|
||||
@@ -121,7 +121,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
R2dbcQueryMethod queryMethod = getQueryMethod("existsByFirstName", String.class);
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
BindableQuery query = r2dbcQuery.createQuery((getAccessor(queryMethod, new Object[] { "John" })));
|
||||
BindableQuery query = createQuery(queryMethod, r2dbcQuery, "John");
|
||||
|
||||
assertThat(query.get())
|
||||
.isEqualTo("SELECT " + TABLE + ".id FROM " + TABLE + " WHERE " + TABLE + ".first_name = $1 LIMIT 1");
|
||||
@@ -133,7 +133,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
R2dbcQueryMethod queryMethod = getQueryMethod("findAllByLastNameAndFirstName", String.class, String.class);
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(getAccessor(queryMethod, new Object[] { "Doe", "John" }));
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, getAccessor(queryMethod, new Object[] { "Doe", "John" }));
|
||||
|
||||
assertThat(bindableQuery.get()).isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE
|
||||
+ ".last_name = $1 AND (" + TABLE + ".first_name = $2)");
|
||||
@@ -145,7 +145,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
R2dbcQueryMethod queryMethod = getQueryMethod("findAllByLastNameOrFirstName", String.class, String.class);
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(getAccessor(queryMethod, new Object[] { "Doe", "John" }));
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, getAccessor(queryMethod, new Object[] { "Doe", "John" }));
|
||||
|
||||
assertThat(bindableQuery.get()).isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE
|
||||
+ ".last_name = $1 OR (" + TABLE + ".first_name = $2)");
|
||||
@@ -160,7 +160,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
Date from = new Date();
|
||||
Date to = new Date();
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { from, to });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".date_of_birth BETWEEN $1 AND $2");
|
||||
@@ -180,7 +180,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { 30 });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".age < $1");
|
||||
@@ -193,7 +193,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { 30 });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".age <= $1");
|
||||
@@ -206,7 +206,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { 30 });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".age > $1");
|
||||
@@ -219,7 +219,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { 30 });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".age >= $1");
|
||||
@@ -232,7 +232,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { new Date() });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".date_of_birth > $1");
|
||||
@@ -244,7 +244,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { new Date() });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".date_of_birth < $1");
|
||||
@@ -257,7 +257,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[0]);
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".age IS NULL");
|
||||
@@ -270,7 +270,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[0]);
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".age IS NOT NULL");
|
||||
@@ -283,7 +283,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "%John%" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".first_name LIKE $1");
|
||||
@@ -296,7 +296,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "%John%" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".first_name NOT LIKE $1");
|
||||
@@ -309,7 +309,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "Jo" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".first_name LIKE $1");
|
||||
@@ -323,7 +323,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "Jo" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
DatabaseClient.GenericExecuteSpec bindSpecMock = mock(DatabaseClient.GenericExecuteSpec.class);
|
||||
bindableQuery.bind(bindSpecMock);
|
||||
|
||||
@@ -337,7 +337,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "hn" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".first_name LIKE $1");
|
||||
@@ -351,7 +351,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "hn" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
DatabaseClient.GenericExecuteSpec bindSpecMock = mock(DatabaseClient.GenericExecuteSpec.class);
|
||||
bindableQuery.bind(bindSpecMock);
|
||||
|
||||
@@ -365,7 +365,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "oh" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".first_name LIKE $1");
|
||||
@@ -379,7 +379,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "oh" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
DatabaseClient.GenericExecuteSpec bindSpecMock = mock(DatabaseClient.GenericExecuteSpec.class);
|
||||
bindableQuery.bind(bindSpecMock);
|
||||
|
||||
@@ -393,7 +393,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "oh" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".first_name NOT LIKE $1");
|
||||
@@ -407,7 +407,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "oh" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
DatabaseClient.GenericExecuteSpec bindSpecMock = mock(DatabaseClient.GenericExecuteSpec.class);
|
||||
bindableQuery.bind(bindSpecMock);
|
||||
|
||||
@@ -421,7 +421,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "oh" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".age = $1 ORDER BY last_name DESC");
|
||||
@@ -433,7 +433,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "oh" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".age = $1 ORDER BY last_name ASC");
|
||||
@@ -445,7 +445,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "Doe" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".last_name != $1");
|
||||
@@ -459,7 +459,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod,
|
||||
new Object[] { Collections.singleton(25) });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".age IN ($1)");
|
||||
@@ -472,7 +472,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod,
|
||||
new Object[] { Collections.singleton(25) });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".age NOT IN ($1)");
|
||||
@@ -485,7 +485,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[0]);
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".active = TRUE");
|
||||
@@ -498,7 +498,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[0]);
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".active = FALSE");
|
||||
@@ -511,7 +511,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "John" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE UPPER(" + TABLE + ".first_name) = UPPER($1)");
|
||||
@@ -525,7 +525,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
dataAccessStrategy);
|
||||
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> r2dbcQuery.createQuery(getAccessor(queryMethod, new Object[] { 1L })));
|
||||
.isThrownBy(() -> createQuery(r2dbcQuery, getAccessor(queryMethod, new Object[] { 1L })));
|
||||
}
|
||||
|
||||
@Test // gh-282
|
||||
@@ -554,7 +554,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
dataAccessStrategy);
|
||||
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> r2dbcQuery.createQuery(getAccessor(queryMethod, new Object[0])));
|
||||
.isThrownBy(() -> createQuery(r2dbcQuery, getAccessor(queryMethod, new Object[0])));
|
||||
}
|
||||
|
||||
@Test // gh-282
|
||||
@@ -565,7 +565,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
dataAccessStrategy);
|
||||
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> r2dbcQuery.createQuery(getAccessor(queryMethod, new Object[0])));
|
||||
.isThrownBy(() -> createQuery(r2dbcQuery, getAccessor(queryMethod, new Object[0])));
|
||||
}
|
||||
|
||||
@Test // gh-282
|
||||
@@ -575,7 +575,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "John" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".first_name = $1 LIMIT 3");
|
||||
@@ -588,7 +588,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "John" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get())
|
||||
.isEqualTo("SELECT " + ALL_FIELDS + " FROM " + TABLE + " WHERE " + TABLE + ".first_name = $1 LIMIT 1");
|
||||
@@ -601,7 +601,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[] { "John" });
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(accessor);
|
||||
BindableQuery bindableQuery = createQuery(r2dbcQuery, accessor);
|
||||
|
||||
assertThat(bindableQuery.get()).isEqualTo("DELETE FROM " + TABLE + " WHERE " + TABLE + ".first_name = $1");
|
||||
}
|
||||
@@ -612,7 +612,7 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
R2dbcQueryMethod queryMethod = getQueryMethod("findDistinctByFirstName", String.class);
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
BindableQuery bindableQuery = r2dbcQuery.createQuery(getAccessor(queryMethod, new Object[] { "John" }));
|
||||
BindableQuery bindableQuery = createQuery(queryMethod, r2dbcQuery, "John");
|
||||
|
||||
assertThat(bindableQuery.get()).isEqualTo("SELECT " + DISTINCT + " " + TABLE + ".first_name, " + TABLE
|
||||
+ ".foo FROM " + TABLE + " WHERE " + TABLE + ".first_name = $1");
|
||||
@@ -624,12 +624,20 @@ public class PartTreeR2dbcQueryUnitTests {
|
||||
R2dbcQueryMethod queryMethod = getQueryMethod("countByFirstName", String.class);
|
||||
PartTreeR2dbcQuery r2dbcQuery = new PartTreeR2dbcQuery(queryMethod, databaseClient, r2dbcConverter,
|
||||
dataAccessStrategy);
|
||||
BindableQuery query = r2dbcQuery.createQuery((getAccessor(queryMethod, new Object[] { "John" })));
|
||||
BindableQuery query = createQuery(queryMethod, r2dbcQuery, "John");
|
||||
|
||||
assertThat(query.get())
|
||||
.isEqualTo("SELECT COUNT(users.id) FROM " + TABLE + " WHERE " + TABLE + ".first_name = $1");
|
||||
}
|
||||
|
||||
private BindableQuery createQuery(R2dbcQueryMethod queryMethod, PartTreeR2dbcQuery r2dbcQuery, Object... parameters) {
|
||||
return createQuery(r2dbcQuery, getAccessor(queryMethod, parameters));
|
||||
}
|
||||
|
||||
private BindableQuery createQuery(PartTreeR2dbcQuery r2dbcQuery, RelationalParametersParameterAccessor accessor) {
|
||||
return r2dbcQuery.createQuery(accessor).block();
|
||||
}
|
||||
|
||||
private R2dbcQueryMethod getQueryMethod(String methodName, Class<?>... parameterTypes) throws Exception {
|
||||
Method method = UserRepository.class.getMethod(methodName, parameterTypes);
|
||||
return new R2dbcQueryMethod(method, new DefaultRepositoryMetadata(UserRepository.class),
|
||||
|
||||
@@ -28,21 +28,20 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.r2dbc.convert.MappingR2dbcConverter;
|
||||
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;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.AbstractRepositoryMetadata;
|
||||
import org.springframework.data.repository.query.ExtensionAwareQueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.r2dbc.core.DatabaseClient;
|
||||
import org.springframework.r2dbc.core.DatabaseClient.GenericExecuteSpec;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
@@ -81,7 +80,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
StringBasedR2dbcQuery query = getQueryMethod("findByLastname", String.class);
|
||||
R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod(), "White");
|
||||
|
||||
BindableQuery stringQuery = query.createQuery(accessor);
|
||||
BindableQuery stringQuery = query.createQuery(accessor).block();
|
||||
|
||||
assertThat(stringQuery.get()).isEqualTo("SELECT * FROM person WHERE lastname = $1");
|
||||
assertThat(stringQuery.bind(bindSpec)).isNotNull();
|
||||
@@ -95,7 +94,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
StringBasedR2dbcQuery query = getQueryMethod("findByLastnamePositional", String.class);
|
||||
R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod(), "White");
|
||||
|
||||
BindableQuery stringQuery = query.createQuery(accessor);
|
||||
BindableQuery stringQuery = query.createQuery(accessor).block();
|
||||
|
||||
assertThat(stringQuery.get()).isEqualTo("SELECT * FROM person WHERE lastname = $1");
|
||||
assertThat(stringQuery.bind(bindSpec)).isNotNull();
|
||||
@@ -109,7 +108,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
StringBasedR2dbcQuery query = getQueryMethod("findByNamedParameter", String.class);
|
||||
R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod(), "White");
|
||||
|
||||
BindableQuery stringQuery = query.createQuery(accessor);
|
||||
BindableQuery stringQuery = query.createQuery(accessor).block();
|
||||
|
||||
assertThat(stringQuery.get()).isEqualTo("SELECT * FROM person WHERE lastname = :lastname");
|
||||
assertThat(stringQuery.bind(bindSpec)).isNotNull();
|
||||
@@ -123,7 +122,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
StringBasedR2dbcQuery query = getQueryMethod("findByNamedBindMarker", String.class);
|
||||
R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod(), "White");
|
||||
|
||||
BindableQuery stringQuery = query.createQuery(accessor);
|
||||
BindableQuery stringQuery = query.createQuery(accessor).block();
|
||||
|
||||
assertThat(stringQuery.get()).isEqualTo("SELECT * FROM person WHERE lastname = @lastname");
|
||||
assertThat(stringQuery.bind(bindSpec)).isNotNull();
|
||||
@@ -137,7 +136,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
StringBasedR2dbcQuery query = getQueryMethod("findNotByNamedBindMarker", String.class);
|
||||
R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod(), "White");
|
||||
|
||||
BindableQuery stringQuery = query.createQuery(accessor);
|
||||
BindableQuery stringQuery = query.createQuery(accessor).block();
|
||||
|
||||
assertThat(stringQuery.get()).isEqualTo("SELECT * FROM person WHERE lastname = :unknown");
|
||||
assertThat(stringQuery.bind(bindSpec)).isNotNull();
|
||||
@@ -151,7 +150,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
StringBasedR2dbcQuery query = getQueryMethod("simpleSpel");
|
||||
R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod());
|
||||
|
||||
BindableQuery stringQuery = query.createQuery(accessor);
|
||||
BindableQuery stringQuery = query.createQuery(accessor).block();
|
||||
|
||||
assertThat(stringQuery.get()).isEqualTo("SELECT * FROM person WHERE lastname = :__synthetic_0__");
|
||||
assertThat(stringQuery.bind(bindSpec)).isNotNull();
|
||||
@@ -165,7 +164,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
StringBasedR2dbcQuery query = getQueryMethod("simpleIndexedSpel", String.class);
|
||||
R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod(), "White");
|
||||
|
||||
BindableQuery stringQuery = query.createQuery(accessor);
|
||||
BindableQuery stringQuery = query.createQuery(accessor).block();
|
||||
|
||||
assertThat(stringQuery.get()).isEqualTo("SELECT * FROM person WHERE lastname = :__synthetic_0__");
|
||||
assertThat(stringQuery.bind(bindSpec)).isNotNull();
|
||||
@@ -180,7 +179,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
StringBasedR2dbcQuery query = getQueryMethod("simplePositionalSpel", String.class, String.class);
|
||||
R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod(), "White", "Walter");
|
||||
|
||||
BindableQuery stringQuery = query.createQuery(accessor);
|
||||
BindableQuery stringQuery = query.createQuery(accessor).block();
|
||||
|
||||
assertThat(stringQuery.get())
|
||||
.isEqualTo("SELECT * FROM person WHERE lastname = :__synthetic_0__ and firstname = :firstname");
|
||||
@@ -197,7 +196,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
StringBasedR2dbcQuery query = getQueryMethod("simpleNamedSpel", String.class, String.class);
|
||||
R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod(), "White", "Walter");
|
||||
|
||||
BindableQuery stringQuery = query.createQuery(accessor);
|
||||
BindableQuery stringQuery = query.createQuery(accessor).block();
|
||||
|
||||
assertThat(stringQuery.get())
|
||||
.isEqualTo("SELECT * FROM person WHERE lastname = :__synthetic_0__ and firstname = :firstname");
|
||||
@@ -214,7 +213,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
StringBasedR2dbcQuery query = getQueryMethod("queryWithSpelObject", Person.class);
|
||||
R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod(), new Person("Walter"));
|
||||
|
||||
BindableQuery stringQuery = query.createQuery(accessor);
|
||||
BindableQuery stringQuery = query.createQuery(accessor).block();
|
||||
|
||||
assertThat(stringQuery.get()).isEqualTo("SELECT * FROM person WHERE lastname = :__synthetic_0__");
|
||||
assertThat(stringQuery.bind(bindSpec)).isNotNull();
|
||||
@@ -229,7 +228,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
StringBasedR2dbcQuery query = getQueryMethod("queryWithUnusedParameter", String.class, Sort.class);
|
||||
R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod(), "Walter", null);
|
||||
|
||||
BindableQuery stringQuery = query.createQuery(accessor);
|
||||
BindableQuery stringQuery = query.createQuery(accessor).block();
|
||||
|
||||
assertThat(stringQuery.get()).isEqualTo("SELECT * FROM person WHERE lastname = :name");
|
||||
assertThat(stringQuery.bind(bindSpec)).isNotNull();
|
||||
@@ -245,7 +244,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
R2dbcQueryMethod queryMethod = new R2dbcQueryMethod(method, metadata, factory, converter.getMappingContext());
|
||||
|
||||
return new StringBasedR2dbcQuery(queryMethod, databaseClient, converter, PARSER,
|
||||
ExtensionAwareQueryMethodEvaluationContextProvider.DEFAULT);
|
||||
ReactiveQueryMethodEvaluationContextProvider.DEFAULT);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
||||
Reference in New Issue
Block a user