Move typed_value to query top level and namespace it

Summary:
Upgraded old uses of TypedValue.
Also, implemented operator<< for EdgeAccessor and VertexAccessor.

Reviewers: buda, florijan, mislav.bradac, mferencevic

Reviewed By: florijan

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D251
This commit is contained in:
Teon Banek 2017-04-10 12:22:48 +02:00
parent b7ee09785b
commit 804d0b09b9
41 changed files with 225 additions and 193 deletions

View File

@ -361,7 +361,7 @@ set(memgraph_src_files
${src_dir}/query/stripper.cpp
${src_dir}/query/console.cpp
${src_dir}/query/frontend/ast/cypher_main_visitor.cpp
${src_dir}/query/backend/cpp/typed_value.cpp
${src_dir}/query/typed_value.cpp
${src_dir}/query/frontend/logical/operator.cpp
${src_dir}/query/frontend/logical/planner.cpp
${src_dir}/query/frontend/semantic/symbol_generator.cpp

View File

@ -4,7 +4,7 @@
#include "database/graph_db_accessor.hpp"
#include "logging/default.hpp"
#include "logging/logger.hpp"
#include "query/backend/cpp/typed_value.hpp"
#include "query/typed_value.hpp"
#include "utils/bswap.hpp"
#include "utils/underlying_cast.hpp"
@ -19,7 +19,7 @@ namespace communication::bolt {
struct DecodedVertex {
int64_t id;
std::vector<std::string> labels;
std::map<std::string, TypedValue> properties;
std::map<std::string, query::TypedValue> properties;
};
/**
@ -31,7 +31,7 @@ struct DecodedEdge {
int64_t from;
int64_t to;
std::string type;
std::map<std::string, TypedValue> properties;
std::map<std::string, query::TypedValue> properties;
};
/**
@ -57,7 +57,7 @@ class Decoder : public Loggable {
* @returns true if data has been written to the data pointer,
* false otherwise
*/
bool ReadTypedValue(TypedValue *data) {
bool ReadTypedValue(query::TypedValue *data) {
uint8_t value;
logger.trace("[ReadTypedValue] Start");
@ -124,7 +124,7 @@ class Decoder : public Loggable {
* @returns true if data has been written to the data pointer and the type
* matches the expected type, false otherwise
*/
bool ReadTypedValue(TypedValue *data, TypedValue::Type type) {
bool ReadTypedValue(query::TypedValue *data, query::TypedValue::Type type) {
if (!ReadTypedValue(data)) {
logger.debug("[ReadTypedValue] ReadTypedValue call failed!");
return false;
@ -146,7 +146,7 @@ class Decoder : public Loggable {
*/
bool ReadVertex(DecodedVertex *data) {
uint8_t value[2];
TypedValue tv;
query::TypedValue tv;
logger.trace("[ReadVertex] Start");
@ -166,21 +166,21 @@ class Decoder : public Loggable {
}
// read ID
if (!ReadTypedValue(&tv, TypedValue::Type::Int)) {
if (!ReadTypedValue(&tv, query::TypedValue::Type::Int)) {
logger.debug("[ReadVertex] Couldn't read ID!");
return false;
}
data->id = tv.Value<int64_t>();
// read labels
if (!ReadTypedValue(&tv, TypedValue::Type::List)) {
if (!ReadTypedValue(&tv, query::TypedValue::Type::List)) {
logger.debug("[ReadVertex] Couldn't read labels!");
return false;
}
std::vector<TypedValue> &labels = tv.Value<std::vector<TypedValue>>();
auto &labels = tv.Value<std::vector<query::TypedValue>>();
data->labels.resize(labels.size());
for (size_t i = 0; i < labels.size(); ++i) {
if (labels[i].type() != TypedValue::Type::String) {
if (labels[i].type() != query::TypedValue::Type::String) {
logger.debug("[ReadVertex] Label has wrong type!");
return false;
}
@ -188,11 +188,11 @@ class Decoder : public Loggable {
}
// read properties
if (!ReadTypedValue(&tv, TypedValue::Type::Map)) {
if (!ReadTypedValue(&tv, query::TypedValue::Type::Map)) {
logger.debug("[ReadVertex] Couldn't read properties!");
return false;
}
data->properties = tv.Value<std::map<std::string, TypedValue>>();
data->properties = tv.Value<std::map<std::string, query::TypedValue>>();
logger.trace("[ReadVertex] Success");
@ -209,7 +209,7 @@ class Decoder : public Loggable {
*/
bool ReadEdge(DecodedEdge *data) {
uint8_t value[2];
TypedValue tv;
query::TypedValue tv;
logger.trace("[ReadEdge] Start");
@ -229,39 +229,39 @@ class Decoder : public Loggable {
}
// read ID
if (!ReadTypedValue(&tv, TypedValue::Type::Int)) {
if (!ReadTypedValue(&tv, query::TypedValue::Type::Int)) {
logger.debug("[ReadEdge] couldn't read ID!");
return false;
}
data->id = tv.Value<int64_t>();
// read from
if (!ReadTypedValue(&tv, TypedValue::Type::Int)) {
if (!ReadTypedValue(&tv, query::TypedValue::Type::Int)) {
logger.debug("[ReadEdge] Couldn't read from_id!");
return false;
}
data->from = tv.Value<int64_t>();
// read to
if (!ReadTypedValue(&tv, TypedValue::Type::Int)) {
if (!ReadTypedValue(&tv, query::TypedValue::Type::Int)) {
logger.debug("[ReadEdge] Couldn't read to_id!");
return false;
}
data->to = tv.Value<int64_t>();
// read type
if (!ReadTypedValue(&tv, TypedValue::Type::String)) {
if (!ReadTypedValue(&tv, query::TypedValue::Type::String)) {
logger.debug("[ReadEdge] Couldn't read type!");
return false;
}
data->type = tv.Value<std::string>();
// read properties
if (!ReadTypedValue(&tv, TypedValue::Type::Map)) {
if (!ReadTypedValue(&tv, query::TypedValue::Type::Map)) {
logger.debug("[ReadEdge] Couldn't read properties!");
return false;
}
data->properties = tv.Value<std::map<std::string, TypedValue>>();
data->properties = tv.Value<std::map<std::string, query::TypedValue>>();
logger.trace("[ReadEdge] Success");
@ -272,28 +272,28 @@ class Decoder : public Loggable {
Buffer &buffer_;
private:
bool ReadNull(const Marker &marker, TypedValue *data) {
bool ReadNull(const Marker &marker, query::TypedValue *data) {
logger.trace("[ReadNull] Start");
debug_assert(marker == Marker::Null, "Received invalid marker!");
*data = TypedValue::Null;
*data = query::TypedValue::Null;
logger.trace("[ReadNull] Success");
return true;
}
bool ReadBool(const Marker &marker, TypedValue *data) {
bool ReadBool(const Marker &marker, query::TypedValue *data) {
logger.trace("[ReadBool] Start");
debug_assert(marker == Marker::False || marker == Marker::True,
"Received invalid marker!");
if (marker == Marker::False) {
*data = TypedValue(false);
*data = query::TypedValue(false);
} else {
*data = TypedValue(true);
*data = query::TypedValue(true);
}
logger.trace("[ReadBool] Success");
return true;
}
bool ReadInt(const Marker &marker, TypedValue *data) {
bool ReadInt(const Marker &marker, query::TypedValue *data) {
uint8_t value = underlying_cast(marker);
bool success = true;
int64_t ret;
@ -338,13 +338,13 @@ class Decoder : public Loggable {
return false;
}
if (success) {
*data = TypedValue(ret);
*data = query::TypedValue(ret);
logger.trace("[ReadInt] Success");
}
return success;
}
bool ReadDouble(const Marker marker, TypedValue *data) {
bool ReadDouble(const Marker marker, query::TypedValue *data) {
uint64_t value;
double ret;
logger.trace("[ReadDouble] Start");
@ -355,7 +355,7 @@ class Decoder : public Loggable {
}
value = bswap(value);
ret = *reinterpret_cast<double *>(&value);
*data = TypedValue(ret);
*data = query::TypedValue(ret);
logger.trace("[ReadDouble] Success");
return true;
}
@ -397,7 +397,7 @@ class Decoder : public Loggable {
}
}
bool ReadString(const Marker &marker, TypedValue *data) {
bool ReadString(const Marker &marker, query::TypedValue *data) {
logger.trace("[ReadString] Start");
auto size = ReadTypeSize(marker, MarkerString);
if (size == -1) {
@ -409,31 +409,31 @@ class Decoder : public Loggable {
logger.debug("[ReadString] Missing data!");
return false;
}
*data = TypedValue(std::string(reinterpret_cast<char *>(ret.get()), size));
*data = query::TypedValue(std::string(reinterpret_cast<char *>(ret.get()), size));
logger.trace("[ReadString] Success");
return true;
}
bool ReadList(const Marker &marker, TypedValue *data) {
bool ReadList(const Marker &marker, query::TypedValue *data) {
logger.trace("[ReadList] Start");
auto size = ReadTypeSize(marker, MarkerList);
if (size == -1) {
logger.debug("[ReadList] Couldn't get size!");
return false;
}
std::vector<TypedValue> ret(size);
std::vector<query::TypedValue> ret(size);
for (int64_t i = 0; i < size; ++i) {
if (!ReadTypedValue(&ret[i])) {
logger.debug("[ReadList] Couldn't read element {}", i);
return false;
}
}
*data = TypedValue(ret);
*data = query::TypedValue(ret);
logger.trace("[ReadList] Success");
return true;
}
bool ReadMap(const Marker &marker, TypedValue *data) {
bool ReadMap(const Marker &marker, query::TypedValue *data) {
logger.trace("[ReadMap] Start");
auto size = ReadTypeSize(marker, MarkerMap);
if (size == -1) {
@ -441,15 +441,15 @@ class Decoder : public Loggable {
return false;
}
TypedValue tv;
query::TypedValue tv;
std::string str;
std::map<std::string, TypedValue> ret;
std::map<std::string, query::TypedValue> ret;
for (int64_t i = 0; i < size; ++i) {
if (!ReadTypedValue(&tv)) {
logger.debug("[ReadMap] Couldn't read index {}", i);
return false;
}
if (tv.type() != TypedValue::Type::String) {
if (tv.type() != query::TypedValue::Type::String) {
logger.debug("[ReadMap] Index {} isn't a string!", i);
return false;
}
@ -466,7 +466,7 @@ class Decoder : public Loggable {
return false;
}
*data = TypedValue(ret);
*data = query::TypedValue(ret);
logger.trace("[ReadMap] Success");
return true;
}

View File

@ -4,7 +4,7 @@
#include "database/graph_db_accessor.hpp"
#include "logging/default.hpp"
#include "logging/logger.hpp"
#include "query/backend/cpp/typed_value.hpp"
#include "query/typed_value.hpp"
#include "utils/bswap.hpp"
#include <string>
@ -115,12 +115,12 @@ class BaseEncoder : public Loggable {
WriteRAW(value.c_str(), value.size());
}
void WriteList(const std::vector<TypedValue> &value) {
void WriteList(const std::vector<query::TypedValue> &value) {
WriteTypeSize(value.size(), MarkerList);
for (auto &x : value) WriteTypedValue(x);
}
void WriteMap(const std::map<std::string, TypedValue> &value) {
void WriteMap(const std::map<std::string, query::TypedValue> &value) {
WriteTypeSize(value.size(), MarkerMap);
for (auto &x : value) {
WriteString(x.first);
@ -193,36 +193,36 @@ class BaseEncoder : public Loggable {
// TODO: this isn't implemented in the backend!
}
void WriteTypedValue(const TypedValue &value) {
void WriteTypedValue(const query::TypedValue &value) {
switch (value.type()) {
case TypedValue::Type::Null:
case query::TypedValue::Type::Null:
WriteNull();
break;
case TypedValue::Type::Bool:
case query::TypedValue::Type::Bool:
WriteBool(value.Value<bool>());
break;
case TypedValue::Type::Int:
case query::TypedValue::Type::Int:
WriteInt(value.Value<int64_t>());
break;
case TypedValue::Type::Double:
case query::TypedValue::Type::Double:
WriteDouble(value.Value<double>());
break;
case TypedValue::Type::String:
case query::TypedValue::Type::String:
WriteString(value.Value<std::string>());
break;
case TypedValue::Type::List:
WriteList(value.Value<std::vector<TypedValue>>());
case query::TypedValue::Type::List:
WriteList(value.Value<std::vector<query::TypedValue>>());
break;
case TypedValue::Type::Map:
WriteMap(value.Value<std::map<std::string, TypedValue>>());
case query::TypedValue::Type::Map:
WriteMap(value.Value<std::map<std::string, query::TypedValue>>());
break;
case TypedValue::Type::Vertex:
case query::TypedValue::Type::Vertex:
WriteVertex(value.Value<VertexAccessor>());
break;
case TypedValue::Type::Edge:
case query::TypedValue::Type::Edge:
WriteEdge(value.Value<EdgeAccessor>());
break;
case TypedValue::Type::Path:
case query::TypedValue::Type::Path:
// TODO: this is not implemeted yet!
WritePath();
break;

View File

@ -39,7 +39,7 @@ class Encoder : private BaseEncoder<Buffer> {
*
* @param values the fields list object that should be sent
*/
void MessageRecord(const std::vector<TypedValue> &values) {
void MessageRecord(const std::vector<query::TypedValue> &values) {
// 0xB1 = struct 1; 0x71 = record signature
WriteRAW("\xB1\x71", 2);
WriteList(values);
@ -57,7 +57,7 @@ class Encoder : private BaseEncoder<Buffer> {
* @param metadata the metadata map object that should be sent
* @param flush should method flush the socket
*/
void MessageSuccess(const std::map<std::string, TypedValue> &metadata,
void MessageSuccess(const std::map<std::string, query::TypedValue> &metadata,
bool flush = true) {
// 0xB1 = struct 1; 0x70 = success signature
WriteRAW("\xB1\x70", 2);
@ -74,7 +74,7 @@ class Encoder : private BaseEncoder<Buffer> {
* This function sends a success message without additional metadata.
*/
void MessageSuccess() {
std::map<std::string, TypedValue> metadata;
std::map<std::string, query::TypedValue> metadata;
MessageSuccess(metadata);
}
@ -88,7 +88,7 @@ class Encoder : private BaseEncoder<Buffer> {
*
* @param metadata the metadata map object that should be sent
*/
void MessageFailure(const std::map<std::string, TypedValue> &metadata) {
void MessageFailure(const std::map<std::string, query::TypedValue> &metadata) {
// 0xB1 = struct 1; 0x7F = failure signature
WriteRAW("\xB1\x7F", 2);
WriteMap(metadata);
@ -105,7 +105,7 @@ class Encoder : private BaseEncoder<Buffer> {
*
* @param metadata the metadata map object that should be sent
*/
void MessageIgnored(const std::map<std::string, TypedValue> &metadata) {
void MessageIgnored(const std::map<std::string, query::TypedValue> &metadata) {
// 0xB1 = struct 1; 0x7E = ignored signature
WriteRAW("\xB1\x7E", 2);
WriteMap(metadata);

View File

@ -2,7 +2,7 @@
#include "communication/bolt/v1/encoder/chunked_encoder_buffer.hpp"
#include "communication/bolt/v1/encoder/encoder.hpp"
#include "query/backend/cpp/typed_value.hpp"
#include "query/typed_value.hpp"
#include "logging/default.hpp"
@ -27,10 +27,10 @@ class ResultStream {
* @param fields the header fields that should be sent.
*/
void Header(const std::vector<std::string> &fields) {
std::vector<TypedValue> vec;
std::map<std::string, TypedValue> data;
for (auto &i : fields) vec.push_back(TypedValue(i));
data.insert(std::make_pair(std::string("fields"), TypedValue(vec)));
std::vector<query::TypedValue> vec;
std::map<std::string, query::TypedValue> data;
for (auto &i : fields) vec.push_back(query::TypedValue(i));
data.insert(std::make_pair(std::string("fields"), query::TypedValue(vec)));
// this call will automaticaly send the data to the client
encoder_.MessageSuccess(data);
}
@ -47,7 +47,7 @@ class ResultStream {
*
* @param values the values that should be sent
*/
void Result(std::vector<TypedValue> &values) {
void Result(std::vector<query::TypedValue> &values) {
encoder_.MessageRecord(values);
}
@ -63,7 +63,7 @@ class ResultStream {
*
* @param summary the summary map object that should be sent
*/
void Summary(const std::map<std::string, TypedValue> &summary) {
void Summary(const std::map<std::string, query::TypedValue> &summary) {
// at this point message should not flush the socket so
// here is false because chunk has to be called instead of flush
encoder_.MessageSuccess(summary, false);

View File

@ -16,8 +16,9 @@ struct Query {
};
template <typename Session>
void StateExecutorFailure(Session &session, Logger &logger,
const std::map<std::string, TypedValue> &metadata) {
void StateExecutorFailure(
Session &session, Logger &logger,
const std::map<std::string, query::TypedValue> &metadata) {
try {
session.encoder_.MessageFailure(metadata);
} catch (const BoltException &e) {

View File

@ -1,6 +1,8 @@
#pragma once
#include "query/backend/cpp/typed_value.hpp"
#include <map>
#include "query/typed_value.hpp"
#include "utils/assert.hpp"
/**
@ -18,13 +20,13 @@ class ResultStreamFaker {
current_state_ = State::WritingResults;
}
void Result(const std::vector<TypedValue> &values) {
void Result(const std::vector<query::TypedValue> &values) {
debug_assert(current_state_ == State::WritingResults,
"Can't accept results before header nor after summary");
results_.push_back(values);
}
void Summary(const std::map<std::string, TypedValue> &summary) {
void Summary(const std::map<std::string, query::TypedValue> &summary) {
debug_assert(current_state_ != State::Done, "Can only send a summary once");
summary_ = summary;
current_state_ = State::Done;
@ -54,6 +56,6 @@ class ResultStreamFaker {
// the data that the record stream can accept
std::vector<std::string> header_;
std::vector<std::vector<TypedValue>> results_;
std::map<std::string, TypedValue> summary_;
std::vector<std::vector<query::TypedValue>> results_;
std::map<std::string, query::TypedValue> summary_;
};

View File

@ -2,15 +2,17 @@
// Copyright 2017 Memgraph
// Created by Florijan Stamenkovic on 23.03.17.
//
#include "console.hpp"
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include "console.hpp"
#include "query/exceptions.hpp"
#include "query/interpreter.hpp"
#include "query/typed_value.hpp"
#include "utils/algorithm.hpp"
#ifdef HAS_READLINE
@ -47,59 +49,17 @@ std::string ReadLine(const char *prompt) {
#endif // HAS_READLINE
/**
* Helper function that outputs a collection of items to
* the given stream, separating them with the given delimiter.
*/
template <typename TStream, typename TIterable, typename TConverter>
void PrintIterable(TStream &stream, const TIterable &iterable,
const std::string &delim, TConverter converter = {}) {
bool first = true;
for (const auto &item : iterable) {
if (first)
first = false;
else
stream << delim;
stream << converter(item);
}
}
/**
* Converts the given TypedValue into a string (single line).
*/
std::string TypedValueToString(const TypedValue &value) {
std::string TypedValueToString(const query::TypedValue &value) {
std::stringstream ss;
switch (value.type()) {
case TypedValue::Type::Vertex: {
auto va = value.Value<VertexAccessor>();
ss << "V(";
PrintIterable(ss, va.labels(), ":", [&](auto label) {
return va.db_accessor().label_name(label);
});
ss << " {";
PrintIterable(ss, va.Properties(), ", ", [&](const auto kv) {
return va.db_accessor().property_name(kv.first) + ": " +
TypedValueToString(kv.second);
});
ss << "})";
case query::TypedValue::Type::List:
break;
}
case TypedValue::Type::Edge: {
auto ea = value.Value<EdgeAccessor>();
ss << "E[" << ea.db_accessor().edge_type_name(ea.edge_type());
ss << " {";
PrintIterable(ss, ea.Properties(), ", ", [&](const auto kv) {
return ea.db_accessor().property_name(kv.first) + ": " +
TypedValueToString(kv.second);
});
ss << "}]";
case query::TypedValue::Type::Map:
break;
}
case TypedValue::Type::List:
break;
case TypedValue::Type::Map:
break;
case TypedValue::Type::Path:
case query::TypedValue::Type::Path:
break;
default:
ss << value;

View File

@ -6,8 +6,8 @@
#include "database/graph_db.hpp"
#include "database/graph_db_datatypes.hpp"
#include "query/backend/cpp/typed_value.hpp"
#include "query/frontend/ast/ast_visitor.hpp"
#include "query/typed_value.hpp"
#include "utils/visitor/visitable.hpp"
namespace query {

View File

@ -3,9 +3,9 @@
#include <map>
#include <vector>
#include "query/backend/cpp/typed_value.hpp"
#include "query/frontend/ast/ast.hpp"
#include "query/frontend/semantic/symbol_table.hpp"
#include "query/typed_value.hpp"
#include "utils/assert.hpp"
#include "utils/exceptions/not_yet_implemented.hpp"

View File

@ -6,7 +6,7 @@
#ifndef MEMGRAPH_PARAMETERS_HPP
#define MEMGRAPH_PARAMETERS_HPP
#include <query/backend/cpp/typed_value.hpp>
#include "query/typed_value.hpp"
/**
* Encapsulates user provided parameters (and stripped literals)
@ -21,7 +21,7 @@ struct Parameters {
* @param value
* @return
*/
const std::string &Add(const TypedValue &value) {
const std::string &Add(const query::TypedValue &value) {
return storage_.emplace(NextName(), value).first->first;
}
@ -33,7 +33,7 @@ struct Parameters {
* @param name Param name.
* @return Value for the given param.
*/
const TypedValue &At(const std::string &name) const {
const query::TypedValue &At(const std::string &name) const {
auto found = storage_.find(name);
permanent_assert(found != storage_.end(),
"Name must be present in stripped arg container");
@ -51,7 +51,7 @@ struct Parameters {
* @param position Which stripped param is sought.
* @return Stripped param.
*/
const TypedValue &At(const size_t position) const {
const query::TypedValue &At(const size_t position) const {
permanent_assert(position < storage_.size(), "Invalid position");
return storage_.find(NameForPosition(position))->second;
}
@ -60,7 +60,7 @@ struct Parameters {
const size_t Size() const { return storage_.size(); }
private:
std::map<std::string, TypedValue> storage_;
std::map<std::string, query::TypedValue> storage_;
/** Generates and returns a new name */
std::string NextName() const { return NameForPosition(storage_.size()); }

View File

@ -2,10 +2,8 @@
#include <map>
#include "query/backend/cpp/typed_value.hpp"
#include "storage/property_value_store.hpp"
#include "parameters.hpp"
#include "storage/property_value_store.hpp"
#include "utils/assert.hpp"
#include "utils/hashing/fnv.hpp"

View File

@ -1,4 +1,4 @@
#include "query/backend/cpp/typed_value.hpp"
#include "query/typed_value.hpp"
#include <fmt/format.h>
#include <cmath>
@ -7,6 +7,8 @@
#include "utils/assert.hpp"
namespace query {
TypedValue::TypedValue(const PropertyValue &value) {
switch (value.type()) {
case PropertyValue::Type::Null:
@ -728,3 +730,5 @@ TypedValue operator^(const TypedValue &a, const TypedValue &b) {
a.type(), b.type());
}
}
} // namespace query

View File

@ -15,6 +15,8 @@
#include "utils/total_ordering.hpp"
#include "utils/underlying_cast.hpp"
namespace query {
typedef traversal_template::Path<VertexAccessor, EdgeAccessor> Path;
// TODO: Neo4j does overflow checking. Should we also implement it?
@ -164,3 +166,5 @@ TypedValue operator^(const TypedValue &a, const TypedValue &b);
// stream output
std::ostream &operator<<(std::ostream &os, const TypedValue::Type type);
} // namespace query

View File

@ -1,6 +1,8 @@
#include "storage/edge_accessor.hpp"
#include "database/graph_db_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "utils/algorithm.hpp"
GraphDbTypes::EdgeType EdgeAccessor::edge_type() const {
return current().edge_type_;
@ -13,3 +15,15 @@ VertexAccessor EdgeAccessor::from() const {
VertexAccessor EdgeAccessor::to() const {
return VertexAccessor(current().to_, db_accessor());
}
std::ostream &operator<<(std::ostream &os, const EdgeAccessor &ea) {
os << "E[" << ea.db_accessor().edge_type_name(ea.edge_type());
os << " {";
auto prop_to_string = [&](const auto kv) {
std::stringstream ss;
ss << ea.db_accessor().property_name(kv.first) << ": " << kv.second;
return ss.str();
};
PrintIterable(os, ea.Properties(), ", ", prop_to_string);
return os << "}]";
}

View File

@ -40,3 +40,5 @@ class EdgeAccessor : public RecordAccessor<Edge> {
// void remove();
};
std::ostream &operator<<(std::ostream &, const EdgeAccessor &);

View File

@ -1,9 +1,10 @@
#include "storage/vertex_accessor.hpp"
#include <algorithm>
#include "database/graph_db_accessor.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/util.hpp"
#include "storage/vertex_accessor.hpp"
#include "utils/algorithm.hpp"
size_t VertexAccessor::out_degree() const { return current().out_.size(); }
@ -38,3 +39,17 @@ bool VertexAccessor::has_label(GraphDbTypes::Label label) const {
const std::vector<GraphDbTypes::Label> &VertexAccessor::labels() const {
return this->current().labels_;
}
std::ostream &operator<<(std::ostream &os, const VertexAccessor &va) {
os << "V(";
PrintIterable(os, va.labels(), ":",
[&](auto label) { return va.db_accessor().label_name(label); });
os << " {";
auto prop_to_string = [&](const auto kv) {
std::stringstream ss;
ss << va.db_accessor().property_name(kv.first) << ": " << kv.second;
return ss.str();
};
PrintIterable(os, va.Properties(), ", ", prop_to_string);
return os << "})";
}

View File

@ -73,3 +73,5 @@ class VertexAccessor : public RecordAccessor<Vertex> {
*/
auto out() { return make_accessor_iterator<EdgeAccessor>(current().out_, db_accessor()); }
};
std::ostream &operator<<(std::ostream &, const VertexAccessor &);

View File

@ -23,3 +23,27 @@ ForwardIt action_remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p,
std::for_each(it, last, a);
return it;
}
/**
* Outputs a collection of items to the given stream, separating them with the
* given delimiter.
*
* @param stream Destination stream.
* @param iterable An iterable collection of items.
* @param delim Delimiter that is put between items.
* @param converter Function which converts an item to a type which supports
* @c operator<<.
*/
template <typename TStream, typename TIterable, typename TConverter>
void PrintIterable(TStream &stream, const TIterable &iterable,
const std::string &delim = ", ", TConverter converter = {}) {
bool first = true;
for (const auto &item : iterable) {
if (first)
first = false;
else
stream << delim;
stream << converter(item);
}
}

View File

@ -4,9 +4,9 @@
#include <string>
#include "data_structures/bitset/static_bitset.hpp"
#include "query/backend/cpp/typed_value.hpp"
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
@ -56,11 +56,11 @@ bool run_general_query(GraphDbAccessor &db_accessor, const Parameters &args,
vertices[i].has_label(db_accessor.label("profile"))) {
auto has_prop =
vertices[i].PropsAt(db_accessor.property("profile_id")) == args.At(0);
if (has_prop.type() == TypedValue::Type::Null) continue;
if (has_prop.type() == query::TypedValue::Type::Null) continue;
if (has_prop.Value<bool>() == false) continue;
has_prop =
vertices[i].PropsAt(db_accessor.property("partner_id")) == args.At(1);
if (has_prop.type() == TypedValue::Type::Null) continue;
if (has_prop.type() == query::TypedValue::Type::Null) continue;
if (has_prop.Value<bool>() == false) continue;
profile_index = i;
}
@ -121,7 +121,7 @@ bool run_general_query(GraphDbAccessor &db_accessor, const Parameters &args,
const VertexAccessor v = *vertices_indexed[i];
auto cmp_res = v.PropsAt(db_accessor.property("garment_id")) ==
args.At(query_type == CliqueQuery::SCORE_AND_LIMIT ? 8 : 0);
if (cmp_res.type() != TypedValue::Type::Bool) continue;
if (cmp_res.type() != query::TypedValue::Type::Bool) continue;
if (cmp_res.Value<bool>() != true) continue;
auto neigh = connected[i].Ones();
for (int j : neigh) {
@ -186,8 +186,8 @@ bool run_general_query(GraphDbAccessor &db_accessor, const Parameters &args,
for (auto x : V) {
auto edge = get_edge(vertices[profile_index], *vertices_indexed[x]);
if (edge == nullptr) continue;
auto prop = TypedValue(edge->PropsAt(db_accessor.property("score")));
if (prop.type() == TypedValue::Type::Int) res += prop.Value<int64_t>();
auto prop = query::TypedValue(edge->PropsAt(db_accessor.property("score")));
if (prop.type() == query::TypedValue::Type::Int) res += prop.Value<int64_t>();
}
return res;
};
@ -203,7 +203,7 @@ bool run_general_query(GraphDbAccessor &db_accessor, const Parameters &args,
? args.At((int)args.Size() - 1).Value<int64_t>()
: (int)results.size();
for (int i = 0; i < std::min(limit, (int)results.size()); ++i) {
std::vector<TypedValue> result;
std::vector<query::TypedValue> result;
for (auto x : results[i]) {
result.push_back(vertices_indexed[x]
->PropsAt(db_accessor.property("garment_id"))
@ -213,8 +213,8 @@ bool run_general_query(GraphDbAccessor &db_accessor, const Parameters &args,
result.push_back(calc_score(results[i]));
stream.Result(result);
}
std::map<std::string, TypedValue> meta{
std::make_pair(std::string("type"), TypedValue(std::string("r")))};
std::map<std::string, query::TypedValue> meta{
std::make_pair(std::string("type"), query::TypedValue(std::string("r")))};
stream.Summary(meta);
return true;
}

View File

@ -3,12 +3,14 @@
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: CREATE (p:profile {profile_id: 112, partner_id: 55, conceals: 10})
// RETURN p

View File

@ -3,12 +3,14 @@
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: CREATE (p:profile {profile_id: 112, partner_id: 55}) RETURN p

View File

@ -3,12 +3,14 @@
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: CREATE (p:profile {profile_id: 112, partner_id: 55, reveals: 30})
// RETURN p

View File

@ -3,12 +3,14 @@
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: CREATE (g:garment {garment_id: 1234, garment_category_id:1}) RETURN g

View File

@ -3,12 +3,14 @@
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: CREATE (g:garment {garment_id: 1234, garment_category_id:
// 1,conceals:30}) RETURN g

View File

@ -3,12 +3,14 @@
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: CREATE (g:garment {garment_id: 1234, garment_category_id:
// 1,reveals:30}) RETURN g

View File

@ -1,14 +1,15 @@
#include <iostream>
#include <string>
#include "query/backend/cpp/typed_value.hpp"
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/stripped.hpp"
#include "query/typed_value.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: MATCH (n) DETACH DELETE n

View File

@ -1,15 +1,16 @@
#include <iostream>
#include <string>
#include "query/backend/cpp/typed_value.hpp"
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: MATCH (g:garment {garment_id: 1234}) RETURN g

View File

@ -1,15 +1,16 @@
#include <iostream>
#include <string>
#include "query/backend/cpp/typed_value.hpp"
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: MATCH (g1:garment {garment_id: 1234}), (g2:garment {garment_id: 4567})
// CREATE (g1)-[r:default_outfit]->(g2) RETURN r

View File

@ -1,9 +1,9 @@
#include <iostream>
#include <string>
#include "query/backend/cpp/typed_value.hpp"
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
@ -20,18 +20,19 @@ bool run_general_query(GraphDbAccessor &db_accessor, const Parameters &args,
stream.Header(headers);
for (auto vertex : db_accessor.vertices()) {
if (vertex.has_label(db_accessor.label("garment"))) {
TypedValue prop = vertex.PropsAt(db_accessor.property("garment_id"));
if (prop.type() == TypedValue::Type::Null) continue;
TypedValue cmp = prop == args.At(0);
if (cmp.type() != TypedValue::Type::Bool) continue;
query::TypedValue prop =
vertex.PropsAt(db_accessor.property("garment_id"));
if (prop.type() == query::TypedValue::Type::Null) continue;
query::TypedValue cmp = prop == args.At(0);
if (cmp.type() != query::TypedValue::Type::Bool) continue;
if (cmp.Value<bool>() != true) continue;
vertex.add_label(db_accessor.label(general_label));
std::vector<TypedValue> result{TypedValue(vertex)};
std::vector<query::TypedValue> result{query::TypedValue(vertex)};
stream.Result(result);
}
}
std::map<std::string, TypedValue> meta{
std::make_pair(std::string("type"), TypedValue(std::string("rw")))};
std::map<std::string, query::TypedValue> meta{std::make_pair(
std::string("type"), query::TypedValue(std::string("rw")))};
stream.Summary(meta);
return true;
}

View File

@ -1,15 +1,16 @@
#include <iostream>
#include <string>
#include "query/backend/cpp/typed_value.hpp"
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: MATCH (p:profile {profile_id: 112, partner_id: 77}) RETURN p

View File

@ -1,16 +1,17 @@
#include <iostream>
#include <string>
#include "query/backend/cpp/typed_value.hpp"
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/stripped.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: MATCH (p:profile {profile_id: 111, partner_id:
// 55})-[s:score]-(g:garment

View File

@ -1,15 +1,16 @@
#include <iostream>
#include <string>
#include "query/backend/cpp/typed_value.hpp"
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: MATCH (p:profile {profile_id: 111, partner_id: 55}), (g:garment
// {garment_id: 1234}) CREATE (p)-[s:score]->(g) SET s.score=1500 RETURN s

View File

@ -1,15 +1,16 @@
#include <iostream>
#include <string>
#include "query/backend/cpp/typed_value.hpp"
#include "query/parameters.hpp"
#include "query/plan_interface.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "using.hpp"
using std::cout;
using std::endl;
using query::TypedValue;
// Query: MATCH (p:profile {profile_id: 111, partner_id:
// 55})-[s:score]-(g:garment

View File

@ -5,38 +5,10 @@
#include <string>
#include <vector>
#include "query/backend/cpp/typed_value.hpp"
#include "query/typed_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
void write_properties(std::ostream &os, const GraphDbAccessor &access,
const PropertyValueStore<GraphDbTypes::Property> &properties) {
if (properties.size() > 0) {
os << "{";
for (auto x : properties) {
os << access.property_name(x.first) << ": " << x.second << ",";
}
os << "}\n";
}
}
std::ostream &operator<<(std::ostream &os, const VertexAccessor &vertex) {
if (vertex.labels().size() > 0) {
for (GraphDbTypes::Label label : vertex.labels()) {
os << vertex.db_accessor().property_name(label) << ", ";
}
os << "\n";
}
write_properties(os, vertex.db_accessor(), vertex.Properties());
return os;
}
std::ostream &operator<<(std::ostream &os, const EdgeAccessor &edge) {
os << "Edge: " << edge.db_accessor().edge_type_name(edge.edge_type()) << "\n";
write_properties(os, edge.db_accessor(), edge.Properties());
return os;
}
class PrintRecordStream {
private:
std::ostream &stream;
@ -49,11 +21,11 @@ class PrintRecordStream {
stream << "Header\n";
}
void Result(std::vector<TypedValue> &values) {
void Result(std::vector<query::TypedValue> &values) {
stream << "Result\n";
}
void Summary(const std::map<std::string, TypedValue> &summary) {
void Summary(const std::map<std::string, query::TypedValue> &summary) {
stream << "Summary\n";
}
};

View File

@ -2,7 +2,9 @@
#include "bolt_testdata.hpp"
#include "communication/bolt/v1/decoder/decoder.hpp"
#include "query/backend/cpp/typed_value.hpp"
#include "query/typed_value.hpp"
using query::TypedValue;
constexpr const int SIZE = 131072;
uint8_t data[SIZE];

View File

@ -4,7 +4,9 @@
#include "communication/bolt/v1/encoder/encoder.hpp"
#include "database/graph_db.hpp"
#include "database/graph_db_accessor.hpp"
#include "query/backend/cpp/typed_value.hpp"
#include "query/typed_value.hpp"
using query::TypedValue;
/**
* TODO (mferencevic): document

View File

@ -3,7 +3,9 @@
#include "communication/bolt/v1/encoder/chunked_encoder_buffer.hpp"
#include "communication/bolt/v1/encoder/encoder.hpp"
#include "communication/bolt/v1/encoder/result_stream.hpp"
#include "query/backend/cpp/typed_value.hpp"
#include "query/typed_value.hpp"
using query::TypedValue;
using BufferT = communication::bolt::ChunkedEncoderBuffer<TestSocket>;
using EncoderT = communication::bolt::Encoder<BufferT>;

View File

@ -12,11 +12,13 @@
#include "query/frontend/ast/ast.hpp"
#include "query/frontend/ast/cypher_main_visitor.hpp"
#include "query/frontend/opencypher/parser.hpp"
#include "query/typed_value.hpp"
namespace {
using namespace query;
using namespace query::frontend;
using query::TypedValue;
using testing::UnorderedElementsAre;
using testing::Pair;

View File

@ -6,6 +6,9 @@
#include "gtest/gtest.h"
#include "query/stripper.hpp"
#include "query/typed_value.hpp"
using query::TypedValue;
void EXPECT_PROP_TRUE(const TypedValue& a) {
EXPECT_TRUE(a.type() == TypedValue::Type::Bool && a.Value<bool>());

View File

@ -6,10 +6,13 @@
#include <vector>
#include "gtest/gtest.h"
#include "query/backend/cpp/typed_value.hpp"
#include "query/typed_value.hpp"
namespace {
using query::TypedValue;
using query::TypedValueException;
std::vector<TypedValue> MakePropsAllTypes() {
return {
true,