From 6ce25c92eefc0ae0ba6f1288b8206f1893ec1430 Mon Sep 17 00:00:00 2001 From: Michael Reiche Date: Thu, 10 Feb 2022 14:33:47 -0800 Subject: [PATCH] Collection support for predicates on meta fields. 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. --- .../repository/query/N1qlQueryCreator.java | 19 +++++++++++++++---- .../couchbase/domain/UserColRepository.java | 7 +++++-- ...sitoryQueryCollectionIntegrationTests.java | 12 +++++++++++- .../query/N1qlQueryCreatorTests.java | 9 +++++---- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreator.java b/src/main/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreator.java index 8af78c70c..08313fc8d 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreator.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreator.java @@ -76,7 +76,7 @@ public N1qlQueryCreator(final PartTree tree, final ParameterAccessor accessor, f protected QueryCriteria create(final Part part, final Iterator iterator) { PersistentPropertyPath 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 @@ private QueryCriteria from(final Part part, final CouchbasePersistentProperty pr } } + /** + * Translate meta-fields to META(bucketName).id, cas, expiry.
+ * If bucketName is null, META().id etc,
+ * 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 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)); } diff --git a/src/test/java/org/springframework/data/couchbase/domain/UserColRepository.java b/src/test/java/org/springframework/data/couchbase/domain/UserColRepository.java index 412a5755d..794186f03 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/UserColRepository.java +++ b/src/test/java/org/springframework/data/couchbase/domain/UserColRepository.java @@ -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, // CouchbaseRepositoryQueryCollectionIntegrationTests.testScopeCollectionAnnotationSwap() relies on this // being commented out. - // S save(S var1); + // S save(S var1); List findByFirstname(String firstname); + @ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS) + UserCol getById(String id); + List findByFirstnameIn(String... firstnames); List findByFirstnameIn(JsonArray firstnames); diff --git a/src/test/java/org/springframework/data/couchbase/repository/query/CouchbaseRepositoryQueryCollectionIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/repository/query/CouchbaseRepositoryQueryCollectionIntegrationTests.java index 82d24e8d5..2eee78b6c 100644 --- a/src/test/java/org/springframework/data/couchbase/repository/query/CouchbaseRepositoryQueryCollectionIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/repository/query/CouchbaseRepositoryQueryCollectionIntegrationTests.java @@ -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 void afterEach() { 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() { diff --git a/src/test/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreatorTests.java b/src/test/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreatorTests.java index 2555625b4..5a610849e 100644 --- a/src/test/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreatorTests.java +++ b/src/test/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreatorTests.java @@ -189,8 +189,8 @@ void createsQueryFindByIdIsNotNullAndFirstname() throws Exception { 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 @@ void createsQueryFindByVersionEqualsAndAndFirstname() throws Exception { 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) {