Handle Collection<> parameters to repository query methods. (#1271)

Closes #1270.

Co-authored-by: mikereiche <michael.reiche@couchbase.com>
This commit is contained in:
Michael Reiche
2021-11-12 07:15:45 -08:00
committed by GitHub
parent e003e4ccd0
commit 6c6acf8ae2
3 changed files with 42 additions and 6 deletions

View File

@@ -18,17 +18,22 @@ package org.springframework.data.couchbase.core.query;
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 @@ public class QueryCriteria implements QueryCriteriaDefinition {
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 @@ public class QueryCriteria implements QueryCriteriaDefinition {
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;

View File

@@ -77,6 +77,12 @@ public interface AirportRepository extends CouchbaseRepository<Airport, String>,
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
Airport findByIata(Iata iata);
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
Airport findByIataIn(java.util.Collection<Iata> iatas);
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
Airport findByIataIn(Iata[] iata);
// NOT_BOUNDED to test ScanConsistency
// @ScanConsistency(query = QueryScanConsistency.NOT_BOUNDED)
Airport iata(String iata);

View File

@@ -69,6 +69,7 @@ import org.springframework.data.couchbase.domain.Airport;
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 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
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<Iata> 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);
}