SGF-534 - Fix ordered GemfireRepository.findAll(:Sort) queries.

(cherry picked from commit a68a31a0521e3e63bfb283f4b7c5dc15f7d0f8cc)
Signed-off-by: John Blum <jblum@pivotal.io>
This commit is contained in:
John Blum
2016-09-22 22:28:57 -07:00
parent 2c17055540
commit 5c3461724f
12 changed files with 695 additions and 248 deletions

View File

@@ -0,0 +1,99 @@
/*
* Copyright 2012 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;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.data.gemfire.repository.query.support.OqlKeyword;
/**
* Test suite of test cases testing the contract and functionality
* of the {@link OqlKeyword} enumerated type.
*
* @author John Blum
* @see org.junit.Test
* @see org.springframework.data.gemfire.repository.query.support.OqlKeyword
* @since 1.0.0
*/
public class OqlKeywordUnitTests {
@Rule
public ExpectedException exception = ExpectedException.none();
@Test
public void valueOfIgnoreCaseWithEnumeratedValuesIsSuccessful() {
for (OqlKeyword oqlKeyword : OqlKeyword.values()) {
assertThat(OqlKeyword.valueOfIgnoreCase(oqlKeyword.getKeyword())).isEqualTo(oqlKeyword);
}
}
@Test
public void valueOfIgnoreCaseWithUnconventionalValuesIsSuccessful() {
assertThat(OqlKeyword.valueOfIgnoreCase("and")).isEqualTo(OqlKeyword.AND);
assertThat(OqlKeyword.valueOfIgnoreCase("As")).isEqualTo(OqlKeyword.AS);
assertThat(OqlKeyword.valueOfIgnoreCase("CoUnT")).isEqualTo(OqlKeyword.COUNT);
assertThat(OqlKeyword.valueOfIgnoreCase(" DISTINCT ")).isEqualTo(OqlKeyword.DISTINCT);
assertThat(OqlKeyword.valueOfIgnoreCase(" Order BY ")).isEqualTo(OqlKeyword.ORDER_BY);
}
@Test
public void valueOfIgnoreCaseWithIllegalValuesThrowsIllegalArgumentException() {
assertIllegalOqlKeyword("AN");
assertIllegalOqlKeyword("ASS");
assertIllegalOqlKeyword("CNT");
assertIllegalOqlKeyword("EXTINCT");
assertIllegalOqlKeyword("TO");
assertIllegalOqlKeyword("EXPORT");
assertIllegalOqlKeyword("OUT");
assertIllegalOqlKeyword("IS DEFINED");
assertIllegalOqlKeyword("IS-UNDEFINED");
assertIllegalOqlKeyword("UNLIKE");
assertIllegalOqlKeyword("NIL");
assertIllegalOqlKeyword("NULL VALUE");
assertIllegalOqlKeyword("XOR");
assertIllegalOqlKeyword("ORDER_BY");
assertIllegalOqlKeyword("INSERT");
assertIllegalOqlKeyword("UPDATE");
assertIllegalOqlKeyword("LIST");
assertIllegalOqlKeyword("CLASS");
assertIllegalOqlKeyword("WHAT");
assertIllegalOqlKeyword("WHEN");
}
protected void assertIllegalOqlKeyword(String keyword) {
exception.expect(IllegalArgumentException.class);
exception.expectCause(is(nullValue(Throwable.class)));
exception.expectMessage(String.format("[%s] is not a valid GemFire OQL Keyword", keyword));
OqlKeyword.valueOfIgnoreCase(keyword);
}
@Test
public void getKeywordEqualsNameExceptForOrderBy() {
for (OqlKeyword oqlKeyword : OqlKeyword.values()) {
if (!OqlKeyword.ORDER_BY.equals(oqlKeyword)) {
assertThat(oqlKeyword.getKeyword()).isEqualTo(oqlKeyword.name());
}
}
}
}

View File

@@ -16,11 +16,10 @@
package org.springframework.data.gemfire.repository.query;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -34,48 +33,46 @@ import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
import org.springframework.data.repository.query.parser.PartTree;
/**
* The QueryBuilderTest class is a test suite of test cases testing the contract and functionality of the QueryBuilder
* class.
* Test suite of test cases testing the contract and functionality of the {@link QueryBuilder} class.
*
* @author John Blum
* @see org.junit.Rule
* @see org.junit.Test
* @see org.mockito.Mockito
* @see org.springframework.data.gemfire.repository.query.QueryBuilder
* @since 1.7.0
*/
public class QueryBuilderTest {
public class QueryBuilderUnitTests {
@Rule
public ExpectedException expectedException = ExpectedException.none();
public ExpectedException exception = ExpectedException.none();
@Test
public void createQueryBuilderNonDistinct() {
GemfirePersistentEntity<?> mockPersistentEntity = mock(GemfirePersistentEntity.class, "MockGemfirePersistentEntity");
PartTree mockPartTree = mock(PartTree.class, "MockPartTree");
when(mockPersistentEntity.getRegionName()).thenReturn("Example");
when(mockPartTree.isDistinct()).thenReturn(false);
QueryBuilder queryBuilder = new QueryBuilder(mockPersistentEntity, mockPartTree);
assertThat(queryBuilder.toString(), is(equalTo("SELECT * FROM /Example x")));
verify(mockPersistentEntity, times(1)).getRegionName();
verify(mockPartTree, times(1)).isDistinct();
}
@Test
public void createQueryBuilderWithDistinct() {
GemfirePersistentEntity<?> mockPersistentEntity = mock(GemfirePersistentEntity.class, "MockGemfirePersistentEntity");
PartTree mockPartTree = mock(PartTree.class, "MockPartTree");
public void createQueryBuilderWithDistinctQuery() {
GemfirePersistentEntity<?> mockPersistentEntity = mock(GemfirePersistentEntity.class);
PartTree mockPartTree = mock(PartTree.class);
when(mockPersistentEntity.getRegionName()).thenReturn("Example");
when(mockPartTree.isDistinct()).thenReturn(true);
QueryBuilder queryBuilder = new QueryBuilder(mockPersistentEntity, mockPartTree);
assertThat(queryBuilder.toString(), is(equalTo("SELECT DISTINCT * FROM /Example x")));
assertThat(queryBuilder.toString()).isEqualTo("SELECT DISTINCT * FROM /Example x");
verify(mockPersistentEntity, times(1)).getRegionName();
verify(mockPartTree, times(1)).isDistinct();
}
@Test
public void createQueryBuilderWithNonDistinctQuery() {
GemfirePersistentEntity<?> mockPersistentEntity = mock(GemfirePersistentEntity.class);
PartTree mockPartTree = mock(PartTree.class);
when(mockPersistentEntity.getRegionName()).thenReturn("Example");
when(mockPartTree.isDistinct()).thenReturn(false);
QueryBuilder queryBuilder = new QueryBuilder(mockPersistentEntity, mockPartTree);
assertThat(queryBuilder.toString()).isEqualTo("SELECT * FROM /Example x");
verify(mockPersistentEntity, times(1)).getRegionName();
verify(mockPartTree, times(1)).isDistinct();
@@ -83,28 +80,38 @@ public class QueryBuilderTest {
@Test
public void createQueryBuilderWithNullQueryString() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectCause(is(nullValue(Throwable.class)));
expectedException.expectMessage(is(equalTo("The OQL Query must be specified")));
exception.expect(IllegalArgumentException.class);
exception.expectCause(is(nullValue(Throwable.class)));
exception.expectMessage(is(equalTo("An OQL Query must be specified")));
new QueryBuilder(null);
}
@Test
@SuppressWarnings("all")
public void createWithPredicate() {
Predicate mockPredicate = mock(Predicate.class, "MockPredicate");
Predicate mockPredicate = mock(Predicate.class);
when(mockPredicate.toString(eq(QueryBuilder.DEFAULT_ALIAS))).thenReturn("x.id = 1");
QueryBuilder queryBuilder = new QueryBuilder(String.format("SELECT * FROM /Example %s",
QueryBuilder.DEFAULT_ALIAS));
QueryBuilder queryBuilder = new QueryBuilder(
String.format("SELECT * FROM /Example %s", QueryBuilder.DEFAULT_ALIAS));
QueryString queryString = queryBuilder.create(mockPredicate);
assertThat(queryString, is(notNullValue()));
assertThat(queryString.toString(), is(equalTo("SELECT * FROM /Example x WHERE x.id = 1")));
assertThat(queryString).isNotNull();
assertThat(queryString.toString()).isEqualTo("SELECT * FROM /Example x WHERE x.id = 1");
verify(mockPredicate, times(1)).toString(eq(QueryBuilder.DEFAULT_ALIAS));
}
@Test
public void createWithNullPredicate() {
QueryBuilder queryBuilder = new QueryBuilder("SELECT * FROM /Example");
QueryString queryString = queryBuilder.create(null);
assertThat(queryString).isNotNull();
assertThat(queryString.toString()).isEqualTo("SELECT * FROM /Example");
}
}

View File

@@ -16,19 +16,26 @@
package org.springframework.data.gemfire.repository.query;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.never;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.data.gemfire.repository.query.QueryString.HINT_PATTERN;
import static org.springframework.data.gemfire.repository.query.QueryString.IMPORT_PATTERN;
import static org.springframework.data.gemfire.repository.query.QueryString.LIMIT_PATTERN;
import static org.springframework.data.gemfire.repository.query.QueryString.TRACE_PATTERN;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import com.gemstone.gemfire.cache.Region;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
@@ -36,250 +43,299 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.gemfire.repository.sample.Person;
import org.springframework.data.gemfire.repository.sample.RootUser;
import com.gemstone.gemfire.cache.Region;
/**
*
* Test suite of test cases testing the contract and functionality of the {@link QueryString} class.
*
* @author Oliver Gierke
* @author John Blum
* @see org.junit.Test
* @see org.mockito.Mock
* @see org.springframework.data.gemfire.repository.query.QueryString
*/
@RunWith(MockitoJUnitRunner.class)
public class QueryStringUnitTests {
@Rule
public ExpectedException exception = ExpectedException.none();
@Mock
@SuppressWarnings("rawtypes")
Region region;
protected Sort.Order createOrder(final String property) {
return createOrder(property, Sort.Direction.ASC);
protected Sort.Order newSortOrder(String property) {
return newSortOrder(property, Sort.Direction.ASC);
}
protected Sort.Order createOrder(final String property, final Sort.Direction direction) {
protected Sort.Order newSortOrder(String property, Sort.Direction direction) {
return new Sort.Order(direction, property);
}
protected Sort createSort(Sort.Order... orders) {
protected Sort newSort(Sort.Order... orders) {
return new Sort(orders);
}
@Test
public void createQueryStringWithCount() {
QueryString queryString = new QueryString(Person.class, true);
assertThat(queryString, is(notNullValue()));
assertThat(queryString.toString(), is(equalTo("SELECT count(*) FROM /Person")));
public void createQueryStringWithDomainType() {
assertThat(new QueryString(Person.class).toString()).isEqualTo("SELECT * FROM /Person");
}
@Test
public void createQueryStringWithoutCount() {
QueryString queryString = new QueryString(Person.class);
public void createQueryStringWithDomainTypeHavingCount() {
assertThat(new QueryString(Person.class, true).toString()).isEqualTo("SELECT count(*) FROM /Person");
}
assertThat(queryString, is(notNullValue()));
assertThat(queryString.toString(), is(equalTo("SELECT * FROM /Person")));
@Test
public void createQueryStringWithNullDomainType() {
exception.expect(IllegalArgumentException.class);
exception.expectCause(is(nullValue(Throwable.class)));
exception.expectMessage(is(equalTo("domainType must not be null")));
new QueryString((Class<?>) null);
}
@Test
public void createQueryStringWithQuery() {
String query = "SELECT * FROM /Example";
assertThat(new QueryString(query).toString()).isEqualTo(query);
}
@Test
public void createQueryStringWithUnspecifiedQueryThrowsIllegalArgumentException() {
assertUnspecifiedQueryThrowsIllegalArgumentException("");
assertUnspecifiedQueryThrowsIllegalArgumentException(" ");
assertUnspecifiedQueryThrowsIllegalArgumentException(null);
}
protected void assertUnspecifiedQueryThrowsIllegalArgumentException(String query) {
exception.expect(IllegalArgumentException.class);
exception.expectCause(is(nullValue(Throwable.class)));
exception.expectMessage(is(equalTo("An OQL Query must be specified")));
new QueryString(query);
}
@Test
public void hintPatternMatches() {
assertThat(QueryString.HINT_PATTERN.matcher("<HINT 'ExampleIdx'>").find(), is(true));
assertThat(QueryString.HINT_PATTERN.matcher("<HINT 'IdIdx'> SELECT * FROM /Example WHERE id = $1").find(), is(true));
assertThat(QueryString.HINT_PATTERN.matcher("<HINT 'LastNameIdx', 'BirthDateIdx'> SELECT * FROM /Person WHERE lastName = $1 AND birthDate = $2").find(), is(true));
assertThat(matches(HINT_PATTERN, "<HINT 'ExampleIndex'>")).isTrue();
assertThat(matches(HINT_PATTERN, "<HINT 'IdIdx'> SELECT * FROM /Example WHERE id = $1")).isTrue();
assertThat(matches(HINT_PATTERN, "<HINT 'LastNameIdx', 'BirthDateIdx'> SELECT * FROM /Person WHERE lastName = $1 AND birthDate = $2")).isTrue();
}
@Test
public void hintPatternNoMatches() {
assertThat(QueryString.HINT_PATTERN.matcher("HINT").find(), is(false));
assertThat(QueryString.HINT_PATTERN.matcher("<HINT>").find(), is(false));
assertThat(QueryString.HINT_PATTERN.matcher("<HINT ''>").find(), is(false));
assertThat(QueryString.HINT_PATTERN.matcher("<HINT IdIdx>").find(), is(false));
assertThat(QueryString.HINT_PATTERN.matcher("<HINT IdIdx, LastNameIdx>").find(), is(false));
assertThat(QueryString.HINT_PATTERN.matcher("SELECT * FROM /Example").find(), is(false));
assertThat(QueryString.HINT_PATTERN.matcher("SELECT * FROM /Hint").find(), is(false));
assertThat(QueryString.HINT_PATTERN.matcher("SELECT x.hint FROM /Clues x WHERE x.hint > $1").find(), is(false));
assertThat(matches(HINT_PATTERN, "HINT")).isFalse();
assertThat(matches(HINT_PATTERN, "<HINT>")).isFalse();
assertThat(matches(HINT_PATTERN, "<HINT ''>")).isFalse();
assertThat(matches(HINT_PATTERN, "<HINT ' '>")).isFalse();
assertThat(matches(HINT_PATTERN, "<HINT IdIdx>")).isFalse();
assertThat(matches(HINT_PATTERN, "<HINT LastNameIdx, FirstNameIdx>")).isFalse();
assertThat(matches(HINT_PATTERN, "SELECT * FROM /Example")).isFalse();
assertThat(matches(HINT_PATTERN, "SELECT * FROM /Hint")).isFalse();
assertThat(matches(HINT_PATTERN, "SELECT x.hint FROM /Clues x WHERE x.hint > $1")).isFalse();
}
@Test
public void importPatternMatches() {
assertThat(QueryString.IMPORT_PATTERN.matcher("IMPORT *;").find(), is(true));
assertThat(QueryString.IMPORT_PATTERN.matcher("IMPORT org.example.*;").find(), is(true));
assertThat(QueryString.IMPORT_PATTERN.matcher("IMPORT org.example.Type;").find(), is(true));
assertThat(QueryString.IMPORT_PATTERN.matcher("IMPORT org.example.app.DomainType; SELECT * FROM /Domain").find(), is(true));
assertThat(matches(IMPORT_PATTERN, "IMPORT *;")).isTrue();
assertThat(matches(IMPORT_PATTERN, "IMPORT org.example.*;")).isTrue();
assertThat(matches(IMPORT_PATTERN, "IMPORT org.example.Type;")).isTrue();
assertThat(matches(IMPORT_PATTERN, "IMPORT org.example.app.domain.DomainType; SELECT * FROM /DomainType")).isTrue();
}
@Test
public void importPatternNoMatches() {
assertThat(QueryString.IMPORT_PATTERN.matcher("IMPORT").find(), is(false));
assertThat(QueryString.IMPORT_PATTERN.matcher("IMPORT ;").find(), is(false));
assertThat(QueryString.IMPORT_PATTERN.matcher("IMPORT *").find(), is(false));
assertThat(QueryString.IMPORT_PATTERN.matcher("SELECT * FROM /Example").find(), is(false));
assertThat(matches(IMPORT_PATTERN, "IMPORT")).isFalse();
assertThat(matches(IMPORT_PATTERN, "IMPORT ;")).isFalse();
assertThat(matches(IMPORT_PATTERN, "IMPORT *")).isFalse();
assertThat(matches(IMPORT_PATTERN, "IMPORT *:")).isFalse();
assertThat(matches(IMPORT_PATTERN, "SELECT * FROM /Example")).isFalse();
}
@Test
public void limitPatternMatches() {
assertThat(QueryString.LIMIT_PATTERN.matcher("LIMIT 10").find(), is(true));
assertThat(QueryString.LIMIT_PATTERN.matcher("SELECT * FROM /Example LIMIT 10").find(), is(true));
assertThat(QueryString.LIMIT_PATTERN.matcher("SELECT * FROM /Example WHERE id = $1 LIMIT 10").find(), is(true));
assertThat(matches(LIMIT_PATTERN, "LIMIT 0")).isTrue();
assertThat(matches(LIMIT_PATTERN, "LIMIT 1")).isTrue();
assertThat(matches(LIMIT_PATTERN, "LIMIT 10")).isTrue();
assertThat(matches(LIMIT_PATTERN, "SELECT * FROM /Example LIMIT 10")).isTrue();
assertThat(matches(LIMIT_PATTERN, "SELECT * FROM /Example WHERE id = $1 LIMIT 10")).isTrue();
}
@Test
public void limitPatternNoMatches() {
assertThat(QueryString.LIMIT_PATTERN.matcher("LIMIT").find(), is(false));
assertThat(QueryString.LIMIT_PATTERN.matcher("LIMIT lO").find(), is(false));
assertThat(QueryString.LIMIT_PATTERN.matcher("LIMIT FF").find(), is(false));
assertThat(QueryString.LIMIT_PATTERN.matcher("LIMIT ten").find(), is(false));
assertThat(QueryString.LIMIT_PATTERN.matcher("SELECT * FROM /Example LIMIT").find(), is(false));
assertThat(QueryString.LIMIT_PATTERN.matcher("SELECT * FROM /Example WHERE id = $1 LIM 10").find(), is(false));
assertThat(matches(LIMIT_PATTERN, "LIMIT")).isFalse();
assertThat(matches(LIMIT_PATTERN, "LIMIT lO")).isFalse();
assertThat(matches(LIMIT_PATTERN, "LIMIT AF")).isFalse();
assertThat(matches(LIMIT_PATTERN, "LIMIT ten")).isFalse();
assertThat(matches(LIMIT_PATTERN, "SELECT * FROM /Example LIMIT")).isFalse();
assertThat(matches(LIMIT_PATTERN, "SELECT * FROM /Example WHERE id = $1 LIM 10")).isFalse();
}
@Test
public void tracePatternMatches() {
assertThat(QueryString.TRACE_PATTERN.matcher("<TRACE>").find(), is(true));
assertThat(QueryString.TRACE_PATTERN.matcher("<TRACE> SELECT * FROM /Example").find(), is(true));
assertThat(QueryString.TRACE_PATTERN.matcher("<TRACE>SELECT * FROM /Example").find(), is(true));
assertThat(QueryString.TRACE_PATTERN.matcher("SELECT * FROM /Example<TRACE>").find(), is(true));
assertThat(matches(TRACE_PATTERN, "<TRACE>")).isTrue();
assertThat(matches(TRACE_PATTERN, "<TRACE> SELECT * FROM /Example")).isTrue();
assertThat(matches(TRACE_PATTERN, "<TRACE>SELECT * FROM /Example")).isTrue();
assertThat(matches(TRACE_PATTERN, "SELECT * FROM /Example<TRACE>")).isTrue();
}
@Test
public void tracePatternNoMatches() {
assertThat(matches(TRACE_PATTERN, "TRACE")).isFalse();
assertThat(matches(TRACE_PATTERN, "TRACE SELECT * FROM /Example")).isFalse();
assertThat(matches(TRACE_PATTERN, "<TRACE SELECT * FROM /Example>")).isFalse();
}
protected boolean matches(Pattern pattern, String value) {
return pattern.matcher(value).find();
}
// SGF-251
@Test
public void replacesDomainObjectWithRegionPathCorrectly() {
QueryString query = new QueryString("SELECT * FROM /Person p WHERE p.firstname = $1");
public void replacesDomainTypeSimpleNameWithRegionPathCorrectly() {
QueryString query = new QueryString(Person.class);
when(region.getFullPath()).thenReturn("/foo/bar");
assertThat(query.forRegion(Person.class, region).toString(), is("SELECT * FROM /foo/bar p WHERE p.firstname = $1"));
assertThat(query.forRegion(Person.class, region).toString()).isEqualTo("SELECT * FROM /foo/bar");
verify(region, never()).getName();
verify(region, times(1)).getFullPath();
}
// SGF-156
// SGF-251
// SGF-156, SGF-251
@Test
public void replacesDomainObjectWithPluralRegionPathCorrectly() {
QueryString query = new QueryString("SELECT * FROM /Persons p WHERE p.firstname = $1");
public void replacesFromClauseWithRegionPathCorrectly() {
QueryString query = new QueryString("SELECT * FROM /Persons p WHERE p.lastname = $1");
when(region.getFullPath()).thenReturn("/People");
assertThat(query.forRegion(Person.class, region).toString(),
is("SELECT * FROM /People p WHERE p.firstname = $1"));
assertThat(query.forRegion(Person.class, region).toString())
.isEqualTo("SELECT * FROM /People p WHERE p.lastname = $1");
verify(region, never()).getName();
verify(region, times(1)).getFullPath();
}
// SGF-252
@Test
public void replacesFullyQualifiedSubRegionReferenceWithRegionPathCorrectly() {
public void replacesFullyQualifiedSubRegionPathWithRegionPathCorrectly() {
QueryString query = new QueryString("SELECT * FROM //Local/Root/Users u WHERE u.username = $1");
when(region.getFullPath()).thenReturn("/Local/Root/Users");
when(region.getFullPath()).thenReturn("/Remote/Root/Users");
assertThat(query.forRegion(RootUser.class, region).toString(), is(equalTo(
"SELECT * FROM /Local/Root/Users u WHERE u.username = $1")));
assertThat(query.forRegion(RootUser.class, region).toString())
.isEqualTo("SELECT * FROM /Remote/Root/Users u WHERE u.username = $1");
verify(region, never()).getName();
verify(region, times(1)).getFullPath();
}
@Test
public void bindsInValuesCorrectly() {
QueryString query = new QueryString("SELECT * FROM /Person p WHERE p.firstname IN SET $1");
List<Integer> values = Arrays.asList(1, 2, 3);
assertThat(query.bindIn(values).toString(), is("SELECT * FROM /Person p WHERE p.firstname IN SET ('1', '2', '3')"));
QueryString query = new QueryString("SELECT * FROM /Collection WHERE elements IN SET $1");
assertThat(query.bindIn(Arrays.asList(1, 2, 3)).toString())
.isEqualTo("SELECT * FROM /Collection WHERE elements IN SET ('1', '2', '3')");
}
@Test
public void detectsInParameterIndexesCorrectly() {
QueryString query = new QueryString("IN SET $1 OR IN SET $2");
Iterable<Integer> indexes = query.getInParameterIndexes();
assertThat(indexes, is((Iterable<Integer>) Arrays.asList(1, 2)));
QueryString query = new QueryString("SELECT * FROM /Example WHERE values IN SET $1 OR IN SET $2");
assertThat(query.getInParameterIndexes()).isEqualTo(Arrays.asList(1, 2));
}
@Test
public void addsNoOrderByClauseCorrectly() {
QueryString query = new QueryString("SELECT * FROM /People p").orderBy(null);
assertThat(query.toString(), is(equalTo("SELECT * FROM /People p")));
assertThat(query.toString()).isEqualTo("SELECT * FROM /People p");
}
@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")));
.orderBy(newSort(newSortOrder("lastName", Sort.Direction.DESC), newSortOrder("firstName")));
assertThat(query.toString(), is(equalTo(
"SELECT * FROM /People p WHERE p.lastName = $1 ORDER BY lastName DESC, firstName ASC")));
assertThat(query.toString())
.isEqualTo("SELECT DISTINCT * FROM /People p WHERE p.lastName = $1 ORDER BY lastName DESC, firstName ASC");
}
@Test
public void addsSingleOrderByClauseCorrectly() {
QueryString query = new QueryString("SELECT DISTINCT p.lastName FROM /People p WHERE p.firstName = $1")
.orderBy(createSort(createOrder("lastName")));
.orderBy(newSort(newSortOrder("lastName")));
assertThat(query.toString(), is(equalTo(
"SELECT DISTINCT p.lastName FROM /People p WHERE p.firstName = $1 ORDER BY lastName ASC")));
assertThat(query.toString())
.isEqualTo("SELECT DISTINCT p.lastName FROM /People p WHERE p.firstName = $1 ORDER BY lastName ASC");
}
@Test
public void withHints() {
assertThat(new QueryString("SELECT * FROM /Example").withHints("IdIdx").toString(),
is(equalTo("<HINT 'IdIdx'> SELECT * FROM /Example")));
assertThat(new QueryString("SELECT * FROM /Example").withHints("IdIdx", "SpatialIdx", "TxDateIdx").toString(),
is(equalTo("<HINT 'IdIdx', 'SpatialIdx', 'TxDateIdx'> SELECT * FROM /Example")));
assertThat(new QueryString("SELECT * FROM /Example").withHints("IdIdx").toString())
.isEqualTo("<HINT 'IdIdx'> SELECT * FROM /Example");
assertThat(new QueryString("SELECT * FROM /Example").withHints("IdIdx", "SpatialIdx", "TxDateIdx").toString())
.isEqualTo("<HINT 'IdIdx', 'SpatialIdx', 'TxDateIdx'> SELECT * FROM /Example");
}
@Test
public void withoutHints() {
QueryString expectedQueryString = new QueryString("SELECT * FROM /Example");
assertThat(expectedQueryString.withHints((String[]) null), is(sameInstance(expectedQueryString)));
assertThat(expectedQueryString.withHints(), is(sameInstance(expectedQueryString)));
assertThat(expectedQueryString.withHints()).isSameAs(expectedQueryString);
assertThat(expectedQueryString.withHints((String[]) null)).isSameAs(expectedQueryString);
}
@Test
public void withImport() {
assertThat(new QueryString("SELECT * FROM /People").withImport("org.example.app.domain.Person").toString(),
is(equalTo("IMPORT org.example.app.domain.Person; SELECT * FROM /People")));
assertThat(new QueryString("SELECT * FROM /People").withImport("org.example.app.domain.Person").toString())
.isEqualTo("IMPORT org.example.app.domain.Person; SELECT * FROM /People");
}
@Test
public void withoutImport() {
QueryString expectedQueryString = new QueryString("SELECT * FROM /Example");
assertThat(expectedQueryString.withImport(null), is(sameInstance(expectedQueryString)));
assertThat(expectedQueryString.withImport(""), is(sameInstance(expectedQueryString)));
assertThat(expectedQueryString.withImport(" "), is(sameInstance(expectedQueryString)));
assertThat(expectedQueryString.withImport(null)).isSameAs(expectedQueryString);
assertThat(expectedQueryString.withImport("")).isSameAs(expectedQueryString);
assertThat(expectedQueryString.withImport(" ")).isSameAs(expectedQueryString);
}
@Test
public void withLimit() {
assertThat(new QueryString("SELECT * FROM /Example").withLimit(10).toString(),
is(equalTo("SELECT * FROM /Example LIMIT 10")));
assertThat(new QueryString("SELECT * FROM /Example").withLimit(-5).toString(),
is(equalTo("SELECT * FROM /Example LIMIT -5")));
assertThat(new QueryString("SELECT * FROM /Example").withLimit(0).toString(),
is(equalTo("SELECT * FROM /Example LIMIT 0")));
assertThat(new QueryString("SELECT * FROM /Example").withLimit(10).toString())
.isEqualTo("SELECT * FROM /Example LIMIT 10");
assertThat(new QueryString("SELECT * FROM /Example").withLimit(0).toString())
.isEqualTo("SELECT * FROM /Example LIMIT 0");
assertThat(new QueryString("SELECT * FROM /Example").withLimit(-5).toString())
.isEqualTo("SELECT * FROM /Example LIMIT -5");
}
@Test
public void withoutLimit() {
QueryString expectedQueryString = new QueryString("SELECT * FROM /Example");
assertThat(expectedQueryString.withLimit(null), is(sameInstance(expectedQueryString)));
assertThat(expectedQueryString.withLimit(null)).isSameAs(expectedQueryString);
}
@Test
public void withTrace() {
assertThat(new QueryString("SELECT * FROM /Example").withTrace().toString(),
is(equalTo("<TRACE> SELECT * FROM /Example")));
assertThat(new QueryString("SELECT * FROM /Example").withTrace().toString())
.isEqualTo("<TRACE> SELECT * FROM /Example");
}
@Test
public void withHintAndTrace() {
assertThat(new QueryString("SELECT * FROM /Example").withHints("IdIdx").withTrace().toString(),
is(equalTo("<TRACE> <HINT 'IdIdx'> SELECT * FROM /Example")));
assertThat(new QueryString("SELECT * FROM /Example").withHints("IdIdx").withTrace().toString())
.isEqualTo("<TRACE> <HINT 'IdIdx'> SELECT * FROM /Example");
}
@Test
public void withHintImportLimitAndTrace() {
assertThat(new QueryString("SELECT * FROM /Example").withImport("org.example.domain.Type")
.withHints("IdIdx", "NameIdx").withLimit(20).withTrace().toString(),
is(equalTo("<TRACE> <HINT 'IdIdx', 'NameIdx'> IMPORT org.example.domain.Type; SELECT * FROM /Example LIMIT 20")));
}
QueryString query = new QueryString("SELECT * FROM /Example");
assertThat(query.withImport("org.example.domain.Type").withHints("IdIdx", "NameIdx").withLimit(20).withTrace().toString())
.isEqualTo("<TRACE> <HINT 'IdIdx', 'NameIdx'> IMPORT org.example.domain.Type; SELECT * FROM /Example LIMIT 20");
}
}

View File

@@ -52,11 +52,14 @@ public interface PersonRepository extends GemfireRepository<Person, Long> {
Collection<Person> findByFirstnameAndLastname(String firstName, String lastName);
@Trace
Collection<Person> findByFirstnameIgnoreCaseAndLastnameIgnoreCase(String firstName, String lastName);
Collection<Person> findByFirstnameAndLastnameAllIgnoringCase(String firstName, String lastName);
Collection<Person> findByFirstnameOrLastname(String firstName, String lastName);
Collection<Person> findDistinctByFirstnameOrLastname(String firstName, String lastName, Sort order);
Person findByLastname(String lastName);
Collection<Person> findByLastnameEndingWith(String lastName);

View File

@@ -16,14 +16,12 @@
package org.springframework.data.gemfire.repository.sample;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicLong;
@@ -48,7 +46,7 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* The PersonRepositoryTest class...
* The PersonRepositoryIntegrationTests class...
*
* @author John Blum
* @see org.junit.Test
@@ -60,18 +58,20 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @since 1.4.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = PersonRepositoryTest.GemFireConfiguration.class)
@ContextConfiguration(classes = PersonRepositoryIntegrationTests.GemFireConfiguration.class)
@SuppressWarnings("unused")
public class PersonRepositoryTest {
public class PersonRepositoryIntegrationTests {
private static final String GEMFIRE_LOG_LEVEL = System.getProperty("gemfire.log-level", "warning");
private static final String DEFAULT_GEMFIRE_LOG_LEVEL = "warning";
private static final String GEMFIRE_LOG_LEVEL = System.getProperty("gemfire.log-level", DEFAULT_GEMFIRE_LOG_LEVEL);
protected final AtomicLong ID_SEQUENCE = new AtomicLong(0l);
protected final AtomicLong ID_SEQUENCE = new AtomicLong(0L);
private Person cookieDoe = newPerson("Cookie", "Doe");
private Person janeDoe = newPerson("Jane", "Doe");
private Person jonDoe = newPerson("Jon", "Doe");
private Person pieDoe = newPerson("Pie", "Doe");
private Person sourDoe = newPerson("Sour", "Doe");
private Person jackHandy = newPerson("Jack", "Handy");
private Person sandyHandy = newPerson("Sandy", "Handy");
private Person imaPigg = newPerson("Ima", "Pigg");
@@ -82,6 +82,7 @@ public class PersonRepositoryTest {
@Before
public void setup() {
if (personRepository.count() == 0) {
sourDoe = personRepository.save(sourDoe);
sandyHandy = personRepository.save(sandyHandy);
jonDoe = personRepository.save(jonDoe);
jackHandy = personRepository.save(jackHandy);
@@ -91,18 +92,28 @@ public class PersonRepositoryTest {
cookieDoe = personRepository.save(cookieDoe);
}
assertThat(personRepository.count(), is(equalTo(7L)));
assertThat(personRepository.count()).isEqualTo(8L);
}
protected <T> List<T> asList(Iterable<T> iterable) {
List<T> list = new ArrayList<T>();
for (T element : iterable) {
list.add(element);
}
return list;
}
protected Person newPerson(String firstName, String lastName) {
return new Person(ID_SEQUENCE.incrementAndGet(), firstName, lastName);
}
protected Sort.Order newOrder(String property) {
return newOrder(property, Sort.Direction.ASC);
protected Sort.Order newSortOrder(String property) {
return newSortOrder(property, Sort.Direction.ASC);
}
protected Sort.Order newOrder(String property, Sort.Direction direction) {
protected Sort.Order newSortOrder(String property, Sort.Direction direction) {
return new Sort.Order(direction, property);
}
@@ -111,33 +122,71 @@ public class PersonRepositoryTest {
}
@Test
public void findDistinctPeopleOrderedByFirstnameDescending() {
List<Person> actualPeople = personRepository.findDistinctPeopleByOrderByLastnameDesc(
newSort(newOrder("firstname")));
public void findAllPeopleSorted() {
Iterable<Person> people = personRepository.findAll(newSort(newSortOrder("firstname")));
assertThat(actualPeople, is(notNullValue(List.class)));
assertThat(actualPeople.size(), is(equalTo(7)));
assertThat(actualPeople, is(equalTo(Arrays.asList(
imaPigg, jackHandy, sandyHandy, cookieDoe, janeDoe, jonDoe, pieDoe))));
assertThat(people).isNotNull();
List<Person> peopleList = asList(people);
assertThat(peopleList.size()).isEqualTo(8);
assertThat(peopleList).isEqualTo(
Arrays.asList(cookieDoe, imaPigg, jackHandy, janeDoe, jonDoe, pieDoe, sandyHandy, sourDoe));
}
@Test
public void findDistinctPersonWithUnordered() {
public void findDistinctPeopleOrderedByLastnameDescendingFirstnameAscending() {
List<Person> actualPeople = personRepository.findDistinctPeopleByOrderByLastnameDesc(
newSort(newSortOrder("firstname")));
assertThat(actualPeople).isNotNull();
assertThat(actualPeople.size()).isEqualTo(8);
assertThat(actualPeople).isEqualTo(Arrays.asList(
imaPigg, jackHandy, sandyHandy, cookieDoe, janeDoe, jonDoe, pieDoe, sourDoe));
}
@Test
public void findDistinctPeopleByLastnameUnordered() {
List<Person> actualPeople = personRepository.findDistinctByLastname("Handy", null);
assertThat(actualPeople, is(notNullValue(List.class)));
assertThat(actualPeople.size(), is(equalTo(2)));
assertThat(String.format("Expected '%1$s'; but was '%2$s'", Arrays.asList(jackHandy, sandyHandy), actualPeople),
actualPeople, contains(jackHandy, sandyHandy));
assertThat(actualPeople).isNotNull();
assertThat(actualPeople.size()).isEqualTo(2);
assertThat(actualPeople).containsAll(Arrays.asList(jackHandy, sandyHandy));
}
@Test
public void findDistinctPeopleByFirstOrLastNameWithSort() {
Collection<Person> people = personRepository.findDistinctByFirstnameOrLastname("Cookie", "Pigg",
newSort(newSortOrder("lastname", Sort.Direction.DESC), newSortOrder("firstname", Sort.Direction.ASC)));
assertThat(people).isNotNull();
assertThat(people.size()).isEqualTo(2);
Iterator<Person> peopleIterator = people.iterator();
assertThat(peopleIterator.hasNext()).isTrue();
assertThat(peopleIterator.next()).isEqualTo(imaPigg);
assertThat(peopleIterator.hasNext()).isTrue();
assertThat(peopleIterator.next()).isEqualTo(cookieDoe);
assertThat(peopleIterator.hasNext()).isFalse();
}
@Test
public void findPersonByFirstAndLastNameIgnoringCase() {
Collection<Person> people = personRepository.findByFirstnameIgnoreCaseAndLastnameIgnoreCase("jON", "doE");
assertThat(people, is(notNullValue(Collection.class)));
assertThat(people.size(), is(equalTo(1)));
assertThat(people.iterator().next(), is(equalTo(jonDoe)));
assertThat(people).isNotNull();
assertThat(people.size()).isEqualTo(1);
assertThat(people.iterator().next()).isEqualTo(jonDoe);
}
@Test
public void findByFirstAndLastNameAllIgnoringCase() {
Collection<Person> people = personRepository.findByFirstnameAndLastnameAllIgnoringCase("IMa", "PIGg");
assertThat(people).isNotNull();
assertThat(people.size()).isEqualTo(1);
assertThat(people.iterator().next()).isEqualTo(imaPigg);
}
@Configuration
@@ -146,24 +195,25 @@ public class PersonRepositoryTest {
value = org.springframework.data.gemfire.repository.sample.PersonRepository.class))
public static class GemFireConfiguration {
String applicationName() {
return PersonRepositoryTest.class.getSimpleName();
}
String logLevel() {
return GEMFIRE_LOG_LEVEL;
}
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", applicationName());
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("locators", "");
gemfireProperties.setProperty("log-level", logLevel());
return gemfireProperties;
}
String applicationName() {
return PersonRepositoryIntegrationTests.class.getSimpleName();
}
String logLevel() {
return GEMFIRE_LOG_LEVEL;
}
@Bean
CacheFactoryBean gemfireCache() {
CacheFactoryBean gemfireCache = new CacheFactoryBean();