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:
parent
70ed1706b8
commit
60d72f489a
@ -80,13 +80,6 @@ void DumpVertex(std::ostream *os, GraphDbAccessor *dba,
|
|||||||
*os << ")";
|
*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,
|
void DumpEdge(std::ostream *os, GraphDbAccessor *dba,
|
||||||
const EdgeAccessor &edge) {
|
const EdgeAccessor &edge) {
|
||||||
*os << "(n" << edge.from().gid() << ")-[";
|
*os << "(n" << edge.from().gid() << ")-[";
|
||||||
@ -99,29 +92,39 @@ void DumpEdge(std::ostream *os, GraphDbAccessor *dba,
|
|||||||
*os << "]->(n" << edge.to().gid() << ")";
|
*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
|
} // namespace
|
||||||
|
|
||||||
void DumpToCypher(std::ostream *os, GraphDbAccessor *dba) {
|
DumpGenerator::DumpGenerator(GraphDbAccessor *dba) : dba_(dba), first_(true) {
|
||||||
CHECK(os);
|
|
||||||
CHECK(dba);
|
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 ";
|
*os << "CREATE ";
|
||||||
DumpVertices(os, dba);
|
} else {
|
||||||
if (dba->EdgesCount() > 0) {
|
*os << ", ";
|
||||||
*os << ", ";
|
|
||||||
DumpEdges(os, dba);
|
|
||||||
}
|
|
||||||
*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
|
} // namespace database
|
||||||
|
@ -6,13 +6,60 @@
|
|||||||
|
|
||||||
namespace database {
|
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.
|
/// Dumps database state to output stream as openCypher queries.
|
||||||
///
|
///
|
||||||
/// Currently, it only dumps vertices and edges of the graph. In the future,
|
/// Currently, it only dumps vertices and edges of the graph. In the future,
|
||||||
/// it should also dump indexes, constraints, roles, etc.
|
/// it should also dump indexes, constraints, roles, etc.
|
||||||
///
|
|
||||||
/// @param os Output stream
|
|
||||||
/// @param dba Database accessor
|
|
||||||
void DumpToCypher(std::ostream *os, GraphDbAccessor *dba);
|
void DumpToCypher(std::ostream *os, GraphDbAccessor *dba);
|
||||||
|
|
||||||
} // namespace database
|
} // namespace database
|
||||||
|
Loading…
Reference in New Issue
Block a user