Check for _ID and _CAS as well as __id and __cas being projected from query and analytics. (#1390)
Closes #1389.
This commit is contained in:
committed by
Michael Reiche
parent
baf198c868
commit
9fe8472b37
@@ -118,19 +118,27 @@ public class ReactiveFindByAnalyticsOperationSupport implements ReactiveFindByAn
|
||||
}
|
||||
}).flatMapMany(ReactiveAnalyticsResult::rowsAsObject).flatMap(row -> {
|
||||
String id = "";
|
||||
long cas = 0;
|
||||
if (row.getString(TemplateUtils.SELECT_ID) == null) {
|
||||
Long cas = Long.valueOf(0);
|
||||
if (row.getString(TemplateUtils.SELECT_ID) == null && row.getString(TemplateUtils.SELECT_ID_3x) == null) {
|
||||
return Flux.error(new CouchbaseException("analytics query did not project " + TemplateUtils.SELECT_ID
|
||||
+ ". Either use #{#n1ql.selectEntity} or project " + TemplateUtils.SELECT_ID + " and "
|
||||
+ TemplateUtils.SELECT_CAS + " : " + statement));
|
||||
}
|
||||
id = row.getString(TemplateUtils.SELECT_ID);
|
||||
if (row.getLong(TemplateUtils.SELECT_CAS) == null) {
|
||||
if (id == null) {
|
||||
id = row.getString(TemplateUtils.SELECT_ID_3x);
|
||||
row.removeKey(TemplateUtils.SELECT_ID_3x);
|
||||
}
|
||||
if (row.getLong(TemplateUtils.SELECT_CAS) == null && row.getLong(TemplateUtils.SELECT_CAS_3x) == null) {
|
||||
return Flux.error(new CouchbaseException("analytics query did not project " + TemplateUtils.SELECT_CAS
|
||||
+ ". Either use #{#n1ql.selectEntity} or project " + TemplateUtils.SELECT_ID + " and "
|
||||
+ TemplateUtils.SELECT_CAS + " : " + statement));
|
||||
}
|
||||
cas = row.getLong(TemplateUtils.SELECT_CAS);
|
||||
if (cas == null) {
|
||||
cas = row.getLong(TemplateUtils.SELECT_CAS_3x);
|
||||
row.removeKey(TemplateUtils.SELECT_CAS_3x);
|
||||
}
|
||||
row.removeKey(TemplateUtils.SELECT_ID);
|
||||
row.removeKey(TemplateUtils.SELECT_CAS);
|
||||
return support.decodeEntity(id, row.toString(), cas, returnType, null, null);
|
||||
|
||||
@@ -90,7 +90,7 @@ public class ReactiveFindByQueryOperationSupport implements ReactiveFindByQueryO
|
||||
public FindByQueryWithQuery<T> matching(Query query) {
|
||||
QueryScanConsistency scanCons;
|
||||
if (query.getScanConsistency() != null) { // redundant, since buildQueryOptions() will use
|
||||
// query.getScanConsistency()
|
||||
// query.getScanConsistency()
|
||||
scanCons = query.getScanConsistency();
|
||||
} else {
|
||||
scanCons = scanConsistency;
|
||||
@@ -185,20 +185,28 @@ public class ReactiveFindByQueryOperationSupport implements ReactiveFindByQueryO
|
||||
}
|
||||
}).flatMapMany(ReactiveQueryResult::rowsAsObject).flatMap(row -> {
|
||||
String id = "";
|
||||
long cas = 0;
|
||||
Long cas = Long.valueOf(0);
|
||||
if (!query.isDistinct() && distinctFields == null) {
|
||||
if (row.getString(TemplateUtils.SELECT_ID) == null) {
|
||||
if (row.getString(TemplateUtils.SELECT_ID) == null && row.getString(TemplateUtils.SELECT_ID_3x) == null) {
|
||||
return Flux.error(new CouchbaseException(
|
||||
"query did not project " + TemplateUtils.SELECT_ID + ". Either use #{#n1ql.selectEntity} or project "
|
||||
+ TemplateUtils.SELECT_ID + " and " + TemplateUtils.SELECT_CAS + " : " + statement));
|
||||
}
|
||||
id = row.getString(TemplateUtils.SELECT_ID);
|
||||
if (row.getLong(TemplateUtils.SELECT_CAS) == null) {
|
||||
if (id == null) {
|
||||
id = row.getString(TemplateUtils.SELECT_ID_3x);
|
||||
row.removeKey(TemplateUtils.SELECT_ID_3x);
|
||||
}
|
||||
if (row.getLong(TemplateUtils.SELECT_CAS) == null && row.getLong(TemplateUtils.SELECT_CAS_3x) == null) {
|
||||
return Flux.error(new CouchbaseException(
|
||||
"query did not project " + TemplateUtils.SELECT_CAS + ". Either use #{#n1ql.selectEntity} or project "
|
||||
+ TemplateUtils.SELECT_ID + " and " + TemplateUtils.SELECT_CAS + " : " + statement));
|
||||
}
|
||||
cas = row.getLong(TemplateUtils.SELECT_CAS);
|
||||
if (cas == null) {
|
||||
cas = row.getLong(TemplateUtils.SELECT_CAS_3x);
|
||||
row.removeKey(TemplateUtils.SELECT_CAS_3x);
|
||||
}
|
||||
row.removeKey(TemplateUtils.SELECT_ID);
|
||||
row.removeKey(TemplateUtils.SELECT_CAS);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ import org.springframework.data.couchbase.repository.query.CountFragment;
|
||||
public class TemplateUtils {
|
||||
public static final String SELECT_ID = "__id";
|
||||
public static final String SELECT_CAS = "__cas";
|
||||
public static final String SELECT_ID_3x = "_ID";
|
||||
public static final String SELECT_CAS_3x = "_CAS";
|
||||
public static final String SELECT_COUNT = CountFragment.COUNT_ALIAS;
|
||||
private static PersistenceExceptionTranslator exceptionTranslator = new CouchbaseExceptionTranslator();
|
||||
|
||||
|
||||
@@ -33,6 +33,9 @@ public interface AirlineRepository extends PagingAndSortingRepository<Airline, S
|
||||
QuerydslPredicateExecutor<Airline>, DynamicProxyable<AirlineRepository> {
|
||||
|
||||
@Query("#{#n1ql.selectEntity} where #{#n1ql.filter} and (name = $1)")
|
||||
List<User> getByName(@Param("airline_name") String airlineName);
|
||||
List<Airline> getByName(@Param("airline_name") String airlineName);
|
||||
|
||||
@Query("select meta().id as _ID, meta().cas as _CAS, #{#n1ql.bucket}.* from #{#n1ql.bucket} where #{#n1ql.filter} and (name = $1)")
|
||||
List<Airline> getByName_3x(@Param("airline_name") String airlineName);
|
||||
|
||||
}
|
||||
|
||||
@@ -116,6 +116,39 @@ class StringN1qlQueryCreatorTests extends ClusterAwareIntegrationTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IgnoreWhen(missesCapabilities = Capabilities.QUERY, clusterTypes = ClusterType.MOCKED)
|
||||
void findUsingStringNq1l_3x_projection_id_cas() throws Exception {
|
||||
Airline airline = new Airline(UUID.randomUUID().toString(), "Continental", "USA");
|
||||
try {
|
||||
Airline modified = couchbaseTemplate.upsertById(Airline.class).one(airline);
|
||||
|
||||
String input = "getByName_3x";
|
||||
Method method = AirlineRepository.class.getMethod(input, String.class);
|
||||
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
|
||||
new DefaultRepositoryMetadata(AirlineRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||
converter.getMappingContext());
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Continental"),
|
||||
queryMethod, converter, config().bucketname(), new SpelExpressionParser(),
|
||||
QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
|
||||
ExecutableFindByQuery q = (ExecutableFindByQuery) couchbaseTemplate.findByQuery(Airline.class)
|
||||
.withConsistency(QueryScanConsistency.REQUEST_PLUS).matching(query);
|
||||
|
||||
Optional<Airline> al = q.one();
|
||||
assertEquals(airline.toString(), al.get().toString());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
couchbaseTemplate.removeById().one(airline.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private ParameterAccessor getAccessor(Parameters<?, ?> params, Object... values) {
|
||||
return new ParametersParameterAccessor(params, values);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user