134 lines
4.6 KiB
C++
134 lines
4.6 KiB
C++
#include <string>
|
|
#include <string_view>
|
|
|
|
#include <gflags/gflags.h>
|
|
#include <mgclient.hpp>
|
|
#include "common.hpp"
|
|
#include "utils/logging.hpp"
|
|
|
|
constexpr std::string_view kTriggerDeletedVertexLabel{"DELETED_VERTEX"};
|
|
constexpr std::string_view kTriggerDeletedEdgeLabel{"DELETED_EDGE"};
|
|
constexpr std::string_view kTriggerDeletedObjectLabel{"DELETED_OBJECT"};
|
|
|
|
void DetachDeleteVertex(mg::Client &client, int vertex_id) {
|
|
mg::Map parameters{{"id", mg::Value{vertex_id}}};
|
|
client.Execute(fmt::format("MATCH (n: {} {{id: $id}}) DETACH DELETE n", kVertexLabel),
|
|
mg::ConstMap{parameters.ptr()});
|
|
client.DiscardAll();
|
|
}
|
|
|
|
void DeleteEdge(mg::Client &client, int edge_id) {
|
|
mg::Map parameters{{"id", mg::Value{edge_id}}};
|
|
client.Execute(fmt::format("MATCH ()-[r: {} {{id: $id}}]->() DELETE r", kEdgeLabel), mg::ConstMap{parameters.ptr()});
|
|
client.DiscardAll();
|
|
}
|
|
|
|
void CreateOnDeleteTriggers(mg::Client &client, bool is_before) {
|
|
const std::string_view before_or_after = is_before ? "BEFORE" : "AFTER";
|
|
client.Execute(
|
|
fmt::format("CREATE TRIGGER DeletedVerticesTrigger ON () DELETE "
|
|
"{} COMMIT "
|
|
"EXECUTE "
|
|
"UNWIND deletedVertices as deletedVertex "
|
|
"CREATE (n: {} {{ id: deletedVertex.id }})",
|
|
before_or_after, kTriggerDeletedVertexLabel));
|
|
client.DiscardAll();
|
|
client.Execute(
|
|
fmt::format("CREATE TRIGGER DeletedEdgesTrigger ON --> DELETE "
|
|
"{} COMMIT "
|
|
"EXECUTE "
|
|
"UNWIND deletedEdges as deletedEdge "
|
|
"CREATE (n: {} {{ id: deletedEdge.id }})",
|
|
before_or_after, kTriggerDeletedEdgeLabel));
|
|
client.DiscardAll();
|
|
client.Execute(
|
|
fmt::format("CREATE TRIGGER DeletedObjectsTrigger ON DELETE "
|
|
"{} COMMIT "
|
|
"EXECUTE "
|
|
"UNWIND deletedObjects as deletedObjectEvent "
|
|
"WITH CASE deletedObjectEvent.event_type WHEN \"deleted_vertex\" THEN deletedObjectEvent.vertex.id "
|
|
"ELSE deletedObjectEvent.edge.id END as id "
|
|
"CREATE (n: {} {{ id: id }})",
|
|
before_or_after, kTriggerDeletedObjectLabel));
|
|
client.DiscardAll();
|
|
}
|
|
|
|
void DropOnDeleteTriggers(mg::Client &client) {
|
|
client.Execute("DROP TRIGGER DeletedVerticesTrigger");
|
|
client.DiscardAll();
|
|
client.Execute("DROP TRIGGER DeletedEdgesTrigger");
|
|
client.DiscardAll();
|
|
client.Execute("DROP TRIGGER DeletedObjectsTrigger");
|
|
client.DiscardAll();
|
|
}
|
|
|
|
struct EdgeInfo {
|
|
int from_vertex;
|
|
int to_vertex;
|
|
int edge_id;
|
|
};
|
|
|
|
int main(int argc, char **argv) {
|
|
gflags::SetUsageMessage("Memgraph E2E ON DELETE Triggers");
|
|
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
|
logging::RedirectToStderr();
|
|
|
|
mg::Client::Init();
|
|
|
|
auto client = Connect();
|
|
|
|
const auto run_delete_trigger_tests = [&](bool is_before) {
|
|
const std::array vertex_ids{1, 2, 3, 4};
|
|
const std::array edges{EdgeInfo{vertex_ids[0], vertex_ids[1], 5}, EdgeInfo{vertex_ids[2], vertex_ids[3], 6}};
|
|
{
|
|
CreateOnDeleteTriggers(*client, is_before);
|
|
|
|
client->BeginTransaction();
|
|
for (const auto vertex_id : vertex_ids) {
|
|
CreateVertex(*client, vertex_id);
|
|
}
|
|
for (const auto &edge : edges) {
|
|
CreateEdge(*client, edge.from_vertex, edge.to_vertex, edge.edge_id);
|
|
}
|
|
client->CommitTransaction();
|
|
CheckNumberOfAllVertices(*client, vertex_ids.size());
|
|
|
|
client->BeginTransaction();
|
|
DetachDeleteVertex(*client, vertex_ids[0]);
|
|
DeleteEdge(*client, edges[1].edge_id);
|
|
client->CommitTransaction();
|
|
|
|
// :VERTEX x 4
|
|
// deleted :VERTEX x -1
|
|
// :DELETED_VERTEX x 1
|
|
// :DELETED_EDGE x 2
|
|
// :DELETED_OBJECT x 3
|
|
constexpr auto kNumberOfExpectedVertices = 9;
|
|
|
|
if (is_before) {
|
|
CheckNumberOfAllVertices(*client, kNumberOfExpectedVertices);
|
|
} else {
|
|
WaitForNumberOfAllVertices(*client, kNumberOfExpectedVertices);
|
|
}
|
|
|
|
CheckVertexExists(*client, kTriggerDeletedVertexLabel, vertex_ids[0]);
|
|
CheckVertexExists(*client, kTriggerDeletedObjectLabel, vertex_ids[0]);
|
|
|
|
for (const auto &edge : edges) {
|
|
CheckVertexExists(*client, kTriggerDeletedEdgeLabel, edge.edge_id);
|
|
CheckVertexExists(*client, kTriggerDeletedObjectLabel, edge.edge_id);
|
|
}
|
|
|
|
DropOnDeleteTriggers(*client);
|
|
client->Execute("MATCH (n) DETACH DELETE n;");
|
|
client->DiscardAll();
|
|
}
|
|
};
|
|
constexpr bool kBeforeCommit = true;
|
|
constexpr bool kAfterCommit = false;
|
|
run_delete_trigger_tests(kBeforeCommit);
|
|
run_delete_trigger_tests(kAfterCommit);
|
|
|
|
return 0;
|
|
}
|