DATACOUCH-265 - Support pageable and sort for String based SpEL queries
Original pull request: #128.
This commit is contained in:
@@ -72,7 +72,7 @@ public class N1qlCouchbaseRepositoryTests {
|
||||
repository = factory.getRepository(PartyPagingRepository.class);
|
||||
partyRepository = factory.getRepository(PartyRepository.class);
|
||||
itemRepository = factory.getRepository(ItemRepository.class);
|
||||
partyRepository.save(new Party(KEY_PARTY, "partyName", "MatchingDescription", null, 0, null));
|
||||
partyRepository.save(new Party(KEY_PARTY, "partyName", "MatchingDescription", null, 1, null));
|
||||
itemRepository.save(new Item(KEY_ITEM, "MatchingDescription"));
|
||||
}
|
||||
|
||||
@@ -151,4 +151,30 @@ public class N1qlCouchbaseRepositoryTests {
|
||||
List<Party> partyList = partyRepository.findByDescriptionOrName("MatchingDescription", "partyName");
|
||||
assertTrue(partyList.size() == 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldPageWithStringBasedQuery() {
|
||||
Pageable pageable = new PageRequest(0, 8, Sort.Direction.DESC, "attendees");
|
||||
Page<Party> page1 = partyRepository.findPartiesWithAttendee(1, pageable);
|
||||
assertEquals(16, page1.getTotalElements()); //12 generated parties + 4 specifically crafted party
|
||||
assertEquals(8, page1.getNumberOfElements());
|
||||
|
||||
List<Party> parties = page1.getContent();
|
||||
Long previousAttendees = null;
|
||||
for (Party party : parties) {
|
||||
if (previousAttendees != null) {
|
||||
assertTrue(party.getAttendees() <= previousAttendees);
|
||||
}
|
||||
previousAttendees = party.getAttendees();
|
||||
}
|
||||
Page<Party> page2 = partyRepository.findPartiesWithAttendee(1, page1.nextPageable());
|
||||
assertEquals(8, page2.getNumberOfElements());
|
||||
parties = page2.getContent();
|
||||
for (Party party : parties) {
|
||||
if (previousAttendees != null) {
|
||||
assertTrue(party.getAttendees() <= previousAttendees);
|
||||
}
|
||||
previousAttendees = party.getAttendees();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import org.springframework.data.couchbase.core.query.N1qlSecondaryIndexed;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.couchbase.core.query.View;
|
||||
import org.springframework.data.couchbase.core.query.ViewIndexed;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
/**
|
||||
@@ -42,6 +44,9 @@ public interface PartyRepository extends CouchbaseRepository<Party, String> {
|
||||
@Query("SELECT 1 = 1")
|
||||
boolean justABoolean();
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND `attendees` >= $1")
|
||||
Page<Party> findPartiesWithAttendee(int count, Pageable pageable);
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND `desc` LIKE '%' || $included || '%' AND attendees >= $min" +
|
||||
" AND `desc` NOT LIKE '%' || $excluded || '%'")
|
||||
List<Party> findAllWithNamedParams(@Param("excluded") String ex, @Param("included") String inc, @Param("min") long minimumAttendees);
|
||||
|
||||
@@ -263,6 +263,8 @@ It adds two methods:
|
||||
|
||||
TIP: You can also use `Page` and `Slice` as method return types as well with a N1QL backed repository.
|
||||
|
||||
NOTE: If pageable and sort parameters are used with inline queries, there should not be any order by, limit or offset clause in the inline query itself otherwise the server would reject the query as malformed.
|
||||
|
||||
The second way of querying, supported also in older versions of Couchbase Server, is the View-backed one that we'll see in the next section.
|
||||
|
||||
[[couchbase.repository.views]]
|
||||
|
||||
@@ -20,14 +20,23 @@ package org.springframework.data.couchbase.repository.query;
|
||||
import com.couchbase.client.java.document.json.JsonValue;
|
||||
import com.couchbase.client.java.query.N1qlQuery;
|
||||
import com.couchbase.client.java.query.Statement;
|
||||
import com.couchbase.client.java.query.dsl.path.DefaultLimitPath;
|
||||
import com.couchbase.client.java.query.dsl.path.DefaultOrderByPath;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.repository.query.support.N1qlUtils;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.repository.query.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.ReturnedType;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A {@link RepositoryQuery} for Couchbase, based on N1QL and a String statement.
|
||||
@@ -76,7 +85,24 @@ public class StringN1qlBasedQuery extends AbstractN1qlBasedQuery {
|
||||
public Statement getStatement(ParameterAccessor accessor, Object[] runtimeParameters, ReturnedType returnedType) {
|
||||
EvaluationContext evaluationContext = evaluationContextProvider.getEvaluationContext(getQueryMethod().getParameters(), runtimeParameters);
|
||||
String parsedStatement = this.queryParser.doParse(parser, evaluationContext, false);
|
||||
return N1qlQuery.simple(parsedStatement).statement();
|
||||
String orderByPart = "";
|
||||
String limitByPart = "";
|
||||
|
||||
Sort sort = accessor.getSort();
|
||||
if (sort != null) {
|
||||
com.couchbase.client.java.query.dsl.Sort[] cbSorts = N1qlUtils.createSort(sort, getCouchbaseOperations().getConverter());
|
||||
orderByPart = " " + new DefaultOrderByPath(null).orderBy(cbSorts).toString();
|
||||
}
|
||||
if (queryMethod.isPageQuery()) {
|
||||
Pageable pageable = accessor.getPageable();
|
||||
Assert.notNull(pageable);
|
||||
limitByPart = " " + new DefaultLimitPath(null).limit(pageable.getPageSize()).offset(pageable.getOffset()).toString();
|
||||
} else if (queryMethod.isSliceQuery()) {
|
||||
Pageable pageable = accessor.getPageable();
|
||||
Assert.notNull(pageable);
|
||||
limitByPart = " " + new DefaultLimitPath(null).limit(pageable.getPageSize() + 1).offset(pageable.getOffset()).toString();
|
||||
}
|
||||
return N1qlQuery.simple(parsedStatement + orderByPart + limitByPart).statement();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user