Files
memgraph/src/communication/bolt/v1/states/executor.hpp
Mislav Bradac a58e269176 Fix bugs needed to run qa tests
Reviewers: buda

Reviewed By: buda

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D216
2017-04-04 17:28:08 +02:00

111 lines
3.7 KiB
C++

#pragma once
#include <string>
#include "communication/bolt/v1/messaging/codes.hpp"
#include "communication/bolt/v1/state.hpp"
#include "logging/default.hpp"
#include "query/exceptions.hpp"
namespace communication::bolt {
struct Query {
Query(std::string &&statement) : statement(statement) {}
std::string statement;
};
/**
* TODO (mferencevic): finish & document
*/
template <typename Session>
State StateExecutorRun(Session &session) {
// initialize logger
static Logger logger = logging::log->logger("State EXECUTOR");
// just read one byte that represents the struct type, we can skip the
// information contained in this byte
session.decoder_.read_byte();
auto message_type = session.decoder_.read_byte();
if (message_type == MessageCode::Run) {
Query query(session.decoder_.read_string());
// TODO (mferencevic): implement proper exception handling
auto db_accessor = session.dbms_.active();
logger.debug("[ActiveDB] '{}'", db_accessor->name());
try {
logger.trace("[Run] '{}'", query.statement);
auto is_successfully_executed = session.query_engine_.Run(
query.statement, *db_accessor, session.output_stream_);
if (!is_successfully_executed) {
db_accessor->abort();
session.encoder_.MessageFailure(
{{"code", "Memgraph.QueryExecutionFail"},
{"message",
"Query execution has failed (probably there is no "
"element or there are some problems with concurrent "
"access -> client has to resolve problems with "
"concurrent access)"}});
return ERROR;
} else {
db_accessor->commit();
}
return EXECUTOR;
// !! QUERY ENGINE -> RUN METHOD -> EXCEPTION HANDLING !!
} catch (const query::SyntaxException &e) {
db_accessor->abort();
session.encoder_.MessageFailure(
{{"code", "Memgraph.SyntaxException"}, {"message", "Syntax error"}});
return ERROR;
} catch (const query::QueryEngineException &e) {
db_accessor->abort();
session.encoder_.MessageFailure(
{{"code", "Memgraph.QueryEngineException"},
{"message", "Query engine was unable to execute the query"}});
return ERROR;
} catch (const StacktraceException &e) {
db_accessor->abort();
session.encoder_.MessageFailure({{"code", "Memgraph.StacktraceException"},
{"message", "Unknown exception"}});
return ERROR;
} catch (std::exception &e) {
db_accessor->abort();
session.encoder_.MessageFailure(
{{"code", "Memgraph.Exception"}, {"message", "Unknown exception"}});
return ERROR;
}
// TODO (mferencevic): finish the error handling, cover all exceptions
// which can be raised from query engine
// * [abort, MessageFailure, return ERROR] should be extracted into
// separate function (or something equivalent)
//
// !! QUERY ENGINE -> RUN METHOD -> EXCEPTION HANDLING !!
} else if (message_type == MessageCode::PullAll) {
logger.trace("[PullAll]");
session.encoder_buffer_.Flush();
} else if (message_type == MessageCode::DiscardAll) {
logger.trace("[DiscardAll]");
// TODO: discard state
// TODO: write_success, send
session.encoder_.MessageSuccess();
} else if (message_type == MessageCode::Reset) {
// TODO: rollback current transaction
// discard all records waiting to be sent
session.encoder_.MessageSuccess();
return EXECUTOR;
} else {
logger.error("Unrecognized message recieved");
logger.debug("Invalid message type 0x{:02X}", message_type);
return ERROR;
}
return EXECUTOR;
}
}