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 << ")";
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user