From 60d72f489acd2891e5ac69f6483e2800de4f3d38 Mon Sep 17 00:00:00 2001 From: Tonko Sabolcec Date: Thu, 9 May 2019 14:24:00 +0200 Subject: [PATCH] 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 --- src/database/single_node/dump.cpp | 51 +++++++++++++++-------------- src/database/single_node/dump.hpp | 53 +++++++++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 27 deletions(-) diff --git a/src/database/single_node/dump.cpp b/src/database/single_node/dump.cpp index ce3d13bb0..2c44414a8 100644 --- a/src/database/single_node/dump.cpp +++ b/src/database/single_node/dump.cpp @@ -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) { - *os << ", "; - DumpEdges(os, dba); - } - *os << ";"; + } else { + *os << ", "; } - // TODO(tsabolcec): Dump other data as well. + + if (!vertices_state_->ReachedEnd()) { + DumpVertex(os, dba_, *vertices_state_->GetCurrentAndAdvance()); + } else if (!edges_state_->ReachedEnd()) { + DumpEdge(os, dba_, *edges_state_->GetCurrentAndAdvance()); + } + + 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 diff --git a/src/database/single_node/dump.hpp b/src/database/single_node/dump.hpp index e2480204c..8e98a4304 100644 --- a/src/database/single_node/dump.hpp +++ b/src/database/single_node/dump.hpp @@ -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 + 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::optionalVertices(false))>> + vertices_state_; + std::optionalEdges(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