Merge pull request #119 from nickithewatt/master
DATAGRAPH-345 : Add support for countBy projections on derived query
This commit is contained in:
@@ -25,13 +25,10 @@ import org.springframework.data.repository.query.Parameter;
|
||||
import org.springframework.data.repository.query.parser.Part;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.springframework.util.StringUtils.collectionToCommaDelimitedString;
|
||||
import static org.springframework.util.StringUtils.collectionToDelimitedString;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
import static org.springframework.util.StringUtils.*;
|
||||
|
||||
public class CypherQuery implements CypherQueryDefinition {
|
||||
private final VariableContext variableContext = new VariableContext();
|
||||
@@ -42,6 +39,7 @@ public class CypherQuery implements CypherQueryDefinition {
|
||||
private int index = 0;
|
||||
private final Neo4jPersistentEntity<?> entity;
|
||||
private final Neo4jTemplate template;
|
||||
private boolean isCountQuery = false;
|
||||
|
||||
public CypherQuery(final Neo4jPersistentEntity<?> entity, Neo4jTemplate template) {
|
||||
this.entity = entity;
|
||||
@@ -176,7 +174,12 @@ public class CypherQuery implements CypherQueryDefinition {
|
||||
builder.append(" WHERE ").append(whereClauses);
|
||||
}
|
||||
|
||||
builder.append(" RETURN ").append(String.format(QueryTemplates.VARIABLE, getEntityName(entity)));
|
||||
String returnEntity = String.format(QueryTemplates.VARIABLE,getEntityName(entity));
|
||||
if (isCountQuery) {
|
||||
builder.append(" RETURN ").append("count(").append(returnEntity).append(")");
|
||||
} else {
|
||||
builder.append(" RETURN ").append(returnEntity);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@@ -235,4 +238,8 @@ public class CypherQuery implements CypherQueryDefinition {
|
||||
public String toString() {
|
||||
return toQueryString();
|
||||
}
|
||||
|
||||
public void setIsCountQuery(boolean isCountQuery) {
|
||||
this.isCountQuery = isCountQuery;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,11 @@ class CypherQueryBuilder {
|
||||
this.query = new CypherQuery(entity, template);
|
||||
}
|
||||
|
||||
public CypherQueryBuilder asCountQuery() {
|
||||
query.setIsCountQuery(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CypherQueryBuilder addRestriction(Part part) {
|
||||
query.addPart(part, context.getPersistentPropertyPath(part.getProperty()));
|
||||
return this;
|
||||
|
||||
@@ -37,6 +37,7 @@ class CypherQueryCreator extends AbstractQueryCreator<CypherQueryDefinition, Cyp
|
||||
private final MappingContext<? extends Neo4jPersistentEntity<?>, Neo4jPersistentProperty> context;
|
||||
private final Class<?> domainClass;
|
||||
private final Neo4jTemplate template;
|
||||
private boolean isCountProjection = false;
|
||||
|
||||
/**
|
||||
* Creates a new {@link CypherQueryCreator} using the given {@link PartTree}, {@link org.springframework.data.neo4j.support.mapping.Neo4jMappingContext} and domain
|
||||
@@ -58,6 +59,7 @@ class CypherQueryCreator extends AbstractQueryCreator<CypherQueryDefinition, Cyp
|
||||
this.template = template;
|
||||
this.context = context;
|
||||
this.domainClass = domainClass;
|
||||
this.isCountProjection = tree.isCountProjection();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -68,6 +70,9 @@ class CypherQueryCreator extends AbstractQueryCreator<CypherQueryDefinition, Cyp
|
||||
protected CypherQueryBuilder create(Part part, Iterator<Object> iterator) {
|
||||
|
||||
CypherQueryBuilder builder = new CypherQueryBuilder(context, domainClass,template);
|
||||
if (isCountProjection) {
|
||||
builder = builder.asCountQuery();
|
||||
}
|
||||
builder.addRestriction(part);
|
||||
|
||||
return builder;
|
||||
|
||||
@@ -151,6 +151,14 @@ interface RecipeRepository extends GraphRepository<Recipe> {
|
||||
|
||||
Set<Recipe> findByIngredientAndCookBook(Ingredient ingredient, CookBook cookBook);
|
||||
Set<Recipe> findBySecrets(Ingredient ingredient);
|
||||
|
||||
Long countByAuthor(String author);
|
||||
|
||||
Long countByIngredientAndAuthor(Ingredient ingredient, String author);
|
||||
|
||||
Long countByIngredient(Ingredient ingredient);
|
||||
|
||||
Integer countByCookBookTitle(String title);
|
||||
}
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@@ -292,6 +300,31 @@ public class DerivedFinderTests {
|
||||
assertThat(single(recipes).author, is(equalTo("Jamie")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCountCorrectlyUsingProperty() throws Exception {
|
||||
Long actualCountVal = recipeRepository.countByAuthor("Hugh");
|
||||
assertThat(actualCountVal, is(equalTo(3L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCountCorrectlyUsingEntityAndProperty() throws Exception {
|
||||
Long actualCountVal = recipeRepository.countByIngredientAndAuthor(oliveOil,"Hugh");
|
||||
assertThat(actualCountVal, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCountCorrectlyUsingEntity() throws Exception {
|
||||
Long actualCountVal = recipeRepository.countByIngredient(chocolate);
|
||||
assertThat(actualCountVal, is(equalTo(2L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCountCorrectlyUsingPropertyTraversal() throws Exception {
|
||||
Integer actualCountVal = recipeRepository.countByCookBookTitle("Naked Chef");
|
||||
assertThat(actualCountVal, is(equalTo(1)));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void shouldFindUsingEntityAndPropertyTraversal() throws Exception {
|
||||
Set<Recipe> recipes = recipeRepository.findByIngredientAndCookBookTitle(oliveOil, "Naked Chef");
|
||||
|
||||
@@ -372,6 +372,14 @@ public class GraphRepositoryTests {
|
||||
assertThat(findByName, hasItem(testTeam.michael));
|
||||
}
|
||||
|
||||
@Test @Transactional
|
||||
public void countByName() {
|
||||
Long num = personRepository.countByName(testTeam.michael.getName());
|
||||
assertEquals((Long)1L,num);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test @Transactional
|
||||
public void findByPersonalityEnum() {
|
||||
testTeam.michael.setPersonality(Personality.EXTROVERT);
|
||||
|
||||
@@ -78,6 +78,8 @@ public interface PersonRepository extends GraphRepository<Person>, NamedIndexRep
|
||||
Iterable<Person> findAllTeamMembersSorted(@Param("p_team") Group team, Sort sort);
|
||||
|
||||
|
||||
Long countByName(String name);
|
||||
|
||||
// Derived queries
|
||||
Iterable<Person> findByName(String name);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user