From 737b2342d08bb8b2eb90b4b5981b815f3d1eb4ed Mon Sep 17 00:00:00 2001 From: mikereiche Date: Mon, 17 Jan 2022 10:58:54 -0800 Subject: [PATCH] Copy sort from pageable to query. Closes #1304. --- .../data/couchbase/core/query/Query.java | 3 +- ...ouchbaseTemplateQueryIntegrationTests.java | 67 ++++++++++++++----- ...chbaseRepositoryQueryIntegrationTests.java | 22 ++++++ 3 files changed, 73 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/springframework/data/couchbase/core/query/Query.java b/src/main/java/org/springframework/data/couchbase/core/query/Query.java index e0b38e66a..391f6409d 100644 --- a/src/main/java/org/springframework/data/couchbase/core/query/Query.java +++ b/src/main/java/org/springframework/data/couchbase/core/query/Query.java @@ -178,8 +178,7 @@ public Query with(final Pageable pageable) { } this.limit = pageable.getPageSize(); this.skip = pageable.getOffset(); - if (!this.sort.equals(pageable.getSort())) - this.sort.and(pageable.getSort()); + this.with(pageable.getSort()); return this; } diff --git a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateQueryIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateQueryIntegrationTests.java index 3239e22c3..4223646ab 100644 --- a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateQueryIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateQueryIntegrationTests.java @@ -16,6 +16,7 @@ package org.springframework.data.couchbase.core; +import static com.couchbase.client.java.query.QueryScanConsistency.REQUEST_PLUS; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -26,9 +27,11 @@ import java.time.temporal.TemporalAccessor; import java.util.Arrays; import java.util.List; +import java.util.Locale; import java.util.UUID; import java.util.stream.Collectors; +import com.couchbase.client.java.query.QueryOptions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.data.couchbase.core.query.Query; @@ -50,6 +53,9 @@ import org.springframework.data.couchbase.util.JavaIntegrationTests; import com.couchbase.client.java.query.QueryScanConsistency; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; /** * Query tests Theses tests rely on a cb server running @@ -73,7 +79,7 @@ public void beforeEach() { // ensure each test starts with clean state couchbaseTemplate.removeByQuery(User.class).all(); - couchbaseTemplate.findByQuery(User.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all(); + couchbaseTemplate.findByQuery(User.class).withConsistency(REQUEST_PLUS).all(); } @Test @@ -85,7 +91,7 @@ void findByQueryAll() { couchbaseTemplate.upsertById(User.class).all(Arrays.asList(user1, user2)); final List foundUsers = couchbaseTemplate.findByQuery(User.class) - .withConsistency(QueryScanConsistency.REQUEST_PLUS).all(); + .withConsistency(REQUEST_PLUS).all(); for (User u : foundUsers) { if (!(u.equals(user1) || u.equals(user2))) { @@ -108,7 +114,7 @@ void findByQueryAll() { couchbaseTemplate.findById(User.class).one(user1.getId()); reactiveCouchbaseTemplate.findById(User.class).one(user1.getId()).block(); } finally { - couchbaseTemplate.removeByQuery(User.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all(); + couchbaseTemplate.removeByQuery(User.class).withConsistency(REQUEST_PLUS).all(); } User usery = couchbaseTemplate.findById(User.class).one("user1"); @@ -128,7 +134,7 @@ void findByMatchingQuery() { Query specialUsers = new Query(QueryCriteria.where(i("firstname")).like("special")); final List foundUsers = couchbaseTemplate.findByQuery(User.class) - .withConsistency(QueryScanConsistency.REQUEST_PLUS).matching(specialUsers).all(); + .withConsistency(REQUEST_PLUS).matching(specialUsers).all(); assertEquals(1, foundUsers.size()); } @@ -142,7 +148,7 @@ void findAssessmentDO() { Query specialUsers = new Query(QueryCriteria.where(i("id")).is(ado.getId())); final List foundUsers = couchbaseTemplate.findByQuery(AssessmentDO.class) - .withConsistency(QueryScanConsistency.REQUEST_PLUS).matching(specialUsers).all(); + .withConsistency(REQUEST_PLUS).matching(specialUsers).all(); assertEquals("123", foundUsers.get(0).getId(), "id"); assertEquals("44444444", foundUsers.get(0).getDocumentId(), "documentId"); assertEquals(ado, foundUsers.get(0)); @@ -169,7 +175,7 @@ void findByMatchingQueryProjected() { Query daveUsers = new Query(QueryCriteria.where("username").like("dave")); final List foundUserSubmissions = couchbaseTemplate.findByQuery(UserSubmission.class) - .as(UserSubmissionProjected.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).matching(daveUsers).all(); + .as(UserSubmissionProjected.class).withConsistency(REQUEST_PLUS).matching(daveUsers).all(); assertEquals(1, foundUserSubmissions.size()); assertEquals(user.getUsername(), foundUserSubmissions.get(0).getUsername()); assertEquals(user.getId(), foundUserSubmissions.get(0).getId()); @@ -186,11 +192,11 @@ void findByMatchingQueryProjected() { Query specialUsers = new Query(QueryCriteria.where("firstname").like("special")); final List foundUsers = couchbaseTemplate.findByQuery(User.class).as(UserJustLastName.class) - .withConsistency(QueryScanConsistency.REQUEST_PLUS).matching(specialUsers).all(); + .withConsistency(REQUEST_PLUS).matching(specialUsers).all(); assertEquals(1, foundUsers.size()); final List foundUsersReactive = reactiveCouchbaseTemplate.findByQuery(User.class) - .as(UserJustLastName.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).matching(specialUsers).all() + .as(UserJustLastName.class).withConsistency(REQUEST_PLUS).matching(specialUsers).all() .collectList().block(); assertEquals(1, foundUsersReactive.size()); @@ -206,7 +212,7 @@ void removeByQueryAll() { assertTrue(couchbaseTemplate.existsById().one(user1.getId())); assertTrue(couchbaseTemplate.existsById().one(user2.getId())); - couchbaseTemplate.removeByQuery(User.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all(); + couchbaseTemplate.removeByQuery(User.class).withConsistency(REQUEST_PLUS).all(); assertNull(couchbaseTemplate.findById(User.class).one(user1.getId())); assertNull(couchbaseTemplate.findById(User.class).one(user2.getId())); @@ -227,7 +233,7 @@ void removeByMatchingQuery() { Query nonSpecialUsers = new Query(QueryCriteria.where(i("firstname")).notLike("special")); - couchbaseTemplate.removeByQuery(User.class).withConsistency(QueryScanConsistency.REQUEST_PLUS) + couchbaseTemplate.removeByQuery(User.class).withConsistency(REQUEST_PLUS) .matching(nonSpecialUsers).all(); assertNull(couchbaseTemplate.findById(User.class).one(user1.getId())); @@ -252,17 +258,17 @@ void distinct() { // distinct icao List airports1 = couchbaseTemplate.findByQuery(Airport.class).distinct(new String[] { "icao" }) - .as(Airport.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all(); + .as(Airport.class).withConsistency(REQUEST_PLUS).all(); assertEquals(2, airports1.size()); // distinct all-fields-in-Airport.class List airports2 = couchbaseTemplate.findByQuery(Airport.class).distinct(new String[] {}).as(Airport.class) - .withConsistency(QueryScanConsistency.REQUEST_PLUS).all(); + .withConsistency(REQUEST_PLUS).all(); assertEquals(7, airports2.size()); // count( distinct { iata, icao } ) long count1 = couchbaseTemplate.findByQuery(Airport.class).distinct(new String[] { "iata", "icao" }) - .as(Airport.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).count(); + .as(Airport.class).withConsistency(REQUEST_PLUS).count(); assertEquals(7, count1); } finally { @@ -287,22 +293,22 @@ void distinctReactive() { // distinct icao List airports1 = reactiveCouchbaseTemplate.findByQuery(Airport.class).distinct(new String[] { "icao" }) - .as(Airport.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all().collectList().block(); + .as(Airport.class).withConsistency(REQUEST_PLUS).all().collectList().block(); assertEquals(2, airports1.size()); // distinct all-fields-in-Airport.class List airports2 = reactiveCouchbaseTemplate.findByQuery(Airport.class).distinct(new String[] {}) - .as(Airport.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all().collectList().block(); + .as(Airport.class).withConsistency(REQUEST_PLUS).all().collectList().block(); assertEquals(7, airports2.size()); // count( distinct icao ) Long count1 = reactiveCouchbaseTemplate.findByQuery(Airport.class).distinct(new String[] { "icao" }) - .as(Airport.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).count().block(); + .as(Airport.class).withConsistency(REQUEST_PLUS).count().block(); assertEquals(2, count1); // count( distinct { icao, iata } ) Long count2 = reactiveCouchbaseTemplate.findByQuery(Airport.class).distinct(new String[] { "icao", "iata" }) - .withConsistency(QueryScanConsistency.REQUEST_PLUS).count().block(); + .withConsistency(REQUEST_PLUS).count().block(); assertEquals(7, count2); } finally { @@ -312,4 +318,31 @@ void distinctReactive() { } } + @Test + void sortedTemplate() { + couchbaseTemplate.removeByQuery(Airport.class).withConsistency(REQUEST_PLUS).all(); + String[] iatas = { "JFK", "IAD", "SFO", "SJC", "SEA", "LAX", "PHX" }; + + try { + couchbaseTemplate.insertById(Airport.class).all( + Arrays.stream(iatas).map((iata) -> new Airport("airports::" + iata, iata, iata.toLowerCase(Locale.ROOT))) + .collect(Collectors.toSet())); + + org.springframework.data.couchbase.core.query.Query query = org.springframework.data.couchbase.core.query.Query.query(QueryCriteria.where("iata").isNotNull()); + Pageable pageableWithSort = PageRequest.of(0, 7, Sort.by("iata")); + query.with(pageableWithSort); + List airports = couchbaseTemplate.findByQuery(Airport.class).withConsistency(REQUEST_PLUS).matching(query).all(); + + String[] sortedIatas = iatas.clone(); + System.out.println(""+iatas.length+" "+sortedIatas.length); + Arrays.sort(sortedIatas); + for(int i=0; i< pageableWithSort.getPageSize(); i++){ + System.out.println(airports.get(i).getIata()); + assertEquals(sortedIatas[i], airports.get(i).getIata()); + } + } finally { + couchbaseTemplate.removeById(Airport.class).all(Arrays.stream(iatas).map((iata) -> "airports::" + iata).collect(Collectors.toSet())); + } + } + } 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 36d003f31..f5353d505 100644 --- a/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java @@ -577,6 +577,28 @@ void stringQueryReturnsSimpleType() { airportRepository.deleteById(airport2.getId()); } + @Test + void sortedRepository() { + airportRepository.withOptions(QueryOptions.queryOptions().scanConsistency(REQUEST_PLUS)).deleteAll(); + String[] iatas = { "JFK", "IAD", "SFO", "SJC", "SEA", "LAX", "PHX" }; + + try { + airportRepository.saveAll( + Arrays.stream(iatas).map((iata) -> new Airport("airports::" + iata, iata, iata.toLowerCase(Locale.ROOT))) + .collect(Collectors.toSet())); + List airports = airportRepository.withOptions(QueryOptions.queryOptions().scanConsistency(REQUEST_PLUS)).findAll(Sort.by("iata")); + String[] sortedIatas = iatas.clone(); + System.out.println(""+iatas.length+" "+sortedIatas.length); + Arrays.sort(sortedIatas); + for(int i=0; i< sortedIatas.length; i++){ + assertEquals(sortedIatas[i], airports.get(i).getIata()); + } + } finally { + airportRepository + .deleteAllById(Arrays.stream(iatas).map((iata) -> "airports::" + iata).collect(Collectors.toSet())); + } + } + @Test void count() { airportRepository.withOptions(QueryOptions.queryOptions().scanConsistency(REQUEST_PLUS)).deleteAll();