From ec22026feda89c0a6d480e77888642515096d275 Mon Sep 17 00:00:00 2001 From: Teon Banek Date: Thu, 5 Sep 2019 10:25:27 +0200 Subject: [PATCH] Add glue::ToBolt(Vertex|Edge|Path|Value) for V2 storage Reviewers: mferencevic, ipaljak Reviewed By: mferencevic Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D2355 --- src/glue/communication.cpp | 116 +++++++++++++++++++++++++++++++++++-- src/glue/communication.hpp | 52 ++++++++++++++++- 2 files changed, 160 insertions(+), 8 deletions(-) diff --git a/src/glue/communication.cpp b/src/glue/communication.cpp index 8f23bb410..f3cf3b95d 100644 --- a/src/glue/communication.cpp +++ b/src/glue/communication.cpp @@ -4,7 +4,13 @@ #include #include +#ifdef MG_SINGLE_NODE_V2 +#include "storage/v2/edge_accessor.hpp" +#include "storage/v2/storage.hpp" +#include "storage/v2/vertex_accessor.hpp" +#else #include "database/graph_db_accessor.hpp" +#endif using communication::bolt::Value; @@ -43,7 +49,13 @@ query::TypedValue ToTypedValue(const Value &value) { } } +#ifdef MG_SINGLE_NODE_V2 +storage::Result ToBoltValue(const query::TypedValue &value, + const storage::Storage &db, + storage::View view) { +#else Value ToBoltValue(const query::TypedValue &value, storage::View view) { +#endif switch (value.type()) { case query::TypedValue::Type::Null: return Value(); @@ -59,35 +71,109 @@ Value ToBoltValue(const query::TypedValue &value, storage::View view) { std::vector values; values.reserve(value.ValueList().size()); for (const auto &v : value.ValueList()) { +#ifdef MG_SINGLE_NODE_V2 + auto maybe_value = ToBoltValue(v, db, view); + if (maybe_value.HasError()) return maybe_value.GetError(); + values.emplace_back(std::move(*maybe_value)); +#else values.push_back(ToBoltValue(v, view)); +#endif } return Value(std::move(values)); } case query::TypedValue::Type::Map: { std::map map; for (const auto &kv : value.ValueMap()) { +#ifdef MG_SINGLE_NODE_V2 + auto maybe_value = ToBoltValue(kv.second, db, view); + if (maybe_value.HasError()) return maybe_value.GetError(); + map.emplace(kv.first, std::move(*maybe_value)); +#else map.emplace(kv.first, ToBoltValue(kv.second, view)); +#endif } return Value(std::move(map)); } case query::TypedValue::Type::Vertex: +#ifdef MG_SINGLE_NODE_V2 + { + auto maybe_vertex = ToBoltVertex(value.ValueVertex(), db, view); + if (maybe_vertex.HasError()) return maybe_vertex.GetError(); + return Value(std::move(*maybe_vertex)); + } +#else return Value(ToBoltVertex(value.ValueVertex(), view)); +#endif case query::TypedValue::Type::Edge: +#ifdef MG_SINGLE_NODE_V2 + { + auto maybe_edge = ToBoltEdge(value.ValueEdge(), db, view); + if (maybe_edge.HasError()) return maybe_edge.GetError(); + return Value(std::move(*maybe_edge)); + } +#else return Value(ToBoltEdge(value.ValueEdge(), view)); +#endif case query::TypedValue::Type::Path: +#ifdef MG_SINGLE_NODE_V2 + { + auto maybe_path = ToBoltPath(value.ValuePath(), db, view); + if (maybe_path.HasError()) return maybe_path.GetError(); + return Value(std::move(*maybe_path)); + } +#else return Value(ToBoltPath(value.ValuePath(), view)); +#endif } } -communication::bolt::Vertex ToBoltVertex(const VertexAccessor &vertex, +#ifdef MG_SINGLE_NODE_V2 +storage::Result ToBoltVertex( + const storage::VertexAccessor &vertex, const storage::Storage &db, + storage::View view) { + auto id = communication::bolt::Id::FromUint(vertex.Gid().AsUint()); + auto maybe_labels = vertex.Labels(view); + if (maybe_labels.HasError()) return maybe_labels.GetError(); + std::vector labels; + labels.reserve(maybe_labels->size()); + for (const auto &label : *maybe_labels) { + labels.push_back(db.LabelToName(label)); + } + auto maybe_properties = vertex.Properties(view); + if (maybe_properties.HasError()) return maybe_properties.GetError(); + std::map properties; + for (const auto &prop : *maybe_properties) { + properties[db.PropertyToName(prop.first)] = ToBoltValue(prop.second); + } + return communication::bolt::Vertex{id, labels, properties}; +} + +storage::Result ToBoltEdge( + const storage::EdgeAccessor &edge, const storage::Storage &db, + storage::View view) { + auto id = communication::bolt::Id::FromUint(edge.Gid().AsUint()); + auto from = + communication::bolt::Id::FromUint(edge.FromVertex().Gid().AsUint()); + auto to = communication::bolt::Id::FromUint(edge.ToVertex().Gid().AsUint()); + auto type = db.EdgeTypeToName(edge.EdgeType()); + auto maybe_properties = edge.Properties(view); + if (maybe_properties.HasError()) return maybe_properties.GetError(); + std::map properties; + for (const auto &prop : *maybe_properties) { + properties[db.PropertyToName(prop.first)] = ToBoltValue(prop.second); + } + return communication::bolt::Edge{id, from, to, type, properties}; +} +#else +communication::bolt::Vertex ToBoltVertex(const ::VertexAccessor &vertex, storage::View view) { // NOTE: This hack will be removed when we switch to storage v2 API. switch (view) { case storage::View::OLD: - const_cast(vertex).SwitchOld(); + const_cast<::VertexAccessor &>(vertex).SwitchOld(); break; case storage::View::NEW: - const_cast(vertex).SwitchNew(); + const_cast<::VertexAccessor &>(vertex).SwitchNew(); break; } auto id = communication::bolt::Id::FromUint(vertex.gid().AsUint()); @@ -105,15 +191,15 @@ communication::bolt::Vertex ToBoltVertex(const VertexAccessor &vertex, std::move(properties)}; } -communication::bolt::Edge ToBoltEdge(const EdgeAccessor &edge, +communication::bolt::Edge ToBoltEdge(const ::EdgeAccessor &edge, storage::View view) { // NOTE: This hack will be removed when we switch to storage v2 API. switch (view) { case storage::View::OLD: - const_cast(edge).SwitchOld(); + const_cast<::EdgeAccessor &>(edge).SwitchOld(); break; case storage::View::NEW: - const_cast(edge).SwitchNew(); + const_cast<::EdgeAccessor &>(edge).SwitchNew(); break; } auto id = communication::bolt::Id::FromUint(edge.gid().AsUint()); @@ -127,18 +213,36 @@ communication::bolt::Edge ToBoltEdge(const EdgeAccessor &edge, } return communication::bolt::Edge{id, from, to, type, std::move(properties)}; } +#endif +#ifdef MG_SINGLE_NODE_V2 +storage::Result ToBoltPath( + const query::Path &path, const storage::Storage &db, storage::View view) { +#else communication::bolt::Path ToBoltPath(const query::Path &path, storage::View view) { +#endif std::vector vertices; vertices.reserve(path.vertices().size()); for (const auto &v : path.vertices()) { +#ifdef MG_SINGLE_NODE_V2 + auto maybe_vertex = ToBoltVertex(v, db, view); + if (maybe_vertex.HasError()) return maybe_vertex.GetError(); + vertices.emplace_back(std::move(*maybe_vertex)); +#else vertices.push_back(ToBoltVertex(v, view)); +#endif } std::vector edges; edges.reserve(path.edges().size()); for (const auto &e : path.edges()) { +#ifdef MG_SINGLE_NODE_V2 + auto maybe_edge = ToBoltEdge(e, db, view); + if (maybe_edge.HasError()) return maybe_edge.GetError(); + edges.emplace_back(std::move(*maybe_edge)); +#else edges.push_back(ToBoltEdge(e, view)); +#endif } return communication::bolt::Path(vertices, edges); } diff --git a/src/glue/communication.hpp b/src/glue/communication.hpp index 5b3dbedb0..46386c9f0 100644 --- a/src/glue/communication.hpp +++ b/src/glue/communication.hpp @@ -6,12 +6,59 @@ #include "storage/common/types/property_value.hpp" #include "storage/v2/view.hpp" +#ifdef MG_SINGLE_NODE_V2 +#include "storage/v2/result.hpp" + +namespace storage { +class EdgeAccessor; +class Storage; +class VertexAccessor; +} // namespace storage +#endif + namespace glue { -communication::bolt::Vertex ToBoltVertex(const VertexAccessor &vertex, +#ifdef MG_SINGLE_NODE_V2 +/// @param storage::VertexAccessor for converting to +/// communication::bolt::Vertex. +/// @param storage::Storage for getting label and property names. +/// @param storage::View for deciding which vertex attributes are visible. +/// +/// @throw std::bad_alloc +storage::Result ToBoltVertex( + const storage::VertexAccessor &vertex, const storage::Storage &db, + storage::View view); + +/// @param storage::EdgeAccessor for converting to communication::bolt::Edge. +/// @param storage::Storage for getting edge type and property names. +/// @param storage::View for deciding which edge attributes are visible. +/// +/// @throw std::bad_alloc +storage::Result ToBoltEdge( + const storage::EdgeAccessor &edge, const storage::Storage &db, + storage::View view); + +/// @param query::Path for converting to communication::bolt::Path. +/// @param storage::Storage for ToBoltVertex and ToBoltEdge. +/// @param storage::View for ToBoltVertex and ToBoltEdge. +/// +/// @throw std::bad_alloc +storage::Result ToBoltPath( + const query::Path &path, const storage::Storage &db, storage::View view); + +/// @param query::TypedValue for converting to communication::bolt::Value. +/// @param storage::Storage for ToBoltVertex and ToBoltEdge. +/// @param storage::View for ToBoltVertex and ToBoltEdge. +/// +/// @throw std::bad_alloc +storage::Result ToBoltValue( + const query::TypedValue &value, const storage::Storage &db, + storage::View view); +#else +communication::bolt::Vertex ToBoltVertex(const ::VertexAccessor &vertex, storage::View view); -communication::bolt::Edge ToBoltEdge(const EdgeAccessor &edge, +communication::bolt::Edge ToBoltEdge(const ::EdgeAccessor &edge, storage::View view); communication::bolt::Path ToBoltPath(const query::Path &path, @@ -19,6 +66,7 @@ communication::bolt::Path ToBoltPath(const query::Path &path, communication::bolt::Value ToBoltValue(const query::TypedValue &value, storage::View view); +#endif query::TypedValue ToTypedValue(const communication::bolt::Value &value);