2018-08-22 16:59:46 +08:00
|
|
|
#include "glue/communication.hpp"
|
2018-07-02 21:34:33 +08:00
|
|
|
|
|
|
|
#include <map>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
2019-09-05 16:25:27 +08:00
|
|
|
#ifdef MG_SINGLE_NODE_V2
|
|
|
|
#include "storage/v2/edge_accessor.hpp"
|
|
|
|
#include "storage/v2/storage.hpp"
|
|
|
|
#include "storage/v2/vertex_accessor.hpp"
|
|
|
|
#else
|
2018-07-02 21:34:33 +08:00
|
|
|
#include "database/graph_db_accessor.hpp"
|
2019-09-05 16:25:27 +08:00
|
|
|
#endif
|
2018-07-02 21:34:33 +08:00
|
|
|
|
2018-07-24 21:11:18 +08:00
|
|
|
using communication::bolt::Value;
|
2018-07-02 21:34:33 +08:00
|
|
|
|
Extract communication to static library
Summary:
Session specifics have been move out of the Bolt `executing` state, and
are accessed via pure virtual Session type. Our server is templated on
the session and we are setting the concrete type, so there should be no
virtual call overhead. Abstract Session is used to indicate the
interface, this could have also been templated, but the explicit
interface definition makes it clearer.
Specific session implementation for running Memgraph is now implemented
in memgraph_bolt, which instantiates the concrete session type. This may
not be 100% appropriate place, but Memgraph specific session isn't
needed anywhere else.
Bolt/communication tests now use a dummy session and depend only on
communication, which significantly improves test run times.
All these changes make the communication a library which doesn't depend
on storage nor the database. Only shared connection points, which aren't
part of the base communication library are:
* glue/conversion -- which converts between storage and bolt types, and
* communication/result_stream_faker -- templated, but used in tests and query/repl
Depends on D1453
Reviewers: mferencevic, buda, mtomic, msantl
Reviewed By: mferencevic, mtomic
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1456
2018-07-10 22:18:19 +08:00
|
|
|
namespace glue {
|
2018-07-02 21:34:33 +08:00
|
|
|
|
2018-07-24 21:11:18 +08:00
|
|
|
query::TypedValue ToTypedValue(const Value &value) {
|
2018-07-02 21:34:33 +08:00
|
|
|
switch (value.type()) {
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Null:
|
2019-06-04 22:11:31 +08:00
|
|
|
return query::TypedValue();
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Bool:
|
2018-07-02 21:34:33 +08:00
|
|
|
return query::TypedValue(value.ValueBool());
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Int:
|
2018-07-02 21:34:33 +08:00
|
|
|
return query::TypedValue(value.ValueInt());
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Double:
|
2018-07-02 21:34:33 +08:00
|
|
|
return query::TypedValue(value.ValueDouble());
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::String:
|
2018-07-02 21:34:33 +08:00
|
|
|
return query::TypedValue(value.ValueString());
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::List: {
|
2018-07-02 21:34:33 +08:00
|
|
|
std::vector<query::TypedValue> list;
|
|
|
|
list.reserve(value.ValueList().size());
|
|
|
|
for (const auto &v : value.ValueList()) list.push_back(ToTypedValue(v));
|
2019-09-02 21:09:25 +08:00
|
|
|
return query::TypedValue(std::move(list));
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Map: {
|
2018-07-02 21:34:33 +08:00
|
|
|
std::map<std::string, query::TypedValue> map;
|
|
|
|
for (const auto &kv : value.ValueMap())
|
|
|
|
map.emplace(kv.first, ToTypedValue(kv.second));
|
2019-09-02 21:09:25 +08:00
|
|
|
return query::TypedValue(std::move(map));
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Vertex:
|
|
|
|
case Value::Type::Edge:
|
|
|
|
case Value::Type::UnboundedEdge:
|
|
|
|
case Value::Type::Path:
|
|
|
|
throw communication::bolt::ValueException(
|
|
|
|
"Unsupported conversion from Value to TypedValue");
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-11 22:10:53 +08:00
|
|
|
#ifdef MG_SINGLE_NODE_V2
|
|
|
|
storage::Result<communication::bolt::Vertex> ToBoltVertex(
|
|
|
|
const query::VertexAccessor &vertex, const storage::Storage &db,
|
|
|
|
storage::View view) {
|
|
|
|
return ToBoltVertex(vertex.impl_, db, view);
|
|
|
|
}
|
|
|
|
|
|
|
|
storage::Result<communication::bolt::Edge> ToBoltEdge(
|
|
|
|
const query::EdgeAccessor &edge, const storage::Storage &db,
|
|
|
|
storage::View view) {
|
|
|
|
return ToBoltEdge(edge.impl_, db, view);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
communication::bolt::Vertex ToBoltVertex(const query::VertexAccessor &vertex,
|
|
|
|
storage::View view) {
|
|
|
|
return ToBoltVertex(vertex.impl_, view);
|
|
|
|
}
|
|
|
|
|
|
|
|
communication::bolt::Edge ToBoltEdge(const query::EdgeAccessor &edge,
|
|
|
|
storage::View view) {
|
|
|
|
return ToBoltEdge(edge.impl_, view);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-09-05 16:25:27 +08:00
|
|
|
#ifdef MG_SINGLE_NODE_V2
|
|
|
|
storage::Result<Value> ToBoltValue(const query::TypedValue &value,
|
|
|
|
const storage::Storage &db,
|
|
|
|
storage::View view) {
|
|
|
|
#else
|
2019-09-04 20:45:49 +08:00
|
|
|
Value ToBoltValue(const query::TypedValue &value, storage::View view) {
|
2019-09-05 16:25:27 +08:00
|
|
|
#endif
|
2018-07-02 21:34:33 +08:00
|
|
|
switch (value.type()) {
|
|
|
|
case query::TypedValue::Type::Null:
|
2018-07-24 21:11:18 +08:00
|
|
|
return Value();
|
2018-07-02 21:34:33 +08:00
|
|
|
case query::TypedValue::Type::Bool:
|
2018-07-24 21:11:18 +08:00
|
|
|
return Value(value.ValueBool());
|
2018-07-02 21:34:33 +08:00
|
|
|
case query::TypedValue::Type::Int:
|
2018-07-24 21:11:18 +08:00
|
|
|
return Value(value.ValueInt());
|
2018-07-02 21:34:33 +08:00
|
|
|
case query::TypedValue::Type::Double:
|
2018-07-24 21:11:18 +08:00
|
|
|
return Value(value.ValueDouble());
|
2018-07-02 21:34:33 +08:00
|
|
|
case query::TypedValue::Type::String:
|
2019-05-30 18:30:36 +08:00
|
|
|
return Value(std::string(value.ValueString()));
|
2018-07-02 21:34:33 +08:00
|
|
|
case query::TypedValue::Type::List: {
|
2018-07-24 21:11:18 +08:00
|
|
|
std::vector<Value> values;
|
2018-07-02 21:34:33 +08:00
|
|
|
values.reserve(value.ValueList().size());
|
|
|
|
for (const auto &v : value.ValueList()) {
|
2019-09-05 16:25:27 +08:00
|
|
|
#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
|
2019-09-04 20:45:49 +08:00
|
|
|
values.push_back(ToBoltValue(v, view));
|
2019-09-05 16:25:27 +08:00
|
|
|
#endif
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
2019-09-02 21:09:25 +08:00
|
|
|
return Value(std::move(values));
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
|
|
|
case query::TypedValue::Type::Map: {
|
2018-07-24 21:11:18 +08:00
|
|
|
std::map<std::string, Value> map;
|
2018-07-02 21:34:33 +08:00
|
|
|
for (const auto &kv : value.ValueMap()) {
|
2019-09-05 16:25:27 +08:00
|
|
|
#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
|
2019-09-04 20:45:49 +08:00
|
|
|
map.emplace(kv.first, ToBoltValue(kv.second, view));
|
2019-09-05 16:25:27 +08:00
|
|
|
#endif
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
2019-09-02 21:09:25 +08:00
|
|
|
return Value(std::move(map));
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
|
|
|
case query::TypedValue::Type::Vertex:
|
2019-09-05 16:25:27 +08:00
|
|
|
#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
|
2019-09-04 20:45:49 +08:00
|
|
|
return Value(ToBoltVertex(value.ValueVertex(), view));
|
2019-09-05 16:25:27 +08:00
|
|
|
#endif
|
2018-07-02 21:34:33 +08:00
|
|
|
case query::TypedValue::Type::Edge:
|
2019-09-05 16:25:27 +08:00
|
|
|
#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
|
2019-09-04 20:45:49 +08:00
|
|
|
return Value(ToBoltEdge(value.ValueEdge(), view));
|
2019-09-05 16:25:27 +08:00
|
|
|
#endif
|
2018-07-02 21:34:33 +08:00
|
|
|
case query::TypedValue::Type::Path:
|
2019-09-05 16:25:27 +08:00
|
|
|
#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
|
2019-09-04 20:45:49 +08:00
|
|
|
return Value(ToBoltPath(value.ValuePath(), view));
|
2019-09-05 16:25:27 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef MG_SINGLE_NODE_V2
|
|
|
|
storage::Result<communication::bolt::Vertex> 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<std::string> 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<std::string, Value> properties;
|
|
|
|
for (const auto &prop : *maybe_properties) {
|
|
|
|
properties[db.PropertyToName(prop.first)] = ToBoltValue(prop.second);
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
2019-09-05 16:25:27 +08:00
|
|
|
return communication::bolt::Vertex{id, labels, properties};
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
|
|
|
|
2019-09-05 16:25:27 +08:00
|
|
|
storage::Result<communication::bolt::Edge> 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<std::string, Value> 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,
|
2019-09-04 20:45:49 +08:00
|
|
|
storage::View view) {
|
|
|
|
// NOTE: This hack will be removed when we switch to storage v2 API.
|
|
|
|
switch (view) {
|
|
|
|
case storage::View::OLD:
|
2019-09-05 16:25:27 +08:00
|
|
|
const_cast<::VertexAccessor &>(vertex).SwitchOld();
|
2019-09-04 20:45:49 +08:00
|
|
|
break;
|
|
|
|
case storage::View::NEW:
|
2019-09-05 16:25:27 +08:00
|
|
|
const_cast<::VertexAccessor &>(vertex).SwitchNew();
|
2019-09-04 20:45:49 +08:00
|
|
|
break;
|
|
|
|
}
|
2019-09-03 20:28:28 +08:00
|
|
|
auto id = communication::bolt::Id::FromUint(vertex.gid().AsUint());
|
2018-07-02 21:34:33 +08:00
|
|
|
std::vector<std::string> labels;
|
|
|
|
labels.reserve(vertex.labels().size());
|
|
|
|
for (const auto &label : vertex.labels()) {
|
|
|
|
labels.push_back(vertex.db_accessor().LabelName(label));
|
|
|
|
}
|
2018-07-24 21:11:18 +08:00
|
|
|
std::map<std::string, Value> properties;
|
2018-07-02 21:34:33 +08:00
|
|
|
for (const auto &prop : vertex.Properties()) {
|
|
|
|
properties[vertex.db_accessor().PropertyName(prop.first)] =
|
2018-07-24 21:11:18 +08:00
|
|
|
ToBoltValue(prop.second);
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
2019-09-02 21:09:25 +08:00
|
|
|
return communication::bolt::Vertex{id, std::move(labels),
|
|
|
|
std::move(properties)};
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
|
|
|
|
2019-09-05 16:25:27 +08:00
|
|
|
communication::bolt::Edge ToBoltEdge(const ::EdgeAccessor &edge,
|
2019-09-04 20:45:49 +08:00
|
|
|
storage::View view) {
|
|
|
|
// NOTE: This hack will be removed when we switch to storage v2 API.
|
|
|
|
switch (view) {
|
|
|
|
case storage::View::OLD:
|
2019-09-05 16:25:27 +08:00
|
|
|
const_cast<::EdgeAccessor &>(edge).SwitchOld();
|
2019-09-04 20:45:49 +08:00
|
|
|
break;
|
|
|
|
case storage::View::NEW:
|
2019-09-05 16:25:27 +08:00
|
|
|
const_cast<::EdgeAccessor &>(edge).SwitchNew();
|
2019-09-04 20:45:49 +08:00
|
|
|
break;
|
|
|
|
}
|
2019-09-03 20:28:28 +08:00
|
|
|
auto id = communication::bolt::Id::FromUint(edge.gid().AsUint());
|
|
|
|
auto from = communication::bolt::Id::FromUint(edge.from().gid().AsUint());
|
|
|
|
auto to = communication::bolt::Id::FromUint(edge.to().gid().AsUint());
|
2018-07-02 21:34:33 +08:00
|
|
|
auto type = edge.db_accessor().EdgeTypeName(edge.EdgeType());
|
2018-07-24 21:11:18 +08:00
|
|
|
std::map<std::string, Value> properties;
|
2018-07-02 21:34:33 +08:00
|
|
|
for (const auto &prop : edge.Properties()) {
|
|
|
|
properties[edge.db_accessor().PropertyName(prop.first)] =
|
2018-07-24 21:11:18 +08:00
|
|
|
ToBoltValue(prop.second);
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
2019-09-02 21:09:25 +08:00
|
|
|
return communication::bolt::Edge{id, from, to, type, std::move(properties)};
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
2019-09-05 16:25:27 +08:00
|
|
|
#endif
|
2018-07-02 21:34:33 +08:00
|
|
|
|
2019-09-05 16:25:27 +08:00
|
|
|
#ifdef MG_SINGLE_NODE_V2
|
|
|
|
storage::Result<communication::bolt::Path> ToBoltPath(
|
|
|
|
const query::Path &path, const storage::Storage &db, storage::View view) {
|
|
|
|
#else
|
2019-09-04 20:45:49 +08:00
|
|
|
communication::bolt::Path ToBoltPath(const query::Path &path,
|
|
|
|
storage::View view) {
|
2019-09-05 16:25:27 +08:00
|
|
|
#endif
|
2018-07-24 21:11:18 +08:00
|
|
|
std::vector<communication::bolt::Vertex> vertices;
|
2018-07-02 21:34:33 +08:00
|
|
|
vertices.reserve(path.vertices().size());
|
|
|
|
for (const auto &v : path.vertices()) {
|
2019-09-05 16:25:27 +08:00
|
|
|
#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
|
2019-09-04 20:45:49 +08:00
|
|
|
vertices.push_back(ToBoltVertex(v, view));
|
2019-09-05 16:25:27 +08:00
|
|
|
#endif
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
2018-07-24 21:11:18 +08:00
|
|
|
std::vector<communication::bolt::Edge> edges;
|
2018-07-02 21:34:33 +08:00
|
|
|
edges.reserve(path.edges().size());
|
|
|
|
for (const auto &e : path.edges()) {
|
2019-09-05 16:25:27 +08:00
|
|
|
#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
|
2019-09-04 20:45:49 +08:00
|
|
|
edges.push_back(ToBoltEdge(e, view));
|
2019-09-05 16:25:27 +08:00
|
|
|
#endif
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
2018-07-24 21:11:18 +08:00
|
|
|
return communication::bolt::Path(vertices, edges);
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
|
|
|
|
2018-07-24 21:11:18 +08:00
|
|
|
PropertyValue ToPropertyValue(const Value &value) {
|
2018-07-02 21:34:33 +08:00
|
|
|
switch (value.type()) {
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Null:
|
2019-08-27 20:24:33 +08:00
|
|
|
return PropertyValue();
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Bool:
|
2018-07-02 21:34:33 +08:00
|
|
|
return PropertyValue(value.ValueBool());
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Int:
|
2018-07-02 21:34:33 +08:00
|
|
|
return PropertyValue(value.ValueInt());
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Double:
|
2018-07-02 21:34:33 +08:00
|
|
|
return PropertyValue(value.ValueDouble());
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::String:
|
2018-07-02 21:34:33 +08:00
|
|
|
return PropertyValue(value.ValueString());
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::List: {
|
2018-07-02 21:34:33 +08:00
|
|
|
std::vector<PropertyValue> vec;
|
|
|
|
vec.reserve(value.ValueList().size());
|
|
|
|
for (const auto &value : value.ValueList())
|
|
|
|
vec.emplace_back(ToPropertyValue(value));
|
|
|
|
return PropertyValue(std::move(vec));
|
|
|
|
}
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Map: {
|
2018-07-02 21:34:33 +08:00
|
|
|
std::map<std::string, PropertyValue> map;
|
|
|
|
for (const auto &kv : value.ValueMap())
|
|
|
|
map.emplace(kv.first, ToPropertyValue(kv.second));
|
|
|
|
return PropertyValue(std::move(map));
|
|
|
|
}
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Vertex:
|
|
|
|
case Value::Type::Edge:
|
|
|
|
case Value::Type::UnboundedEdge:
|
|
|
|
case Value::Type::Path:
|
|
|
|
throw communication::bolt::ValueException(
|
|
|
|
"Unsupported conversion from Value to PropertyValue");
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-24 21:11:18 +08:00
|
|
|
Value ToBoltValue(const PropertyValue &value) {
|
2018-07-02 21:34:33 +08:00
|
|
|
switch (value.type()) {
|
|
|
|
case PropertyValue::Type::Null:
|
2018-07-24 21:11:18 +08:00
|
|
|
return Value();
|
2018-07-02 21:34:33 +08:00
|
|
|
case PropertyValue::Type::Bool:
|
2019-08-22 20:50:57 +08:00
|
|
|
return Value(value.ValueBool());
|
2018-07-02 21:34:33 +08:00
|
|
|
case PropertyValue::Type::Int:
|
2019-08-22 20:50:57 +08:00
|
|
|
return Value(value.ValueInt());
|
2018-07-02 21:34:33 +08:00
|
|
|
break;
|
|
|
|
case PropertyValue::Type::Double:
|
2019-08-22 20:50:57 +08:00
|
|
|
return Value(value.ValueDouble());
|
2018-07-02 21:34:33 +08:00
|
|
|
case PropertyValue::Type::String:
|
2019-08-22 20:50:57 +08:00
|
|
|
return Value(value.ValueString());
|
2018-07-02 21:34:33 +08:00
|
|
|
case PropertyValue::Type::List: {
|
2019-08-22 20:50:57 +08:00
|
|
|
const auto &values = value.ValueList();
|
2018-07-24 21:11:18 +08:00
|
|
|
std::vector<Value> vec;
|
2018-07-02 21:34:33 +08:00
|
|
|
vec.reserve(values.size());
|
|
|
|
for (const auto &v : values) {
|
2018-07-24 21:11:18 +08:00
|
|
|
vec.push_back(ToBoltValue(v));
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
2019-09-02 21:09:25 +08:00
|
|
|
return Value(std::move(vec));
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
|
|
|
case PropertyValue::Type::Map: {
|
2019-08-22 20:50:57 +08:00
|
|
|
const auto &map = value.ValueMap();
|
2018-07-24 21:11:18 +08:00
|
|
|
std::map<std::string, Value> dv_map;
|
2018-07-02 21:34:33 +08:00
|
|
|
for (const auto &kv : map) {
|
2018-07-24 21:11:18 +08:00
|
|
|
dv_map.emplace(kv.first, ToBoltValue(kv.second));
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
2019-09-02 21:09:25 +08:00
|
|
|
return Value(std::move(dv_map));
|
2018-07-02 21:34:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Extract communication to static library
Summary:
Session specifics have been move out of the Bolt `executing` state, and
are accessed via pure virtual Session type. Our server is templated on
the session and we are setting the concrete type, so there should be no
virtual call overhead. Abstract Session is used to indicate the
interface, this could have also been templated, but the explicit
interface definition makes it clearer.
Specific session implementation for running Memgraph is now implemented
in memgraph_bolt, which instantiates the concrete session type. This may
not be 100% appropriate place, but Memgraph specific session isn't
needed anywhere else.
Bolt/communication tests now use a dummy session and depend only on
communication, which significantly improves test run times.
All these changes make the communication a library which doesn't depend
on storage nor the database. Only shared connection points, which aren't
part of the base communication library are:
* glue/conversion -- which converts between storage and bolt types, and
* communication/result_stream_faker -- templated, but used in tests and query/repl
Depends on D1453
Reviewers: mferencevic, buda, mtomic, msantl
Reviewed By: mferencevic, mtomic
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1456
2018-07-10 22:18:19 +08:00
|
|
|
} // namespace glue
|