DATACOUCH-605 - Support ScanConsistency in n1ql queries

This commit is contained in:
mikereiche
2020-10-01 21:35:19 -07:00
parent fab72ee9c9
commit 82edad5759
17 changed files with 117 additions and 28 deletions

View File

@@ -126,7 +126,7 @@ public interface ExecutableFindByQueryOperation {
*
* @param scanConsistency the custom scan consistency to use for this query.
*/
FindByQueryWithQuery<T> consistentWith(QueryScanConsistency scanConsistency);
FindByQueryConsistentWith<T> consistentWith(QueryScanConsistency scanConsistency);
}

View File

@@ -21,6 +21,7 @@ import java.util.stream.Stream;
import org.springframework.data.couchbase.core.query.Query;
import com.couchbase.client.java.query.QueryScanConsistency;
import org.springframework.data.couchbase.core.ReactiveFindByQueryOperationSupport.ReactiveFindByQuerySupport;
public class ExecutableFindByQueryOperationSupport implements ExecutableFindByQueryOperation {
@@ -50,8 +51,7 @@ public class ExecutableFindByQueryOperationSupport implements ExecutableFindByQu
this.template = template;
this.domainType = domainType;
this.query = query;
this.reactiveSupport = new ReactiveFindByQueryOperationSupport.ReactiveFindByQuerySupport<T>(
template.reactive(), domainType, query, scanConsistency);
this.reactiveSupport = new ReactiveFindByQuerySupport<T>(template.reactive(), domainType, query, scanConsistency);
this.scanConsistency = scanConsistency;
}
@@ -72,11 +72,17 @@ public class ExecutableFindByQueryOperationSupport implements ExecutableFindByQu
@Override
public TerminatingFindByQuery<T> matching(final Query query) {
return new ExecutableFindByQuerySupport<>(template, domainType, query, scanConsistency);
QueryScanConsistency scanCons;
if (query.getScanConsistency() != null) {
scanCons = query.getScanConsistency();
} else {
scanCons = scanConsistency;
}
return new ExecutableFindByQuerySupport<>(template, domainType, query, scanCons);
}
@Override
public FindByQueryWithQuery<T> consistentWith(final QueryScanConsistency scanConsistency) {
public FindByQueryConsistentWith<T> consistentWith(final QueryScanConsistency scanConsistency) {
return new ExecutableFindByQuerySupport<>(template, domainType, query, scanConsistency);
}

View File

@@ -100,7 +100,7 @@ public interface ReactiveFindByQueryOperation {
*
* @param scanConsistency the custom scan consistency to use for this query.
*/
FindByQueryWithQuery<T> consistentWith(QueryScanConsistency scanConsistency);
FindByQueryConsistentWith<T> consistentWith(QueryScanConsistency scanConsistency);
}

View File

@@ -60,11 +60,17 @@ public class ReactiveFindByQueryOperationSupport implements ReactiveFindByQueryO
@Override
public TerminatingFindByQuery<T> matching(Query query) {
return new ReactiveFindByQuerySupport<>(template, domainType, query, scanConsistency);
QueryScanConsistency scanCons;
if (query.getScanConsistency() != null) {
scanCons = query.getScanConsistency();
} else {
scanCons = scanConsistency;
}
return new ReactiveFindByQuerySupport<>(template, domainType, query, scanCons);
}
@Override
public FindByQueryWithQuery<T> consistentWith(QueryScanConsistency scanConsistency) {
public FindByQueryConsistentWith<T> consistentWith(QueryScanConsistency scanConsistency) {
return new ReactiveFindByQuerySupport<>(template, domainType, query, scanConsistency);
}

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.data.couchbase.core;
import com.couchbase.client.java.kv.UpsertOptions;
import org.springframework.data.couchbase.core.mapping.Document;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -98,7 +97,7 @@ public class ReactiveInsertByIdOperationSupport implements ReactiveInsertByIdOpe
} else if (durabilityLevel != DurabilityLevel.NONE) {
options.durability(durabilityLevel);
}
if (expiry != null) {
if (expiry != null && ! expiry.isZero()) {
options.expiry(expiry);
} else if (domainType.isAnnotationPresent(Document.class)) {
Document documentAnn = domainType.getAnnotation(Document.class);

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.data.couchbase.core;
import com.couchbase.client.java.kv.Expiry;
import org.springframework.data.couchbase.core.mapping.Document;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -98,7 +97,7 @@ public class ReactiveUpsertByIdOperationSupport implements ReactiveUpsertByIdOpe
} else if (durabilityLevel != DurabilityLevel.NONE) {
options.durability(durabilityLevel);
}
if (expiry != null) {
if (expiry != null && !expiry.isZero()) {
options.expiry(expiry);
} else if (domainType.isAnnotationPresent(Document.class)) {
Document documentAnn = domainType.getAnnotation(Document.class);

View File

@@ -47,6 +47,7 @@ public class Query {
private long skip;
private int limit;
private Sort sort = Sort.unsorted();
private QueryScanConsistency queryScanConsistency;
static private final Pattern WHERE_PATTERN = Pattern.compile("\\sWHERE\\s");
@@ -127,6 +128,27 @@ public class Query {
return with(pageable.getSort());
}
/**
* queryScanConsistency
*
* @return queryScanConsistency
*/
public QueryScanConsistency getScanConsistency() {
return queryScanConsistency;
}
/**
* Sets the given scan consistency on the {@link Query} instance.
*
* @param queryScanConsistency
* @return this
*/
public Query scanConsistency(final QueryScanConsistency queryScanConsistency) {
this.queryScanConsistency = queryScanConsistency;
return this;
}
/**
* Adds a {@link Sort} to the {@link Query} instance.
*
@@ -280,7 +302,7 @@ public class Query {
}
/**
* build QueryOptions forom parameters and scanConsistency
* build QueryOptions from parameters and scanConsistency
*
* @param scanConsistency
* @return QueryOptions

View File

@@ -18,6 +18,7 @@ package org.springframework.data.couchbase.repository;
import java.util.List;
import com.couchbase.client.java.query.QueryScanConsistency;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
@@ -34,6 +35,8 @@ public interface CouchbaseRepository<T, ID> extends PagingAndSortingRepository<T
@Override
List<T> findAll(Sort sort);
List<T> findAll(QueryScanConsistency queryScanConsistency);
@Override
List<T> findAll();

View File

@@ -25,6 +25,7 @@ import org.springframework.data.couchbase.core.query.Dimensional;
import org.springframework.data.couchbase.core.query.View;
import org.springframework.data.couchbase.core.query.WithConsistency;
import org.springframework.data.couchbase.repository.Query;
import org.springframework.data.couchbase.repository.ScanConsistency;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.core.RepositoryMetadata;
@@ -152,6 +153,24 @@ public class CouchbaseQueryMethod extends QueryMethod {
return method.getAnnotation(WithConsistency.class);
}
/**
* If the method has a @ScanConsistency annotation
*
* @return true if this has the @ScanConsistency annotation
*/
public boolean hasScanConsistencyAnnotation() {
return getScanConsistencyAnnotation() != null;
}
/**
* ScanConsistency annotation
*
* @return the @ScanConsistency annotation
*/
public ScanConsistency getScanConsistencyAnnotation() {
return method.getAnnotation(ScanConsistency.class);
}
/**
* Returns the query string declared in a {@link Query} annotation or {@literal null} if neither the annotation found
* nor the attribute was specified.

View File

@@ -15,9 +15,7 @@
*/
package org.springframework.data.couchbase.repository.query;
import java.util.ArrayList;
import java.util.List;
import com.couchbase.client.java.query.QueryScanConsistency;
import org.springframework.data.couchbase.core.CouchbaseOperations;
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation;
import org.springframework.data.couchbase.core.query.Query;
@@ -65,7 +63,8 @@ public class N1qlRepositoryQueryExecutor {
final PartTree tree = new PartTree(queryMethod.getName(), domainClass);
query = new N1qlQueryCreator(tree, accessor, queryMethod, operations.getConverter()).createQuery();
}
q = (ExecutableFindByQueryOperation.ExecutableFindByQuery) operations.findByQuery(domainClass).matching(query);
q = (ExecutableFindByQueryOperation.ExecutableFindByQuery) operations.findByQuery(domainClass)
.consistentWith(buildQueryScanConsistency()).matching(query);
if (queryMethod.isCountQuery()) {
return q.count();
} else if (queryMethod.isCollectionQuery()) {
@@ -76,4 +75,14 @@ public class N1qlRepositoryQueryExecutor {
}
private QueryScanConsistency buildQueryScanConsistency() {
QueryScanConsistency scanConsistency = QueryScanConsistency.NOT_BOUNDED;
if (queryMethod.hasConsistencyAnnotation()) {
scanConsistency = queryMethod.getConsistencyAnnotation().value();
} else if (queryMethod.hasScanConsistencyAnnotation()) {
scanConsistency = queryMethod.getScanConsistencyAnnotation().query();
}
return scanConsistency;
}
}

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.couchbase.repository.query;
import com.couchbase.client.java.query.QueryScanConsistency;
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation;
import org.springframework.data.couchbase.core.ReactiveFindByQueryOperation;
import org.springframework.data.mapping.context.MappingContext;
@@ -69,7 +70,8 @@ public class ReactiveN1qlRepositoryQueryExecutor {
final PartTree tree = new PartTree(queryMethod.getName(), domainClass);
query = new N1qlQueryCreator(tree, accessor, queryMethod, operations.getConverter()).createQuery();
}
q = (ReactiveFindByQueryOperation.ReactiveFindByQuery) operations.findByQuery(domainClass).matching(query);
q = (ReactiveFindByQueryOperation.ReactiveFindByQuery) operations.findByQuery(domainClass)
.consistentWith(buildQueryScanConsistency()).matching(query);
if (queryMethod.isCountQuery()) {
return q.count();
} else if (queryMethod.isCollectionQuery()) {
@@ -79,4 +81,14 @@ public class ReactiveN1qlRepositoryQueryExecutor {
}
}
private QueryScanConsistency buildQueryScanConsistency() {
QueryScanConsistency scanConsistency = QueryScanConsistency.NOT_BOUNDED;
if (queryMethod.hasConsistencyAnnotation()) {
scanConsistency = queryMethod.getConsistencyAnnotation().value();
} else if (queryMethod.hasScanConsistencyAnnotation()) {
scanConsistency = queryMethod.getScanConsistencyAnnotation().query();
}
return scanConsistency;
}
}

View File

@@ -147,6 +147,11 @@ public class SimpleCouchbaseRepository<T, ID> implements CouchbaseRepository<T,
return findAll(new Query().with(sort));
}
@Override
public List<T> findAll(final QueryScanConsistency queryScanConsistency) {
return findAll(new Query().scanConsistency(queryScanConsistency));
}
@Override
public Page<T> findAll(final Pageable pageable) {
List<T> results = findAll(new Query().with(pageable));