From 1f914a409ae218d23e6d577abeebcef47537fbb1 Mon Sep 17 00:00:00 2001 From: mikereiche Date: Fri, 12 Nov 2021 07:04:23 -0800 Subject: [PATCH] Handle Collection<> parameters to repository query methods. Closes #1270. --- .../couchbase/core/query/QueryCriteria.java | 28 +++++++++++++++---- .../couchbase/domain/AirportRepository.java | 6 ++++ ...chbaseRepositoryQueryIntegrationTests.java | 14 +++++++++- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/springframework/data/couchbase/core/query/QueryCriteria.java b/src/main/java/org/springframework/data/couchbase/core/query/QueryCriteria.java index 4b7da2459..9726e0737 100644 --- a/src/main/java/org/springframework/data/couchbase/core/query/QueryCriteria.java +++ b/src/main/java/org/springframework/data/couchbase/core/query/QueryCriteria.java @@ -18,17 +18,22 @@ import static org.springframework.data.couchbase.core.query.N1QLExpression.x; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.Formatter; import java.util.LinkedList; import java.util.List; import org.springframework.data.couchbase.core.convert.CouchbaseConverter; +import org.springframework.data.couchbase.core.mapping.CouchbaseDocument; +import org.springframework.data.couchbase.core.mapping.CouchbaseList; import org.springframework.lang.Nullable; import com.couchbase.client.core.error.InvalidArgumentException; import com.couchbase.client.java.json.JsonArray; import com.couchbase.client.java.json.JsonObject; import com.couchbase.client.java.json.JsonValue; +import org.springframework.util.CollectionUtils; /** * @author Michael Nitschinger @@ -412,8 +417,8 @@ private String maybeWrapValue(N1QLExpression key, Object value, int[] paramIndex try { params.add(convert(converter, value)); } catch (InvalidArgumentException iae) { - if (value instanceof Object[]) { - addAsArray(params, value, converter); + if (value instanceof Object[] || value instanceof Collection) { + addAsCollection(params, asCollection(value), converter); } else { throw iae; } @@ -462,15 +467,28 @@ private static Object convert(CouchbaseConverter converter, Object value) { return converter != null ? converter.convertForWriteIfNeeded(value) : value; } - private void addAsArray(JsonArray posValues, Object o, CouchbaseConverter converter) { - Object[] array = (Object[]) o; + private void addAsCollection(JsonArray posValues, Collection collection, CouchbaseConverter converter) { JsonArray ja = JsonValue.ja(); - for (Object e : array) { + for (Object e : collection) { ja.add(String.valueOf(convert(converter, e))); } posValues.add(ja); } + /** + * Returns a collection from the given source object. From MappingCouchbaseConverter. + * + * @param source the source object. + * @return the target collection. + */ + private static Collection asCollection(final Object source) { + if (source instanceof Collection) { + return (Collection) source; + } + return source.getClass().isArray() ? CollectionUtils.arrayToList(source) : Collections.singleton(source); + } + + private String maybeBackTic(String value) { if (value == null || (value.startsWith("`") && value.endsWith("`"))) { return value; diff --git a/src/test/java/org/springframework/data/couchbase/domain/AirportRepository.java b/src/test/java/org/springframework/data/couchbase/domain/AirportRepository.java index 327557bd2..8c39699c0 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/AirportRepository.java +++ b/src/test/java/org/springframework/data/couchbase/domain/AirportRepository.java @@ -77,6 +77,12 @@ public interface AirportRepository extends CouchbaseRepository, @ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS) Airport findByIata(Iata iata); + @ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS) + Airport findByIataIn(java.util.Collection iatas); + + @ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS) + Airport findByIataIn(Iata[] iata); + // NOT_BOUNDED to test ScanConsistency // @ScanConsistency(query = QueryScanConsistency.NOT_BOUNDED) Airport iata(String iata); diff --git a/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java index c4d1f9f30..b9f093991 100644 --- a/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java @@ -69,6 +69,7 @@ import org.springframework.data.couchbase.domain.AirportMini; import org.springframework.data.couchbase.domain.AirportRepository; import org.springframework.data.couchbase.domain.AirportRepositoryScanConsistencyTest; +import org.springframework.data.couchbase.domain.Iata; import org.springframework.data.couchbase.domain.NaiveAuditorAware; import org.springframework.data.couchbase.domain.Person; import org.springframework.data.couchbase.domain.PersonRepository; @@ -370,10 +371,21 @@ void findByEnum() { try { vie = new Airport("airports::vie", "vie", "loww"); vie = airportRepository.save(vie); - Airport airport2 = airportRepository.findByIata(vie.getIata()); + Airport airport2 = airportRepository.findByIata(Iata.vie); assertNotNull(airport2, "should have found " + vie); assertEquals(airport2.getId(), vie.getId()); + Airport airport3 = airportRepository.findByIataIn(new Iata[]{Iata.vie, Iata.xxx}); + assertNotNull(airport3, "should have found " + vie); + assertEquals(airport3.getId(), vie.getId()); + + java.util.Collection iatas = new ArrayList<>(); + iatas.add(Iata.vie); + iatas.add(Iata.xxx); + Airport airport4 = airportRepository.findByIataIn( iatas ); + assertNotNull(airport4, "should have found " + vie); + assertEquals(airport4.getId(), vie.getId()); + } finally { airportRepository.delete(vie); }