/* * 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.embedded.dialect.impl; import java.util.Collections; import java.util.Map; import org.hibernate.ogm.datastore.neo4j.dialect.impl.BaseNeo4jEntityQueries; import org.hibernate.ogm.dialect.spi.TupleTypeContext; import org.hibernate.ogm.model.key.spi.EntityKey; import org.hibernate.ogm.model.key.spi.EntityKeyMetadata; import org.hibernate.ogm.util.impl.ArrayHelper; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.ResourceIterator; import org.neo4j.graphdb.Result; /** * Container for the queries related to one entity type in Neo4j. Unfortunately, we cannot use the same queries for all * entities, as Neo4j does not allow to parameterize on node labels which would be required, as the entity name is * stored as a label. * * @author Davide D'Alto */ public class EmbeddedNeo4jEntityQueries extends BaseNeo4jEntityQueries { public EmbeddedNeo4jEntityQueries(EntityKeyMetadata entityKeyMetadata) { this( entityKeyMetadata, null ); } public EmbeddedNeo4jEntityQueries(EntityKeyMetadata entityKeyMetadata, TupleTypeContext tupleTypeContext) { super( entityKeyMetadata, tupleTypeContext, false ); } /** * Find the relationships representing the association. * * @param executionEngine the queries executor * @param columnValues the values for the entity key column names of the owner node * @param role the relationship type mapping the role of the association * @return an iterator on the results */ // We should move this in EmbeddedNeo4jAssociationQueries but, at the moment, having a query that only requires an // EntityKeyMetadata make it easier // to deal with the *ToOne scenario public ResourceIterator<Relationship> findAssociation(GraphDatabaseService executionEngine, Object[] columnValues, String role) { String query = getFindAssociationQuery( role ); Map<String, Object> params = params( columnValues ); executionEngine.execute( query, params ); return executionEngine.execute( query, params( columnValues ) ).columnAs( "r" ); } /** * Create a single node representing an embedded element. * * @param executionEngine the {@link GraphDatabaseService} used to run the query * @param columnValues the values in {@link org.hibernate.ogm.model.key.spi.EntityKey#getColumnValues()} * @return the corresponding node; */ public Node createEmbedded(GraphDatabaseService executionEngine, Object[] columnValues) { Map<String, Object> params = params( columnValues ); Result result = executionEngine.execute( getCreateEmbeddedNodeQuery(), params ); return singleResult( result ); } /** * Find the node corresponding to an entity. * * @param executionEngine the {@link GraphDatabaseService} used to run the query * @param columnValues the values in {@link org.hibernate.ogm.model.key.spi.EntityKey#getColumnValues()} * @return the corresponding node */ public Node findEntity(GraphDatabaseService executionEngine, Object[] columnValues) { Map<String, Object> params = params( columnValues ); Result result = executionEngine.execute( getFindEntityQuery(), params ); return singleResult( result ); } /** * Find the nodes corresponding to an array of entity keys. * * @param executionEngine the {@link GraphDatabaseService} used to run the query * @param keys an array of keys identifying the nodes to return * @return the list of nodes representing the entities */ public ResourceIterator<Node> findEntities(GraphDatabaseService executionEngine, EntityKey[] keys) { if ( singlePropertyKey ) { return singlePropertyIdFindEntities( executionEngine, keys ); } else { return multiPropertiesIdFindEntities( executionEngine, keys ); } } /* * When the id is mapped on several properties */ private ResourceIterator<Node> multiPropertiesIdFindEntities(GraphDatabaseService executionEngine, EntityKey[] keys) { String query = getMultiGetQueryCacheQuery( keys ); Map<String, Object> params = multiGetParams( keys ); Result result = executionEngine.execute( query, params ); return result.columnAs( ENTITY_ALIAS ); } /* * When the id is mapped with a single property */ private ResourceIterator<Node> singlePropertyIdFindEntities(GraphDatabaseService executionEngine, EntityKey[] keys) { Object[] paramsValues = new Object[keys.length]; for ( int i = 0; i < keys.length; i++ ) { paramsValues[i] = keys[i].getColumnValues()[0]; } Map<String, Object> params = Collections.singletonMap( "0", (Object) paramsValues ); Result result = executionEngine.execute( multiGetQuery, params ); return result.columnAs( ENTITY_ALIAS ); } /** * Creates the node corresponding to an entity. * * @param executionEngine the {@link GraphDatabaseService} used to run the query * @param columnValues the values in {@link org.hibernate.ogm.model.key.spi.EntityKey#getColumnValues()} * @return the corresponding node */ public Node insertEntity(GraphDatabaseService executionEngine, Object[] columnValues) { Map<String, Object> params = params( columnValues ); Result result = executionEngine.execute( getCreateEntityQuery(), params ); return singleResult( result ); } /** * Find all the node representing the entity. * * @param executionEngine the {@link GraphDatabaseService} used to run the query * @return an iterator over the nodes representing an entity */ public ResourceIterator<Node> findEntities(GraphDatabaseService executionEngine) { Result result = executionEngine.execute( getFindEntitiesQuery() ); return result.columnAs( BaseNeo4jEntityQueries.ENTITY_ALIAS ); } /** * Remove the nodes representing the entity and the embedded elements attached to it. * * @param executionEngine the {@link GraphDatabaseService} used to run the query * @param columnValues the values of the key identifying the entity to remove */ public void removeEntity(GraphDatabaseService executionEngine, Object[] columnValues) { Map<String, Object> params = params( columnValues ); executionEngine.execute( getRemoveEntityQuery(), params ); } /** * Update the value of an embedded node property. * * @param executionEngine the {@link GraphDatabaseService} used to run the query * @param keyValues the columns representing the identifier in the entity owning the embedded * @param embeddedColumn the column on the embedded node (dot-separated properties) * @param value the new value for the property */ public void updateEmbeddedColumn(GraphDatabaseService executionEngine, Object[] keyValues, String embeddedColumn, Object value) { String query = getUpdateEmbeddedColumnQuery( keyValues, embeddedColumn ); Map<String, Object> params = params( ArrayHelper.concat( keyValues, value, value ) ); executionEngine.execute( query, params ); } }