Skip to content

Commit

Permalink
Improve computation of branch on which create the deleted edge
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasG0 committed Feb 17, 2025
1 parent 29424c6 commit 55db64d
Showing 1 changed file with 67 additions and 79 deletions.
146 changes: 67 additions & 79 deletions backend/infrahub/core/migrations/graph/m019_restore_rels_to_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
"""

query = """
MATCH (node:Node)-[global_edge:IS_RELATED {branch: $global_branch}]-(rel:Relationship)
WHERE rel.branch_support=$branch_aware
MATCH (node:Node)-[global_edge:IS_RELATED {branch: "-global-"}]-(rel:Relationship)
WHERE rel.branch_support="aware"
MATCH (rel)-[non_global_edge:IS_RELATED]-(node_2: Node)
WHERE non_global_edge.branch <> $global_branch
WHERE non_global_edge.branch <> "-global-"
SET global_edge.branch = non_global_edge.branch
"""

Expand Down Expand Up @@ -63,8 +63,6 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
SET active_edge.to = deleted_edge.from
"""

params = {"global_branch": GLOBAL_BRANCH_NAME}
self.params.update(params)
self.add_to_query(query)


Expand Down Expand Up @@ -103,8 +101,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
// Get distinct rel nodes linked to a deleted node, with the time at which we should delete rel edges.
// Take the MAX time so if it does not take the deleted time of a node deleted through a duplication migration.
WITH DISTINCT rel, deleted_edge.branch AS deleted_edge_branch,
deleted_edge.branch_level AS branch_level, MAX(deleted_edge.from) as deleted_time
WITH DISTINCT rel,
deleted_edge.branch AS deleted_edge_branch,
deleted_edge.branch_level AS branch_level,
MAX(deleted_edge.from) as deleted_time,
deleted_node.branch_support as deleted_node_branch_support
// No need to check deleted edge branch because
Expand All @@ -121,19 +122,20 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
WITH DISTINCT
CASE
// Branch on which `deleted` edge should be created depends on rel.branch_support.
WHEN rel.branch_support = $branch_agnostic THEN [$global_branch]
WHEN rel.branch_aware = $branch_aware THEN
WHEN rel.branch_support = "agnostic" THEN ["-global-"]
WHEN rel.branch_support = "aware" THEN
CASE
WHEN deleted_node.branch_support = $branch_aware AND exists((rel)-[{status: "active", branch: deleted_edge_branch}]-(peer_2))
WHEN deleted_node_branch_support = "aware" AND exists((rel)-[{status: "active", branch: deleted_edge_branch}]-(peer_2))
THEN [deleted_edge_branch]
WHEN deleted_node.branch_support = $branch_agnostic
WHEN deleted_node_branch_support = "agnostic"
THEN COLLECT {
WITH rel
MATCH (rel)-[active_edge {status: "active"}]-(peer_2)
RETURN DISTINCT active_edge.branch
} as branches
ELSE [] // deleted_node.branch_support = -local-, TODO what to do?
ELSE [] // rel.branch_support = -local-, TODO what to do?
}
ELSE [] // deleted_node.branch_support = -local-
END
ELSE [] // rel.branch_support = -local-
END AS branches,
branch_level,
deleted_time,
Expand All @@ -146,79 +148,65 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
// Below CALL subqueries are called once for each rel-peer_2 pair for which we want to create a deleted edge.
// Note that with current infrahub relationships edges design, only one of this CALL should be matched per pair.
CALL {
WITH rel, peer_2, branch, branch_level, deleted_time
MATCH (rel)-[:IS_RELATED]->(peer_2)
MERGE (rel)-[:IS_RELATED {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
}
CALL {
WITH rel, peer_2, branch, branch_level, deleted_time
MATCH (rel)-[:IS_PROTECTED]->(peer_2)
MERGE (rel)-[:IS_PROTECTED {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
}
CALL {
WITH rel, peer_2, branch, branch_level, deleted_time
MATCH (rel)-[:IS_VISIBLE]->(peer_2)
MERGE (rel)-[:IS_VISIBLE {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
}
CALL {
WITH rel, peer_2, branch, branch_level, deleted_time
MATCH (rel)-[:HAS_OWNER]->(peer_2)
MERGE (rel)-[:HAS_OWNER {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
}
CALL {
WITH rel, peer_2, branch, branch_level, deleted_time
MATCH (rel)-[:HAS_SOURCE]->(peer_2)
MERGE (rel)-[:HAS_SOURCE {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
}
CALL {
WITH rel, peer_2, branch, branch_level, deleted_time
MATCH (rel)-[e]->(peer_2)
MERGE (rel)-[:type(e) {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
MATCH (rel)<-[:IS_RELATED]-(peer_2)
MERGE (rel)<-[:IS_RELATED {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
}
CALL {
WITH rel, peer_2, branch, branch_level, deleted_time
MATCH (rel)-[e]->(peer_2)
MERGE (rel)-[:type(e) {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
MATCH (rel)<-[:IS_PROTECTED]-(peer_2)
MERGE (rel)<-[:IS_PROTECTED {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
}
CALL {
WITH rel, peer_2, branch, branch_level, deleted_time
MATCH (rel)<-[:IS_VISIBLE]-(peer_2)
MERGE (rel)<-[:IS_VISIBLE {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
}
# CALL {
# WITH rel, peer_2, branch, branch_level, deleted_time
# MATCH (rel)-[:IS_RELATED]->(peer_2)
# MERGE (rel)-[:IS_RELATED {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
# }
#
# CALL {
# WITH rel, peer_2, branch, branch_level, deleted_time
# MATCH (rel)-[:IS_PROTECTED]->(peer_2)
# MERGE (rel)-[:IS_PROTECTED {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
# }
#
# CALL {
# WITH rel, peer_2, branch, branch_level, deleted_time
# MATCH (rel)-[:IS_VISIBLE]->(peer_2)
# MERGE (rel)-[:IS_VISIBLE {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
# }
#
# CALL {
# WITH rel, peer_2, branch, branch_level, deleted_time
# MATCH (rel)<-[:IS_RELATED]-(peer_2)
# MERGE (rel)<-[:IS_RELATED {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
# }
#
# CALL {
# WITH rel, peer_2, branch, branch_level, deleted_time
# MATCH (rel)<-[:IS_PROTECTED]-(peer_2)
# MERGE (rel)<-[:IS_PROTECTED {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
# }
#
# CALL {
# WITH rel, peer_2, branch, branch_level, deleted_time
# MATCH (rel)<-[:IS_VISIBLE]-(peer_2)
# MERGE (rel)<-[:IS_VISIBLE {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
# }
#
# CALL {
# WITH rel, peer_2, branch, branch_level, deleted_time
# MATCH (rel)<-[:HAS_OWNER]-(peer_2)
# MERGE (rel)<-[:HAS_OWNER {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
# }
#
# CALL {
# WITH rel, peer_2, branch, branch_level, deleted_time
# MATCH (rel)<-[:HAS_SOURCE]-(peer_2)
# MERGE (rel)<-[:HAS_SOURCE {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
# }
#
# CALL {
# WITH rel, peer_2, branch, branch_level, deleted_time
# MATCH (rel)-[:HAS_OWNER]->(peer_2)
# MERGE (rel)-[:HAS_OWNER {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
# }
#
# CALL {
# WITH rel, peer_2, branch, branch_level, deleted_time
# MATCH (rel)<-[:HAS_SOURCE]->(peer_2)
# MERGE (rel)<-[:HAS_SOURCE {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]->(peer_2)
# }
CALL {
WITH rel, peer_2, branch, branch_level, deleted_time
MATCH (rel)<-[:HAS_OWNER]-(peer_2)
MERGE (rel)<-[:HAS_OWNER {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
}
CALL {
WITH rel, peer_2, branch, branch_level, deleted_time
MATCH (rel)<-[:HAS_SOURCE]-(peer_2)
MERGE (rel)<-[:HAS_SOURCE {status: "deleted", branch: branch, branch_level: branch_level, from: deleted_time}]-(peer_2)
}
"""

params = {
Expand All @@ -236,8 +224,8 @@ class Migration019(GraphMigration):
Fix corrupted state introduced by Migration012 when duplicating a CoreAccount (branch Aware)
being part of a CoreStandardGroup (branch Agnostic). Database is corrupted at multiple points:
- Old CoreAccount node <> group_member node `active` edge has no `to` time (possibly because of #5590).
- Old CoreAccount node <> group_member node `deleted` edge is on `$global_branch` branch instead of `main`.
- New CoreAccount node <> group_member node `active` edge is on `$global_branch` branch instead of `main`.
- Old CoreAccount node <> group_member node `deleted` edge is on `"-global-"` branch instead of `main`.
- New CoreAccount node <> group_member node `active` edge is on `"-global-"` branch instead of `main`.
Also, users having deleted corresponding CoreStandardGroup will also have the following data corruption,
as deletion did not happen correctly due to above issues:
Expand Down

0 comments on commit 55db64d

Please sign in to comment.