tmp commit, work in progress, relationship create

This commit is contained in:
Marko Budiselic 2016-08-30 01:01:03 +01:00
parent eaf2025cab
commit be820ce915
10 changed files with 107 additions and 23 deletions

View File

@ -307,6 +307,7 @@ endif()
set(CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE} -Wall")
# TODO: find a way how to applay the defines at the query compile time
# -- configure defines -- default is ON | true | enabled ----------------------
# -- logging ------------------------------------------------------------------
option(LOG_NO_TRACE "Disable trace logging" OFF)
@ -376,6 +377,16 @@ message(STATUS "TOOLS binaries: ${TOOLS}")
option(TESTS "Build test binaries" ON)
message(STATUS "TESTS binaries: ${TESTS}")
# -- binaries -----------------------------------------------------------------
# -- barrier - this is the way how the engine is isolated so it can be shipped
# wherever, the code is completely hidden behind the barrier, during the
# development the barrier can be turned off because it is much easier to
# debug
option(BARRIER "Barrier" ON)
message(STATUS "Barrier: ${BARRIER} (Source code isolation)")
if(BARRIER)
add_definitions( -DBARRIER )
endif()
# -- barrier ------------------------------------------------------------------
# -- configure defines --------------------------------------------------------
# -- includes -----------------------------------------------------------------

View File

@ -58,7 +58,7 @@ public:
{"stream", type_name<Stream>().to_string()},
{"code", cpp_traverser.code}});
// logger.trace("generated code: {}", generated);
logger.debug("generated code: {}", generated);
utils::write_file(generated, path);
}

View File

@ -22,23 +22,33 @@ enum class CypherState : uint8_t
enum class EntityStatus : uint8_t
{
NotFound,
None,
Matched,
Created
};
enum class EntityType : uint8_t
{
NotFound,
None,
Node,
Relationship
};
// where OR how entity can be found
enum class EntitySource : uint8_t
{
None,
InternalId,
LabelIndex,
MainStorage
};
class CypherStateData
{
private:
std::map<std::string, EntityStatus> entity_status;
std::map<std::string, EntityType> entity_type;
std::map<std::string, EntitySource> entity_source;
// TODO: container that keeps track about c++ variable names
@ -51,7 +61,7 @@ public:
EntityStatus status(const std::string &name)
{
if (entity_status.find(name) == entity_status.end())
return EntityStatus::NotFound;
return EntityStatus::None;
return entity_status.at(name);
}
@ -59,11 +69,18 @@ public:
EntityType type(const std::string &name) const
{
if (entity_type.find(name) == entity_type.end())
return EntityType::NotFound;
return EntityType::None;
return entity_type.at(name);
}
EntitySource source(const std::string &name) const
{
if (entity_source.find(name) == entity_source.end())
return EntitySource::None;
return entity_source.at(name);
}
const std::map<std::string, EntityType> &all_typed_enteties()
{
return entity_type;
@ -92,4 +109,9 @@ public:
entity_type[name] = EntityType::Relationship;
entity_status[name] = EntityStatus::Created;
}
void source(const std::string& name, EntitySource source)
{
entity_source[name] = source;
}
};

View File

@ -30,26 +30,29 @@ auto match_query_action =
for (auto const &kv : action_data.actions) {
// TODO: the same code REFACTOR!
auto name = kv.first;
// find node
if (kv.second == ClauseAction::MatchNode) {
auto name = kv.first;
if (already_matched(cypher_data, name, EntityType::Node)) continue;
if (already_matched(cypher_data, name, EntityType::Node))
continue;
cypher_data.node_matched(name);
auto place = action_data.csm.min(kv.first);
auto place = action_data.csm.min(name);
if (place == entity_search::search_internal_id) {
auto index = fetch_internal_index(action_data, name);
code += code_line(code::match_vertex_by_id, name, index);
}
if (place == entity_search::search_main_storage) {
cypher_data.source(name, EntitySource::MainStorage);
}
}
// find relationship
if (kv.second == ClauseAction::MatchRelationship) {
auto name = kv.first;
if (already_matched(cypher_data, name, EntityType::Relationship))
continue;
cypher_data.relationship_matched(name);
auto place = action_data.csm.min(kv.first);
auto place = action_data.csm.min(name);
if (place == entity_search::search_internal_id) {
auto index = fetch_internal_index(action_data, name);
code += code_line(code::match_edge_by_id, name, index);

View File

@ -11,16 +11,37 @@ auto return_query_action =
const auto &elements = action_data.return_elements;
code += code_line("// number of elements {}", elements.size());
// TODO: call bolt serialization
for (const auto &element : elements) {
for (const auto &element : elements)
{
auto &entity = element.entity;
if (!cypher_data.exist(entity)) {
if (!cypher_data.exist(entity))
throw SemanticError(
fmt::format("{} couldn't be found (RETURN clause).", entity));
}
if (element.is_entity_only()) {
code += code_line(code::write_entity, entity);
} else if (element.is_projection()) {
if (element.is_entity_only())
{
// if the node has just recently been created on can be found
// with the internal id then it can be sent to the client
if (cypher_data.status(entity) == EntityStatus::Created ||
(cypher_data.source(entity) == EntitySource::InternalId &&
cypher_data.status(entity) == EntityStatus::Matched))
{
code += code_line(code::write_entity, entity);
}
// the client has to receive all elements from the main storage
if (cypher_data.source(entity) == EntitySource::MainStorage)
{
code += code_line(code::write_all_vertices, entity);
}
if (cypher_data.source(entity) == EntitySource::LabelIndex)
{
// TODO: fetch somehow label name
// TODO: code_line
}
}
else if (element.is_projection())
{
code += code_line("// TODO: implement projection");
// auto &property = element.property;
// code += code_line(code::print_property, entity, property);

View File

@ -6,14 +6,15 @@
struct Code
{
void reset() { code = ""; }
std::string code;
void reset() { code = ""; }
};
namespace code
{
// TODO: one more abstraction level
// TODO: UNIT tests
const std::string transaction_begin = "DbAccessor t(db);";
@ -58,6 +59,18 @@ const std::string write_entity = "stream.write_field(\"{0}\");\n"
" stream.chunk();"
" stream.write_meta(\"rw\");\n";
const std::string write_all_vertices =
"stream.write_field(\"{0}\");\n"
" iter::for_all(t.vertex_access(), [&](auto vertex) {{\n"
" if (vertex.fill()) {{\n"
" stream.write_record();\n"
" stream.write_list_header(1);\n"
" stream.write(vertex);\n"
" stream.chunk();\n"
" }}\n"
" }});\n"
" stream.write_meta(\"rw\");\n";
const std::string return_true = "return true;";
const std::string todo = "// TODO: {}";

View File

@ -255,7 +255,11 @@ public:
Traverser::visit(ast_node);
if (state == CypherState::Create) {
// this is here because of RETURN clause
// CREATE (n {...}) RETURN n
if (cypher_data.status(name) != EntityStatus::Matched &&
state == CypherState::Create)
{
cypher_data.node_created(name);
}
}
@ -447,7 +451,7 @@ public:
auto &cypher_data = generator.cypher_data();
auto entity_type = cypher_data.type(entity);
if (entity_type == EntityType::NotFound)
if (entity_type == EntityType::None)
throw SemanticError("Entity (" + entity + ") doesn't exist");
auto &action_data = generator.action_data();

View File

@ -30,6 +30,9 @@ public:
// Creates new Vertex and returns filled VertexAccessor.
VertexAccessor insert(DbTransaction &t);
// TODO: how can I know how many elements exist
// without iterating through all of them? MVCC?
VertexPropertyFamily &
property_family_find_or_create(const std::string &name);

View File

@ -1,5 +1,8 @@
#include "communication/bolt/v1/serialization/bolt_serializer.hpp"
#include "communication/bolt/v1/transport/chunked_buffer.hpp"
#include "communication/bolt/v1/transport/chunked_encoder.hpp"
#include "communication/bolt/v1/transport/socket_stream.hpp"
#include "storage/edge_x_vertex.hpp"
template <class Stream>
@ -28,3 +31,6 @@ void bolt::BoltSerializer<Stream>::write(const EdgeAccessor &edge)
write(*prop.second);
}
}
// template class bolt::BoltSerializer<bolt::BoltEncoder<
// bolt::ChunkedEncoder<bolt::ChunkedBuffer<bolt::SocketStream<io::Socket>>>>>;

View File

@ -57,7 +57,8 @@ void Executor::run(Session& session, Query& query)
auto &db = session.active_db();
logger.debug("[ActiveDB] '{}'", db.name());
// TODO: hangle syntax error use case
// TODO: error handling
query_engine.execute(query.statement, db, session.output_stream);
}