
org.neo4j.ogm.drivers.embedded.request.EmbeddedRequest Maven / Gradle / Ivy
/*
* Copyright (c) 2002-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product may include a number of subcomponents with
* separate copyright notices and license terms. Your use of the source
* code for these subcomponents is subject to the terms and
* conditions of the subcomponent's license, as noted in the LICENSE file.
*/
package org.neo4j.ogm.drivers.embedded.request;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.QueryExecutionException;
import org.neo4j.graphdb.Result;
import org.neo4j.ogm.drivers.embedded.response.GraphModelResponse;
import org.neo4j.ogm.drivers.embedded.response.GraphRowModelResponse;
import org.neo4j.ogm.drivers.embedded.response.RestModelResponse;
import org.neo4j.ogm.drivers.embedded.response.RowModelResponse;
import org.neo4j.ogm.drivers.embedded.transaction.EmbeddedTransaction;
import org.neo4j.ogm.exception.CypherException;
import org.neo4j.ogm.json.ObjectMapperFactory;
import org.neo4j.ogm.model.GraphModel;
import org.neo4j.ogm.model.GraphRowListModel;
import org.neo4j.ogm.model.RestModel;
import org.neo4j.ogm.model.RowModel;
import org.neo4j.ogm.request.DefaultRequest;
import org.neo4j.ogm.request.GraphModelRequest;
import org.neo4j.ogm.request.GraphRowListModelRequest;
import org.neo4j.ogm.request.Request;
import org.neo4j.ogm.request.RestModelRequest;
import org.neo4j.ogm.request.RowModelRequest;
import org.neo4j.ogm.request.Statement;
import org.neo4j.ogm.response.EmptyResponse;
import org.neo4j.ogm.response.Response;
import org.neo4j.ogm.transaction.TransactionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author vince
* @author Luanne Misquitta
*/
public class EmbeddedRequest implements Request {
private static final ObjectMapper mapper = ObjectMapperFactory.objectMapper();
private final GraphDatabaseService graphDatabaseService;
private final Logger logger = LoggerFactory.getLogger(EmbeddedRequest.class);
private final TransactionManager transactionManager;
public EmbeddedRequest(GraphDatabaseService graphDatabaseService, TransactionManager transactionManager) {
this.graphDatabaseService = graphDatabaseService;
this.transactionManager = transactionManager;
}
@Override
public Response execute(GraphModelRequest request) {
if (request.getStatement().length() == 0) {
return new EmptyResponse();
}
return new GraphModelResponse(executeRequest(request), transactionManager);
}
@Override
public Response execute(RowModelRequest request) {
if (request.getStatement().length() == 0) {
return new EmptyResponse();
}
return new RowModelResponse(executeRequest(request), transactionManager);
}
@Override
public Response execute(DefaultRequest query) {
//TODO this is a hack to get the embedded driver to work with executing multiple statements
final List rowmodels = new ArrayList<>();
String[] columns = null;
for (Statement statement : query.getStatements()) {
Result result = executeRequest(statement);
if (columns == null) {
columns = result.columns().toArray(new String[result.columns().size()]);
}
RowModelResponse rowModelResponse = new RowModelResponse(result, transactionManager);
RowModel model;
while ((model = rowModelResponse.next()) != null) {
rowmodels.add(model);
}
result.close();
}
final String[] finalColumns = columns;
return new Response() {
int currentRow = 0;
@Override
public RowModel next() {
if (currentRow < rowmodels.size()) {
return rowmodels.get(currentRow++);
}
return null;
}
@Override
public void close() {
if (transactionManager.getCurrentTransaction() != null) {
logger.debug("Response closed: {}", this);
// if the current transaction is an autocommit one, we should commit and close it now,
EmbeddedTransaction tx = (EmbeddedTransaction) transactionManager.getCurrentTransaction();
if (tx.isAutoCommit()) {
tx.commit();
tx.close();
}
}
}
@Override
public String[] columns() {
return finalColumns;
}
};
}
@Override
public Response execute(GraphRowListModelRequest request) {
if (request.getStatement().length() == 0) {
return new EmptyResponse();
}
return new GraphRowModelResponse(executeRequest(request), transactionManager);
}
@Override
public Response execute(RestModelRequest request) {
if (request.getStatement().length() == 0) {
return new EmptyResponse();
}
return new RestModelResponse(executeRequest(request), transactionManager);
}
private Result executeRequest(Statement statement) {
try {
String cypher = statement.getStatement();
String params = mapper.writeValueAsString(statement.getParameters());
TypeReference> typeRef = new TypeReference>() {};
HashMap parameterMap = mapper.readValue(params.getBytes(), typeRef);
logger.info("Request: {} with params {}", cypher, parameterMap);
// If we don't have a current transactional context for this operation
// we must create one, and mark the transaction as autoCommit. This will ensure the
// transaction is closed on the database as soon as the response has been consumed.
// An EmbeddedTransaction marked as autoCommit will then function the same way
// as the generic autoCommit http endpoint from the perspective of user code.
// From an implementation perspective in the OGM, the difference is that the server
// looks after committing and closing the http endpoint "/commit", whereas in embedded
// mode, the OGM has to do this. See {@link EmbeddedResponse} for where this is done.
if (transactionManager.getCurrentTransaction() == null) {
transactionManager.openTransaction();
EmbeddedTransaction tx = (EmbeddedTransaction) transactionManager.getCurrentTransaction();
tx.setAutoCommit(true);
}
return graphDatabaseService.execute(cypher, parameterMap);
}
catch (QueryExecutionException qee) {
EmbeddedTransaction tx = (EmbeddedTransaction) transactionManager.getCurrentTransaction();
tx.rollback();
throw new CypherException("Error executing Cypher", qee, qee.getStatusCode(),qee.getMessage());
}
catch (Exception e) {
EmbeddedTransaction tx = (EmbeddedTransaction) transactionManager.getCurrentTransaction();
tx.rollback();
throw new RuntimeException(e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy