Skip to content

Commit 51d349b

Browse files
committed
DATACOUCH-1066 - N1qlExpression as QueryCriteria key.
This is a merge of mmonti's changeset into master. The changeset was made on top of 4.1.x instead of master so it has a little catching up to do. Merge branch 'gh-1066-n1qlexpression-as-querycriteria-key' of github.com:mmonti/spring-data-couchbase into datacouch_1066_1072_mmonti_n1ql_query_creator_expression Original pull request #1076
2 parents 6ab350d + 66d18f0 commit 51d349b

20 files changed

+199
-474
lines changed

src/main/java/org/springframework/data/couchbase/core/ReactiveReplaceByIdOperationSupport.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Collection;
2323

2424
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
25+
import org.springframework.data.couchbase.core.mapping.Document;
2526
import org.springframework.util.Assert;
2627

2728
import com.couchbase.client.core.msg.kv.DurabilityLevel;

src/main/java/org/springframework/data/couchbase/core/query/QueryCriteria.java

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors
2+
* Copyright 2012-2021 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,13 +27,16 @@
2727
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
2828
import org.springframework.lang.Nullable;
2929

30+
import static org.springframework.data.couchbase.core.query.N1QLExpression.*;
31+
3032
/**
3133
* @author Michael Nitschinger
3234
* @author Michael Reiche
35+
* @author Mauro Monti
3336
*/
3437
public class QueryCriteria implements QueryCriteriaDefinition {
3538

36-
private final String key;
39+
private final N1QLExpression key;
3740
/**
3841
* Holds the chain itself, the current operator being always the last one.
3942
*/
@@ -46,15 +49,15 @@ public class QueryCriteria implements QueryCriteriaDefinition {
4649
private Object[] value;
4750
private String format;
4851

49-
QueryCriteria(List<QueryCriteria> chain, String key, Object[] value, ChainOperator chainOperator) {
52+
QueryCriteria(List<QueryCriteria> chain, N1QLExpression key, Object[] value, ChainOperator chainOperator) {
5053
this(chain, key, value, chainOperator, null, null);
5154
}
5255

53-
QueryCriteria(List<QueryCriteria> chain, String key, Object value, ChainOperator chainOperator) {
56+
QueryCriteria(List<QueryCriteria> chain, N1QLExpression key, Object value, ChainOperator chainOperator) {
5457
this(chain, key, new Object[] { value }, chainOperator, null, null);
5558
}
5659

57-
QueryCriteria(List<QueryCriteria> chain, String key, Object[] value, ChainOperator chainOperator, String operator,
60+
QueryCriteria(List<QueryCriteria> chain, N1QLExpression key, Object[] value, ChainOperator chainOperator, String operator,
5861
String format) {
5962
this.criteriaChain = chain;
6063
criteriaChain.add(this);
@@ -70,9 +73,16 @@ Object[] getValue() {
7073
}
7174

7275
/**
73-
* Static factory method to create a Criteria using the provided key.
76+
* Static factory method to create a Criteria using the provided String key.
7477
*/
7578
public static QueryCriteria where(String key) {
79+
return where(x(key));
80+
}
81+
82+
/**
83+
* Static factory method to create a Criteria using the provided N1QLExpression key.
84+
*/
85+
public static QueryCriteria where(N1QLExpression key) {
7686
return new QueryCriteria(new ArrayList<>(), key, null, null);
7787
}
7888

@@ -83,21 +93,29 @@ private static QueryCriteria wrap(QueryCriteria criteria) {
8393
}
8494

8595
public QueryCriteria and(String key) {
96+
return and(x(key));
97+
}
98+
99+
public QueryCriteria and(N1QLExpression key) {
86100
return new QueryCriteria(this.criteriaChain, key, null, ChainOperator.AND);
87101
}
88102

89103
public QueryCriteria and(QueryCriteria criteria) {
90104
return new QueryCriteria(this.criteriaChain, null, criteria, ChainOperator.AND);
91105
}
92106

93-
public QueryCriteria or(QueryCriteria criteria) {
94-
return new QueryCriteria(this.criteriaChain, null, criteria, ChainOperator.OR);
107+
public QueryCriteria or(String key) {
108+
return or(x(key));
95109
}
96110

97-
public QueryCriteria or(String key) {
111+
public QueryCriteria or(N1QLExpression key) {
98112
return new QueryCriteria(this.criteriaChain, key, null, ChainOperator.OR);
99113
}
100114

115+
public QueryCriteria or(QueryCriteria criteria) {
116+
return new QueryCriteria(this.criteriaChain, null, criteria, ChainOperator.OR);
117+
}
118+
101119
public QueryCriteria eq(@Nullable Object o) {
102120
return is(o);
103121
}
@@ -343,7 +361,7 @@ public String export() { // used only by tests
343361
*/
344362
private StringBuilder exportSingle(StringBuilder sb, int[] paramIndexPtr, JsonValue parameters,
345363
CouchbaseConverter converter) {
346-
String fieldName = maybeBackTic(key);
364+
String fieldName = key == null ? null : key.toString(); // maybeBackTic(key);
347365
int valueLen = value == null ? 0 : value.length;
348366
Object[] v = new Object[valueLen + 2];
349367
v[0] = fieldName;
@@ -377,7 +395,7 @@ private StringBuilder exportSingle(StringBuilder sb, int[] paramIndexPtr, JsonVa
377395
* @param parameters - parameters of the query. If operands are parameterized, their values are added to parameters
378396
* @return string containing part of N1QL query
379397
*/
380-
private String maybeWrapValue(String key, Object value, int[] paramIndexPtr, JsonValue parameters,
398+
private String maybeWrapValue(N1QLExpression key, Object value, int[] paramIndexPtr, JsonValue parameters,
381399
CouchbaseConverter converter) {
382400
if (paramIndexPtr != null) {
383401
if (paramIndexPtr[0] >= 0) {
@@ -397,10 +415,10 @@ private String maybeWrapValue(String key, Object value, int[] paramIndexPtr, Jso
397415
JsonObject params = (JsonObject) parameters;
398416
// from StringBasedN1qlQueryParser.getNamedPlaceholderValues()
399417
try {
400-
params.put(key, convert(converter, value));
418+
params.put(key.toString(), convert(converter, value));
401419
} catch (InvalidArgumentException iae) {
402420
if (value instanceof Object[]) {
403-
params.put(key, JsonArray.from((Object[]) value));
421+
params.put(key.toString(), JsonArray.from((Object[]) value));
404422
} else {
405423
throw iae;
406424
}
@@ -416,7 +434,7 @@ private String maybeWrapValue(String key, Object value, int[] paramIndexPtr, Jso
416434
} else if (value == null) {
417435
return "null";
418436
} else if (value instanceof Object[]) { // convert array into sequence of comma-separated values
419-
StringBuffer l = new StringBuffer();
437+
StringBuilder l = new StringBuilder();
420438
l.append("[");
421439
Object[] array = (Object[]) value;
422440
for (int i = 0; i < array.length; i++) {

src/main/java/org/springframework/data/couchbase/repository/query/CouchbaseRepositoryQuery.java

Lines changed: 0 additions & 57 deletions
This file was deleted.

src/main/java/org/springframework/data/couchbase/repository/query/N1qlCountQueryCreator.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ public Pageable first() {
118118
return delegate.first();
119119
}
120120

121+
@Override
122+
public Pageable withPage(int i) {
123+
return new CountPageable(delegate.withPage(i));
124+
}
125+
121126
public boolean hasPrevious() {
122127
return delegate.hasPrevious();
123128
}

src/main/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreator.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors
2+
* Copyright 2012-2021 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,12 +16,15 @@
1616
package org.springframework.data.couchbase.repository.query;
1717

1818
import static org.springframework.data.couchbase.core.query.QueryCriteria.where;
19+
import static org.springframework.data.couchbase.core.query.N1QLExpression.*;
20+
import static org.springframework.data.couchbase.core.query.QueryCriteria.*;
1921

2022
import java.util.Iterator;
2123

2224
import org.springframework.core.convert.converter.Converter;
2325
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
2426
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
27+
import org.springframework.data.couchbase.core.query.N1QLExpression;
2528
import org.springframework.data.couchbase.core.query.Query;
2629
import org.springframework.data.couchbase.core.query.QueryCriteria;
2730
import org.springframework.data.domain.Sort;
@@ -36,32 +39,38 @@
3639
/**
3740
* @author Michael Nitschinger
3841
* @author Michael Reiche
42+
* @author Mauro Monti
3943
*/
4044
public class N1qlQueryCreator extends AbstractQueryCreator<Query, QueryCriteria> {
4145

46+
private static final String META_ID_PROPERTY = "id";
47+
private static final String META_CAS_PROPERTY = "cas";
48+
4249
private final ParameterAccessor accessor;
4350
private final MappingContext<?, CouchbasePersistentProperty> context;
4451
private final QueryMethod queryMethod;
4552
private final CouchbaseConverter converter;
53+
private final String bucketName;
4654

47-
public N1qlQueryCreator(final PartTree tree, final ParameterAccessor accessor, QueryMethod queryMethod,
48-
CouchbaseConverter converter) {
55+
public N1qlQueryCreator(final PartTree tree, final ParameterAccessor accessor, final QueryMethod queryMethod,
56+
final CouchbaseConverter converter, final String bucketName) {
4957
super(tree, accessor);
5058
this.accessor = accessor;
5159
this.context = converter.getMappingContext();
5260
this.queryMethod = queryMethod;
5361
this.converter = converter;
62+
this.bucketName = bucketName;
5463
}
5564

5665
@Override
5766
protected QueryCriteria create(final Part part, final Iterator<Object> iterator) {
5867
PersistentPropertyPath<CouchbasePersistentProperty> path = context.getPersistentPropertyPath(part.getProperty());
5968
CouchbasePersistentProperty property = path.getLeafProperty();
60-
return from(part, property, where(path.toDotPath(cvtr)), iterator);
69+
return from(part, property, where(addMetaIfRequired(path, property)), iterator);
6170
}
6271

6372
static Converter<? super CouchbasePersistentProperty, String> cvtr = (
64-
source) -> new StringBuilder(source.getName().length() + 2).append('`').append(source.getName()).append('`')
73+
source) -> new StringBuilder(source.getFieldName().length() + 2).append('`').append(source.getFieldName()).append('`')
6574
.toString();
6675

6776
@Override
@@ -73,7 +82,7 @@ protected QueryCriteria and(final Part part, final QueryCriteria base, final Ite
7382
PersistentPropertyPath<CouchbasePersistentProperty> path = context.getPersistentPropertyPath(part.getProperty());
7483
CouchbasePersistentProperty property = path.getLeafProperty();
7584

76-
return from(part, property, base.and(path.toDotPath()), iterator);
85+
return from(part, property, base.and(addMetaIfRequired(path, property)), iterator);
7786
}
7887

7988
@Override
@@ -149,4 +158,15 @@ private QueryCriteria from(final Part part, final CouchbasePersistentProperty pr
149158
}
150159
}
151160

161+
private N1QLExpression addMetaIfRequired(final PersistentPropertyPath<CouchbasePersistentProperty> persistentPropertyPath,
162+
final CouchbasePersistentProperty property) {
163+
if (property.isIdProperty()) {
164+
return path(meta(i(bucketName)), i(META_ID_PROPERTY));
165+
}
166+
if (property.isVersionProperty()) {
167+
return path(meta(i(bucketName)), i(META_CAS_PROPERTY));
168+
}
169+
return x(persistentPropertyPath.toDotPath(cvtr));
170+
}
171+
152172
}

0 commit comments

Comments
 (0)