Fixes JIRA issue SGF-273 - OrderBy (static) and Sort parameter (dynamic) Repository Queries do not work.
This commit is contained in:
@@ -44,10 +44,9 @@ class GemfireQueryCreator extends AbstractQueryCreator<QueryString, Predicates>
|
||||
* @param entity must not be {@literal null}.
|
||||
*/
|
||||
public GemfireQueryCreator(PartTree tree, GemfirePersistentEntity<?> entity) {
|
||||
|
||||
super(tree);
|
||||
|
||||
this.query = new QueryBuilder(entity);
|
||||
this.query = new QueryBuilder(entity, tree);
|
||||
this.indexes = new IndexProvider();
|
||||
}
|
||||
|
||||
@@ -57,7 +56,6 @@ class GemfireQueryCreator extends AbstractQueryCreator<QueryString, Predicates>
|
||||
*/
|
||||
@Override
|
||||
public QueryString createQuery(Sort dynamicSort) {
|
||||
|
||||
this.indexes = new IndexProvider();
|
||||
return super.createQuery(dynamicSort);
|
||||
}
|
||||
@@ -95,11 +93,10 @@ class GemfireQueryCreator extends AbstractQueryCreator<QueryString, Predicates>
|
||||
*/
|
||||
@Override
|
||||
protected QueryString complete(Predicates criteria, Sort sort) {
|
||||
|
||||
QueryString result = query.create(criteria);
|
||||
QueryString result = query.create(criteria).orderBy(sort);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Created query: " + result.toString());
|
||||
LOG.debug(String.format("Created Query '%1$s'", result.toString()));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -119,6 +116,7 @@ class GemfireQueryCreator extends AbstractQueryCreator<QueryString, Predicates>
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
// TODO really?
|
||||
return index <= Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@@ -140,4 +138,5 @@ class GemfireQueryCreator extends AbstractQueryCreator<QueryString, Predicates>
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,13 +15,15 @@
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.parser.Part;
|
||||
import org.springframework.data.repository.query.parser.Part.Type;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
|
||||
/**
|
||||
@@ -71,35 +73,31 @@ public class PartTreeGemfireRepositoryQuery extends GemfireRepositoryQuery {
|
||||
}
|
||||
|
||||
private Object[] prepareStringParameters(Object[] parameters) {
|
||||
Iterator<Part> partsIterator = tree.getParts().iterator();
|
||||
List<Object> stringParameters = new ArrayList<Object>(parameters.length);
|
||||
|
||||
Iterator<Part> iterator = tree.getParts().iterator();
|
||||
Object[] result = new Object[parameters.length];
|
||||
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
Object parameter = parameters[i];
|
||||
|
||||
if (parameter == null) {
|
||||
result[i] = parameter;
|
||||
continue;
|
||||
for (Object parameter : parameters) {
|
||||
if (parameter == null || parameter instanceof Sort) {
|
||||
stringParameters.add(parameter);
|
||||
}
|
||||
|
||||
Type type = iterator.next().getType();
|
||||
|
||||
switch (type) {
|
||||
case CONTAINING:
|
||||
result[i] = String.format("%%%s%%", parameter.toString());
|
||||
break;
|
||||
case STARTING_WITH:
|
||||
result[i] = String.format("%s%%", parameter.toString());
|
||||
break;
|
||||
case ENDING_WITH:
|
||||
result[i] = String.format("%%%s", parameter.toString());
|
||||
break;
|
||||
default:
|
||||
result[i] = parameter;
|
||||
else {
|
||||
switch (partsIterator.next().getType()) {
|
||||
case CONTAINING:
|
||||
stringParameters.add(String.format("%%%s%%", parameter.toString()));
|
||||
break;
|
||||
case STARTING_WITH:
|
||||
stringParameters.add(String.format("%s%%", parameter.toString()));
|
||||
break;
|
||||
case ENDING_WITH:
|
||||
stringParameters.add(String.format("%%%s", parameter.toString()));
|
||||
break;
|
||||
default:
|
||||
stringParameters.add(parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return stringParameters.toArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,9 +20,12 @@ import org.springframework.data.repository.query.parser.PartTree;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
*
|
||||
* The QueryBuilder class is used to build a QueryString.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.repository.query.QueryString
|
||||
*/
|
||||
class QueryBuilder {
|
||||
|
||||
@@ -31,17 +34,18 @@ class QueryBuilder {
|
||||
private final String query;
|
||||
|
||||
public QueryBuilder(String source) {
|
||||
Assert.hasText(source);
|
||||
Assert.hasText(source, "The OQL Query string must be specified.");
|
||||
this.query = source;
|
||||
}
|
||||
|
||||
public QueryBuilder(GemfirePersistentEntity<?> entity) {
|
||||
this(String.format("SELECT * FROM /%s %s", entity.getRegionName(), DEFAULT_ALIAS));
|
||||
public QueryBuilder(GemfirePersistentEntity<?> entity, PartTree tree) {
|
||||
this(String.format(tree.isDistinct() ? "SELECT DISTINCT * FROM /%1$s %2$s" : "SELECT * FROM /%1$s %2$s",
|
||||
entity.getRegionName(), DEFAULT_ALIAS));
|
||||
}
|
||||
|
||||
public QueryString create(Predicate predicate) {
|
||||
|
||||
return new QueryString(query + " WHERE " + predicate.toString(DEFAULT_ALIAS));
|
||||
return new QueryString(predicate != null ? String.format("%1$s WHERE %2$s", query,
|
||||
predicate.toString(DEFAULT_ALIAS)) : query);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -52,4 +56,5 @@ class QueryBuilder {
|
||||
public String toString() {
|
||||
return query;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,11 +21,12 @@ import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* Value object to work with OQL query strings.
|
||||
*
|
||||
@@ -33,7 +34,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
*/
|
||||
class QueryString {
|
||||
public class QueryString {
|
||||
|
||||
private static final String IN_PATTERN = "(?<=IN (SET|LIST) )\\$\\d";
|
||||
private static final String IN_PARAMETER_PATTERN = "(?<=IN (SET|LIST) \\$)\\d";
|
||||
@@ -44,7 +45,7 @@ class QueryString {
|
||||
/**
|
||||
* Creates a {@link QueryString} from the given {@link String} query.
|
||||
*
|
||||
* @param source
|
||||
* @param source a String containing the OQL Query.
|
||||
*/
|
||||
public QueryString(String source) {
|
||||
Assert.hasText(source, "The OQL statement (Query) to execute must be specified!");
|
||||
@@ -56,8 +57,8 @@ class QueryString {
|
||||
*
|
||||
* @param domainClass must not be {@literal null}.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public QueryString(Class<?> domainClass) {
|
||||
@SuppressWarnings("unused")
|
||||
public QueryString(Class<?> domainClass) {
|
||||
this(domainClass, false);
|
||||
}
|
||||
|
||||
@@ -68,41 +69,45 @@ class QueryString {
|
||||
* @param isCountQuery indicates if this is a count query
|
||||
*/
|
||||
public QueryString(Class<?> domainClass, boolean isCountQuery) {
|
||||
this(String.format(isCountQuery ? "SELECT count(*) FROM /%s" : "SELECT * FROM /%s", domainClass.getSimpleName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the domain classes referenced inside the current query with the given {@link Region}.
|
||||
*
|
||||
* @param domainClass must not be {@literal null}.
|
||||
* @param region must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public QueryString forRegion(Class<?> domainClass, Region<?, ?> region) {
|
||||
return new QueryString(query.replaceAll(REGION_PATTERN, region.getFullPath()));
|
||||
this(String.format(isCountQuery ? "SELECT count(*) FROM /%s" : "SELECT * FROM /%s",
|
||||
domainClass.getSimpleName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the given values to the {@literal IN} parameter keyword by expanding the given values into a comma-separated
|
||||
* {@link String}.
|
||||
*
|
||||
*
|
||||
* @param values the values to bind, returns the {@link QueryString} as is if {@literal null} is given.
|
||||
* @return
|
||||
* @return a Query String having "in" parameters bound with values.
|
||||
*/
|
||||
public QueryString bindIn(Collection<?> values) {
|
||||
if (values != null) {
|
||||
String valueString = StringUtils.collectionToDelimitedString(values, ", ", "'", "'");
|
||||
return new QueryString(query.replaceFirst(IN_PATTERN, String.format("(%s)", valueString)));
|
||||
}
|
||||
public QueryString bindIn(Collection<?> values) {
|
||||
if (values != null) {
|
||||
String valueString = StringUtils.collectionToDelimitedString(values, ", ", "'", "'");
|
||||
return new QueryString(query.replaceFirst(IN_PATTERN, String.format("(%s)", valueString)));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the domain classes referenced inside the current query with the given {@link Region}.
|
||||
*
|
||||
* @param domainClass the class type of the GemFire persistent entity to query; must not be {@literal null}.
|
||||
* @param region the GemFire Region in which to query; must not be {@literal null}.
|
||||
* @return a Query String with the FROM clause in the OQL statement evaluated and replaced with
|
||||
* the fully-qualified Region to query.
|
||||
* @see com.gemstone.gemfire.cache.Region
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public QueryString forRegion(Class<?> domainClass, Region<?, ?> region) {
|
||||
return new QueryString(query.replaceAll(REGION_PATTERN, region.getFullPath()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parameter indexes used in this query.
|
||||
*
|
||||
* @return the parameter indexes used in this query or an empty {@link Iterable} if none are used.
|
||||
* @see java.lang.Iterable
|
||||
*/
|
||||
public Iterable<Integer> getInParameterIndexes() {
|
||||
Pattern pattern = Pattern.compile(IN_PARAMETER_PATTERN);
|
||||
@@ -116,6 +121,31 @@ class QueryString {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the Sort order to this GemFire OQL Query string.
|
||||
*
|
||||
* @param sort the Sort object indicating the order by criteria.
|
||||
* @return this QueryString with an ORDER BY clause if the Sort object is not null, or this QueryString as-is
|
||||
* if the Sort object is null.
|
||||
* @see org.springframework.data.domain.Sort
|
||||
* @see org.springframework.data.gemfire.repository.query.QueryString
|
||||
*/
|
||||
public QueryString orderBy(Sort sort) {
|
||||
if (sort != null) {
|
||||
StringBuilder orderClause = new StringBuilder("ORDER BY ");
|
||||
int count = 0;
|
||||
|
||||
for (Sort.Order order : sort) {
|
||||
orderClause.append(count++ > 0 ? ", " : "");
|
||||
orderClause.append(String.format("%1$s %2$s", order.getProperty(), order.getDirection()));
|
||||
}
|
||||
|
||||
return new QueryString(String.format("%1$s %2$s", this.query, orderClause.toString()));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.springframework.data.gemfire.GemfireCallback;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.repository.GemfireRepository;
|
||||
import org.springframework.data.gemfire.repository.Wrapper;
|
||||
import org.springframework.data.gemfire.repository.query.QueryString;
|
||||
import org.springframework.data.repository.core.EntityInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -111,32 +112,15 @@ public class SimpleGemfireRepository<T, ID extends Serializable> implements Gemf
|
||||
*/
|
||||
@Override
|
||||
public Iterable<T> findAll(final Sort sort) {
|
||||
SelectResults<T> selectResults = template.find(String.format("SELECT * FROM %1$s%2$s",
|
||||
template.getRegion().getFullPath(), toString(sort)));
|
||||
QueryString query = new QueryString("SELECT * FROM /RegionPlaceholder")
|
||||
.forRegion(entityInformation.getJavaType(), template.getRegion())
|
||||
.orderBy(sort);
|
||||
|
||||
SelectResults<T> selectResults = template.find(query.toString());
|
||||
|
||||
return selectResults.asList();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Sort
|
||||
*/
|
||||
private String toString(final Sort sort) {
|
||||
if (sort != null) {
|
||||
StringBuilder orderClause = new StringBuilder(" ORDER BY ");
|
||||
int count = 0;
|
||||
|
||||
for (Sort.Order order : sort) {
|
||||
orderClause.append(count++ > 0 ? ", " : "");
|
||||
orderClause.append(String.format("%1$s %2$s", order.getProperty(), order.getDirection()));
|
||||
}
|
||||
|
||||
return orderClause.toString();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -28,6 +29,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
import org.springframework.data.gemfire.repository.sample.RootUser;
|
||||
|
||||
@@ -45,14 +47,26 @@ public class QueryStringUnitTests {
|
||||
@SuppressWarnings("rawtypes")
|
||||
Region region;
|
||||
|
||||
protected Sort.Order createOrder(final String property) {
|
||||
return createOrder(property, Sort.Direction.ASC);
|
||||
}
|
||||
|
||||
protected Sort.Order createOrder(final String property, final Sort.Direction direction) {
|
||||
return new Sort.Order(direction, property);
|
||||
}
|
||||
|
||||
protected Sort createSort(Sort.Order... orders) {
|
||||
return new Sort(orders);
|
||||
}
|
||||
|
||||
// SGF-251
|
||||
@Test
|
||||
public void replacesDomainObjectWithRegionPathCorrectly() {
|
||||
QueryString query = new QueryString("SELECT * FROM /Person p WHERE p.firstname = $1");
|
||||
|
||||
when(region.getFullPath()).thenReturn("/foo");
|
||||
when(region.getFullPath()).thenReturn("/foo/bar");
|
||||
|
||||
assertThat(query.forRegion(Person.class, region).toString(), is("SELECT * FROM /foo p WHERE p.firstname = $1"));
|
||||
assertThat(query.forRegion(Person.class, region).toString(), is("SELECT * FROM /foo/bar p WHERE p.firstname = $1"));
|
||||
|
||||
verify(region, never()).getName();
|
||||
}
|
||||
@@ -63,16 +77,16 @@ public class QueryStringUnitTests {
|
||||
public void replacesDomainObjectWithPluralRegionPathCorrectly() {
|
||||
QueryString query = new QueryString("SELECT * FROM /Persons p WHERE p.firstname = $1");
|
||||
|
||||
when(region.getFullPath()).thenReturn("/Persons");
|
||||
when(region.getFullPath()).thenReturn("/People");
|
||||
|
||||
assertThat(query.forRegion(Person.class, region).toString(), is("SELECT * FROM /Persons p WHERE p.firstname = $1"));
|
||||
assertThat(query.forRegion(Person.class, region).toString(), is("SELECT * FROM /People p WHERE p.firstname = $1"));
|
||||
|
||||
verify(region, never()).getName();
|
||||
}
|
||||
|
||||
// SGF-252
|
||||
@Test
|
||||
public void replacesFullyQualifiedSubegionReferenceWithRegionPathCorrectly() {
|
||||
public void replacesFullyQualifiedSubregionReferenceWithRegionPathCorrectly() {
|
||||
QueryString query = new QueryString("SELECT * FROM //Local/Root/Users u WHERE u.username = $1");
|
||||
|
||||
when(region.getFullPath()).thenReturn("/Local/Root/Users");
|
||||
@@ -96,4 +110,29 @@ public class QueryStringUnitTests {
|
||||
assertThat(indexes, is((Iterable<Integer>) Arrays.asList(1, 2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addsOrderByClauseCorrectly() {
|
||||
QueryString query = new QueryString("SELECT * FROM /People p WHERE p.lastName = $1")
|
||||
.orderBy(createSort(createOrder("lastName", Sort.Direction.DESC), createOrder("firstName")));
|
||||
|
||||
assertEquals("SELECT * FROM /People p WHERE p.lastName = $1 ORDER BY lastName DESC, firstName ASC",
|
||||
query.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addsSingleOrderByClauseCorrectly() {
|
||||
QueryString query = new QueryString("SELECT DISTINCT p.lastName FROM /People p WHERE p.firstName = $1")
|
||||
.orderBy(createSort(createOrder("lastName")));
|
||||
|
||||
assertEquals("SELECT DISTINCT p.lastName FROM /People p WHERE p.firstName = $1 ORDER BY lastName ASC",
|
||||
query.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addsNoOrderByClauseCorrectly() {
|
||||
QueryString query = new QueryString("SELECT * FROM /People p").orderBy(null);
|
||||
|
||||
assertEquals("SELECT * FROM /People p", query.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
package org.springframework.data.gemfire.repository.sample;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.gemfire.repository.GemfireRepository;
|
||||
import org.springframework.data.gemfire.repository.Query;
|
||||
|
||||
@@ -53,4 +55,9 @@ public interface PersonRepository extends GemfireRepository<Person, Long> {
|
||||
Collection<Person> findByLastnameEndingWith(String lastname);
|
||||
|
||||
Collection<Person> findByFirstnameContaining(String firstname);
|
||||
|
||||
List<Person> findDistinctByLastname(String lastName, Sort order);
|
||||
|
||||
List<Person> findDistinctPeopleByOrderByLastnameDesc(Sort order);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.repository.sample;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* The PersonRepositoryTest class...
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.junit.runner.RunWith
|
||||
* @see org.springframework.data.gemfire.repository.sample.Person
|
||||
* @see org.springframework.data.gemfire.repository.sample.PersonRepository
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* @since 1.4.0
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class PersonRepositoryTest {
|
||||
|
||||
protected final AtomicLong ID_SEQUENCE = new AtomicLong(0l);
|
||||
|
||||
private Person cookieDoe = createPerson("Cookie", "Doe");
|
||||
private Person janeDoe = createPerson("Jane", "Doe");
|
||||
private Person jonDoe = createPerson("Jon", "Doe");
|
||||
private Person pieDoe = createPerson("Pie", "Doe");
|
||||
private Person jackHandy = createPerson("Jack", "Handy");
|
||||
private Person sandyHandy = createPerson("Sandy", "Handy");
|
||||
private Person imaPigg = createPerson("Ima", "Pigg");
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepo;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
if (personRepo.count() == 0) {
|
||||
sandyHandy = personRepo.save(sandyHandy);
|
||||
jonDoe = personRepo.save(jonDoe);
|
||||
jackHandy = personRepo.save(jackHandy);
|
||||
janeDoe = personRepo.save(janeDoe);
|
||||
pieDoe = personRepo.save(pieDoe);
|
||||
imaPigg = personRepo.save(imaPigg);
|
||||
cookieDoe = personRepo.save(cookieDoe);
|
||||
}
|
||||
|
||||
assertEquals(7l, personRepo.count());
|
||||
}
|
||||
|
||||
protected Person createPerson(final String firstName, final String lastName) {
|
||||
return new Person(ID_SEQUENCE.incrementAndGet(), firstName, lastName);
|
||||
}
|
||||
|
||||
protected Sort.Order createOrder(final String property) {
|
||||
return createOrder(property, Sort.Direction.ASC);
|
||||
}
|
||||
|
||||
protected Sort.Order createOrder(final String property, final Sort.Direction direction) {
|
||||
return new Sort.Order(direction, property);
|
||||
}
|
||||
|
||||
protected Sort createSort(final Sort.Order... orders) {
|
||||
return new Sort(orders);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindDistinctPeopleWithOrder() {
|
||||
List<Person> actualPeople = personRepo.findDistinctPeopleByOrderByLastnameDesc(
|
||||
createSort(createOrder("firstname")));
|
||||
|
||||
assertNotNull(actualPeople);
|
||||
assertFalse(actualPeople.isEmpty());
|
||||
assertEquals(7, actualPeople.size());
|
||||
assertEquals(Arrays.asList(imaPigg, jackHandy, sandyHandy, cookieDoe, janeDoe, jonDoe, pieDoe), actualPeople);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindDistinctPersonWithNoOrder() {
|
||||
List<Person> actualPeople = personRepo.findDistinctByLastname("Pigg", null);
|
||||
|
||||
assertNotNull(actualPeople);
|
||||
assertFalse(actualPeople.isEmpty());
|
||||
assertEquals(1, actualPeople.size());
|
||||
assertEquals(String.format("Expected '%1$s'; but was '%2$s'", imaPigg, actualPeople.get(0)),
|
||||
imaPigg, actualPeople.get(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -213,14 +213,14 @@ public class SubRegionRepositoryIntegrationTest {
|
||||
assertNotNull(javaProgrammers);
|
||||
assertFalse(javaProgrammers.isEmpty());
|
||||
assertEquals(2, javaProgrammers.size());
|
||||
assertTrue(javaProgrammers.containsAll(getProgrammers("JamesGosling", "JoshuaBloch")));
|
||||
assertEquals(javaProgrammers, getProgrammers("JamesGosling", "JoshuaBloch"));
|
||||
|
||||
List<Programmer> groovyProgrammers = programmersRepo.findDistinctByProgrammingLanguageLikeOrderByUsernameAsc("Groovy");
|
||||
|
||||
assertNotNull(groovyProgrammers);
|
||||
assertFalse(groovyProgrammers.isEmpty());
|
||||
assertEquals(1, groovyProgrammers.size());
|
||||
assertTrue(groovyProgrammers.containsAll(getProgrammers("JamesStrachan")));
|
||||
assertEquals(groovyProgrammers, getProgrammers("JamesStrachan"));
|
||||
|
||||
programmersRepo.save(new Wrapper<Programmer, String>(createProgrammer("RodJohnson", "Java"), "RodJohnson"));
|
||||
programmersRepo.save(new Wrapper<Programmer, String>(createProgrammer("GuillaumeLaforge", "Groovy"), "GuillaumeLaforge"));
|
||||
@@ -231,21 +231,21 @@ public class SubRegionRepositoryIntegrationTest {
|
||||
assertNotNull(javaProgrammers);
|
||||
assertFalse(javaProgrammers.isEmpty());
|
||||
assertEquals(3, javaProgrammers.size());
|
||||
assertTrue(javaProgrammers.containsAll(getProgrammers("JamesGosling", "JoshuaBloch", "RodJohnson")));
|
||||
assertEquals(javaProgrammers, getProgrammers("JamesGosling", "JoshuaBloch", "RodJohnson"));
|
||||
|
||||
groovyProgrammers = programmersRepo.findDistinctByProgrammingLanguageLikeOrderByUsernameAsc("Groovy");
|
||||
|
||||
assertNotNull(groovyProgrammers);
|
||||
assertFalse(groovyProgrammers.isEmpty());
|
||||
assertEquals(3, groovyProgrammers.size());
|
||||
assertTrue(groovyProgrammers.containsAll(getProgrammers("GraemeRocher", "GuillaumeLaforge", "JamesStrachan")));
|
||||
assertEquals(groovyProgrammers, getProgrammers("GraemeRocher", "GuillaumeLaforge", "JamesStrachan"));
|
||||
|
||||
List<Programmer> javaLikeProgrammers = programmersRepo.findDistinctByProgrammingLanguageLikeOrderByUsernameAsc("Java%");
|
||||
|
||||
assertNotNull(javaLikeProgrammers);
|
||||
assertFalse(javaLikeProgrammers.isEmpty());
|
||||
assertEquals(4, javaLikeProgrammers.size());
|
||||
assertTrue(javaLikeProgrammers.containsAll(getProgrammers("BrendanEich", "JamesGosling", "JoshuaBloch", "RodJohnson")));
|
||||
assertEquals(javaLikeProgrammers, getProgrammers("BrendanEich", "JamesGosling", "JoshuaBloch", "RodJohnson"));
|
||||
|
||||
List<Programmer> pseudoCodeProgrammers = programmersRepo.findDistinctByProgrammingLanguageLikeOrderByUsernameAsc("PseudoCode");
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:gfe="http://www.springframework.org/schema/gemfire"
|
||||
xmlns:gfe-data="http://www.springframework.org/schema/data/gemfire"
|
||||
xmlns:repo="http://www.springframework.org/schema/data/repository"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
|
||||
http://www.springframework.org/schema/data/gemfire http://www.springframework.org/schema/data/gemfire/spring-data-gemfire.xsd
|
||||
http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
">
|
||||
|
||||
<util:properties id="gemfireConfigurationSettings">
|
||||
<prop key="name">springGemFirePersonRepositoryTest</prop>
|
||||
<prop key="mcast-port">0</prop>
|
||||
<prop key="log-level">config</prop>
|
||||
</util:properties>
|
||||
|
||||
<gfe:cache properties-ref="gemfireConfigurationSettings"/>
|
||||
|
||||
<gfe:replicated-region id="simple" persistent="false" key-constraint="java.lang.Long"
|
||||
value-constraint="org.springframework.data.gemfire.repository.sample.Person"/>
|
||||
|
||||
<gfe-data:repositories base-package="org.springframework.data.gemfire.repository.sample">
|
||||
<repo:include-filter type="assignable" expression="org.springframework.data.gemfire.repository.sample.PersonRepository"/>
|
||||
</gfe-data:repositories>
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user