Add DumpGenerator class

Summary: DumpGenerator dumps parts of query to stream.

Reviewers: teon.banek

Reviewed By: teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D2023
This commit is contained in:
Tonko Sabolcec 2019-05-09 14:24:00 +02:00
parent 70ed1706b8
commit 60d72f489a
2 changed files with 77 additions and 27 deletions

View File

@ -80,13 +80,6 @@ void DumpVertex(std::ostream *os, GraphDbAccessor *dba,
*os << ")";
}
void DumpVertices(std::ostream *os, GraphDbAccessor *dba) {
auto vertices = dba->Vertices(false);
utils::PrintIterable(
os, vertices.begin(), vertices.end(), ", ",
[&dba](auto &os, const auto &vertex) { DumpVertex(&os, dba, vertex); });
}
void DumpEdge(std::ostream *os, GraphDbAccessor *dba,
const EdgeAccessor &edge) {
*os << "(n" << edge.from().gid() << ")-[";
@ -99,29 +92,39 @@ void DumpEdge(std::ostream *os, GraphDbAccessor *dba,
*os << "]->(n" << edge.to().gid() << ")";
}
void DumpEdges(std::ostream *os, GraphDbAccessor *dba) {
auto edges = dba->Edges(false);
utils::PrintIterable(
os, edges.begin(), edges.end(), ", ",
[&dba](auto &os, const auto &edge) { DumpEdge(&os, dba, edge); });
}
} // namespace
void DumpToCypher(std::ostream *os, GraphDbAccessor *dba) {
CHECK(os);
DumpGenerator::DumpGenerator(GraphDbAccessor *dba) : dba_(dba), first_(true) {
CHECK(dba);
vertices_state_.emplace(dba->Vertices(false));
edges_state_.emplace(dba->Edges(false));
}
if (dba->VerticesCount() > 0) {
bool DumpGenerator::NextQuery(std::ostream *os) {
if (vertices_state_->ReachedEnd() && edges_state_->ReachedEnd()) return false;
if (first_) {
first_ = false;
*os << "CREATE ";
DumpVertices(os, dba);
if (dba->EdgesCount() > 0) {
} else {
*os << ", ";
DumpEdges(os, dba);
}
*os << ";";
if (!vertices_state_->ReachedEnd()) {
DumpVertex(os, dba_, *vertices_state_->GetCurrentAndAdvance());
} else if (!edges_state_->ReachedEnd()) {
DumpEdge(os, dba_, *edges_state_->GetCurrentAndAdvance());
}
// TODO(tsabolcec): Dump other data as well.
if (vertices_state_->ReachedEnd() && edges_state_->ReachedEnd()) *os << ";";
return true;
}
void DumpToCypher(std::ostream *os, GraphDbAccessor *dba) {
CHECK(os && dba);
DumpGenerator dump(dba);
while (dump.NextQuery(os)) continue;
}
} // namespace database

View File

@ -6,13 +6,60 @@
namespace database {
/// Class which generates parts of openCypher query which can be used to dump
/// the database state.
///
/// Currently, all parts combined form a single query which dumps an entire
/// graph (vertices and edges). Since query can be quite long for larger graphs,
/// the graph should be split in multiple queries in the future. Indexes,
/// constraints, roles, etc. are currently not dumped.
class DumpGenerator {
public:
explicit DumpGenerator(GraphDbAccessor *dba);
bool NextQuery(std::ostream *os);
private:
// A helper class that keeps container and its iterators.
template <typename TContainer>
class ContainerState {
public:
explicit ContainerState(TContainer container)
: container_(std::move(container)),
current_(container_.begin()),
end_(container_.end()) {}
auto GetCurrentAndAdvance() {
auto to_be_returned = current_;
if (current_ != end_) ++current_;
return to_be_returned;
}
bool ReachedEnd() const { return current_ == end_; }
private:
TContainer container_;
using TIterator = decltype(container_.begin());
TIterator current_;
TIterator end_;
};
GraphDbAccessor *dba_;
// Boolean which indicates if the `NextQuery` method is called for the first
// time.
bool first_;
std::optional<ContainerState<decltype(dba_->Vertices(false))>>
vertices_state_;
std::optional<ContainerState<decltype(dba_->Edges(false))>> edges_state_;
};
/// Dumps database state to output stream as openCypher queries.
///
/// Currently, it only dumps vertices and edges of the graph. In the future,
/// it should also dump indexes, constraints, roles, etc.
///
/// @param os Output stream
/// @param dba Database accessor
void DumpToCypher(std::ostream *os, GraphDbAccessor *dba);
} // namespace database