Add ToString on C++ API mgp types(#1140)
This commit is contained in:
parent
a6ec81b179
commit
d516e40841
178
include/mgp.hpp
178
include/mgp.hpp
@ -554,6 +554,9 @@ class List {
|
||||
/// @exception std::runtime_error List contains value of unknown type.
|
||||
bool operator!=(const List &other) const;
|
||||
|
||||
/// @brief returns the string representation
|
||||
const std::string ToString() const;
|
||||
|
||||
private:
|
||||
mgp_list *ptr_;
|
||||
};
|
||||
@ -669,6 +672,9 @@ class Map {
|
||||
/// @exception std::runtime_error Map contains value of unknown type.
|
||||
bool operator!=(const Map &other) const;
|
||||
|
||||
/// @brief returns the string representation
|
||||
const std::string ToString() const;
|
||||
|
||||
private:
|
||||
mgp_map *ptr_;
|
||||
};
|
||||
@ -740,6 +746,9 @@ class Node {
|
||||
/// @exception std::runtime_error Node properties contain value(s) of unknown type.
|
||||
bool operator!=(const Node &other) const;
|
||||
|
||||
/// @brief returns the string representation
|
||||
const std::string ToString() const;
|
||||
|
||||
private:
|
||||
mgp_vertex *ptr_;
|
||||
};
|
||||
@ -798,6 +807,9 @@ class Relationship {
|
||||
/// @exception std::runtime_error Relationship properties contain value(s) of unknown type.
|
||||
bool operator!=(const Relationship &other) const;
|
||||
|
||||
/// @brief returns the string representation
|
||||
const std::string ToString() const;
|
||||
|
||||
private:
|
||||
mgp_edge *ptr_;
|
||||
};
|
||||
@ -846,6 +858,9 @@ class Path {
|
||||
/// @exception std::runtime_error Path contains element(s) with unknown value.
|
||||
bool operator!=(const Path &other) const;
|
||||
|
||||
/// @brief returns the string representation
|
||||
const std::string ToString() const;
|
||||
|
||||
private:
|
||||
mgp_path *ptr_;
|
||||
};
|
||||
@ -903,6 +918,9 @@ class Date {
|
||||
|
||||
bool operator<(const Date &other) const;
|
||||
|
||||
/// @brief returns the string representation
|
||||
const std::string ToString() const;
|
||||
|
||||
private:
|
||||
mgp_date *ptr_;
|
||||
};
|
||||
@ -962,6 +980,9 @@ class LocalTime {
|
||||
|
||||
bool operator<(const LocalTime &other) const;
|
||||
|
||||
/// @brief returns the string representation
|
||||
const std::string ToString() const;
|
||||
|
||||
private:
|
||||
mgp_local_time *ptr_;
|
||||
};
|
||||
@ -1027,6 +1048,9 @@ class LocalDateTime {
|
||||
|
||||
bool operator<(const LocalDateTime &other) const;
|
||||
|
||||
/// @brief returns the string representation
|
||||
const std::string ToString() const;
|
||||
|
||||
private:
|
||||
mgp_local_date_time *ptr_;
|
||||
};
|
||||
@ -1078,6 +1102,9 @@ class Duration {
|
||||
|
||||
bool operator<(const Duration &other) const;
|
||||
|
||||
/// @brief returns the string representation
|
||||
const std::string ToString() const;
|
||||
|
||||
private:
|
||||
mgp_duration *ptr_;
|
||||
};
|
||||
@ -1288,6 +1315,9 @@ class Value {
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, const mgp::Value &value);
|
||||
|
||||
/// @brief returns the string representation
|
||||
const std::string ToString() const;
|
||||
|
||||
private:
|
||||
mgp_value *ptr_;
|
||||
};
|
||||
@ -2400,6 +2430,22 @@ inline bool List::operator==(const List &other) const { return util::ListsEqual(
|
||||
|
||||
inline bool List::operator!=(const List &other) const { return !(*this == other); }
|
||||
|
||||
inline const std::string List::ToString() const {
|
||||
const size_t size = Size();
|
||||
if (size == 0) {
|
||||
return "[]";
|
||||
}
|
||||
std::string return_str{"["};
|
||||
size_t i = 0;
|
||||
const mgp::List &list = (*this);
|
||||
while (i < size - 1) {
|
||||
return_str.append(list[i].ToString() + ", ");
|
||||
i++;
|
||||
}
|
||||
return_str.append(list[i].ToString() + "]");
|
||||
return return_str;
|
||||
}
|
||||
|
||||
// MapItem:
|
||||
|
||||
inline bool MapItem::operator==(MapItem &other) const { return key == other.key && value == other.value; }
|
||||
@ -2569,6 +2615,24 @@ inline bool Map::operator==(const Map &other) const { return util::MapsEqual(ptr
|
||||
|
||||
inline bool Map::operator!=(const Map &other) const { return !(*this == other); }
|
||||
|
||||
inline const std::string Map::ToString() const {
|
||||
const size_t map_size = Size();
|
||||
if (map_size == 0) {
|
||||
return "{}";
|
||||
}
|
||||
std::string return_string{"{"};
|
||||
size_t i = 0;
|
||||
for (const auto &[key, value] : *this) {
|
||||
if (i == map_size - 1) {
|
||||
return_string.append(std::string(key) + ": " + value.ToString() + "}");
|
||||
break;
|
||||
}
|
||||
return_string.append(std::string(key) + ": " + value.ToString() + ", ");
|
||||
++i;
|
||||
}
|
||||
return return_string;
|
||||
}
|
||||
|
||||
/* #endregion */
|
||||
|
||||
/* #region Graph elements (Node, Relationship & Path) */
|
||||
@ -2674,6 +2738,35 @@ inline bool Node::operator==(const Node &other) const { return util::NodesEqual(
|
||||
|
||||
inline bool Node::operator!=(const Node &other) const { return !(*this == other); }
|
||||
|
||||
// this functions is used both in relationship and node ToString
|
||||
inline std::string PropertiesToString(const std::map<std::string, Value> &property_map) {
|
||||
std::string properties{""};
|
||||
const auto map_size = property_map.size();
|
||||
size_t i = 0;
|
||||
for (const auto &[key, value] : property_map) {
|
||||
if (i == map_size - 1) {
|
||||
properties.append(std::string(key) + ": " + value.ToString());
|
||||
break;
|
||||
}
|
||||
properties.append(std::string(key) + ": " + value.ToString() + ", ");
|
||||
++i;
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
inline const std::string Node::ToString() const {
|
||||
std::string labels{", "};
|
||||
for (auto label : Labels()) {
|
||||
labels.append(":" + std::string(label));
|
||||
}
|
||||
if (labels == ", ") {
|
||||
labels = ""; // dont use labels if they dont exist
|
||||
}
|
||||
std::map<std::string, Value> properties_map{Properties()};
|
||||
std::string properties{PropertiesToString(properties_map)};
|
||||
return "(id: " + std::to_string(Id().AsInt()) + labels + ", properties: {" + properties + "})";
|
||||
}
|
||||
|
||||
// Relationship:
|
||||
|
||||
inline Relationship::Relationship(mgp_edge *ptr) : ptr_(mgp::MemHandlerCallback(edge_copy, ptr)) {}
|
||||
@ -2748,6 +2841,18 @@ inline bool Relationship::operator==(const Relationship &other) const {
|
||||
|
||||
inline bool Relationship::operator!=(const Relationship &other) const { return !(*this == other); }
|
||||
|
||||
inline const std::string Relationship::ToString() const {
|
||||
const auto from = From();
|
||||
const auto to = To();
|
||||
|
||||
const std::string type{Type()};
|
||||
std::map<std::string, Value> properties_map{Properties()};
|
||||
std::string properties{PropertiesToString(properties_map)};
|
||||
const std::string relationship{"[type: " + type + ", id: " + std::to_string(Id().AsInt()) + ", properties: {" +
|
||||
properties + "}]"};
|
||||
|
||||
return from.ToString() + "-" + relationship + "->" + to.ToString();
|
||||
}
|
||||
// Path:
|
||||
|
||||
inline Path::Path(mgp_path *ptr) : ptr_(mgp::MemHandlerCallback(path_copy, ptr)) {}
|
||||
@ -2810,6 +2915,26 @@ inline bool Path::operator==(const Path &other) const { return util::PathsEqual(
|
||||
|
||||
inline bool Path::operator!=(const Path &other) const { return !(*this == other); }
|
||||
|
||||
inline const std::string Path::ToString() const {
|
||||
const auto length = Length();
|
||||
size_t i = 0;
|
||||
std::string return_string{""};
|
||||
for (i = 0; i < length; i++) {
|
||||
const auto node = GetNodeAt(i);
|
||||
return_string.append(node.ToString() + "-");
|
||||
|
||||
const Relationship rel = GetRelationshipAt(i);
|
||||
std::map<std::string, Value> properties_map{rel.Properties()};
|
||||
std::string properties = PropertiesToString(properties_map);
|
||||
return_string.append("[type: " + std::string(rel.Type()) + ", id: " + std::to_string(rel.Id().AsInt()) +
|
||||
", properties: {" + properties + "}]->");
|
||||
}
|
||||
|
||||
const auto node = GetNodeAt(i);
|
||||
return_string.append(node.ToString());
|
||||
return return_string;
|
||||
}
|
||||
|
||||
/* #endregion */
|
||||
|
||||
/* #region Temporal types (Date, LocalTime, LocalDateTime, Duration) */
|
||||
@ -2907,6 +3032,10 @@ inline bool Date::operator<(const Date &other) const {
|
||||
return is_less;
|
||||
}
|
||||
|
||||
inline const std::string Date::ToString() const {
|
||||
return std::to_string(Year()) + "-" + std::to_string(Month()) + "-" + std::to_string(Day());
|
||||
}
|
||||
|
||||
// LocalTime:
|
||||
|
||||
inline LocalTime::LocalTime(mgp_local_time *ptr) : ptr_(mgp::MemHandlerCallback(local_time_copy, ptr)) {}
|
||||
@ -3006,6 +3135,11 @@ inline bool LocalTime::operator<(const LocalTime &other) const {
|
||||
return is_less;
|
||||
}
|
||||
|
||||
inline const std::string LocalTime::ToString() const {
|
||||
return std::to_string(Hour()) + ":" + std::to_string(Minute()) + ":" + std::to_string(Second()) + "," +
|
||||
std::to_string(Millisecond()) + std::to_string(Microsecond());
|
||||
}
|
||||
|
||||
// LocalDateTime:
|
||||
|
||||
inline LocalDateTime::LocalDateTime(mgp_local_date_time *ptr)
|
||||
@ -3120,6 +3254,12 @@ inline bool LocalDateTime::operator<(const LocalDateTime &other) const {
|
||||
return is_less;
|
||||
}
|
||||
|
||||
inline const std::string LocalDateTime::ToString() const {
|
||||
return std::to_string(Year()) + "-" + std::to_string(Month()) + "-" + std::to_string(Day()) + "T" +
|
||||
std::to_string(Hour()) + ":" + std::to_string(Minute()) + ":" + std::to_string(Second()) + "," +
|
||||
std::to_string(Millisecond()) + std::to_string(Microsecond());
|
||||
}
|
||||
|
||||
// Duration:
|
||||
|
||||
inline Duration::Duration(mgp_duration *ptr) : ptr_(mgp::MemHandlerCallback(duration_copy, ptr)) {}
|
||||
@ -3209,6 +3349,8 @@ inline bool Duration::operator<(const Duration &other) const {
|
||||
return is_less;
|
||||
}
|
||||
|
||||
inline const std::string Duration::ToString() const { return std::to_string(Microseconds()) + "ms"; }
|
||||
|
||||
/* #endregion */
|
||||
|
||||
/* #endregion */
|
||||
@ -3673,6 +3815,42 @@ inline std::ostream &operator<<(std::ostream &os, const mgp::Type &type) {
|
||||
}
|
||||
}
|
||||
|
||||
inline const std::string Value::ToString() const {
|
||||
const mgp::Type &type = Type();
|
||||
switch (type) {
|
||||
case Type::Null:
|
||||
return "";
|
||||
case Type::Bool:
|
||||
return ValueBool() ? "true" : "false";
|
||||
case Type::Int:
|
||||
return std::to_string(ValueInt());
|
||||
case Type::Double:
|
||||
return std::to_string(ValueDouble());
|
||||
case Type::String:
|
||||
return std::string(ValueString());
|
||||
case Type::Node:
|
||||
return ValueNode().ToString();
|
||||
case Type::Relationship:
|
||||
return ValueRelationship().ToString();
|
||||
case Type::Date:
|
||||
return ValueDate().ToString();
|
||||
case Type::LocalTime:
|
||||
return ValueLocalTime().ToString();
|
||||
case Type::LocalDateTime:
|
||||
return ValueLocalDateTime().ToString();
|
||||
case Type::Duration:
|
||||
return ValueDuration().ToString();
|
||||
case Type::List:
|
||||
return ValueList().ToString();
|
||||
case Type::Map:
|
||||
return ValueMap().ToString();
|
||||
case Type::Path:
|
||||
return ValuePath().ToString();
|
||||
default:
|
||||
throw ValueException("Undefined behaviour");
|
||||
}
|
||||
}
|
||||
|
||||
/* #endregion */
|
||||
|
||||
/* #region Record */
|
||||
|
@ -615,3 +615,77 @@ TYPED_TEST(CppApiTestFixture, TestValuePrint) {
|
||||
std::string date_test = oss_date.str();
|
||||
ASSERT_EQ("2020-12-12", date_test);
|
||||
}
|
||||
|
||||
TYPED_TEST(CppApiTestFixture, TestValueToString) {
|
||||
/*graph and node shared by multiple types*/
|
||||
mgp_graph raw_graph = this->CreateGraph(memgraph::storage::View::NEW);
|
||||
auto graph = mgp::Graph(&raw_graph);
|
||||
|
||||
/*null*/
|
||||
ASSERT_EQ(mgp::Value().ToString(), "");
|
||||
/*bool*/
|
||||
ASSERT_EQ(mgp::Value(false).ToString(), "false");
|
||||
/*int*/
|
||||
const int64_t int1 = 60;
|
||||
ASSERT_EQ(mgp::Value(int1).ToString(), "60");
|
||||
/*double*/
|
||||
const double double1 = 2.567891;
|
||||
ASSERT_EQ(mgp::Value(double1).ToString(), "2.567891");
|
||||
/*string*/
|
||||
const std::string str = "string";
|
||||
ASSERT_EQ(mgp::Value(str).ToString(), "string");
|
||||
/*list*/
|
||||
mgp::List list;
|
||||
auto node_list = graph.CreateNode();
|
||||
node_list.AddLabel("Label_list");
|
||||
list.AppendExtend(mgp::Value("inside"));
|
||||
list.AppendExtend(mgp::Value("2"));
|
||||
list.AppendExtend(mgp::Value(node_list));
|
||||
ASSERT_EQ(mgp::Value(list).ToString(), "[inside, 2, (id: 0, :Label_list, properties: {})]");
|
||||
/*map*/
|
||||
mgp::Map map;
|
||||
auto node_map = graph.CreateNode();
|
||||
node_map.AddLabel("Label_map");
|
||||
map.Insert("key", mgp::Value(int1));
|
||||
map.Insert("node", mgp::Value(node_map));
|
||||
ASSERT_EQ(mgp::Value(map).ToString(), "{key: 60, node: (id: 1, :Label_map, properties: {})}");
|
||||
/*date*/
|
||||
mgp::Date date_1{"2020-12-12"};
|
||||
ASSERT_EQ(mgp::Value(date_1).ToString(), "2020-12-12");
|
||||
|
||||
/*local time*/
|
||||
mgp::LocalTime local_time{"09:15:00.360"};
|
||||
ASSERT_EQ(mgp::Value(local_time).ToString(), "9:15:0,3600");
|
||||
|
||||
/*local date time*/
|
||||
mgp::LocalDateTime local_date_time{"2021-10-05T14:15:00"};
|
||||
ASSERT_EQ(mgp::Value(local_date_time).ToString(), "2021-10-5T14:15:0,00");
|
||||
|
||||
/*duration*/
|
||||
mgp::Duration duration{"P14DT17H2M45S"};
|
||||
ASSERT_EQ(mgp::Value(duration).ToString(), "1270965000000ms");
|
||||
|
||||
/*node and relationship*/
|
||||
auto node1 = graph.CreateNode();
|
||||
node1.AddLabel("Label1");
|
||||
node1.AddLabel("Label2");
|
||||
auto node2 = graph.CreateNode();
|
||||
node2.SetProperty("key", mgp::Value("node_property"));
|
||||
node2.SetProperty("key2", mgp::Value("node_property2"));
|
||||
auto rel = graph.CreateRelationship(node1, node2, "Loves");
|
||||
|
||||
rel.SetProperty("key", mgp::Value("property"));
|
||||
ASSERT_EQ(mgp::Value(rel).ToString(),
|
||||
"(id: 2, :Label1:Label2, properties: {})-[type: Loves, id: 0, properties: {key: property}]->(id: 3, "
|
||||
"properties: {key: node_property, key2: node_property2})");
|
||||
/*path*/
|
||||
mgp::Path path = mgp::Path(node1);
|
||||
path.Expand(rel);
|
||||
auto node3 = graph.CreateNode();
|
||||
auto rel2 = graph.CreateRelationship(node2, node3, "Loves2");
|
||||
path.Expand(rel2);
|
||||
ASSERT_EQ(
|
||||
mgp::Value(path).ToString(),
|
||||
"(id: 2, :Label1:Label2, properties: {})-[type: Loves, id: 0, properties: {key: property}]->(id: 3, properties: "
|
||||
"{key: node_property, key2: node_property2})-[type: Loves2, id: 1, properties: {}]->(id: 4, properties: {})");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user