Skip to content

Commit cd3d2cc

Browse files
committed
wip: handle named parameters
1 parent 0a0fc75 commit cd3d2cc

13 files changed

+120
-20
lines changed

src/main/java/org/springframework/data/elasticsearch/annotations/Query.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,11 @@
5252
* @since 4.2
5353
*/
5454
boolean count() default false;
55+
56+
/**
57+
* Returns whether the query defined should be built using named parameters instead of positional parameters.
58+
*
59+
* @return false by default
60+
*/
61+
boolean useNamedParameters() default false;
5562
}

src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ private Object execute(ElasticsearchParameterAccessor parameterAccessor) {
8383
ResultProcessor processor = queryMethod.getResultProcessor().withDynamicProjection(parameterAccessor);
8484

8585
Query query = createQuery(
86-
new ConvertingParameterAccessor(elasticsearchOperations.getElasticsearchConverter(), parameterAccessor));
86+
new ConvertingParameterAccessor(elasticsearchOperations.getElasticsearchConverter(), parameterAccessor),
87+
queryMethod.hasNamedParameters());
8788

8889
if (queryMethod.hasAnnotatedHighlight()) {
8990
query.setHighlightQuery(queryMethod.getAnnotatedHighlightQuery());
@@ -108,9 +109,10 @@ private ReactiveElasticsearchQueryExecution getExecution(ElasticsearchParameterA
108109
* Creates a {@link Query} instance using the given {@link ParameterAccessor}
109110
*
110111
* @param accessor must not be {@literal null}.
112+
* @param useNamedParameters whether to use named parameters or not
111113
* @return
112114
*/
113-
protected abstract Query createQuery(ElasticsearchParameterAccessor accessor);
115+
protected abstract Query createQuery(ElasticsearchParameterAccessor accessor, boolean useNamedParameters);
114116

115117
private ReactiveElasticsearchQueryExecution getExecutionToWrap(ElasticsearchParameterAccessor accessor,
116118
ReactiveElasticsearchOperations operations) {

src/main/java/org/springframework/data/elasticsearch/repository/query/ConvertingParameterAccessor.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
package org.springframework.data.elasticsearch.repository.query;
1717

1818
import java.util.Iterator;
19-
import java.util.Optional;
2019

2120
import org.springframework.data.domain.Pageable;
2221
import org.springframework.data.domain.Sort;
2322
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
23+
import org.springframework.data.repository.query.Parameter;
24+
import org.springframework.data.repository.query.Parameters;
2425
import org.springframework.lang.Nullable;
2526

2627
/**
@@ -39,6 +40,16 @@ public ConvertingParameterAccessor(ElasticsearchConverter converter, Elasticsear
3940
this.delegate = delegate;
4041
}
4142

43+
@Override
44+
public Parameters<?, ?> getParameters() {
45+
return delegate.getParameters();
46+
}
47+
48+
@Override
49+
public <T> T getValue(Parameter parameter) {
50+
return delegate.getValue(parameter);
51+
}
52+
4253
@Override
4354
public Object[] getValues() {
4455
return delegate.getValues();

src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameterAccessor.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,22 @@
1515
*/
1616
package org.springframework.data.elasticsearch.repository.query;
1717

18+
import org.springframework.data.repository.query.Parameter;
1819
import org.springframework.data.repository.query.ParameterAccessor;
20+
import org.springframework.data.repository.query.Parameters;
21+
import org.springframework.lang.Nullable;
1922

2023
/**
2124
* @author Christoph Strobl
2225
* @since 3.2
2326
*/
2427
public interface ElasticsearchParameterAccessor extends ParameterAccessor {
2528

29+
Parameters<?, ?> getParameters();
30+
31+
@Nullable
32+
<T> T getValue(Parameter parameter);
33+
2634
/**
2735
* Returns the raw parameter values of the underlying query method.
2836
*

src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParametersParameterAccessor.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
import java.util.Arrays;
1919
import java.util.List;
2020

21+
import org.springframework.data.repository.query.Parameter;
2122
import org.springframework.data.repository.query.ParametersParameterAccessor;
23+
import org.springframework.lang.Nullable;
2224

2325
/**
2426
* @author Christoph Strobl
@@ -41,6 +43,12 @@ class ElasticsearchParametersParameterAccessor extends ParametersParameterAccess
4143
this.values = Arrays.asList(values);
4244
}
4345

46+
@Nullable
47+
@Override
48+
public <T> T getValue(Parameter parameter) {
49+
return super.getValue(parameter.getIndex());
50+
}
51+
4452
@Override
4553
public Object[] getValues() {
4654
return values.toArray();

src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,4 +247,10 @@ public boolean hasCountQueryAnnotation() {
247247
return queryAnnotation != null && queryAnnotation.count();
248248
}
249249

250+
/**
251+
* @return {@literal true} if the method is annotated with {@link Query}(useNamedParameters = true)
252+
*/
253+
public boolean hasNamedParameters() {
254+
return queryAnnotation != null && queryAnnotation.useNamedParameters();
255+
}
250256
}

src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
2424
import org.springframework.data.elasticsearch.core.query.StringQuery;
2525
import org.springframework.data.elasticsearch.repository.support.StringQueryUtil;
26-
import org.springframework.data.repository.query.ParametersParameterAccessor;
2726
import org.springframework.data.util.StreamUtils;
2827
import org.springframework.util.Assert;
2928

@@ -56,9 +55,10 @@ public boolean isCountQuery() {
5655
public Object execute(Object[] parameters) {
5756

5857
Class<?> clazz = queryMethod.getResultProcessor().getReturnedType().getDomainType();
59-
ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters);
58+
ElasticsearchParametersParameterAccessor accessor = new ElasticsearchParametersParameterAccessor(queryMethod,
59+
parameters);
6060

61-
StringQuery stringQuery = createQuery(accessor);
61+
StringQuery stringQuery = createQuery(accessor, queryMethod.hasNamedParameters());
6262

6363
Assert.notNull(stringQuery, "unsupported query");
6464

@@ -97,9 +97,10 @@ public Object execute(Object[] parameters) {
9797
: result;
9898
}
9999

100-
protected StringQuery createQuery(ParametersParameterAccessor parameterAccessor) {
101-
String queryString = new StringQueryUtil(elasticsearchOperations.getElasticsearchConverter().getConversionService())
102-
.replacePlaceholders(this.query, parameterAccessor);
100+
protected StringQuery createQuery(ElasticsearchParametersParameterAccessor parameterAccessor,
101+
boolean useNamedParameters) {
102+
String queryString = new StringQueryUtil(elasticsearchOperations.getElasticsearchConverter().getConversionService(),
103+
useNamedParameters).replacePlaceholders(this.query, parameterAccessor);
103104
return new StringQuery(queryString);
104105
}
105106

src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQuery.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ public ReactiveElasticsearchStringQuery(String query, ReactiveElasticsearchQuery
4646
}
4747

4848
@Override
49-
protected StringQuery createQuery(ElasticsearchParameterAccessor parameterAccessor) {
49+
protected StringQuery createQuery(ElasticsearchParameterAccessor parameterAccessor, boolean useNamedParameters) {
5050
String queryString = new StringQueryUtil(
51-
getElasticsearchOperations().getElasticsearchConverter().getConversionService()).replacePlaceholders(this.query,
52-
parameterAccessor);
51+
getElasticsearchOperations().getElasticsearchConverter().getConversionService(), useNamedParameters)
52+
.replacePlaceholders(this.query, parameterAccessor);
5353
return new StringQuery(queryString);
5454
}
5555

src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public ReactivePartTreeElasticsearchQuery(ReactiveElasticsearchQueryMethod query
4040
}
4141

4242
@Override
43-
protected Query createQuery(ElasticsearchParameterAccessor accessor) {
43+
protected Query createQuery(ElasticsearchParameterAccessor accessor, boolean useNamedParameters) {
4444
CriteriaQuery query = new ElasticsearchQueryCreator(tree, accessor, getMappingContext()).createQuery();
4545

4646
if (tree.isLimiting()) {

src/main/java/org/springframework/data/elasticsearch/repository/support/StringQueryUtil.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.stream.Collectors;
2222

2323
import org.springframework.core.convert.ConversionService;
24+
import org.springframework.data.elasticsearch.repository.query.ElasticsearchParameterAccessor;
2425
import org.springframework.data.repository.query.ParameterAccessor;
2526
import org.springframework.util.NumberUtils;
2627

@@ -34,11 +35,17 @@ final public class StringQueryUtil {
3435

3536
private final ConversionService conversionService;
3637

37-
public StringQueryUtil(ConversionService conversionService) {
38+
private final boolean useNamedParameters;
39+
40+
public StringQueryUtil(ConversionService conversionService, boolean useNamedParameters) {
3841
this.conversionService = conversionService;
42+
this.useNamedParameters = useNamedParameters;
3943
}
4044

41-
public String replacePlaceholders(String input, ParameterAccessor accessor) {
45+
public String replacePlaceholders(String input, ElasticsearchParameterAccessor accessor) {
46+
if (useNamedParameters) {
47+
return replaceNamedParameters(input, accessor);
48+
}
4249

4350
Matcher matcher = PARAMETER_PLACEHOLDER.matcher(input);
4451
String result = input;
@@ -51,6 +58,14 @@ public String replacePlaceholders(String input, ParameterAccessor accessor) {
5158
return result;
5259
}
5360

61+
private String replaceNamedParameters(String input, ElasticsearchParameterAccessor accessor) {
62+
63+
final String[] result = { input };
64+
accessor.getParameters().forEach(parameter -> result[0] = result[0]
65+
.replaceAll(Pattern.quote(parameter.getPlaceholder()), getParameterWithIndex(accessor, parameter.getIndex())));
66+
return result[0];
67+
}
68+
5469
private String getParameterWithIndex(ParameterAccessor accessor, int index) {
5570

5671
Object parameter = accessor.getBindableValue(index);

0 commit comments

Comments
 (0)