tmp commit, work in progress, relationship create
This commit is contained in:
parent
eaf2025cab
commit
be820ce915
@ -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 -----------------------------------------------------------------
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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: {}";
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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>>>>>;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user