/*
* Hibernate OGM, Domain model persistence for NoSQL datastores
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.ogm.datastore.neo4j.utils;
import java.io.File;
import java.util.Map;
import org.fest.util.Files;
import org.hibernate.Session;
import org.hibernate.ogm.datastore.neo4j.EmbeddedNeo4jDialect;
import org.hibernate.ogm.datastore.neo4j.Neo4jProperties;
import org.hibernate.ogm.datastore.neo4j.embedded.impl.EmbeddedNeo4jDatastoreProvider;
import org.hibernate.ogm.datastore.neo4j.logging.impl.Log;
import org.hibernate.ogm.datastore.neo4j.logging.impl.LoggerFactory;
import org.hibernate.ogm.datastore.neo4j.test.dsl.NodeForGraphAssertions;
import org.hibernate.ogm.datastore.neo4j.test.dsl.RelationshipsChainForGraphAssertions;
import org.hibernate.ogm.datastore.spi.DatastoreProvider;
import org.hibernate.ogm.dialect.spi.GridDialect;
import org.hibernate.service.spi.Stoppable;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.QueryExecutionException;
import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.Transaction;
/**
* @author Davide D'Alto
*/
public class EmbeddedNeo4jTestHelperDelegate implements Neo4jTestHelperDelegate {
public static final EmbeddedNeo4jTestHelperDelegate INSTANCE = new EmbeddedNeo4jTestHelperDelegate();
private static final Log log = LoggerFactory.getLogger();
private static final Map<String, String> hibernateProperties = PropertiesReader.getHibernateProperties();
private static final String ROOT_FOLDER = hibernateProperties.get( Neo4jProperties.DATABASE_PATH ) + File.separator + "NEO4J";
private EmbeddedNeo4jTestHelperDelegate() {
}
@Override
public long getNumberOfEntities(Session session, DatastoreProvider provider) {
GraphDatabaseService graphDb = ( (EmbeddedNeo4jDatastoreProvider) provider ).getDatabase();
ResourceIterator<Long> result = graphDb.execute( ENTITY_COUNT_QUERY ).columnAs( "count" );
Long count = result.next();
result.close();
return count.longValue();
}
@Override
public long getNumberOfAssociations(Session session, DatastoreProvider provider) {
GraphDatabaseService graphDb = ( (EmbeddedNeo4jDatastoreProvider) provider ).getDatabase();
ResourceIterator<Long> result = graphDb.execute( ASSOCIATION_COUNT_QUERY ).columnAs( "count" );
Long count = result.next();
result.close();
return count.longValue();
}
@Override
public GridDialect getDialect(DatastoreProvider datastoreProvider) {
return new EmbeddedNeo4jDialect( (EmbeddedNeo4jDatastoreProvider) datastoreProvider );
}
@Override
public void dropDatabase(DatastoreProvider datastoreProvider) {
( (Stoppable) datastoreProvider ).stop();
final String rootFolder = rootFolder( hibernateProperties );
Files.delete( new File( rootFolder ) );
}
private static String rootFolder(Map<String, String> hibernateProperties) {
String databasePath = hibernateProperties.get( Neo4jProperties.DATABASE_PATH );
return databasePath( databasePath );
}
private static String databasePath(String databasePath) {
return databasePath + File.separator + "NEO4J";
}
@Override
public void deleteAllElements(DatastoreProvider datastoreProvider) {
GraphDatabaseService graphDb = createExecutionEngine( datastoreProvider );
graphDb.execute( DELETE_ALL ).close();
}
/**
* Returns a random location where to create a neo4j database
*/
public static String dbLocation() {
return ROOT_FOLDER + File.separator + "neo4j-db-" + System.currentTimeMillis();
}
@Override
public Long executeCountQuery(DatastoreProvider datastoreProvider, String queryString) {
GraphDatabaseService graphDb = createExecutionEngine( datastoreProvider );
Transaction tx = graphDb.beginTx();
Result result = graphDb.execute( queryString );
ResourceIterator<Long> count = result.columnAs( "count" );
try {
tx.success();
return count.next();
}
finally {
try {
count.close();
}
finally {
tx.close();
}
}
}
private GraphDatabaseService createExecutionEngine(DatastoreProvider datastoreProvider) {
return ( (EmbeddedNeo4jDatastoreProvider) datastoreProvider ).getDatabase();
}
@Override
public void executeCypherQuery(DatastoreProvider datastoreProvider, String query, Map<String, Object> parameters) {
EmbeddedNeo4jDatastoreProvider provider = (EmbeddedNeo4jDatastoreProvider) datastoreProvider;
GraphDatabaseService engine = provider.getDatabase();
try {
engine.execute( query, parameters );
}
catch (QueryExecutionException qe) {
throw log.nativeQueryException( qe.getStatusCode(), qe.getMessage(), qe );
}
}
@Override
public PropertyContainer findNode(DatastoreProvider datastoreProvider, NodeForGraphAssertions node) {
String nodeAsCypher = node.toCypher();
String query = "MATCH " + nodeAsCypher + " RETURN " + node.getAlias();
GraphDatabaseService engine = createExecutionEngine( datastoreProvider );
Transaction tx = engine.beginTx();
try {
ResourceIterator<Object> nodes = engine.execute( query, node.getParams() ).columnAs( node.getAlias() );
PropertyContainer propertyContainer = (PropertyContainer) nodes.next();
if ( nodes.hasNext() ) {
throw new NotUniqueException();
}
tx.success();
return propertyContainer;
}
finally {
tx.close();
}
}
@Override
public Map<String, Object> findProperties(DatastoreProvider datastoreProvider, NodeForGraphAssertions node) {
String nodeAsCypher = node.toCypher();
String query = "MATCH " + nodeAsCypher + " RETURN " + node.getAlias();
GraphDatabaseService engine = createExecutionEngine( datastoreProvider );
Transaction tx = engine.beginTx();
try {
ResourceIterator<Object> nodes = engine.execute( query, node.getParams() ).columnAs( node.getAlias() );
PropertyContainer propertyContainer = (PropertyContainer) nodes.next();
if ( nodes.hasNext() ) {
throw new NotUniqueException();
}
Map<String, Object> allProperties = propertyContainer.getAllProperties();
tx.success();
return allProperties;
}
finally {
tx.close();
}
}
@Override
public PropertyContainer findRelationshipStartNode(DatastoreProvider datastoreProvider, RelationshipsChainForGraphAssertions relationship) {
GraphDatabaseService engine = createExecutionEngine( datastoreProvider );
Transaction tx = engine.beginTx();
try {
String relationshipAsCypher = relationship.toCypher();
NodeForGraphAssertions node = relationship.getStart();
String query = "MATCH " + relationshipAsCypher + " RETURN " + node.getAlias();
ResourceIterator<Object> results = engine.execute( query, relationship.getParams() ).columnAs( node.getAlias() );
if ( !results.hasNext() ) {
return null;
}
PropertyContainer startNode = (PropertyContainer) results.next();
if ( results.hasNext() ) {
throw new NotUniqueException();
}
tx.success();
return startNode;
}
finally {
tx.close();
}
}
}