From eada7d0e7a9c8608d19800fc59ede1cf69332c26 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 24 Aug 2016 12:55:51 +0200 Subject: [PATCH 1/2] DATAKV-142 - Consider PartTree.isLimiting() and PartTree.getMaxResults() when creating queries. Prepare issue branch. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2695f312..cd87b4be 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-keyvalue - 1.2.0.BUILD-SNAPSHOT + 1.2.0.DATAKV-142-SNAPSHOT Spring Data KeyValue From a0bd4a5850ef7b7a6b140bead378035ef373cc75 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 24 Aug 2016 12:56:04 +0200 Subject: [PATCH 2/2] DATAKV-142 - Consider PartTree.isLimiting() and PartTree.getMaxResults() when creating queries. We now pick up result size limiting constraints from the query methods name. This allows usage of `findTopN` and `findFirst` keywords. --- .../query/KeyValuePartTreeQuery.java | 15 +++- .../query/KeyValuePartTreeQueryUnitTests.java | 80 +++++++++++++++++++ 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java b/src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java index c2704d4b..a28cdd69 100644 --- a/src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java +++ b/src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java @@ -150,7 +150,13 @@ protected KeyValueQuery prepareQuery(KeyValueQuery instance, Object[] para Sort sort = accessor.getSort(); query.setOffset(pageable == null ? -1 : pageable.getOffset()); - query.setRows(pageable == null ? -1 : pageable.getPageSize()); + + if (pageable != null) { + query.setRows(pageable.getPageSize()); + } else if (instance.getRows() >= 0) { + query.setRows(instance.getRows()); + } + query.setSort(sort == null ? instance.getSort() : sort); return query; @@ -175,7 +181,12 @@ public KeyValueQuery createQuery(ParameterAccessor accessor) { Constructor> constructor = (Constructor>) ClassUtils .getConstructorIfAvailable(queryCreator, PartTree.class, ParameterAccessor.class); - return (KeyValueQuery) BeanUtils.instantiateClass(constructor, tree, accessor).createQuery(); + KeyValueQuery query = (KeyValueQuery) BeanUtils.instantiateClass(constructor, tree, accessor).createQuery(); + + if (tree.isLimiting()) { + query.setRows(tree.getMaxResults()); + } + return query; } /* diff --git a/src/test/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQueryUnitTests.java b/src/test/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQueryUnitTests.java index 0e305aac..733ccf88 100644 --- a/src/test/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQueryUnitTests.java +++ b/src/test/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQueryUnitTests.java @@ -15,7 +15,9 @@ */ package org.springframework.data.keyvalue.repository.query; +import static org.hamcrest.core.Is.*; import static org.hamcrest.core.IsNot.*; +import static org.hamcrest.core.IsNull.*; import static org.hamcrest.core.IsSame.*; import static org.junit.Assert.*; import static org.mockito.Matchers.*; @@ -24,12 +26,17 @@ import java.lang.reflect.Method; import java.util.List; +import org.hamcrest.core.IsInstanceOf; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.data.keyvalue.Person; import org.springframework.data.keyvalue.core.KeyValueOperations; +import org.springframework.data.keyvalue.core.SpelCriteria; +import org.springframework.data.keyvalue.core.query.KeyValueQuery; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.query.DefaultEvaluationContextProvider; @@ -69,8 +76,81 @@ public void spelExpressionAndContextShouldNotBeReused() throws NoSuchMethodExcep assertThat(first, not(sameInstance(second))); } + /** + * @see DATAKV-142 + */ + @Test + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void shouldApplayPageableParameterToCollectionQuery() throws SecurityException, NoSuchMethodException { + + when(metadataMock.getDomainType()).thenReturn((Class) Person.class); + when(metadataMock.getReturnedDomainClass(any(Method.class))).thenReturn((Class) Person.class); + + QueryMethod qm = new QueryMethod(Repo.class.getMethod("findBy", Pageable.class), metadataMock, + projectionFactoryMock); + + KeyValuePartTreeQuery partTreeQuery = new KeyValuePartTreeQuery(qm, DefaultEvaluationContextProvider.INSTANCE, + kvOpsMock, SpelQueryCreator.class); + + KeyValueQuery query = partTreeQuery.prepareQuery(new Object[] { new PageRequest(2, 3) }); + + assertThat(query.getOffset(), is(6)); + assertThat(query.getRows(), is(3)); + } + + /** + * @see DATAKV-142 + */ + @Test + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void shouldApplyDerivedMaxResultsToQuery() throws SecurityException, NoSuchMethodException { + + when(metadataMock.getDomainType()).thenReturn((Class) Person.class); + when(metadataMock.getReturnedDomainClass(any(Method.class))).thenReturn((Class) Person.class); + + QueryMethod qm = new QueryMethod(Repo.class.getMethod("findTop3By"), metadataMock, projectionFactoryMock); + + KeyValuePartTreeQuery partTreeQuery = new KeyValuePartTreeQuery(qm, DefaultEvaluationContextProvider.INSTANCE, + kvOpsMock, SpelQueryCreator.class); + + KeyValueQuery query = partTreeQuery.prepareQuery(new Object[] {}); + + assertThat(query.getRows(), is(3)); + } + + /** + * @see DATAKV-142 + */ + @Test + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void shouldApplyDerivedMaxResultsToQueryWithParameters() throws SecurityException, NoSuchMethodException { + + when(metadataMock.getDomainType()).thenReturn((Class) Person.class); + when(metadataMock.getReturnedDomainClass(any(Method.class))).thenReturn((Class) Person.class); + + QueryMethod qm = new QueryMethod(Repo.class.getMethod("findTop3ByFirstname", String.class), metadataMock, + projectionFactoryMock); + + KeyValuePartTreeQuery partTreeQuery = new KeyValuePartTreeQuery(qm, DefaultEvaluationContextProvider.INSTANCE, + kvOpsMock, SpelQueryCreator.class); + + KeyValueQuery query = partTreeQuery.prepareQuery(new Object[] { "firstname" }); + + assertThat(query.getCritieria(), is(notNullValue())); + assertThat(query.getCritieria(), IsInstanceOf.instanceOf(SpelCriteria.class)); + assertThat(((SpelCriteria) query.getCritieria()).getExpression().getExpressionString(), + is("#it?.firstname?.equals([0])")); + assertThat(query.getRows(), is(3)); + } + static interface Repo { List findByFirstname(String firstname); + + List findBy(Pageable page); + + List findTop3By(); + + List findTop3ByFirstname(String firstname); } }