memgraph/src/communication/bolt/v1/decoder/decoded_value.cpp
Matej Ferencevic c507e74384 First version of bolt cpp client.
Reviewers: buda, mislav.bradac

Reviewed By: mislav.bradac

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D689
2017-08-24 17:44:44 +02:00

299 lines
7.6 KiB
C++

#include "communication/bolt/v1/decoder/decoded_value.hpp"
namespace communication::bolt {
bool DecodedValue::ValueBool() const {
if (type_ != Type::Bool) {
throw DecodedValueException();
}
return bool_v;
}
int64_t DecodedValue::ValueInt() const {
if (type_ != Type::Int) {
throw DecodedValueException();
}
return int_v;
}
double DecodedValue::ValueDouble() const {
if (type_ != Type::Double) {
throw DecodedValueException();
}
return double_v;
}
const std::string &DecodedValue::ValueString() const {
if (type_ != Type::String) {
throw DecodedValueException();
}
return string_v;
}
const std::vector<DecodedValue> &DecodedValue::ValueList() const {
if (type_ != Type::List) {
throw DecodedValueException();
}
return list_v;
}
const std::map<std::string, DecodedValue> &DecodedValue::ValueMap() const {
if (type_ != Type::Map) {
throw DecodedValueException();
}
return map_v;
}
const DecodedVertex &DecodedValue::ValueVertex() const {
if (type_ != Type::Vertex) {
throw DecodedValueException();
}
return vertex_v;
}
const DecodedEdge &DecodedValue::ValueEdge() const {
if (type_ != Type::Edge) {
throw DecodedValueException();
}
return edge_v;
}
bool &DecodedValue::ValueBool() {
if (type_ != Type::Bool) {
throw DecodedValueException();
}
return bool_v;
}
int64_t &DecodedValue::ValueInt() {
if (type_ != Type::Int) {
throw DecodedValueException();
}
return int_v;
}
double &DecodedValue::ValueDouble() {
if (type_ != Type::Double) {
throw DecodedValueException();
}
return double_v;
}
std::string &DecodedValue::ValueString() {
if (type_ != Type::String) {
throw DecodedValueException();
}
return string_v;
}
std::vector<DecodedValue> &DecodedValue::ValueList() {
if (type_ != Type::List) {
throw DecodedValueException();
}
return list_v;
}
std::map<std::string, DecodedValue> &DecodedValue::ValueMap() {
if (type_ != Type::Map) {
throw DecodedValueException();
}
return map_v;
}
DecodedVertex &DecodedValue::ValueVertex() {
if (type_ != Type::Vertex) {
throw DecodedValueException();
}
return vertex_v;
}
DecodedEdge &DecodedValue::ValueEdge() {
if (type_ != Type::Edge) {
throw DecodedValueException();
}
return edge_v;
}
DecodedValue::DecodedValue(const DecodedValue &other) : type_(other.type_) {
switch (other.type_) {
case Type::Null:
return;
case Type::Bool:
this->bool_v = other.bool_v;
return;
case Type::Int:
this->int_v = other.int_v;
return;
case Type::Double:
this->double_v = other.double_v;
return;
case Type::String:
new (&string_v) std::string(other.string_v);
return;
case Type::List:
new (&list_v) std::vector<DecodedValue>(other.list_v);
return;
case Type::Map:
new (&map_v) std::map<std::string, DecodedValue>(other.map_v);
return;
case Type::Vertex:
new (&vertex_v) DecodedVertex(other.vertex_v);
return;
case Type::Edge:
new (&edge_v) DecodedEdge(other.edge_v);
return;
}
permanent_fail("Unsupported DecodedValue::Type");
}
DecodedValue &DecodedValue::operator=(const DecodedValue &other) {
if (this != &other) {
this->~DecodedValue();
// set the type of this
type_ = other.type_;
switch (other.type_) {
case Type::Null:
return *this;
case Type::Bool:
this->bool_v = other.bool_v;
return *this;
case Type::Int:
this->int_v = other.int_v;
return *this;
case Type::Double:
this->double_v = other.double_v;
return *this;
case Type::String:
new (&string_v) std::string(other.string_v);
return *this;
case Type::List:
new (&list_v) std::vector<DecodedValue>(other.list_v);
return *this;
case Type::Map:
new (&map_v) std::map<std::string, DecodedValue>(other.map_v);
return *this;
case Type::Vertex:
new (&vertex_v) DecodedVertex(other.vertex_v);
return *this;
case Type::Edge:
new (&edge_v) DecodedEdge(other.edge_v);
return *this;
}
permanent_fail("Unsupported DecodedValue::Type");
}
return *this;
}
DecodedValue::~DecodedValue() {
switch (type_) {
// destructor for primitive types does nothing
case Type::Null:
case Type::Bool:
case Type::Int:
case Type::Double:
return;
// we need to call destructors for non primitive types since we used
// placement new
case Type::String:
// Clang fails to compile ~std::string. It seems it is a bug in some
// versions of clang. using namespace std statement solves the issue.
using namespace std;
string_v.~string();
return;
case Type::List:
using namespace std;
list_v.~vector<DecodedValue>();
return;
case Type::Map:
using namespace std;
map_v.~map<std::string, DecodedValue>();
return;
case Type::Vertex:
vertex_v.~DecodedVertex();
return;
case Type::Edge:
edge_v.~DecodedEdge();
return;
}
permanent_fail("Unsupported DecodedValue::Type");
}
DecodedValue::operator query::TypedValue() const {
switch (type_) {
case Type::Null:
return query::TypedValue::Null;
case Type::Bool:
return query::TypedValue(bool_v);
case Type::Int:
return query::TypedValue(int_v);
case Type::Double:
return query::TypedValue(double_v);
case Type::String:
return query::TypedValue(string_v);
case Type::List:
return query::TypedValue(
std::vector<query::TypedValue>(list_v.begin(), list_v.end()));
case Type::Map:
return query::TypedValue(
std::map<std::string, query::TypedValue>(map_v.begin(), map_v.end()));
default:
throw DecodedValueException(
"Unsupported conversion from DecodedValue to TypedValue");
}
}
std::ostream &operator<<(std::ostream &os, const DecodedVertex &vertex) {
os << "V(";
PrintIterable(os, vertex.labels, ":",
[&](auto &stream, auto label) { stream << label; });
os << " {";
PrintIterable(os, vertex.properties, ", ",
[&](auto &stream, const auto &pair) {
stream << pair.first << ": " << pair.second;
});
return os << "})";
}
std::ostream &operator<<(std::ostream &os, const DecodedEdge &edge) {
os << "E[" << edge.type;
os << " {";
PrintIterable(os, edge.properties, ", ", [&](auto &stream, const auto &pair) {
stream << pair.first << ": " << pair.second;
});
return os << "}]";
}
std::ostream &operator<<(std::ostream &os, const DecodedValue &value) {
switch (value.type_) {
case DecodedValue::Type::Null:
return os << "Null";
case DecodedValue::Type::Bool:
return os << (value.ValueBool() ? "true" : "false");
case DecodedValue::Type::Int:
return os << value.ValueInt();
case DecodedValue::Type::Double:
return os << value.ValueDouble();
case DecodedValue::Type::String:
return os << value.ValueString();
case DecodedValue::Type::List:
os << "[";
PrintIterable(os, value.ValueList());
return os << "]";
case DecodedValue::Type::Map:
os << "{";
PrintIterable(os, value.ValueMap(), ", ",
[](auto &stream, const auto &pair) {
stream << pair.first << ": " << pair.second;
});
return os << "}";
case DecodedValue::Type::Vertex:
return os << value.ValueVertex();
case DecodedValue::Type::Edge:
return os << value.ValueEdge();
}
permanent_fail("Unsupported DecodedValue::Type");
}
}