committed by
Michael Simons
parent
190bd4bbbc
commit
5e06bdc82f
@@ -26,6 +26,7 @@ import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.data.util.ReactiveWrappers;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -56,7 +57,7 @@ final class ReactiveNeo4jQueryMethod extends Neo4jQueryMethod {
|
||||
ReactiveNeo4jQueryMethod(Method method, RepositoryMetadata metadata, ProjectionFactory factory) {
|
||||
super(method, metadata, factory, ClassUtils.hasMethod(ReactiveCypherdslStatementExecutor.class, method));
|
||||
|
||||
if (org.springframework.data.repository.util.ClassUtils.hasParameterOfType(method, Pageable.class)) {
|
||||
if (ReflectionUtils.hasParameterOfType(method, Pageable.class)) {
|
||||
|
||||
TypeInformation<?> returnType = TypeInformation.fromReturnTypeOf(method);
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.repository.query.Parameter;
|
||||
import org.springframework.data.repository.query.Parameters;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.SpelQueryContext;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.data.repository.query.ValueExpressionQueryRewriter;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -58,12 +57,6 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
final class ReactiveStringBasedNeo4jQuery extends AbstractReactiveNeo4jQuery {
|
||||
|
||||
/**
|
||||
* Used for extracting SpEL expressions inside Cypher query templates.
|
||||
*/
|
||||
static final SpelQueryContext SPEL_QUERY_CONTEXT = SpelQueryContext
|
||||
.of(ReactiveStringBasedNeo4jQuery::parameterNameSource, ReactiveStringBasedNeo4jQuery::replacementSource);
|
||||
|
||||
private final ValueExpressionQueryRewriter.EvaluatingValueExpressionQueryRewriter queryRewriter;
|
||||
|
||||
private final ValueExpressionQueryRewriter.QueryExpressionEvaluator parsedQuery;
|
||||
@@ -79,8 +72,8 @@ final class ReactiveStringBasedNeo4jQuery extends AbstractReactiveNeo4jQuery {
|
||||
* @return A new instance of a String based Neo4j query.
|
||||
*/
|
||||
static ReactiveStringBasedNeo4jQuery create(ReactiveNeo4jOperations neo4jOperations,
|
||||
Neo4jMappingContext mappingContext, ValueExpressionDelegate delegate,
|
||||
Neo4jQueryMethod queryMethod, ProjectionFactory factory) {
|
||||
Neo4jMappingContext mappingContext, ValueExpressionDelegate delegate, Neo4jQueryMethod queryMethod,
|
||||
ProjectionFactory factory) {
|
||||
|
||||
Query queryAnnotation = queryMethod.getQueryAnnotation()
|
||||
.orElseThrow(() -> new MappingException("Expected @Query annotation on the query method"));
|
||||
@@ -88,8 +81,8 @@ final class ReactiveStringBasedNeo4jQuery extends AbstractReactiveNeo4jQuery {
|
||||
String cypherTemplate = Optional.ofNullable(queryAnnotation.value()).filter(StringUtils::hasText)
|
||||
.orElseThrow(() -> new MappingException("Expected @Query annotation to have a value, but it did not"));
|
||||
|
||||
return new ReactiveStringBasedNeo4jQuery(neo4jOperations, mappingContext, delegate, queryMethod,
|
||||
cypherTemplate, Neo4jQueryType.fromDefinition(queryAnnotation), factory);
|
||||
return new ReactiveStringBasedNeo4jQuery(neo4jOperations, mappingContext, delegate, queryMethod, cypherTemplate,
|
||||
Neo4jQueryType.fromDefinition(queryAnnotation), factory);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,45 +96,44 @@ final class ReactiveStringBasedNeo4jQuery extends AbstractReactiveNeo4jQuery {
|
||||
* @return A new instance of a String based Neo4j query.
|
||||
*/
|
||||
static ReactiveStringBasedNeo4jQuery create(ReactiveNeo4jOperations neo4jOperations,
|
||||
Neo4jMappingContext mappingContext, ValueExpressionDelegate delegate,
|
||||
Neo4jQueryMethod queryMethod, String cypherTemplate, ProjectionFactory factory) {
|
||||
Neo4jMappingContext mappingContext, ValueExpressionDelegate delegate, Neo4jQueryMethod queryMethod,
|
||||
String cypherTemplate, ProjectionFactory factory) {
|
||||
|
||||
Assert.hasText(cypherTemplate, "Cannot create String based Neo4j query without a cypher template");
|
||||
|
||||
return new ReactiveStringBasedNeo4jQuery(neo4jOperations, mappingContext, delegate, queryMethod,
|
||||
cypherTemplate, Neo4jQueryType.DEFAULT, factory);
|
||||
return new ReactiveStringBasedNeo4jQuery(neo4jOperations, mappingContext, delegate, queryMethod, cypherTemplate,
|
||||
Neo4jQueryType.DEFAULT, factory);
|
||||
}
|
||||
|
||||
private ReactiveStringBasedNeo4jQuery(ReactiveNeo4jOperations neo4jOperations, Neo4jMappingContext mappingContext,
|
||||
ValueExpressionDelegate delegate, Neo4jQueryMethod queryMethod,
|
||||
String cypherTemplate, Neo4jQueryType queryType, ProjectionFactory factory) {
|
||||
ValueExpressionDelegate delegate, Neo4jQueryMethod queryMethod, String cypherTemplate, Neo4jQueryType queryType,
|
||||
ProjectionFactory factory) {
|
||||
|
||||
super(neo4jOperations, mappingContext, queryMethod, queryType, factory);
|
||||
|
||||
this.queryRewriter = ValueExpressionQueryRewriter.of(delegate,
|
||||
StringBasedNeo4jQuery::parameterNameSource, StringBasedNeo4jQuery::replacementSource);
|
||||
this.queryRewriter = createQueryRewriter(delegate);
|
||||
this.parsedQuery = queryRewriter.parse(cypherTemplate, queryMethod.getParameters());
|
||||
}
|
||||
|
||||
static ValueExpressionQueryRewriter.EvaluatingValueExpressionQueryRewriter createQueryRewriter(ValueExpressionDelegate delegate) {
|
||||
return ValueExpressionQueryRewriter.of(delegate, StringBasedNeo4jQuery::parameterNameSource,
|
||||
StringBasedNeo4jQuery::replacementSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T extends Object> PreparedQuery<T> prepareQuery(Class<T> returnedType, Collection<PropertyFilter.ProjectedPath> includedProperties,
|
||||
Neo4jParameterAccessor parameterAccessor, @Nullable Neo4jQueryType queryType,
|
||||
@Nullable Supplier<BiFunction<TypeSystem, MapAccessor, ?>> mappingFunction, @Nullable UnaryOperator<Integer> limitModifier) {
|
||||
protected <T extends Object> PreparedQuery<T> prepareQuery(Class<T> returnedType,
|
||||
Collection<PropertyFilter.ProjectedPath> includedProperties, Neo4jParameterAccessor parameterAccessor,
|
||||
@Nullable Neo4jQueryType queryType, @Nullable Supplier<BiFunction<TypeSystem, MapAccessor, ?>> mappingFunction,
|
||||
@Nullable UnaryOperator<Integer> limitModifier) {
|
||||
|
||||
Map<String, Object> boundParameters = bindParameters(parameterAccessor);
|
||||
QueryContext queryContext = new QueryContext(
|
||||
queryMethod.getRepositoryName() + "." + queryMethod.getName(),
|
||||
parsedQuery.getQueryString(),
|
||||
boundParameters
|
||||
);
|
||||
QueryContext queryContext = new QueryContext(queryMethod.getRepositoryName() + "." + queryMethod.getName(),
|
||||
parsedQuery.getQueryString(), boundParameters);
|
||||
|
||||
logWarningsIfNecessary(queryContext, parameterAccessor);
|
||||
|
||||
return PreparedQuery.queryFor(returnedType)
|
||||
.withCypherQuery(queryContext.query)
|
||||
.withParameters(boundParameters)
|
||||
.usingMappingFunction(mappingFunction)
|
||||
.build();
|
||||
return PreparedQuery.queryFor(returnedType).withCypherQuery(queryContext.query).withParameters(boundParameters)
|
||||
.usingMappingFunction(mappingFunction).build();
|
||||
}
|
||||
|
||||
Map<String, Object> bindParameters(Neo4jParameterAccessor parameterAccessor) {
|
||||
|
||||
@@ -39,7 +39,6 @@ import org.springframework.data.repository.core.support.RepositoryFactorySupport
|
||||
import org.springframework.data.repository.core.support.RepositoryFragment;
|
||||
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.ValueExpressionDelegate;
|
||||
|
||||
/**
|
||||
@@ -61,8 +60,6 @@ final class Neo4jRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
this.neo4jOperations = neo4jOperations;
|
||||
this.mappingContext = mappingContext;
|
||||
|
||||
setEvaluationContextProvider(QueryMethodEvaluationContextProvider.DEFAULT);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -54,8 +54,8 @@ import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.data.repository.query.QueryMethodValueEvaluationContextAccessor;
|
||||
import org.springframework.data.repository.query.SpelQueryContext;
|
||||
import org.springframework.data.repository.query.ValueExpressionDelegate;
|
||||
import org.springframework.data.repository.query.ValueExpressionQueryRewriter;
|
||||
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
@@ -95,24 +95,24 @@ final class ReactiveRepositoryQueryTest {
|
||||
@Test
|
||||
void spelQueryContextShouldBeConfiguredCorrectly() {
|
||||
|
||||
SpelQueryContext spelQueryContext = ReactiveStringBasedNeo4jQuery.SPEL_QUERY_CONTEXT;
|
||||
ValueExpressionQueryRewriter rewriter = ReactiveStringBasedNeo4jQuery.createQueryRewriter(ValueExpressionDelegate.create());
|
||||
|
||||
String template;
|
||||
String query;
|
||||
SpelQueryContext.SpelExtractor spelExtractor;
|
||||
ValueExpressionQueryRewriter.ParsedQuery parsedQuery;
|
||||
|
||||
template = "MATCH (user:User) WHERE user.name = :#{#searchUser.name} and user.middleName = ?#{#searchUser.middleName} RETURN user";
|
||||
|
||||
spelExtractor = spelQueryContext.parse(template);
|
||||
query = spelExtractor.getQueryString();
|
||||
parsedQuery = rewriter.parse(template);
|
||||
query = parsedQuery.getQueryString();
|
||||
|
||||
assertThat(query)
|
||||
.isEqualTo(
|
||||
"MATCH (user:User) WHERE user.name = $__SpEL__0 and user.middleName = $__SpEL__1 RETURN user");
|
||||
|
||||
template = "MATCH (user:User) WHERE user.name=?#{[0]} and user.name=:#{[0]} RETURN user";
|
||||
spelExtractor = spelQueryContext.parse(template);
|
||||
query = spelExtractor.getQueryString();
|
||||
parsedQuery = rewriter.parse(template);
|
||||
query = parsedQuery.getQueryString();
|
||||
|
||||
assertThat(query)
|
||||
.isEqualTo("MATCH (user:User) WHERE user.name=$__SpEL__0 and user.name=$__SpEL__1 RETURN user");
|
||||
|
||||
Reference in New Issue
Block a user