Fixed Query compiler to use new interface.
This commit is contained in:
parent
e5f161974f
commit
eba7fd8be4
@ -146,6 +146,7 @@ endforeach()
|
||||
# TODO: somehow automate (in destination dir should be only required include files)
|
||||
FILE(COPY ${include_dir}/database/db.hpp DESTINATION ${build_include_dir}/database)
|
||||
FILE(COPY ${include_dir}/database/db_transaction.hpp DESTINATION ${build_include_dir}/database)
|
||||
FILE(COPY ${include_dir}/database/db_accessor.hpp DESTINATION ${build_include_dir}/database)
|
||||
|
||||
FILE(COPY ${include_dir}/storage/common.hpp DESTINATION ${build_include_dir}/storage)
|
||||
FILE(COPY ${include_dir}/storage/graph.hpp DESTINATION ${build_include_dir}/storage)
|
||||
@ -163,6 +164,7 @@ FILE(COPY ${include_dir}/storage/edge_type/edge_type_store.hpp DESTINATION ${bui
|
||||
FILE(COPY ${include_dir}/storage/edge_type/edge_type.hpp DESTINATION ${build_include_dir}/storage/edge_type)
|
||||
FILE(COPY ${include_dir}/storage/label/label_store.hpp DESTINATION ${build_include_dir}/storage/label)
|
||||
FILE(COPY ${include_dir}/storage/model/edge_map.hpp DESTINATION ${build_include_dir}/storage/model)
|
||||
FILE(COPY ${include_dir}/storage/model/properties/flags.hpp DESTINATION ${build_include_dir}/storage/model/properties)
|
||||
|
||||
FILE(COPY ${include_dir}/query_engine/util.hpp DESTINATION ${build_include_dir}/query_engine)
|
||||
FILE(COPY ${include_dir}/query_engine/i_code_cpu.hpp DESTINATION ${build_include_dir}/query_engine)
|
||||
@ -171,6 +173,7 @@ FILE(COPY ${include_dir}/query_engine/query_stripped.hpp DESTINATION ${build_inc
|
||||
|
||||
FILE(COPY ${include_dir}/data_structures/concurrent/concurrent_map.hpp DESTINATION ${build_include_dir}/data_structures/concurrent)
|
||||
FILE(COPY ${include_dir}/data_structures/concurrent/concurrent_set.hpp DESTINATION ${build_include_dir}/data_structures/concurrent)
|
||||
FILE(COPY ${include_dir}/data_structures/concurrent/concurrent_list.hpp DESTINATION ${build_include_dir}/data_structures/concurrent)
|
||||
FILE(COPY ${include_dir}/data_structures/concurrent/common.hpp DESTINATION ${build_include_dir}/data_structures/concurrent)
|
||||
FILE(COPY ${include_dir}/data_structures/concurrent/skiplist.hpp DESTINATION ${build_include_dir}/data_structures/concurrent)
|
||||
FILE(COPY ${include_dir}/data_structures/concurrent/skiplist_gc.hpp DESTINATION ${build_include_dir}/data_structures/concurrent)
|
||||
@ -236,6 +239,8 @@ FILE(COPY ${include_dir}/storage/label/label_store.hpp DESTINATION ${build_inclu
|
||||
FILE(COPY ${include_dir}/storage/indexes/index.hpp DESTINATION ${build_include_dir}/storage/indexes)
|
||||
FILE(COPY ${include_dir}/storage/indexes/index_record.hpp DESTINATION ${build_include_dir}/storage/indexes)
|
||||
FILE(COPY ${include_dir}/storage/indexes/index_record_collection.hpp DESTINATION ${build_include_dir}/storage/indexes)
|
||||
FILE(COPY ${include_dir}/storage/indexes/index_base.hpp DESTINATION ${build_include_dir}/storage/indexes)
|
||||
FILE(COPY ${include_dir}/storage/indexes/impl/nonunique_unordered_index.hpp DESTINATION ${build_include_dir}/storage/indexes/impl)
|
||||
|
||||
FILE(COPY ${include_dir}/utils/sys.hpp DESTINATION ${build_include_dir}/utils)
|
||||
FILE(COPY ${include_dir}/utils/bswap.hpp DESTINATION ${build_include_dir}/utils)
|
||||
@ -257,7 +262,10 @@ FILE(COPY ${include_dir}/utils/exceptions/basic_exception.hpp DESTINATION ${buil
|
||||
FILE(COPY ${include_dir}/utils/datetime/timestamp.hpp DESTINATION ${build_include_dir}/utils/datetime)
|
||||
FILE(COPY ${include_dir}/utils/datetime/datetime_error.hpp DESTINATION ${build_include_dir}/utils/datetime)
|
||||
FILE(COPY ${include_dir}/utils/types/byte.hpp DESTINATION ${build_include_dir}/utils/types)
|
||||
FILE(COPY ${include_dir}/utils/iterator/iterator_base.hpp DESTINATION ${build_include_dir}/utils/iterator)
|
||||
FILE(COPY ${include_dir}/utils/option_ptr.hpp DESTINATION ${build_include_dir}/utils)
|
||||
FILE(COPY ${include_dir}/utils/option.hpp DESTINATION ${build_include_dir}/utils)
|
||||
FILE(COPY ${include_dir}/utils/border.hpp DESTINATION ${build_include_dir}/utils)
|
||||
|
||||
FILE(COPY ${include_dir}/communication/communication.hpp DESTINATION ${build_include_dir}/communication)
|
||||
FILE(COPY ${include_dir}/communication/bolt/v1/config.hpp DESTINATION ${build_include_dir}/communication/bolt/v1)
|
||||
@ -463,7 +471,7 @@ execute_process(
|
||||
COMMAND git rev-parse --short HEAD
|
||||
)
|
||||
execute_process(
|
||||
OUTPUT_VARIABLE COMMIT_NO
|
||||
OUTPUT_VARIABLE COMMIT_NO
|
||||
COMMAND git rev-list --count HEAD
|
||||
)
|
||||
string(STRIP ${COMMIT_BRANCH} COMMIT_BRANCH)
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
encoder.write_map_header(props.size());
|
||||
|
||||
for (auto &prop : props) {
|
||||
write(prop.first);
|
||||
write(prop.first.family_name());
|
||||
write(*prop.second);
|
||||
}
|
||||
}
|
||||
@ -93,7 +93,7 @@ public:
|
||||
encoder.write_map_header(props.size());
|
||||
|
||||
for (auto &prop : props) {
|
||||
write(prop.first);
|
||||
write(prop.first.family_name());
|
||||
write(*prop.second);
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,13 @@ public:
|
||||
|
||||
PropertyFamily &edge_property_family_get(const std::string &name);
|
||||
|
||||
// ******************** PROPERTY HELPER METHODS
|
||||
PropertyFamily::PropertyType::PropertyFamilyKey
|
||||
vertex_property_key(const std::string &name, Type type);
|
||||
|
||||
PropertyFamily::PropertyType::PropertyFamilyKey
|
||||
edge_property_key(const std::string &name, Type type);
|
||||
|
||||
// ******************** TRANSACTION METHODS
|
||||
|
||||
void commit();
|
||||
|
@ -4,6 +4,9 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "query_engine/code_generator/namer.hpp"
|
||||
#include "storage/model/properties/flags.hpp"
|
||||
|
||||
// main states that are used while ast is traversed
|
||||
// in order to generate ActionSequence
|
||||
enum class CypherState : uint8_t
|
||||
@ -36,10 +39,11 @@ class CypherStateData
|
||||
private:
|
||||
std::map<std::string, EntityStatus> entity_status;
|
||||
std::map<std::string, EntityType> entity_type;
|
||||
|
||||
// TODO: container that keeps track about c++ variable names
|
||||
|
||||
public:
|
||||
bool exist(const std::string& name) const
|
||||
bool exist(const std::string &name) const
|
||||
{
|
||||
return entity_status.find(name) != entity_status.end();
|
||||
}
|
||||
@ -52,7 +56,7 @@ public:
|
||||
return entity_status.at(name);
|
||||
}
|
||||
|
||||
EntityType type(const std::string &name)
|
||||
EntityType type(const std::string &name) const
|
||||
{
|
||||
if (entity_type.find(name) == entity_type.end())
|
||||
return EntityType::NotFound;
|
||||
@ -60,6 +64,11 @@ public:
|
||||
return entity_type.at(name);
|
||||
}
|
||||
|
||||
const std::map<std::string, EntityType> &all_typed_enteties()
|
||||
{
|
||||
return entity_type;
|
||||
}
|
||||
|
||||
void node_matched(const std::string &name)
|
||||
{
|
||||
entity_type[name] = EntityType::Node;
|
||||
|
@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "query_engine/code_generator/handlers/create.hpp"
|
||||
#include "query_engine/code_generator/handlers/delete.hpp"
|
||||
#include "query_engine/code_generator/handlers/match.hpp"
|
||||
#include "query_engine/code_generator/handlers/return.hpp"
|
||||
#include "query_engine/code_generator/handlers/set.hpp"
|
||||
#include "query_engine/code_generator/handlers/delete.hpp"
|
||||
#include "query_engine/code_generator/handlers/transaction_begin.hpp"
|
||||
#include "query_engine/code_generator/handlers/transaction_commit.hpp"
|
||||
|
@ -16,7 +16,7 @@ auto create_query_action =
|
||||
code += code_line(code::create_vertex, name);
|
||||
|
||||
// update properties
|
||||
code += update_properties(action_data, name);
|
||||
code += update_properties(cypher_data, action_data, name);
|
||||
|
||||
// update labels
|
||||
auto entity_data = action_data.get_entity_property(name);
|
||||
@ -30,19 +30,7 @@ auto create_query_action =
|
||||
}
|
||||
|
||||
if (kv.second == ClauseAction::CreateRelationship) {
|
||||
// create relationship
|
||||
auto name = kv.first;
|
||||
code += code_line(code::create_edge, name);
|
||||
|
||||
// update properties
|
||||
code += update_properties(action_data, name);
|
||||
|
||||
// update tag
|
||||
auto entity_data = action_data.get_entity_property(name);
|
||||
for (auto &tag : entity_data.tags) {
|
||||
code += code_line(code::find_type, tag);
|
||||
code += code_line(code::set_type, name, tag);
|
||||
}
|
||||
|
||||
// find start and end node
|
||||
auto &relationships_data = action_data.relationship_data;
|
||||
@ -63,19 +51,32 @@ auto create_query_action =
|
||||
" can't be found");
|
||||
}
|
||||
|
||||
// define direction
|
||||
if (relationship_data.direction == Direction::Right) {
|
||||
code += code_line(code::node_out, left_node, name);
|
||||
code += code_line(code::node_in, right_node, name);
|
||||
code += code_line(code::edge_from, name, left_node);
|
||||
code += code_line(code::edge_to, name, right_node);
|
||||
} else if (relationship_data.direction == Direction::Left) {
|
||||
code += code_line(code::node_out, right_node, name);
|
||||
code += code_line(code::node_in, left_node, name);
|
||||
code += code_line(code::edge_from, name, right_node);
|
||||
code += code_line(code::edge_to, name, left_node);
|
||||
// create relationship
|
||||
code += code_line(code::create_edge, name, left_node, right_node);
|
||||
|
||||
// update properties
|
||||
code += update_properties(cypher_data, action_data, name);
|
||||
|
||||
// update tag
|
||||
auto entity_data = action_data.get_entity_property(name);
|
||||
for (auto &tag : entity_data.tags) {
|
||||
code += code_line(code::find_type, tag);
|
||||
code += code_line(code::set_type, name, tag);
|
||||
}
|
||||
|
||||
// define direction
|
||||
// if (relationship_data.direction == Direction::Right) {
|
||||
// code += code_line(code::node_out, left_node, name);
|
||||
// code += code_line(code::node_in, right_node, name);
|
||||
// code += code_line(code::edge_from, name, left_node);
|
||||
// code += code_line(code::edge_to, name, right_node);
|
||||
// } else if (relationship_data.direction == Direction::Left) {
|
||||
// code += code_line(code::node_out, right_node, name);
|
||||
// code += code_line(code::node_in, left_node, name);
|
||||
// code += code_line(code::edge_from, name, right_node);
|
||||
// code += code_line(code::edge_to, name, left_node);
|
||||
// }
|
||||
|
||||
// mark relationship as created
|
||||
cypher_data.relationship_created(name);
|
||||
}
|
||||
|
@ -6,11 +6,12 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "query_engine/util.hpp"
|
||||
#include "query_engine/code_generator/cypher_state.hpp"
|
||||
#include "query_engine/code_generator/namer.hpp"
|
||||
#include "query_engine/code_generator/query_action_data.hpp"
|
||||
#include "query_engine/traverser/code.hpp"
|
||||
#include "query_engine/exceptions/errors.hpp"
|
||||
#include "query_engine/traverser/code.hpp"
|
||||
#include "query_engine/util.hpp"
|
||||
|
||||
using ParameterIndexKey::Type::InternalId;
|
||||
using Direction = RelationshipData::Direction;
|
||||
@ -18,7 +19,8 @@ using Direction = RelationshipData::Direction;
|
||||
namespace
|
||||
{
|
||||
|
||||
auto update_properties(const QueryActionData &action_data,
|
||||
auto update_properties(const CypherStateData &cypher_state,
|
||||
const QueryActionData &action_data,
|
||||
const std::string &name)
|
||||
{
|
||||
std::string code = "";
|
||||
@ -27,10 +29,14 @@ auto update_properties(const QueryActionData &action_data,
|
||||
for (auto &property : entity_data.properties) {
|
||||
auto index =
|
||||
action_data.parameter_index.at(ParameterIndexKey(name, property));
|
||||
code += code_line(code::set_property, name, property, index);
|
||||
auto tmp_name = name::unique();
|
||||
code += code_line((cypher_state.type(name) == EntityType::Node
|
||||
? code::vertex_property_key
|
||||
: code::edge_property_key),
|
||||
tmp_name, property, index);
|
||||
code += code_line(code::set_property, name, tmp_name, index);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ auto fetch_internal_index(const QueryActionData &action_data,
|
||||
{
|
||||
return action_data.parameter_index.at(ParameterIndexKey(InternalId, name));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
auto match_query_action =
|
||||
@ -40,8 +39,7 @@ auto match_query_action =
|
||||
auto place = action_data.csm.min(kv.first);
|
||||
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);
|
||||
code += code_line(code::match_vertex_by_id, name, index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ auto return_query_action =
|
||||
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)) {
|
||||
throw SemanticError(
|
||||
@ -26,6 +26,6 @@ auto return_query_action =
|
||||
// code += code_line(code::print_property, entity, property);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return code;
|
||||
};
|
||||
|
@ -13,13 +13,13 @@ auto set_query_action = [](CypherStateData &cypher_data,
|
||||
if (kv.second == ClauseAction::UpdateNode &&
|
||||
cypher_data.status(name) == EntityStatus::Matched &&
|
||||
cypher_data.type(name) == EntityType::Node) {
|
||||
code += update_properties(action_data, name);
|
||||
code += update_properties(cypher_data, action_data, name);
|
||||
}
|
||||
|
||||
if (kv.second == ClauseAction::UpdateRelationship &&
|
||||
cypher_data.status(name) == EntityStatus::Matched &&
|
||||
cypher_data.type(name) == EntityType::Relationship) {
|
||||
code += update_properties(action_data, name);
|
||||
code += update_properties(cypher_data, action_data, name);
|
||||
}
|
||||
}
|
||||
|
||||
|
18
include/query_engine/code_generator/namer.hpp
Normal file
18
include/query_engine/code_generator/namer.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "storage/model/properties/flags.hpp"
|
||||
|
||||
// This namespace names stuff
|
||||
namespace
|
||||
{
|
||||
namespace name
|
||||
{
|
||||
|
||||
std::string variable_property_key(const std::string &property_name, Type type)
|
||||
{
|
||||
return "prop_" + property_name + "_" + type.to_str();
|
||||
}
|
||||
|
||||
std::string unique() { return "unique_" + std::to_string(std::rand()); }
|
||||
}
|
||||
}
|
@ -4,9 +4,9 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "query_engine/exceptions/exceptions.hpp"
|
||||
#include "query_engine/code_generator/clause_action.hpp"
|
||||
#include "query_engine/code_generator/entity_search.hpp"
|
||||
#include "query_engine/exceptions/exceptions.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "utils/assert.hpp"
|
||||
#include "utils/underlying_cast.hpp"
|
||||
@ -97,9 +97,9 @@ struct RelationshipData
|
||||
|
||||
struct ReturnElement
|
||||
{
|
||||
ReturnElement(const std::string& entity) : entity(entity) {}
|
||||
ReturnElement(const std::string& entity, const std::string& property) :
|
||||
entity(entity), property(property) {};
|
||||
ReturnElement(const std::string &entity) : entity(entity) {}
|
||||
ReturnElement(const std::string &entity, const std::string &property)
|
||||
: entity(entity), property(property){};
|
||||
|
||||
std::string entity;
|
||||
std::string property;
|
||||
@ -143,7 +143,7 @@ struct QueryActionData
|
||||
}
|
||||
|
||||
// TODO: refactor name
|
||||
auto get_entity_property(const std::string& entity) const
|
||||
auto get_entity_property(const std::string &entity) const
|
||||
{
|
||||
if (entity_data.find(entity) == entity_data.end())
|
||||
throw CppGeneratorException("Entity " + entity + " doesn't exist");
|
||||
|
@ -18,9 +18,7 @@ auto load_queries(Db &db)
|
||||
// CREATE (n {prop: 0}) RETURN n)
|
||||
auto create_node = [&db](const properties_t &args) {
|
||||
DbAccessor t(db);
|
||||
auto prop_key = t.vertex_property_family_get("prop")
|
||||
.get(args[0]->flags)
|
||||
.family_key();
|
||||
auto prop_key = t.vertex_property_key("prop", args[0]->flags);
|
||||
|
||||
auto vertex_accessor = t.vertex_insert();
|
||||
vertex_accessor.set(prop_key, args[0]);
|
||||
@ -31,13 +29,11 @@ auto load_queries(Db &db)
|
||||
|
||||
auto create_labeled_and_named_node = [&db](const properties_t &args) {
|
||||
DbAccessor t(db);
|
||||
auto prop_key = t.vertex_property_family_get("name")
|
||||
.get(args[0]->flags)
|
||||
.family_key();
|
||||
auto prop_key = t.vertex_property_key("name", args[0]->flags);
|
||||
auto &label = t.label_find_or_create("LABEL");
|
||||
|
||||
auto vertex_accessor = t.vertex_insert();
|
||||
vertex_accessor.set(prop_key, args[0]);
|
||||
auto &label = t.label_find_or_create("LABEL");
|
||||
vertex_accessor.add_label(label);
|
||||
cout_properties(vertex_accessor.properties());
|
||||
t.commit();
|
||||
@ -46,24 +42,17 @@ auto load_queries(Db &db)
|
||||
|
||||
auto create_account = [&db](const properties_t &args) {
|
||||
DbAccessor t(db);
|
||||
auto prop_id =
|
||||
t.vertex_property_family_get("id").get(args[0]->flags).family_key();
|
||||
auto prop_name = t.vertex_property_family_get("name")
|
||||
.get(args[1]->flags)
|
||||
.family_key();
|
||||
auto prop_country = t.vertex_property_family_get("country")
|
||||
.get(args[2]->flags)
|
||||
.family_key();
|
||||
auto prop_created = t.vertex_property_family_get("created_at")
|
||||
.get(args[3]->flags)
|
||||
.family_key();
|
||||
auto prop_id = t.vertex_property_key("id", args[0]->flags);
|
||||
auto prop_name = t.vertex_property_key("name", args[1]->flags);
|
||||
auto prop_country = t.vertex_property_key("country", args[2]->flags);
|
||||
auto prop_created = t.vertex_property_key("created_at", args[3]->flags);
|
||||
auto &label = t.label_find_or_create("ACCOUNT");
|
||||
|
||||
auto vertex_accessor = t.vertex_insert();
|
||||
vertex_accessor.set(prop_id, args[0]);
|
||||
vertex_accessor.set(prop_name, args[1]);
|
||||
vertex_accessor.set(prop_country, args[2]);
|
||||
vertex_accessor.set(prop_created, args[3]);
|
||||
auto &label = t.label_find_or_create("ACCOUNT");
|
||||
vertex_accessor.add_label(label);
|
||||
cout_properties(vertex_accessor.properties());
|
||||
t.commit();
|
||||
@ -90,6 +79,7 @@ auto load_queries(Db &db)
|
||||
|
||||
auto create_edge = [&db](const properties_t &args) {
|
||||
DbAccessor t(db);
|
||||
auto &edge_type = t.type_find_or_create("IS");
|
||||
|
||||
auto v1 = t.vertex_find(args[0]->as<Int32>().value);
|
||||
if (!option_fill(v1)) return t.commit(), false;
|
||||
@ -99,7 +89,6 @@ auto load_queries(Db &db)
|
||||
|
||||
auto edge_accessor = t.edge_insert(v1.get(), v2.get());
|
||||
|
||||
auto &edge_type = t.type_find_or_create("IS");
|
||||
edge_accessor.edge_type(edge_type);
|
||||
|
||||
t.commit();
|
||||
@ -139,9 +128,7 @@ auto load_queries(Db &db)
|
||||
|
||||
auto update_node = [&db](const properties_t &args) {
|
||||
DbAccessor t(db);
|
||||
auto prop_name = t.vertex_property_family_get("name")
|
||||
.get(args[1]->flags)
|
||||
.family_key();
|
||||
auto prop_name = t.vertex_property_key("name", args[1]->flags);
|
||||
|
||||
auto maybe_v = t.vertex_find(args[0]->as<Int32>().value);
|
||||
if (!option_fill(maybe_v)) return t.commit(), false;
|
||||
@ -160,11 +147,8 @@ auto load_queries(Db &db)
|
||||
auto create_edge_v2 = [&db](const properties_t &args) {
|
||||
DbAccessor t(db);
|
||||
|
||||
auto prop_age =
|
||||
t.edge_property_family_get("age").get(args[2]->flags).family_key();
|
||||
auto prop_weight = t.edge_property_family_get("weight")
|
||||
.get(args[3]->flags)
|
||||
.family_key();
|
||||
auto prop_age = t.edge_property_key("age", args[2]->flags);
|
||||
auto prop_weight = t.edge_property_key("weight", args[3]->flags);
|
||||
|
||||
auto n1 = t.vertex_find(args[0]->as<Int64>().value);
|
||||
if (!option_fill(n1)) return t.commit(), false;
|
||||
@ -202,8 +186,7 @@ auto load_queries(Db &db)
|
||||
DbAccessor t(db);
|
||||
|
||||
auto &label = t.label_find_or_create("LABEL");
|
||||
auto prop_key =
|
||||
t.vertex_property_family_get("name").get(Type::String).family_key();
|
||||
auto prop_key = t.vertex_property_key("name", Flags::String);
|
||||
|
||||
cout << "VERTICES" << endl;
|
||||
iter::for_all(label.index->for_range_exact(t),
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "communication/communication.hpp"
|
||||
#include "database/db.hpp"
|
||||
#include "database/db_accessor.hpp"
|
||||
#include "query_engine/query_stripped.hpp"
|
||||
|
||||
class ICodeCPU
|
||||
|
@ -16,56 +16,53 @@ namespace code
|
||||
|
||||
// TODO: UNIT tests
|
||||
|
||||
const std::string transaction_begin = "auto& t = db.tx_engine.begin();";
|
||||
const std::string transaction_begin = "DbAccessor t(db);";
|
||||
|
||||
const std::string transaction_commit = "t.commit();";
|
||||
|
||||
const std::string set_property = "{}.property(\"{}\", args[{}]);";
|
||||
const std::string set_property = "{}.set({}, args[{}]);";
|
||||
|
||||
// create vertex e.g. CREATE (n:PERSON {name: "Test", age: 23})
|
||||
const std::string create_vertex = "auto {} = db.graph.vertices.insert(t);";
|
||||
const std::string create_label =
|
||||
"auto &{0} = db.graph.label_store.find_or_create(\"{0}\");";
|
||||
const std::string create_vertex = "auto {} = t.vertex_insert();";
|
||||
const std::string create_label = "auto &{0} = t.label_find_or_create(\"{0}\");";
|
||||
const std::string add_label = "{}.add_label({});";
|
||||
|
||||
const std::string vertex_property_key =
|
||||
"auto {}=t.vertex_property_key(\"{}\",args[{}]->flags);";
|
||||
const std::string edge_property_key =
|
||||
"auto {}=t.edge_property_key(\"{}\",args[{}]->flags);";
|
||||
|
||||
// create edge e.g CREATE (n1)-[r:COST {cost: 100}]->(n2)
|
||||
const std::string create_edge = "auto {} = db.graph.edges.insert(t);";
|
||||
const std::string find_type =
|
||||
"auto &{0} = db.graph.edge_type_store.find_or_create(\"{0}\");";
|
||||
const std::string create_edge = "auto {} = t.edge_insert({},{});";
|
||||
const std::string find_type = "auto &{0} = t.type_find_or_create(\"{0}\");";
|
||||
const std::string set_type = "{}.edge_type({});";
|
||||
const std::string node_out = "{}.vlist->update(t)->data.out.add({}.vlist);";
|
||||
const std::string node_in = "{}.vlist->update(t)->data.in.add({}.vlist);";
|
||||
const std::string edge_from = "{}.from({}.vlist);";
|
||||
const std::string edge_to = "{}.to({}.vlist);";
|
||||
|
||||
const std::string args_id = "auto id = args[{}]->as<Int32>();";
|
||||
|
||||
const std::string vertex_accessor_args_id =
|
||||
"auto vertex_accessor = db.graph.vertices.find(t, id.value);";
|
||||
"auto vertex_accessor = t.vertex_find(id.value);";
|
||||
|
||||
const std::string match_vertex_by_id =
|
||||
"auto {0} = db.graph.vertices.find(t, args[{1}]->as<Int64>().value);\n"
|
||||
" if (!{0}) return t.commit(), false;";
|
||||
"auto option_{0} = t.vertex_find(args[{1}]->as<Int64>().value);\n"
|
||||
" if (!option_fill(option_{0})) return t.commit(), false;\n"
|
||||
" auto {0}=option_{0}.take();";
|
||||
const std::string match_edge_by_id =
|
||||
"auto {0} = db.graph.edges.find(t, args[{1}]->as<Int64>().value);\n"
|
||||
" if (!{0}) return t.commit(), false;";
|
||||
"auto option_{0} = t.edge_find(args[{1}]->as<Int64>().value);\n"
|
||||
" if (!option_fill(option_{0})) return t.commit(), false;\n"
|
||||
" auto {0}=option_{0}.take();";
|
||||
|
||||
const std::string write_entity =
|
||||
"stream.write_field(\"{0}\");\n"
|
||||
" stream.write_record();\n"
|
||||
" stream.write_list_header(1);\n"
|
||||
" stream.write({0});\n"
|
||||
" stream.write_success_empty();\n";
|
||||
const std::string write_entity = "stream.write_field(\"{0}\");\n"
|
||||
" stream.write_record();\n"
|
||||
" stream.write_list_header(1);\n"
|
||||
" stream.write({0});\n"
|
||||
" stream.write_success_empty();\n";
|
||||
|
||||
const std::string return_true = "return true;";
|
||||
|
||||
const std::string update_property = "{}.property(\"{}\", args[{}]);";
|
||||
|
||||
const std::string todo = "// TODO: {}";
|
||||
const std::string print_properties =
|
||||
"cout << \"{0}\" << endl;\n"
|
||||
" cout_properties({0}.properties());";
|
||||
const std::string print_property =
|
||||
"cout_property(\"{0}\", {0}.property(\"{1}\"));";
|
||||
|
||||
}
|
||||
|
@ -8,8 +8,6 @@
|
||||
#include "storage/vertex_accessor.hpp"
|
||||
#include "utils/reference_wrapper.hpp"
|
||||
#include "utils/total_ordering.hpp"
|
||||
#include "utils/void.hpp"
|
||||
|
||||
using LabelIndexRecord = VertexIndexRecord<std::nullptr_t>;
|
||||
|
||||
class Label : public TotalOrdering<Label>
|
||||
|
@ -1,5 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include "utils/total_ordering.hpp"
|
||||
#include "utils/underlying_cast.hpp"
|
||||
|
||||
enum class Flags : unsigned
|
||||
{
|
||||
// Type | Mask
|
||||
@ -42,4 +46,64 @@ enum class Flags : unsigned
|
||||
Array = 0x1000,
|
||||
|
||||
type_mask = 0xFFF
|
||||
|
||||
};
|
||||
|
||||
// Mask to turn flags into type. It passes all bits except 0x2 and 0x4 which
|
||||
// correspond
|
||||
// to True and False.
|
||||
const unsigned flags_equal_mask = 0xFF9;
|
||||
|
||||
class Type : public TotalOrdering<Type>
|
||||
{
|
||||
public:
|
||||
Type(Flags f) : value(underlying_cast(f) & flags_equal_mask)
|
||||
{
|
||||
Flags o = Flags(value);
|
||||
assert(o == Flags::Null || o == Flags::Bool || o == Flags::String ||
|
||||
o == Flags::Int32 || o == Flags::Int64 || o == Flags::Float ||
|
||||
o == Flags::Double || o == Flags::Array);
|
||||
}
|
||||
|
||||
const std::string to_str()
|
||||
{
|
||||
switch (Flags(value)) {
|
||||
case Flags::Null:
|
||||
return "null";
|
||||
case Flags::Bool:
|
||||
return "bool";
|
||||
case Flags::String:
|
||||
return "str";
|
||||
case Flags::Int32:
|
||||
return "int32";
|
||||
case Flags::Int64:
|
||||
return "int64";
|
||||
case Flags::Float:
|
||||
return "float";
|
||||
case Flags::Double:
|
||||
return "double";
|
||||
case Flags::Array:
|
||||
return "array";
|
||||
default:
|
||||
assert(false);
|
||||
return "err_unknown_type_" + std::to_string(value);
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(Flags other) const { return *this == Type(other); }
|
||||
|
||||
bool operator!=(Flags other) const { return *this != Type(other); }
|
||||
|
||||
friend bool operator<(const Type &lhs, const Type &rhs)
|
||||
{
|
||||
return lhs.value < rhs.value;
|
||||
}
|
||||
|
||||
friend bool operator==(const Type &lhs, const Type &rhs)
|
||||
{
|
||||
return lhs.value == rhs.value;
|
||||
}
|
||||
|
||||
private:
|
||||
const unsigned value;
|
||||
};
|
||||
|
@ -24,6 +24,8 @@ public:
|
||||
|
||||
size_t size() const { return props.size(); }
|
||||
|
||||
const Property &at(PropertyFamily &key) const;
|
||||
|
||||
const Property &at(prop_key_t &key) const;
|
||||
|
||||
template <class T>
|
||||
@ -36,6 +38,8 @@ public:
|
||||
|
||||
void clear(prop_key_t &key);
|
||||
|
||||
void clear(PropertyFamily &key);
|
||||
|
||||
template <class Handler>
|
||||
void accept(Handler &handler) const
|
||||
{
|
||||
|
@ -7,8 +7,6 @@
|
||||
#include "utils/total_ordering.hpp"
|
||||
#include "utils/underlying_cast.hpp"
|
||||
|
||||
typedef Flags Type;
|
||||
|
||||
// Family of properties with the same name but different types.
|
||||
// Ordered on name.
|
||||
class PropertyFamily : public TotalOrdering<PropertyFamily>
|
||||
@ -28,7 +26,10 @@ public:
|
||||
|
||||
public:
|
||||
// Ordered on POINTERS to PropertyFamily
|
||||
class PropertyFamilyKey : public TotalOrdering<PropertyFamilyKey>
|
||||
class PropertyFamilyKey
|
||||
: public TotalOrdering<PropertyFamilyKey>,
|
||||
public TotalOrdering<PropertyFamilyKey, PropertyFamily>,
|
||||
public TotalOrdering<PropertyFamily, PropertyFamilyKey>
|
||||
{
|
||||
friend class PropertyType;
|
||||
friend class PropertyTypeKey;
|
||||
@ -48,6 +49,30 @@ public:
|
||||
return &(lhs.type->family) < &(rhs.type->family);
|
||||
}
|
||||
|
||||
friend bool operator==(const PropertyFamilyKey &lhs,
|
||||
const PropertyFamily &rhs)
|
||||
{
|
||||
return &(lhs.type->family) == &(rhs);
|
||||
}
|
||||
|
||||
friend bool operator<(const PropertyFamilyKey &lhs,
|
||||
const PropertyFamily &rhs)
|
||||
{
|
||||
return &(lhs.type->family) < &(rhs);
|
||||
}
|
||||
|
||||
friend bool operator==(const PropertyFamily &lhs,
|
||||
const PropertyFamilyKey &rhs)
|
||||
{
|
||||
return &(lhs) == &(rhs.type->family);
|
||||
}
|
||||
|
||||
friend bool operator<(const PropertyFamily &lhs,
|
||||
const PropertyFamilyKey &rhs)
|
||||
{
|
||||
return &(lhs) < &(rhs.type->family);
|
||||
}
|
||||
|
||||
Type prop_type() const { return type->type; }
|
||||
|
||||
std::string const &family_name() const
|
||||
@ -62,10 +87,7 @@ public:
|
||||
// Ordered on POINTERS to PropertyType.
|
||||
// When compared with PropertyFamilyKey behaves as PropertyFamilyKey.
|
||||
template <class T>
|
||||
class PropertyTypeKey
|
||||
: public TotalOrdering<PropertyTypeKey<T>>,
|
||||
public TotalOrdering<PropertyFamilyKey, PropertyTypeKey<T>>,
|
||||
public TotalOrdering<PropertyTypeKey<T>, PropertyFamilyKey>
|
||||
class PropertyTypeKey : public TotalOrdering<PropertyTypeKey<T>>
|
||||
{
|
||||
friend class PropertyType;
|
||||
|
||||
@ -87,30 +109,6 @@ public:
|
||||
return &(lhs.type) < &(rhs.type);
|
||||
}
|
||||
|
||||
friend bool operator==(const PropertyFamilyKey &lhs,
|
||||
const PropertyTypeKey &rhs)
|
||||
{
|
||||
return &(lhs.type->family) == &(rhs.type.family);
|
||||
}
|
||||
|
||||
friend bool operator<(const PropertyFamilyKey &lhs,
|
||||
const PropertyTypeKey &rhs)
|
||||
{
|
||||
return &(lhs.type->family) < &(rhs.type.family);
|
||||
}
|
||||
|
||||
friend bool operator==(const PropertyTypeKey &lhs,
|
||||
const PropertyFamilyKey &rhs)
|
||||
{
|
||||
return &(lhs.type.family) == &(rhs.type->family);
|
||||
}
|
||||
|
||||
friend bool operator<(const PropertyTypeKey &lhs,
|
||||
const PropertyFamilyKey &rhs)
|
||||
{
|
||||
return &(lhs.type.family) < &(rhs.type->family);
|
||||
}
|
||||
|
||||
private:
|
||||
const PropertyType &type;
|
||||
};
|
||||
@ -124,7 +122,7 @@ public:
|
||||
template <class T>
|
||||
bool is() const
|
||||
{
|
||||
return underlying_cast(type) & underlying_cast(T::type);
|
||||
return type == T::type;
|
||||
}
|
||||
|
||||
bool is(Type &t) const;
|
||||
@ -167,6 +165,9 @@ public:
|
||||
// Returns type if it exists otherwise creates it.
|
||||
PropertyType &get(Type type);
|
||||
|
||||
// Return pointer for NULL type. Extremly fast.
|
||||
PropertyType &getNull() { return *null_type; }
|
||||
|
||||
friend bool operator<(const PropertyFamily &lhs, const PropertyFamily &rhs);
|
||||
|
||||
friend bool operator==(const PropertyFamily &lhs,
|
||||
@ -174,7 +175,8 @@ public:
|
||||
|
||||
private:
|
||||
const std::string name_v;
|
||||
|
||||
// This is exclusivly for getNull method.
|
||||
PropertyType *null_type{nullptr};
|
||||
// TODO: Because types wont be removed this could be done with more efficent
|
||||
// data structure.
|
||||
ConcurrentMap<Type, std::unique_ptr<PropertyType>> types;
|
||||
|
@ -39,11 +39,7 @@ public:
|
||||
return record != nullptr;
|
||||
}
|
||||
|
||||
const Id &id() const
|
||||
{
|
||||
assert(!empty());
|
||||
return vlist->id;
|
||||
}
|
||||
const Id &id() const { return vlist->id; }
|
||||
|
||||
Derived update() const
|
||||
{
|
||||
@ -59,6 +55,11 @@ public:
|
||||
return vlist->remove(record, db.trans);
|
||||
}
|
||||
|
||||
const Property &at(PropertyFamily &key) const
|
||||
{
|
||||
return properties().at(key);
|
||||
}
|
||||
|
||||
const Property &at(prop_key_t &key) const { return properties().at(key); }
|
||||
|
||||
template <class V>
|
||||
@ -77,6 +78,8 @@ public:
|
||||
|
||||
void clear(prop_key_t &key) { properties().clear(key); }
|
||||
|
||||
void clear(PropertyFamily &key) { properties().clear(key); }
|
||||
|
||||
template <class Handler>
|
||||
void accept(Handler &handler) const
|
||||
{
|
||||
|
@ -189,7 +189,7 @@ auto a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
|
||||
{
|
||||
DbAccessor t(db);
|
||||
type_key_t<Double> tkey = t.vertex_property_family_get("score")
|
||||
.get(Type::Double)
|
||||
.get(Flags::Double)
|
||||
.type_key<Double>();
|
||||
|
||||
auto best_found = new std::map<Id, Score>[max_depth];
|
||||
@ -366,16 +366,16 @@ int load_csv(Db &db, char *file_path, char *edge_file_path)
|
||||
|
||||
DbAccessor t(db);
|
||||
auto key_id =
|
||||
t.vertex_property_family_get("id").get(Type::Int32).family_key();
|
||||
t.vertex_property_family_get("id").get(Flags::Int32).family_key();
|
||||
auto key_garment_id = t.vertex_property_family_get("garment_id")
|
||||
.get(Type::Int32)
|
||||
.get(Flags::Int32)
|
||||
.family_key();
|
||||
auto key_garment_category_id =
|
||||
t.vertex_property_family_get("garment_category_id")
|
||||
.get(Type::Int32)
|
||||
.get(Flags::Int32)
|
||||
.family_key();
|
||||
auto key_score =
|
||||
t.vertex_property_family_get("score").get(Type::Double).family_key();
|
||||
t.vertex_property_family_get("score").get(Flags::Double).family_key();
|
||||
|
||||
int max_score = 1000000;
|
||||
|
||||
@ -457,7 +457,7 @@ int load_csv(Db &db, char *file_path, char *edge_file_path)
|
||||
void load_graph_dummy(Db &db)
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
|
||||
// TODO: update code
|
||||
// auto v = [&](auto id, auto score) {
|
||||
// auto vertex_accessor = t.vertex_insert();
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "database/db_accessor.hpp"
|
||||
#include "database/db.hpp"
|
||||
#include "database/db_accessor.hpp"
|
||||
#include "utils/iterator/iterator.hpp"
|
||||
|
||||
DbAccessor::DbAccessor(Db &db)
|
||||
@ -70,6 +70,7 @@ bool DbAccessor::type_contains(const std::string &name)
|
||||
std::forward<const std::string &>(name));
|
||||
}
|
||||
|
||||
// PROPERTY METHODS
|
||||
PropertyFamily &DbAccessor::vertex_property_family_get(const std::string &name)
|
||||
{
|
||||
return db_transaction.db.graph.vertices.property_family_find_or_create(
|
||||
@ -81,6 +82,19 @@ PropertyFamily &DbAccessor::edge_property_family_get(const std::string &name)
|
||||
return db_transaction.db.graph.edges.property_family_find_or_create(name);
|
||||
}
|
||||
|
||||
// PROPERTY HELPER METHODS
|
||||
PropertyFamily::PropertyType::PropertyFamilyKey
|
||||
DbAccessor::vertex_property_key(const std::string &name, Type type)
|
||||
{
|
||||
return vertex_property_family_get(name).get(type).family_key();
|
||||
}
|
||||
|
||||
PropertyFamily::PropertyType::PropertyFamilyKey
|
||||
DbAccessor::edge_property_key(const std::string &name, Type type)
|
||||
{
|
||||
return edge_property_family_get(name).get(type).family_key();
|
||||
}
|
||||
|
||||
// TRANSACTION METHODS
|
||||
void DbAccessor::commit() { db_transaction.trans.commit(); }
|
||||
void DbAccessor::abort() { db_transaction.trans.abort(); }
|
||||
|
@ -24,12 +24,12 @@ public:
|
||||
};
|
||||
|
||||
|
||||
extern "C" ICodeCPU* produce()
|
||||
extern "C" ICodeCPU* produce()
|
||||
{
|
||||
return new {{class_name}}();
|
||||
}
|
||||
|
||||
extern "C" void destruct(ICodeCPU* p)
|
||||
extern "C" void destruct(ICodeCPU* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
|
@ -4,11 +4,26 @@
|
||||
#include "storage/model/properties/property_family.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
const Property &Properties::at(PropertyFamily &fam) const
|
||||
{
|
||||
// It doesn't matter whit which type
|
||||
// find is called, thats why getNull
|
||||
// method is here to give fast access
|
||||
// to such key.
|
||||
auto key = fam.getNull().family_key();
|
||||
auto it = props.find(key);
|
||||
|
||||
if (it == props.end()) return Property::Null;
|
||||
|
||||
return *it->second.get();
|
||||
}
|
||||
|
||||
const Property &Properties::at(prop_key_t &key) const
|
||||
{
|
||||
auto it = props.find(key);
|
||||
|
||||
if (it == props.end()) return Property::Null;
|
||||
if (it == props.end() || it->first.prop_type() != key.prop_type())
|
||||
return Property::Null;
|
||||
|
||||
return *it->second.get();
|
||||
}
|
||||
@ -59,14 +74,15 @@ void Properties::set(prop_key_t &key, Property::sptr value)
|
||||
|
||||
void Properties::clear(prop_key_t &key) { props.erase(key); }
|
||||
|
||||
// template <class Handler>
|
||||
// void Properties::accept(Handler& handler) const
|
||||
// {
|
||||
// for(auto& kv : props)
|
||||
// handler.handle(kv.first, *kv.second);
|
||||
//
|
||||
// handler.finish();
|
||||
// }
|
||||
void Properties::clear(PropertyFamily &fam)
|
||||
{
|
||||
// It doesn't matter whit which type
|
||||
// find is called, thats why getNull
|
||||
// method is here to give fast access
|
||||
// to such key.
|
||||
auto key = fam.getNull().family_key();
|
||||
props.erase(key);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void Properties::set<Null>(type_key_t<Null> &key)
|
||||
|
@ -3,9 +3,11 @@
|
||||
PropertyFamily::PropertyFamily(std::string const &name_v)
|
||||
: name_v(std::forward<const std::string>(name_v))
|
||||
{
|
||||
null_type = &get(Flags::Null);
|
||||
}
|
||||
PropertyFamily::PropertyFamily(std::string &&name_v) : name_v(std::move(name_v))
|
||||
{
|
||||
null_type = &get(Flags::Null);
|
||||
}
|
||||
|
||||
std::string const &PropertyFamily::name() const { return name_v; }
|
||||
|
Loading…
Reference in New Issue
Block a user