From e12bd9b68173b04c96cc46965b08122ed98eb57f Mon Sep 17 00:00:00 2001 From: Aaron McCarty Date: Tue, 24 Sep 2024 16:26:40 -0700 Subject: [PATCH] fix save query for memgraph --- .../infrahub/core/diff/query/save_query.py | 142 ++++++++++-------- .../unit/core/diff/test_conflicts_enricher.py | 2 + 2 files changed, 81 insertions(+), 63 deletions(-) diff --git a/backend/infrahub/core/diff/query/save_query.py b/backend/infrahub/core/diff/query/save_query.py index 5c1c7060e0..1b6b9439fb 100644 --- a/backend/infrahub/core/diff/query/save_query.py +++ b/backend/infrahub/core/diff/query/save_query.py @@ -28,6 +28,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # ruff: noqa: E501 query = """ UNWIND [$base_branch_diff, $diff_branch_diff] AS diff_root_map + WITH diff_root_map CALL { WITH diff_root_map MERGE (diff_root:DiffRoot { @@ -42,81 +43,96 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: num_conflicts: diff_root_map.diff_root_props.num_conflicts, contains_conflict: diff_root_map.diff_root_props.contains_conflict }) + + SET diff_root.tracking_id = diff_root_map.diff_root_props.tracking_id WITH diff_root, diff_root_map - UNWIND diff_root_map.node_maps AS node_map - CREATE (diff_root)-[:DIFF_HAS_NODE]->(diff_node:DiffNode) - SET diff_node = node_map.node_properties - // node conflict - FOREACH (i in CASE WHEN node_map.conflict_params IS NOT NULL THEN [1] ELSE [] END | - CREATE (diff_node)-[:DIFF_HAS_CONFLICT]->(diff_node_conflict:DiffConflict) - SET diff_node_conflict = node_map.conflict_params - ) - - // attributes - WITH diff_root, diff_root_map, diff_node, node_map CALL { - WITH diff_node, node_map - UNWIND node_map.attributes AS node_attribute - CREATE (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(diff_attribute:DiffAttribute) - SET diff_attribute = node_attribute.node_properties - - // node attribute properties - WITH diff_attribute, node_attribute - UNWIND node_attribute.properties AS attr_property - CREATE (diff_attribute)-[:DIFF_HAS_PROPERTY]->(diff_attr_prop:DiffProperty) - SET diff_attr_prop = attr_property.node_properties - // attribute property conflict - FOREACH (i in CASE WHEN attr_property.conflict_params IS NOT NULL THEN [1] ELSE [] END | - CREATE (diff_attr_prop)-[:DIFF_HAS_CONFLICT]->(diff_attribute_property_conflict:DiffConflict) - SET diff_attribute_property_conflict = attr_property.conflict_params + WITH diff_root, diff_root_map + UNWIND diff_root_map.node_maps AS node_map + CREATE (diff_root)-[:DIFF_HAS_NODE]->(diff_node:DiffNode) + SET diff_node = node_map.node_properties + // node conflict + FOREACH (i in CASE WHEN node_map.conflict_params IS NOT NULL THEN [1] ELSE [] END | + CREATE (diff_node)-[:DIFF_HAS_CONFLICT]->(diff_node_conflict:DiffConflict) + SET diff_node_conflict = node_map.conflict_params ) - } - // relationships - WITH diff_root, diff_root_map, diff_node, node_map - CALL { - WITH diff_node, node_map - UNWIND node_map.relationships as node_relationship - CREATE (diff_node)-[:DIFF_HAS_RELATIONSHIP]->(diff_relationship:DiffRelationship) - SET diff_relationship = node_relationship.node_properties + // attributes + WITH diff_root, diff_root_map, diff_node, node_map + CALL { + WITH diff_node, node_map + UNWIND node_map.attributes AS node_attribute + CREATE (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(diff_attribute:DiffAttribute) + SET diff_attribute = node_attribute.node_properties - // node single relationships - WITH diff_relationship, node_relationship - UNWIND node_relationship.relationships as node_single_relationship - CREATE (diff_relationship)-[:DIFF_HAS_ELEMENT]->(diff_relationship_element:DiffRelationshipElement) - SET diff_relationship_element = node_single_relationship.node_properties - // single relationship conflict - FOREACH (i in CASE WHEN node_single_relationship.conflict_params IS NOT NULL THEN [1] ELSE [] END | - CREATE (diff_relationship_element)-[:DIFF_HAS_CONFLICT]->(diff_relationship_conflict:DiffConflict) - SET diff_relationship_conflict = node_single_relationship.conflict_params - ) + // node attribute properties + WITH diff_attribute, node_attribute + UNWIND node_attribute.properties AS attr_property + CREATE (diff_attribute)-[:DIFF_HAS_PROPERTY]->(diff_attr_prop:DiffProperty) + SET diff_attr_prop = attr_property.node_properties + // attribute property conflict + FOREACH (i in CASE WHEN attr_property.conflict_params IS NOT NULL THEN [1] ELSE [] END | + CREATE (diff_attr_prop)-[:DIFF_HAS_CONFLICT]->(diff_attribute_property_conflict:DiffConflict) + SET diff_attribute_property_conflict = attr_property.conflict_params + ) + } - // node relationship properties - WITH diff_relationship_element, node_single_relationship - UNWIND node_single_relationship.properties as node_relationship_property - CREATE (diff_relationship_element)-[:DIFF_HAS_PROPERTY]->(diff_relationship_property:DiffProperty) - SET diff_relationship_property = node_relationship_property.node_properties - // relationship property conflict - FOREACH (i in CASE WHEN node_relationship_property.conflict_params IS NOT NULL THEN [1] ELSE [] END | - CREATE (diff_relationship_property)-[:DIFF_HAS_CONFLICT]->(diff_relationship_property_conflict:DiffConflict) - SET diff_relationship_property_conflict = node_relationship_property.conflict_params - ) + // relationships + WITH diff_root, diff_root_map, diff_node, node_map + CALL { + WITH diff_node, node_map + UNWIND node_map.relationships as node_relationship + CREATE (diff_node)-[:DIFF_HAS_RELATIONSHIP]->(diff_relationship:DiffRelationship) + SET diff_relationship = node_relationship.node_properties + + // node single relationships + WITH diff_relationship, node_relationship + UNWIND node_relationship.relationships as node_single_relationship + CREATE (diff_relationship)-[:DIFF_HAS_ELEMENT]->(diff_relationship_element:DiffRelationshipElement) + SET diff_relationship_element = node_single_relationship.node_properties + // single relationship conflict + FOREACH (i in CASE WHEN node_single_relationship.conflict_params IS NOT NULL THEN [1] ELSE [] END | + CREATE (diff_relationship_element)-[:DIFF_HAS_CONFLICT]->(diff_relationship_conflict:DiffConflict) + SET diff_relationship_conflict = node_single_relationship.conflict_params + ) + + // node relationship properties + WITH diff_relationship_element, node_single_relationship + UNWIND node_single_relationship.properties as node_relationship_property + CREATE (diff_relationship_element)-[:DIFF_HAS_PROPERTY]->(diff_relationship_property:DiffProperty) + SET diff_relationship_property = node_relationship_property.node_properties + // relationship property conflict + FOREACH (i in CASE WHEN node_relationship_property.conflict_params IS NOT NULL THEN [1] ELSE [] END | + CREATE (diff_relationship_property)-[:DIFF_HAS_CONFLICT]->(diff_relationship_property_conflict:DiffConflict) + SET diff_relationship_property_conflict = node_relationship_property.conflict_params + ) + } } + WITH diff_root, diff_root_map - UNWIND diff_root_map.node_parent_links AS node_parent_link CALL { - WITH diff_root, node_parent_link - MATCH (diff_root)-[:DIFF_HAS_NODE]->(parent_node:DiffNode {uuid: node_parent_link.parent_uuid})-[:DIFF_HAS_RELATIONSHIP]->(diff_rel_group:DiffRelationship {name: node_parent_link.relationship_name}) - MATCH (diff_root)-[:DIFF_HAS_NODE]->(child_node:DiffNode {uuid: node_parent_link.child_uuid}) - MERGE (diff_rel_group)-[:DIFF_HAS_NODE]->(child_node) + WITH diff_root, diff_root_map + UNWIND diff_root_map.node_parent_links AS node_parent_link + CALL { + WITH diff_root, node_parent_link + MATCH (diff_root)-[:DIFF_HAS_NODE]->(parent_node:DiffNode {uuid: node_parent_link.parent_uuid})-[:DIFF_HAS_RELATIONSHIP]->(diff_rel_group:DiffRelationship {name: node_parent_link.relationship_name}) + MATCH (diff_root)-[:DIFF_HAS_NODE]->(child_node:DiffNode {uuid: node_parent_link.child_uuid}) + MERGE (diff_rel_group)-[:DIFF_HAS_NODE]->(child_node) + } } + RETURN diff_root + } + + WITH DISTINCT diff_root AS diff_root + WITH collect(diff_root) AS diff_roots + CALL { + WITH diff_roots + WITH diff_roots[0] AS base_diff_node, diff_roots[1] AS branch_diff_node + MERGE (base_diff_node)-[:DIFF_HAS_PARTNER]-(branch_diff_node) + SET (base_diff_node).partner_uuid = (branch_diff_node).uuid + SET (branch_diff_node).partner_uuid = (base_diff_node).uuid } - MATCH (base_diff_node {uuid: $base_branch_diff.diff_root_props.uuid}) - MATCH (branch_diff_node {uuid: $diff_branch_diff.diff_root_props.uuid}) - MERGE (base_diff_node)-[:DIFF_HAS_PARTNER]-(branch_diff_node) - SET (base_diff_node).partner_uuid = (branch_diff_node).uuid - SET (branch_diff_node).partner_uuid = (base_diff_node).uuid """ self.add_to_query(query=query) diff --git a/backend/tests/unit/core/diff/test_conflicts_enricher.py b/backend/tests/unit/core/diff/test_conflicts_enricher.py index 0599d89bba..5eadf9f67b 100644 --- a/backend/tests/unit/core/diff/test_conflicts_enricher.py +++ b/backend/tests/unit/core/diff/test_conflicts_enricher.py @@ -208,6 +208,7 @@ async def test_cardinality_one_conflicts(self, db: InfrahubDatabase, car_person_ peer_id=new_base_peer_id, properties=base_properties, action=DiffAction.UPDATED ) }, + cardinality=RelationshipCardinality.ONE, ) } base_nodes = { @@ -235,6 +236,7 @@ async def test_cardinality_one_conflicts(self, db: InfrahubDatabase, car_person_ peer_id=previous_peer_id, properties=branch_properties, action=DiffAction.REMOVED ) }, + cardinality=RelationshipCardinality.ONE, ) } branch_nodes = {