API cleanup Neo4jTemplate, Renaming EmbeddedQueryEngine to CypherQueryEngine
This commit is contained in:
@@ -26,15 +26,15 @@ import java.util.*;
|
||||
* @author mh
|
||||
* @since 22.06.11
|
||||
*/
|
||||
public class RestQueryEngine implements QueryEngine {
|
||||
public class RestCypherQueryEngine implements QueryEngine {
|
||||
private final RestRequest restRequest;
|
||||
private final RestGraphDatabase restGraphDatabase;
|
||||
private final ResultConverter resultConverter;
|
||||
|
||||
public RestQueryEngine(RestGraphDatabase restGraphDatabase) {
|
||||
public RestCypherQueryEngine(RestGraphDatabase restGraphDatabase) {
|
||||
this(restGraphDatabase,null);
|
||||
}
|
||||
public RestQueryEngine(RestGraphDatabase restGraphDatabase, ResultConverter resultConverter) {
|
||||
public RestCypherQueryEngine(RestGraphDatabase restGraphDatabase, ResultConverter resultConverter) {
|
||||
this.restGraphDatabase = restGraphDatabase;
|
||||
this.resultConverter = resultConverter!=null ? resultConverter : new DefaultConverter();
|
||||
this.restRequest = restGraphDatabase.getRestRequest();
|
||||
@@ -65,6 +65,11 @@ public class RestQueryEngine implements QueryEngine {
|
||||
return result.to(type,converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Handler<Map<String, Object>> handler) {
|
||||
result.handle(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Map<String, Object>> iterator() {
|
||||
return result.iterator();
|
||||
@@ -27,7 +27,6 @@ import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.core.Property;
|
||||
import org.springframework.data.neo4j.conversion.ResultConverter;
|
||||
import org.springframework.data.neo4j.rest.index.RestIndexManager;
|
||||
import org.springframework.data.neo4j.rest.index.RestIndexManager;
|
||||
import org.springframework.data.neo4j.support.query.ConversionServiceQueryResultConverter;
|
||||
import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
|
||||
@@ -106,7 +105,7 @@ public class RestGraphDatabase implements GraphDatabaseService, GraphDatabase {
|
||||
|
||||
@Override
|
||||
public QueryEngine queryEngineFor(QueryEngine.Type type) {
|
||||
return new RestQueryEngine(this, createResultConverter());
|
||||
return new RestCypherQueryEngine(this, createResultConverter());
|
||||
}
|
||||
|
||||
private ResultConverter createResultConverter() {
|
||||
|
||||
@@ -23,4 +23,5 @@ package org.springframework.data.neo4j.conversion;
|
||||
public interface QueryResult<T> extends Iterable<T> {
|
||||
<R> ConvertedResult<R> to(Class<R> type);
|
||||
<R> ConvertedResult<R> to(Class<R> type, ResultConverter<T, R> resultConverter);
|
||||
void handle(Handler<T> handler);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.data.neo4j.conversion;
|
||||
|
||||
import org.neo4j.graphdb.index.IndexHits;
|
||||
import org.neo4j.helpers.collection.ClosableIterable;
|
||||
import org.neo4j.helpers.collection.IteratorWrapper;
|
||||
|
||||
import java.util.Iterator;
|
||||
@@ -27,6 +29,8 @@ import java.util.Iterator;
|
||||
public class QueryResultBuilder<T> implements QueryResult<T> {
|
||||
private Iterable<T> result;
|
||||
private final ResultConverter defaultConverter;
|
||||
private final boolean isClosableIterable;
|
||||
private boolean isClosed;
|
||||
|
||||
public QueryResultBuilder(Iterable<T> result) {
|
||||
this(result, new DefaultConverter());
|
||||
@@ -34,6 +38,7 @@ public class QueryResultBuilder<T> implements QueryResult<T> {
|
||||
|
||||
public QueryResultBuilder(Iterable<T> result, final ResultConverter<T,?> defaultConverter) {
|
||||
this.result = result;
|
||||
this.isClosableIterable = result instanceof IndexHits || result instanceof ClosableIterable;
|
||||
this.defaultConverter = defaultConverter;
|
||||
}
|
||||
|
||||
@@ -47,17 +52,26 @@ public class QueryResultBuilder<T> implements QueryResult<T> {
|
||||
return new ConvertedResult<R>() {
|
||||
@Override
|
||||
public R single() {
|
||||
final Iterator<T> it = result.iterator();
|
||||
if (!it.hasNext()) throw new IllegalStateException("Expected at least one result, got none.");
|
||||
final T value = it.next();
|
||||
if (it.hasNext()) throw new IllegalStateException("Expected at least one result, got more than one.");
|
||||
return resultConverter.convert(value, type);
|
||||
try {
|
||||
final Iterator<T> it = result.iterator();
|
||||
if (!it.hasNext()) throw new IllegalStateException("Expected at least one result, got none.");
|
||||
final T value = it.next();
|
||||
if (it.hasNext())
|
||||
throw new IllegalStateException("Expected at least one result, got more than one.");
|
||||
return resultConverter.convert(value, type);
|
||||
} finally {
|
||||
closeIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Handler<R> handler) {
|
||||
for (T value : result) {
|
||||
handler.handle(resultConverter.convert(value, type));
|
||||
try {
|
||||
for (T value : result) {
|
||||
handler.handle(resultConverter.convert(value, type));
|
||||
}
|
||||
} finally {
|
||||
closeIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +86,29 @@ public class QueryResultBuilder<T> implements QueryResult<T> {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Handler<T> handler) {
|
||||
try {
|
||||
for (T value : result) {
|
||||
handler.handle(value);
|
||||
}
|
||||
} finally {
|
||||
closeIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void closeIfNeeded() {
|
||||
if (isClosableIterable && !isClosed) {
|
||||
if (result instanceof IndexHits) {
|
||||
((IndexHits) result).close();
|
||||
} else if (result instanceof ClosableIterable) {
|
||||
((ClosableIterable) result).close();
|
||||
}
|
||||
isClosed=true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return result.iterator();
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.neo4j.graphdb.RelationshipType;
|
||||
import org.neo4j.graphdb.index.Index;
|
||||
import org.neo4j.graphdb.traversal.TraversalDescription;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.neo4j.support.query.EmbeddedQueryEngine;
|
||||
import org.springframework.data.neo4j.support.query.CypherQueryEngine;
|
||||
import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ public interface GraphDatabase {
|
||||
*/
|
||||
TraversalDescription createTraversalDescription();
|
||||
|
||||
QueryEngine queryEngineFor(EmbeddedQueryEngine.Type type);
|
||||
QueryEngine queryEngineFor(CypherQueryEngine.Type type);
|
||||
|
||||
void setConversionService(ConversionService conversionService);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.core.Property;
|
||||
import org.springframework.data.neo4j.support.query.ConversionServiceQueryResultConverter;
|
||||
import org.springframework.data.neo4j.support.query.EmbeddedQueryEngine;
|
||||
import org.springframework.data.neo4j.support.query.CypherQueryEngine;
|
||||
import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -126,8 +126,8 @@ public class DelegatingGraphDatabase implements GraphDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryEngine queryEngineFor(EmbeddedQueryEngine.Type type) {
|
||||
return new EmbeddedQueryEngine(delegate, createResultConverter());
|
||||
public QueryEngine queryEngineFor(CypherQueryEngine.Type type) {
|
||||
return new CypherQueryEngine(delegate, createResultConverter());
|
||||
}
|
||||
|
||||
private ConversionServiceQueryResultConverter createResultConverter() {
|
||||
|
||||
@@ -29,18 +29,18 @@ import org.springframework.data.neo4j.conversion.ResultConverter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class EmbeddedQueryEngine implements QueryEngine, QueryOperations {
|
||||
public class CypherQueryEngine implements QueryEngine, QueryOperations {
|
||||
|
||||
final ExecutionEngine executionEngine;
|
||||
private ResultConverter resultConverter;
|
||||
private final DefaultQueryOperations queryOperations;
|
||||
|
||||
public EmbeddedQueryEngine(GraphDatabaseService graphDatabaseService) {
|
||||
public CypherQueryEngine(GraphDatabaseService graphDatabaseService) {
|
||||
this(graphDatabaseService, new DefaultConverter());
|
||||
}
|
||||
|
||||
|
||||
public EmbeddedQueryEngine(GraphDatabaseService graphDatabaseService, ResultConverter resultConverter) {
|
||||
public CypherQueryEngine(GraphDatabaseService graphDatabaseService, ResultConverter resultConverter) {
|
||||
this.resultConverter = resultConverter != null ? resultConverter : new DefaultConverter();
|
||||
this.executionEngine = new ExecutionEngine(graphDatabaseService);
|
||||
this.queryOperations = new DefaultQueryOperations(this);
|
||||
@@ -31,7 +31,7 @@ public class QueryExecutor implements QueryOperations {
|
||||
|
||||
public QueryExecutor(GraphDatabaseContext ctx) {
|
||||
EntityResultConverter converter = new EntityResultConverter(ctx);
|
||||
queryEngine = new EmbeddedQueryEngine(ctx.getGraphDatabaseService(), converter);
|
||||
queryEngine = new CypherQueryEngine(ctx.getGraphDatabaseService(), converter);
|
||||
}
|
||||
|
||||
public Iterable<Map<String, Object>> queryForList(String statement) {
|
||||
|
||||
@@ -18,10 +18,8 @@ package org.springframework.data.neo4j.template;
|
||||
|
||||
import org.neo4j.graphdb.*;
|
||||
import org.neo4j.graphdb.traversal.TraversalDescription;
|
||||
import org.neo4j.helpers.collection.ClosableIterable;
|
||||
import org.springframework.data.neo4j.conversion.QueryResult;
|
||||
import org.springframework.data.neo4j.core.Property;
|
||||
import org.springframework.data.neo4j.support.path.PathMapper;
|
||||
import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -89,73 +87,6 @@ public interface Neo4jOperations {
|
||||
*/
|
||||
Relationship createRelationship(Node startNode, Node endNode, RelationshipType type, Property... props);
|
||||
|
||||
/**
|
||||
* Queries the supplied index with a lucene query string or query object (if the neo4j-index provider is lucene)
|
||||
*
|
||||
*
|
||||
* @param indexName Name of the index, will be checked against existing indexes, first relationship-indexes, then node indexes
|
||||
* assumes a "node" node index for a null value
|
||||
* @param queryOrQueryObject a lucene query string or query object (if the neo4j-index provider is lucene)
|
||||
* @param pathMapper a mapper that translates from the resulting paths into some domain object, might use PathMapper.WithoutResult for a callback behaviour
|
||||
* @return a lazy (when mapped) or eagerly (when called back) iterable containing the results of the query result mapping
|
||||
* @see org.springframework.data.neo4j.support.path.IterationController for controlling eagerness of iteration
|
||||
*/
|
||||
<T> ClosableIterable<T> lookup(String indexName, Object queryOrQueryObject, PathMapper<T> pathMapper);
|
||||
|
||||
/**
|
||||
* Queries the supplied index with a field - value combination
|
||||
*
|
||||
*
|
||||
* @param indexName Name of the index, will be checked against existing indexes, first relationship-indexes, then node indexes
|
||||
* assumes a "node" node index for a null value
|
||||
* @param field field to query
|
||||
* @param value value to supply to index query
|
||||
* @param pathMapper a mapper that translates from the resulting paths into some domain object, might use PathMapper.WithoutResult for a callback behaviour
|
||||
* @return a lazy (when mapped) or eagerly (when called back) iterable containing the results of the query result mapping
|
||||
* @see org.springframework.data.neo4j.support.path.IterationController for controlling eagerness of iteration
|
||||
*/
|
||||
<T> ClosableIterable<T> lookup(String indexName, String field, String value, PathMapper<T> pathMapper);
|
||||
|
||||
/**
|
||||
* Traverses the whole path with the given traversal descripting starting at the start node.
|
||||
*
|
||||
* @param traversal a traversal description, possibly generated by the Traversal.description()... DSL
|
||||
* @param startNode start node for the traversal
|
||||
* @param pathMapper pathMapper a mapper that translates from the resulting paths into some domain object, might use PathMapper.WithoutResult for a callback behaviour
|
||||
* @return a lazy (when mapped) or eagerly (when called back) iterable containing the results of the traversal result mapping
|
||||
*/
|
||||
<T> Iterable<T> traverse(TraversalDescription traversal, Node startNode, PathMapper<T> pathMapper);
|
||||
|
||||
/**
|
||||
* Traverses only to the direct neighbours of the start node
|
||||
* @param startNode start node for the traversal
|
||||
* @param pathMapper pathMapper a mapper that translates from the resulting paths into some domain object, might use PathMapper.WithoutResult for a callback behaviour
|
||||
* @param type type of relationships to consider
|
||||
* @param direction direction of relationship to consider (can be OUTGOING, INCOMING, BOTH)
|
||||
* @param <T> expected type of result
|
||||
* @return a lazy (when mapped) or eagerly (when called back) iterable containing the results of the traversal result mapping
|
||||
*/
|
||||
<T> Iterable<T> traverseNext(Node startNode, PathMapper<T> pathMapper, RelationshipType type, Direction direction);
|
||||
|
||||
/**
|
||||
* Traverses only to the direct neighbours of the start node for the specified relationship types
|
||||
* @param startNode start node for the traversal
|
||||
* @param pathMapper pathMapper a mapper that translates from the resulting paths into some domain object, might use PathMapper.WithoutResult for a callback behaviour
|
||||
* @param types types of relationships to consider
|
||||
* @param <T> expected type of result
|
||||
* @return a lazy (when mapped) or eagerly (when called back) iterable containing the results of the traversal result mapping
|
||||
*/
|
||||
<T> Iterable<T> traverseNext(Node startNode, PathMapper<T> pathMapper, RelationshipType... types);
|
||||
|
||||
/**
|
||||
* Traverses only to all direct neighbours of the start node for all relationships
|
||||
* @param startNode start node for the traversal
|
||||
* @param pathMapper pathMapper a mapper that translates from the resulting paths into some domain object, might use PathMapper.WithoutResult for a callback behaviour
|
||||
* @param <T> expected type of result
|
||||
* @return a lazy (when mapped) or eagerly (when called back) iterable containing the results of the traversal result mapping
|
||||
*/
|
||||
<T> Iterable<T> traverseNext(Node startNode, PathMapper<T> pathMapper);
|
||||
|
||||
/**
|
||||
* Indexes the given field and value for the element.
|
||||
* @param indexName Name of the index, will be checked against existing indexes according to the given element
|
||||
@@ -168,9 +99,13 @@ public interface Neo4jOperations {
|
||||
*/
|
||||
<T extends PropertyContainer> T index(String indexName, T element, String field, Object value);
|
||||
|
||||
Iterable<Map<String, Object>> query(QueryEngine.Type engineType, String statement);
|
||||
<T> QueryResult<T> convert(Iterable<T> iterable);
|
||||
|
||||
<T> Iterable<T> query(QueryEngine.Type engineType, String statement, Class<T> type);
|
||||
QueryResult<Map<String, Object>> query(String statement);
|
||||
|
||||
<T> T queryForObject(QueryEngine.Type engineType, String statement, Class<T> type);
|
||||
QueryResult<Path> traverse(Node startNode, TraversalDescription traversal);
|
||||
|
||||
<T extends PropertyContainer> QueryResult<T> lookup(String indexName, String field, Object value);
|
||||
|
||||
<T extends PropertyContainer> QueryResult<T> lookup(String indexName, Object valueOrQueryObject);
|
||||
}
|
||||
|
||||
@@ -30,9 +30,8 @@ import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.core.Property;
|
||||
import org.springframework.data.neo4j.support.path.NodePath;
|
||||
import org.springframework.data.neo4j.support.path.PathMapper;
|
||||
import org.springframework.data.neo4j.support.path.PathMappingIterator;
|
||||
import org.springframework.data.neo4j.support.path.RelationshipPath;
|
||||
import org.springframework.data.neo4j.support.query.EmbeddedQueryEngine;
|
||||
import org.springframework.data.neo4j.support.query.CypherQueryEngine;
|
||||
import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
@@ -167,34 +166,11 @@ public class Neo4jTemplate implements Neo4jOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ClosableIterable<T> lookup(String indexName, Object queryOrQueryObject, final PathMapper<T> pathMapper) {
|
||||
notNull(queryOrQueryObject, "queryOrQueryObject", pathMapper, "pathMapper",indexName,"indexName");
|
||||
try {
|
||||
Index<? extends PropertyContainer> index = graphDatabase.getIndex(indexName);
|
||||
if (Relationship.class.isAssignableFrom(index.getEntityType())) {
|
||||
return mapRelationships(((Index<Relationship>)index).query(queryOrQueryObject), pathMapper);
|
||||
}
|
||||
return mapNodes(((Index<Node>)index).query(queryOrQueryObject), pathMapper);
|
||||
} catch (RuntimeException e) {
|
||||
throw translateExceptionIfPossible(e);
|
||||
}
|
||||
public <T> QueryResult<T> convert(Iterable<T> iterable) {
|
||||
return new QueryResultBuilder<T>(iterable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ClosableIterable<T> lookup(String indexName, String field, String value, final PathMapper<T> pathMapper) {
|
||||
notNull(field, "field", value, "value", pathMapper, "pathMapper", indexName, "indexName");
|
||||
try {
|
||||
Index<? extends PropertyContainer> index = graphDatabase.getIndex(indexName);
|
||||
if (Relationship.class.isAssignableFrom(index.getEntityType())) {
|
||||
return mapRelationships(((Index<Relationship>)index).get(field, value), pathMapper);
|
||||
}
|
||||
return mapNodes(((Index<Node>)index).get(field, value), pathMapper);
|
||||
} catch (RuntimeException e) {
|
||||
throw translateExceptionIfPossible(e);
|
||||
}
|
||||
}
|
||||
|
||||
private QueryEngine queryEngineFor(EmbeddedQueryEngine.Type type) {
|
||||
private QueryEngine queryEngineFor(CypherQueryEngine.Type type) {
|
||||
return graphDatabase.queryEngineFor(type);
|
||||
}
|
||||
|
||||
@@ -219,62 +195,6 @@ public class Neo4jTemplate implements Neo4jOperations {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Iterable<T> traverse(TraversalDescription traversal, Node startNode, final PathMapper<T> pathMapper) {
|
||||
notNull(startNode, "startNode", traversal, "traversal", pathMapper, "pathMapper");
|
||||
try {
|
||||
return mapPaths(traversal.traverse(startNode), pathMapper);
|
||||
} catch (RuntimeException e) {
|
||||
throw translateExceptionIfPossible(e);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> Iterable<T> mapPaths(final Iterable<Path> paths, final PathMapper<T> pathMapper) {
|
||||
return new PathMappingIterator().mapPaths(paths,pathMapper);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> Iterable<T> traverseNext(Node startNode, final PathMapper<T> pathMapper, RelationshipType relationshipType, Direction direction) {
|
||||
notNull(startNode, "startNode", relationshipType, "relationshipType", direction, "direction", pathMapper, "pathMapper");
|
||||
try {
|
||||
return mapRelationships(startNode.getRelationships(relationshipType, direction), pathMapper);
|
||||
} catch (RuntimeException e) {
|
||||
throw translateExceptionIfPossible(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Iterable<T> traverseNext(Node startNode, final PathMapper<T> pathMapper, RelationshipType... relationshipTypes) {
|
||||
notNull(startNode, "startNode", relationshipTypes, "relationshipType", pathMapper, "pathMapper");
|
||||
try {
|
||||
return mapRelationships(startNode.getRelationships(relationshipTypes), pathMapper);
|
||||
} catch (RuntimeException e) {
|
||||
throw translateExceptionIfPossible(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Iterable<T> traverseNext(Node startNode, final PathMapper<T> pathMapper) {
|
||||
notNull(startNode, "startNode", pathMapper, "pathMapper");
|
||||
try {
|
||||
return mapRelationships(startNode.getRelationships(), pathMapper);
|
||||
} catch (RuntimeException e) {
|
||||
throw translateExceptionIfPossible(e);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> Iterable<T> mapRelationships(final Iterable<Relationship> relationships, final PathMapper<T> pathMapper) {
|
||||
assert relationships != null;
|
||||
assert pathMapper != null;
|
||||
return new IterableWrapper<T, Relationship>(relationships) {
|
||||
@Override
|
||||
protected T underlyingObjectToObject(Relationship relationship) {
|
||||
return pathMapper.mapPath(new RelationshipPath(relationship));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Relationship createRelationship(final Node startNode, final Node endNode, final RelationshipType relationshipType, final Property... properties) {
|
||||
notNull(startNode, "startNode", endNode, "endNode", relationshipType, "relationshipType", properties, "properties");
|
||||
@@ -286,19 +206,6 @@ public class Neo4jTemplate implements Neo4jOperations {
|
||||
});
|
||||
}
|
||||
|
||||
private <T extends PropertyContainer> T setProperties(T primitive, Map<String, Object> properties) {
|
||||
assert primitive != null;
|
||||
if (properties==null) return primitive;
|
||||
for (Map.Entry<String, Object> prop : properties.entrySet()) {
|
||||
if (prop.getValue()==null) {
|
||||
primitive.removeProperty(prop.getKey());
|
||||
} else {
|
||||
primitive.setProperty(prop.getKey(), prop.getValue());
|
||||
}
|
||||
}
|
||||
return primitive;
|
||||
}
|
||||
|
||||
private static abstract class IndexHitsIterableWrapper<T, S extends PropertyContainer> extends IterableWrapper<T, S> implements ClosableIterable<T> {
|
||||
private final IndexHits<S> indexHits;
|
||||
private final PathMapper<T> pathMapper;
|
||||
@@ -323,25 +230,12 @@ public class Neo4jTemplate implements Neo4jOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Map<String, Object>> query(QueryEngine.Type engineType, String statement) {
|
||||
return queryEngineFor(engineType).query(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Iterable<T> query(QueryEngine.Type engineType, String statement, Class<T> type) {
|
||||
return queryEngineFor(engineType).query(statement).to(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T queryForObject(QueryEngine.Type engineType, String statement, Class<T> type) {
|
||||
return queryEngineFor(engineType).query(statement).to(type).single();
|
||||
}
|
||||
|
||||
public QueryResult<Map<String, Object>> query(String statement) {
|
||||
notNull(statement, "statement");
|
||||
return queryEngineFor(QueryEngine.Type.Cypher).query(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryResult<Path> traverse(Node startNode, TraversalDescription traversal) {
|
||||
notNull(startNode, "startNode", traversal, "traversal");
|
||||
try {
|
||||
@@ -351,6 +245,7 @@ public class Neo4jTemplate implements Neo4jOperations {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends PropertyContainer> QueryResult<T> lookup(String indexName, String field, Object value) {
|
||||
notNull(field, "field", value, "value", indexName, "indexName");
|
||||
try {
|
||||
@@ -360,6 +255,7 @@ public class Neo4jTemplate implements Neo4jOperations {
|
||||
throw translateExceptionIfPossible(e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public <T extends PropertyContainer> QueryResult<T> lookup(String indexName, Object valueOrQueryObject) {
|
||||
notNull(valueOrQueryObject, "valueOrQueryObject", indexName, "indexName");
|
||||
try {
|
||||
@@ -369,35 +265,6 @@ public class Neo4jTemplate implements Neo4jOperations {
|
||||
throw translateExceptionIfPossible(e);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
final Iterable<Node> nodes = query("start n=(0) return n").to(Node.class);
|
||||
final Iterable<Path> nodePaths = query("start n=(0) return n").to(Path.class);
|
||||
final Iterable<Long> costs = lookup("index", "field", "value").to(Long.class, new ResultConverter<Relationship, Long>() {
|
||||
@Override
|
||||
public Long convert(Relationship value, Class<Long> type) {
|
||||
return (Long) value.getProperty("cost");
|
||||
}
|
||||
});
|
||||
final Iterable<Person> people = lookup("index", "field:value*").to(Person.class);
|
||||
|
||||
lookup("index", "field:value*").to(Node.class).handle(new Handler<Node>() {
|
||||
@Override
|
||||
public void handle(Node node) {
|
||||
node.setProperty("count",((Integer)node.getProperty("count",0))+1);
|
||||
}
|
||||
});
|
||||
|
||||
final Iterable<Node> endNodes = traverse(start, desc).to(Node.class);
|
||||
final Iterable<Relationship> lastRelationships = traverse(start, desc).to(Relationship.class);
|
||||
final Iterable<Integer> pathLengths = traverse(start, desc).to(Integer.class, new ResultConverter<Path, Integer>() {
|
||||
public Integer convert(Path path, Class<Integer> type) {
|
||||
return path.length();
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -24,13 +24,14 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.neo4j.graphdb.*;
|
||||
import org.neo4j.graphdb.index.Index;
|
||||
import org.neo4j.graphdb.traversal.TraversalDescription;
|
||||
import org.neo4j.test.ImpermanentGraphDatabase;
|
||||
import org.neo4j.kernel.Traversal;
|
||||
import org.neo4j.kernel.impl.transaction.SpringTransactionManager;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.neo4j.conversion.ResultConverter;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.support.DelegatingGraphDatabase;
|
||||
import org.springframework.data.neo4j.support.path.PathMapper;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
@@ -248,40 +249,41 @@ public class Neo4jTemplateApiTest {
|
||||
|
||||
@Test
|
||||
public void testQueryNodes() throws Exception {
|
||||
assertSingleResult("node0", template.lookup("node", new TermQuery(new Term("name", "node0")), new NodeNameMapper()));
|
||||
assertSingleResult("node0", template.lookup("node", new TermQuery(new Term("name", "node0"))).to(String.class, new PropertyContainerNameConverter()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetrieveNodes() throws Exception {
|
||||
assertSingleResult("node0", template.lookup("node", "name", "node0", new NodeNameMapper()));
|
||||
assertSingleResult("node0", template.lookup("node", "name", "node0").to(String.class, new PropertyContainerNameConverter()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryRelationships() throws Exception {
|
||||
assertSingleResult("rel1", template.lookup("relationship", new TermQuery(new Term("name", "rel1")), new RelationshipNameMapper()));
|
||||
assertSingleResult("rel1", template.lookup("relationship", new TermQuery(new Term("name", "rel1"))).to(String.class, new PropertyContainerNameConverter()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetrieveRelationships() throws Exception {
|
||||
assertSingleResult("rel1",template.lookup("relationship", "name", "rel1", new RelationshipNameMapper()));
|
||||
assertSingleResult("rel1",template.lookup("relationship", "name", "rel1").to(String.class, new PropertyContainerNameConverter()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTraverse() throws Exception {
|
||||
assertSingleResult("node1",template.traverse(Traversal.description().relationships(KNOWS).prune(Traversal.pruneAfterDepth(1)).filter(Traversal.returnAllButStartNode()), referenceNode, new NodeNameMapper()));
|
||||
final TraversalDescription description = Traversal.description().relationships(KNOWS).prune(Traversal.pruneAfterDepth(1)).filter(Traversal.returnAllButStartNode());
|
||||
assertSingleResult("node1",template.traverse(referenceNode, description).to(String.class,new PathNodeNameMapper()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetDirectRelationship() throws Exception {
|
||||
assertSingleResult("rel1", template.traverseNext(referenceNode, new RelationshipNameMapper()));
|
||||
assertSingleResult("rel1", template.convert(referenceNode.getRelationships()).to(String.class, new RelationshipNameConverter()));
|
||||
}
|
||||
@Test
|
||||
public void shouldGetDirectRelationshipForType() throws Exception {
|
||||
assertSingleResult("rel1", template.traverseNext(referenceNode, new RelationshipNameMapper(), KNOWS));
|
||||
assertSingleResult("rel1", template.convert(referenceNode.getRelationships(KNOWS)).to(String.class, new RelationshipNameConverter()));
|
||||
}
|
||||
@Test
|
||||
public void shouldGetDirectRelationshipForTypeAndDirection() throws Exception {
|
||||
assertSingleResult("rel1", template.traverseNext(referenceNode, new RelationshipNameMapper(), KNOWS, Direction.OUTGOING));
|
||||
assertSingleResult("rel1", template.convert(referenceNode.getRelationships(KNOWS, Direction.OUTGOING)).to(String.class, new RelationshipNameConverter()));
|
||||
}
|
||||
|
||||
private <T> void assertSingleResult(T expected, Iterable<T> iterable) {
|
||||
@@ -301,16 +303,30 @@ public class Neo4jTemplateApiTest {
|
||||
assertEquals("rel2",relationship.getProperty("name","not set"));
|
||||
}
|
||||
|
||||
private static class RelationshipNameMapper implements PathMapper<String> {
|
||||
private static class PathRelationshipNameMapper implements ResultConverter<Path,String> {
|
||||
@Override
|
||||
public String mapPath(Path path) {
|
||||
public String convert(Path path, Class<String> type) {
|
||||
return (String) path.lastRelationship().getProperty("name","not set");
|
||||
}
|
||||
}
|
||||
private static class NodeNameMapper implements PathMapper<String> {
|
||||
private static class PathNodeNameMapper implements ResultConverter<Path,String> {
|
||||
@Override
|
||||
public String mapPath(Path path) {
|
||||
public String convert(Path path, Class<String> type) {
|
||||
return (String) path.endNode().getProperty("name","not set");
|
||||
}
|
||||
}
|
||||
|
||||
private static class RelationshipNameConverter implements ResultConverter<Relationship,String> {
|
||||
@Override
|
||||
public String convert(Relationship value, Class<String> type) {
|
||||
return (String) value.getProperty("name");
|
||||
}
|
||||
}
|
||||
|
||||
private static class PropertyContainerNameConverter implements ResultConverter<PropertyContainer, String> {
|
||||
@Override
|
||||
public String convert(PropertyContainer value, Class<String> type) {
|
||||
return (String) value.getProperty("name");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
package org.springframework.data.neo4j.template;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Path;
|
||||
import org.neo4j.graphdb.RelationshipType;
|
||||
import org.neo4j.graphdb.traversal.TraversalDescription;
|
||||
import org.neo4j.kernel.Traversal;
|
||||
import org.springframework.data.neo4j.support.path.PathMapper;
|
||||
import org.springframework.data.neo4j.conversion.Handler;
|
||||
import org.springframework.data.neo4j.conversion.QueryResult;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -49,13 +51,14 @@ public class NeoTraversalTest extends NeoApiTest {
|
||||
});
|
||||
|
||||
final Set<String> resultSet = new HashSet<String>();
|
||||
template.traverse(Traversal.description().relationships(HAS).filter(returnAllButStartNode()).prune(Traversal.pruneAfterDepth(2)), template.getReferenceNode(), new PathMapper.WithoutResult() {
|
||||
final TraversalDescription description = Traversal.description().relationships(HAS).filter(returnAllButStartNode()).prune(Traversal.pruneAfterDepth(2));
|
||||
final QueryResult<Path> queryResult = template.traverse(template.getReferenceNode(), description);
|
||||
queryResult.handle(new Handler<Path>() {
|
||||
@Override
|
||||
public void eachPath(Path path) {
|
||||
String nodeName = (String) path.endNode().getProperty("name", "");
|
||||
resultSet.add(nodeName);
|
||||
}
|
||||
});
|
||||
public void handle(Path value) {
|
||||
final String name = (String) value.endNode().getProperty("name", "");
|
||||
resultSet.add(name);
|
||||
}});
|
||||
assertEquals("all members", new HashSet<String>(asList("grandpa", "grandma", "daughter", "son", "man", "wife", "family")), resultSet);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user