Collection support for predicates on meta fields. (#1338)
When a derived query is being created and there is a predicate on a meta-field ( meta().id, cas, expiry), translate that field (i.e. id -> meta().id) *without* the bucket or collection name, as it might apply to a collelction which we do not know yet (for instance, if there is a withCollection() specified).. This is fine, because in a derived query, meta() without the bucket or collection name is unambigous.
This commit is contained in:
committed by
Michael Reiche
parent
9048c7ca82
commit
6ebb0dd20e
@@ -76,7 +76,7 @@ public class N1qlQueryCreator extends AbstractQueryCreator<Query, QueryCriteria>
|
||||
protected QueryCriteria create(final Part part, final Iterator<Object> iterator) {
|
||||
PersistentPropertyPath<CouchbasePersistentProperty> path = context.getPersistentPropertyPath(part.getProperty());
|
||||
CouchbasePersistentProperty property = path.getLeafProperty();
|
||||
return from(part, property, where(addMetaIfRequired(bucketName, path, property, entity)), iterator);
|
||||
return from(part, property, where(addMetaIfRequired(null, path, property, entity)), iterator);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -187,17 +187,28 @@ public class N1qlQueryCreator extends AbstractQueryCreator<Query, QueryCriteria>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate meta-fields to META(bucketName).id, cas, expiry.<br>
|
||||
* If bucketName is null, META().id etc, <br>
|
||||
* If not a meta-field, just create the corresponding path
|
||||
*
|
||||
* @param bucketName
|
||||
* @param persistentPropertyPath
|
||||
* @param property
|
||||
* @param entity
|
||||
* @return N1QLExpression
|
||||
*/
|
||||
public static N1QLExpression addMetaIfRequired(String bucketName,
|
||||
final PersistentPropertyPath<CouchbasePersistentProperty> persistentPropertyPath,
|
||||
final CouchbasePersistentProperty property, final PersistentEntity entity) {
|
||||
if (entity != null && property == entity.getIdProperty()) {
|
||||
return path(meta(i(bucketName)), i(META_ID_PROPERTY));
|
||||
return path(meta(bucketName != null ? i(bucketName) : x("")), i(META_ID_PROPERTY));
|
||||
}
|
||||
if (property == entity.getVersionProperty()) {
|
||||
return path(meta(i(bucketName)), i(META_CAS_PROPERTY));
|
||||
return path(meta(bucketName != null ? i(bucketName) : x("")), i(META_CAS_PROPERTY));
|
||||
}
|
||||
if (property.isExpirationProperty()) {
|
||||
return path(meta(i(bucketName)), i(META_EXPIRATION_PROPERTY));
|
||||
return path(meta(bucketName != null ? i(bucketName) : x("")), i(META_EXPIRATION_PROPERTY));
|
||||
}
|
||||
return x(persistentPropertyPath.toDotPath(cvtr));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors
|
||||
* Copyright 2012-2022 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.
|
||||
@@ -40,10 +40,13 @@ public interface UserColRepository extends CouchbaseRepository<UserCol, String>,
|
||||
|
||||
// CouchbaseRepositoryQueryCollectionIntegrationTests.testScopeCollectionAnnotationSwap() relies on this
|
||||
// being commented out.
|
||||
//<S extends UserCol> S save(S var1);
|
||||
// <S extends UserCol> S save(S var1);
|
||||
|
||||
List<UserCol> findByFirstname(String firstname);
|
||||
|
||||
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
|
||||
UserCol getById(String id);
|
||||
|
||||
List<UserCol> findByFirstnameIn(String... firstnames);
|
||||
|
||||
List<UserCol> findByFirstnameIn(JsonArray firstnames);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2021 the original author or authors.
|
||||
* Copyright 2017-2022 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.
|
||||
@@ -91,6 +91,16 @@ public class CouchbaseRepositoryQueryCollectionIntegrationTests extends Collecti
|
||||
super.afterEach();
|
||||
}
|
||||
|
||||
@Test
|
||||
void findByKey() {
|
||||
UserCol userCol = new UserCol("101", "userColFirst", "userColLast");
|
||||
userColRepository.save(userCol);
|
||||
UserCol found = userColRepository.getById(userCol.getId());
|
||||
System.err.println("found: " + found);
|
||||
assertEquals(userCol, found);
|
||||
userColRepository.delete(found);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void myTest() {
|
||||
|
||||
|
||||
@@ -189,8 +189,8 @@ class N1qlQueryCreatorTests {
|
||||
converter, bucketName);
|
||||
Query query = creator.createQuery();
|
||||
|
||||
assertEquals(query.export(),
|
||||
" WHERE " + where(x("META(`" + bucketName + "`).`id`")).isNotNull().and(i("firstname")).is("Oliver").export());
|
||||
assertEquals(" WHERE " + where(x("META().`id`")).isNotNull().and(i("firstname")).is("Oliver").export(),
|
||||
query.export());
|
||||
}
|
||||
|
||||
@Test // https://github.com/spring-projects/spring-data-couchbase/issues/1072
|
||||
@@ -204,8 +204,9 @@ class N1qlQueryCreatorTests {
|
||||
getAccessor(getParameters(method), 1611287177404088320L, "Oliver"), queryMethod, converter, bucketName);
|
||||
Query query = creator.createQuery();
|
||||
|
||||
assertEquals(query.export(), " WHERE " + where(x("META(`" + bucketName + "`).`cas`")).is(1611287177404088320L)
|
||||
.and(i("firstname")).is("Oliver").export());
|
||||
assertEquals(
|
||||
" WHERE " + where(x("META().`cas`")).is(1611287177404088320L).and(i("firstname")).is("Oliver").export(),
|
||||
query.export());
|
||||
}
|
||||
|
||||
private ParameterAccessor getAccessor(Parameters<?, ?> params, Object... values) {
|
||||
|
||||
Reference in New Issue
Block a user