DATACOUCH-206 - Provides a way to set distinct consistency on repository methods.

* add @WithConsistency annotation
* evaluate it and set consistency in AbstractN1qlBasedQuery
* evaluate it and set consistency in ReactiveAbstractN1qlBasedQuery
* add documentation on @WithConsistency

Original pull request: #198.
This commit is contained in:
Johannes Jasper
2019-06-24 22:49:44 +02:00
committed by Oliver Drotbohm
parent b7f063ce68
commit 55235b2bc2
9 changed files with 287 additions and 14 deletions

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2013-2019 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.couchbase.core.query;
import com.couchbase.client.java.query.consistency.ScanConsistency;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.data.annotation.QueryAnnotation;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
/**
* Annotation to set the scan consistency of N1QL queries with Couchbase.
* This controls whether couchbase waits for all changes to be processed by an index
* or whether stale results are acceptable.
* <p/>
* If not set, the default consistency set in {@link AbstractCouchbaseConfiguration#getDefaultConsistency()} is used.
*
* @author Johannes Jasper.
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@QueryAnnotation
public @interface WithConsistency {
ScanConsistency value();
}

View File

@@ -16,11 +16,6 @@
package org.springframework.data.couchbase.repository.query;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import com.couchbase.client.java.document.json.JsonArray;
import com.couchbase.client.java.document.json.JsonObject;
import com.couchbase.client.java.document.json.JsonValue;
@@ -28,9 +23,11 @@ import com.couchbase.client.java.query.N1qlParams;
import com.couchbase.client.java.query.N1qlQuery;
import com.couchbase.client.java.query.Statement;
import com.couchbase.client.java.query.consistency.ScanConsistency;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.couchbase.core.CouchbaseOperations;
import org.springframework.data.couchbase.core.CouchbaseQueryExecutionException;
import org.springframework.data.domain.PageImpl;
@@ -52,6 +49,7 @@ import org.springframework.util.Assert;
* @author Simon Baslé
* @author Subhashni Balakrishnan
* @author Mark Paluch
* @author Johannes Jasper
*/
public abstract class AbstractN1qlBasedQuery implements RepositoryQuery {
@@ -82,6 +80,15 @@ public abstract class AbstractN1qlBasedQuery implements RepositoryQuery {
protected abstract JsonValue getPlaceholderValues(ParameterAccessor accessor);
protected ScanConsistency getScanConsistency() {
if (queryMethod.hasConsistencyAnnotation()) {
return queryMethod.getConsistencyAnnotation().value();
}
return getCouchbaseOperations().getDefaultConsistency().n1qlConsistency();
}
@Override
public Object execute(Object[] parameters) {
ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters);
@@ -96,14 +103,12 @@ public abstract class AbstractN1qlBasedQuery implements RepositoryQuery {
JsonValue queryPlaceholderValues = getPlaceholderValues(accessor);
//prepare the final query
N1qlQuery query = buildQuery(statement, queryPlaceholderValues,
getCouchbaseOperations().getDefaultConsistency().n1qlConsistency());
N1qlQuery query = buildQuery(statement, queryPlaceholderValues, getScanConsistency());
//prepare a count query
Statement countStatement = getCount(accessor, parameters);
//the place holder values are the same for the count query as well
N1qlQuery countQuery = buildQuery(countStatement, queryPlaceholderValues,
getCouchbaseOperations().getDefaultConsistency().n1qlConsistency());
N1qlQuery countQuery = buildQuery(countStatement, queryPlaceholderValues, getScanConsistency());
return processor.processResult(executeDependingOnType(query, countQuery, queryMethod, accessor.getPageable(), typeToRead));
}

View File

@@ -24,6 +24,7 @@ import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProper
import org.springframework.data.couchbase.core.query.Dimensional;
import org.springframework.data.couchbase.core.query.Query;
import org.springframework.data.couchbase.core.query.View;
import org.springframework.data.couchbase.core.query.WithConsistency;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.core.RepositoryMetadata;
@@ -144,6 +145,14 @@ public class CouchbaseQueryMethod extends QueryMethod {
return getInlineN1qlQuery() != null;
}
public boolean hasConsistencyAnnotation() {
return getConsistencyAnnotation() != null;
}
public WithConsistency getConsistencyAnnotation() {
return method.getAnnotation(WithConsistency.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,6 +15,7 @@
*/
package org.springframework.data.couchbase.repository.query;
import com.couchbase.client.java.query.consistency.ScanConsistency;
import java.util.Map;
import com.couchbase.client.java.document.json.JsonValue;
import com.couchbase.client.java.query.N1qlQuery;
@@ -31,6 +32,7 @@ import reactor.core.publisher.Flux;
/**
* @author Subhashni Balakrishnan
* @author Mark Paluch
* @author Johannes Jasper
* @since 3.0
*/
public abstract class ReactiveAbstractN1qlBasedQuery implements RepositoryQuery {
@@ -61,8 +63,7 @@ public abstract class ReactiveAbstractN1qlBasedQuery implements RepositoryQuery
JsonValue queryPlaceholderValues = getPlaceholderValues(accessor);
//prepare the final query
N1qlQuery query = N1qlUtils.buildQuery(statement, queryPlaceholderValues,
getCouchbaseOperations().getDefaultConsistency().n1qlConsistency());
N1qlQuery query = N1qlUtils.buildQuery(statement, queryPlaceholderValues, getScanConsistency());
return ReactiveWrapperConverters.toWrapper(
processor.processResult(executeDependingOnType(query, queryMethod, typeToRead)), Flux.class);
}
@@ -115,4 +116,13 @@ public abstract class ReactiveAbstractN1qlBasedQuery implements RepositoryQuery
protected RxJavaCouchbaseOperations getCouchbaseOperations() {
return this.couchbaseOperations;
}
protected ScanConsistency getScanConsistency() {
if (queryMethod.hasConsistencyAnnotation()) {
return queryMethod.getConsistencyAnnotation().value();
}
return getCouchbaseOperations().getDefaultConsistency().n1qlConsistency();
}
}