Skip to content

Commit

Permalink
SGF-507 - Handle case-insensitive OQL queries defined as Repository q…
Browse files Browse the repository at this point in the history
…uery methods.
  • Loading branch information
jxblum committed Jul 18, 2016
1 parent 9c37a5a commit 96a5990
Show file tree
Hide file tree
Showing 21 changed files with 622 additions and 318 deletions.
8 changes: 4 additions & 4 deletions .gitignore
@@ -1,8 +1,8 @@
.DS_Store
target
bin
build
out
bin/
build/
out/
target/
.gradle
.springBeans
*.iml
Expand Down
4 changes: 4 additions & 0 deletions src/main/asciidoc/reference/repositories.adoc
Expand Up @@ -109,6 +109,10 @@ gets to verbose you can annotate the query methods with `@Query` as seen for met
| `findByFirstnameNotIn(Collection<String> x)`
| `x.firstname NOT IN SET $1`

| `IgnoreCase`
| `findByFirstnameIgnoreCase(String firstName)`
| `x.firstname.equalsIgnoreCase($1)`

| (No keyword)
| `findByFirstname(String name)`
| `x.firstname = $1`
Expand Down
Expand Up @@ -24,7 +24,7 @@
import org.springframework.data.util.TypeInformation;

/**
*
*
* @author Oliver Gierke
* @author John Blum
*/
Expand Down Expand Up @@ -58,7 +58,7 @@ protected <T> GemfirePersistentEntity<T> createPersistentEntity(TypeInformation<
@Override
protected GemfirePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
GemfirePersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {

return new GemfirePersistentProperty(field, descriptor, owner, simpleTypeHolder);
}

}
33 changes: 17 additions & 16 deletions src/main/java/org/springframework/data/gemfire/mapping/Regions.java
Expand Up @@ -36,29 +36,30 @@ public class Regions implements Iterable<Region<?, ?>> {

private final Map<String, Region<?, ?>> regions;

private final MappingContext<? extends GemfirePersistentEntity<?>, ?> context;
private final MappingContext<? extends GemfirePersistentEntity<?>, ?> mappingContext;

/**
* Creates a new {@link Regions} wrapper for the given {@link Region}s and
* {@link MappingContext}.
*
*
* @param regions must not be {@literal null}.
* @param context must not be {@literal null}.
* @param mappingContext must not be {@literal null}.
*/
public Regions(Iterable<Region<?, ?>> regions, MappingContext<? extends GemfirePersistentEntity<?>, ?> context) {
public Regions(Iterable<Region<?, ?>> regions,
MappingContext<? extends GemfirePersistentEntity<?>, ?> mappingContext) {

Assert.notNull(regions);
Assert.notNull(context);
Assert.notNull(regions, "Regions must not be null");
Assert.notNull(mappingContext, "MappingContext must not be null");

Map<String, com.gemstone.gemfire.cache.Region<?, ?>> regionMap = new HashMap<String, Region<?, ?>>();
Map<String, Region<?, ?>> regionMap = new HashMap<String, Region<?, ?>>();

for (Region<?, ?> region : regions) {
regionMap.put(region.getName(), region);
regionMap.put(region.getFullPath(), region);
}

this.regions = Collections.unmodifiableMap(regionMap);
this.context = context;
this.mappingContext = mappingContext;
}

/**
Expand All @@ -67,15 +68,15 @@ public Regions(Iterable<Region<?, ?>> regions, MappingContext<? extends GemfireP
* information is found.
*
* @param <T> the Region value class type.
* @param type must not be {@literal null}.
* @param entityType must not be {@literal null}.
* @return the {@link Region} the given type is mapped to.
*/
@SuppressWarnings("unchecked")
public <T> Region<?, T> getRegion(Class<T> type) {
Assert.notNull(type);
public <T> Region<?, T> getRegion(Class<T> entityType) {
Assert.notNull(entityType, "entityType must not be null");

GemfirePersistentEntity<?> entity = context.getPersistentEntity(type);
String regionName = (entity != null ? entity.getRegionName() : type.getSimpleName());
GemfirePersistentEntity<?> entity = mappingContext.getPersistentEntity(entityType);
String regionName = (entity != null ? entity.getRegionName() : entityType.getSimpleName());

return (Region<?, T>) regions.get(regionName);
}
Expand All @@ -90,18 +91,18 @@ public <T> Region<?, T> getRegion(Class<T> type) {
*/
@SuppressWarnings("unchecked")
public <S, T> Region<S, T> getRegion(String namePath) {
Assert.notNull(namePath);
Assert.hasText(namePath, "Region name/path is required");

return (Region<S, T>) regions.get(namePath);
}

/*
* (non-Javadoc)
*
*
* @see java.lang.Iterable#iterator()
*/
@Override
public Iterator<Region<?, ?>> iterator() {
return regions.values().iterator();
}

}
Expand Up @@ -27,30 +27,32 @@

/**
* Query creator to create {@link QueryString} instances.
*
*
* @author Oliver Gierke
* @author John Blum
*/
class GemfireQueryCreator extends AbstractQueryCreator<QueryString, Predicates> {

private static final Log LOG = LogFactory.getLog(GemfireQueryCreator.class);

private final QueryBuilder query;
private Iterator<Integer> indexes;

private final QueryBuilder queryBuilder;

/**
* Creates a new {@link GemfireQueryCreator} using the given {@link PartTree} and domain class.
*
*
* @param tree must not be {@literal null}.
* @param entity must not be {@literal null}.
*/
public GemfireQueryCreator(PartTree tree, GemfirePersistentEntity<?> entity) {
super(tree);

this.query = new QueryBuilder(entity, tree);
this.queryBuilder = new QueryBuilder(entity, tree);
this.indexes = new IndexProvider();
}

/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#createQuery(org.springframework.data.domain.Sort)
*/
Expand All @@ -69,7 +71,7 @@ protected Predicates create(Part part, Iterator<Object> iterator) {
return Predicates.create(part, this.indexes);
}

/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#and(org.springframework.data.repository.query.parser.Part, java.lang.Object, java.util.Iterator)
*/
Expand All @@ -78,7 +80,7 @@ protected Predicates and(Part part, Predicates base, Iterator<Object> iterator)
return base.and(Predicates.create(part, this.indexes));
}

/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#or(java.lang.Object, java.lang.Object)
*/
Expand All @@ -87,21 +89,28 @@ protected Predicates or(Predicates base, Predicates criteria) {
return base.or(criteria);
}

/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#complete(java.lang.Object, org.springframework.data.domain.Sort)
*/
@Override
protected QueryString complete(Predicates criteria, Sort sort) {
QueryString result = query.create(criteria).orderBy(sort);
QueryString query = queryBuilder.create(criteria).orderBy(sort);

if (LOG.isDebugEnabled()) {
LOG.debug(String.format("Created Query '%1$s'", result.toString()));
LOG.debug(String.format("Created Query '%1$s'", query.toString()));
}

return result;
return query;
}

/**
* {@link IndexProvider} is an {@link Iterator} providing sequentially numbered placeholders (starting at 1),
* in a generated GemFire OQL statement corresponding to all possible arguments passed to
* the query's indexed parameters.
*
* @see java.util.Iterator
*/
private static class IndexProvider implements Iterator<Integer> {

private int index;
Expand All @@ -110,17 +119,17 @@ public IndexProvider() {
this.index = 1;
}

/*
/*
* (non-Javadoc)
* @see java.util.Iterator#hasNext()
*/
@Override
@SuppressWarnings("all")
public boolean hasNext() {
// TODO really?
return index <= Integer.MAX_VALUE;
return (index <= Integer.MAX_VALUE);
}

/*
/*
* (non-Javadoc)
* @see java.util.Iterator#next()
*/
Expand All @@ -129,7 +138,7 @@ public Integer next() {
return index++;
}

/*
/*
* (non-Javadoc)
* @see java.util.Iterator#remove()
*/
Expand All @@ -138,5 +147,4 @@ public void remove() {
throw new UnsupportedOperationException();
}
}

}
Expand Up @@ -36,7 +36,7 @@

/**
* GemFire specific {@link QueryMethod}.
*
*
* @author Oliver Gierke
* @author John Blum
* @see org.springframework.data.repository.query.QueryMethod
Expand All @@ -50,7 +50,7 @@ public class GemfireQueryMethod extends QueryMethod {

/**
* Creates a new {@link GemfireQueryMethod} from the given {@link Method} and {@link RepositoryMetadata}.
*
*
* @param method must not be {@literal null}.
* @param metadata must not be {@literal null}.
* @param factory must not be {@literal null}.
Expand All @@ -77,11 +77,11 @@ public GemfireQueryMethod(Method method, RepositoryMetadata metadata, Projection
* @see org.springframework.data.domain.Pageable
* @see java.lang.reflect.Method#getParameterTypes()
*/
private void assertNonPagingQueryMethod(final Method method) {
private void assertNonPagingQueryMethod(Method method) {
for (Class<?> type : method.getParameterTypes()) {
if (Pageable.class.isAssignableFrom(type)) {
throw new IllegalStateException(String.format("Pagination is not supported by GemFire Repositories!"
+ " Offending method: %1$s", method.toString()));
throw new IllegalStateException(String.format("Pagination is not supported by GemFire Repositories;"
+ " Offending method: %1$s", method.getName()));
}
}
}
Expand All @@ -108,7 +108,7 @@ public boolean hasAnnotatedQuery() {

/**
* Returns the annotated query for the query method if present.
*
*
* @return the annotated query or {@literal null} in case it's empty or not present.
* @see org.springframework.data.gemfire.repository.Query
* @see java.lang.reflect.Method#getAnnotation(Class)
Expand Down
Expand Up @@ -3,4 +3,5 @@
interface Predicate {

String toString(String alias);
}

}

0 comments on commit 96a5990

Please sign in to comment.