Skip to content

update rel cypher queries for migrated kind nodes #6433

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 12, 2025
Next Next commit
update rel cypher queries for migrated kind nodes
  • Loading branch information
ajtmccarty committed May 9, 2025
commit 2f591c0ac51f98317c123bb82add234810a4450d
110 changes: 59 additions & 51 deletions backend/infrahub/core/query/relationship.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,50 +205,18 @@ def get_relationship_properties_dict(self, status: RelationshipStatus) -> dict[s
rel_prop_dict["hierarchy"] = self.schema.hierarchical
return rel_prop_dict


class RelationshipCreateQuery(RelationshipQuery):
name = "relationship_create"

type: QueryType = QueryType.WRITE

def __init__(
self,
destination: Node = None,
destination_id: UUID | None = None,
**kwargs,
):
if not destination and not destination_id:
raise ValueError("Either destination or destination_id must be provided.")

super().__init__(destination=destination, destination_id=destination_id, **kwargs)

async def query_init(self, db: InfrahubDatabase, **kwargs) -> None: # noqa: ARG002
self.params["source_id"] = self.source_id
self.params["destination_id"] = self.destination_id
self.params["name"] = self.schema.identifier
self.params["branch_support"] = self.schema.branch.value

self.params["uuid"] = str(UUIDT())

self.params["branch"] = self.branch.name
self.params["branch_level"] = self.branch.hierarchy_level
self.params["at"] = self.at.to_string()

self.params["is_protected"] = self.rel.is_protected
self.params["is_visible"] = self.rel.is_visible

source_branch = self.source.get_branch_based_on_support_type()
def add_source_match_to_query(self, source_branch: Branch) -> None:
self.params["source_id"] = self.source_id or self.source.get_id()
if source_branch.is_global or source_branch.is_default:
source_query_match = """
MATCH (s:Node { uuid: $source_id })
WHERE NOT exists((s)-[:IS_PART_OF {status: "deleted", branch: $source_branch}]->(:Root))
"""
self.params["source_branch"] = source_branch.name
else:
source_filter, source_filter_params = source_branch.get_query_filter_path(
at=self.at, variable_name="r", params_prefix="src_"
)
source_query_match = """
source_filter, source_filter_params = source_branch.get_query_filter_path(
at=self.at, variable_name="r", params_prefix="src_"
)
source_query_match = """
MATCH (s:Node { uuid: $source_id })
CALL {
WITH s
Expand All @@ -260,10 +228,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None: # noqa: ARG
}
WITH s WHERE s_is_active = TRUE
""" % {"source_filter": source_filter}
self.params.update(source_filter_params)
self.params.update(source_filter_params)
self.add_to_query(source_query_match)

destination_branch = self.destination.get_branch_based_on_support_type()
def add_dest_match_to_query(self, destination_branch: Branch, destination_id: str) -> None:
self.params["destination_id"] = destination_id
if destination_branch.is_global or destination_branch.is_default:
destination_query_match = """
MATCH (d:Node { uuid: $destination_id })
Expand All @@ -289,6 +258,41 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None: # noqa: ARG
self.params.update(destination_filter_params)
self.add_to_query(destination_query_match)


class RelationshipCreateQuery(RelationshipQuery):
name = "relationship_create"

type: QueryType = QueryType.WRITE

def __init__(
self,
destination: Node = None,
destination_id: UUID | None = None,
**kwargs,
):
if not destination and not destination_id:
raise ValueError("Either destination or destination_id must be provided.")

super().__init__(destination=destination, destination_id=destination_id, **kwargs)

async def query_init(self, db: InfrahubDatabase, **kwargs) -> None: # noqa: ARG002
self.params["name"] = self.schema.identifier
self.params["branch_support"] = self.schema.branch.value

self.params["uuid"] = str(UUIDT())

self.params["branch"] = self.branch.name
self.params["branch_level"] = self.branch.hierarchy_level
self.params["at"] = self.at.to_string()

self.params["is_protected"] = self.rel.is_protected
self.params["is_visible"] = self.rel.is_visible

self.add_source_match_to_query(source_branch=self.source.get_branch_based_on_support_type())
self.add_dest_match_to_query(
destination_branch=self.destination.get_branch_based_on_support_type(),
destination_id=self.destination_id or self.destination.get_id(),
)
self.query_add_all_node_property_match()

self.params["rel_prop"] = self.get_relationship_properties_dict(status=RelationshipStatus.ACTIVE)
Expand Down Expand Up @@ -433,7 +437,6 @@ def __init__(

async def query_init(self, db: InfrahubDatabase, **kwargs) -> None: # noqa: ARG002
self.params["source_id"] = self.source_id
self.params["destination_id"] = self.data.peer_id
self.params["rel_node_id"] = self.data.rel_node_id
self.params["name"] = self.schema.identifier
self.params["branch"] = self.branch.name
Expand All @@ -443,9 +446,10 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None: # noqa: ARG
# -----------------------------------------------------------------------
# Match all nodes, including properties
# -----------------------------------------------------------------------

self.add_source_match_to_query(source_branch=self.source.get_branch_based_on_support_type())
self.add_dest_match_to_query(destination_branch=self.branch, destination_id=self.data.peer_id)
query = """
MATCH (s:Node { uuid: $source_id })
MATCH (d:Node { uuid: $destination_id })
MATCH (rl:Relationship { uuid: $rel_node_id })
"""
self.add_to_query(query)
Expand Down Expand Up @@ -497,8 +501,6 @@ def __init__(self, **kwargs):

async def query_init(self, db: InfrahubDatabase, **kwargs) -> None: # noqa: ARG002
rel_filter, rel_params = self.branch.get_query_filter_path(at=self.at, variable_name="edge")
self.params["source_id"] = self.source_id
self.params["destination_id"] = self.destination_id
self.params["rel_id"] = self.rel.id
self.params["branch"] = self.branch.name
self.params["rel_prop"] = self.get_relationship_properties_dict(status=RelationshipStatus.DELETED)
Expand All @@ -509,9 +511,14 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None: # noqa: ARG
r1 = f"{arrows.left.start}[r1:{self.rel_type} $rel_prop ]{arrows.left.end}"
r2 = f"{arrows.right.start}[r2:{self.rel_type} $rel_prop ]{arrows.right.end}"

self.add_source_match_to_query(source_branch=self.source.get_branch_based_on_support_type())
self.add_dest_match_to_query(
destination_branch=self.destination.get_branch_based_on_support_type(),
destination_id=self.destination_id or self.destination.get_id(),
)
query = """
MATCH (s:Node { uuid: $source_id })-[:IS_RELATED]-(rl:Relationship {uuid: $rel_id})-[:IS_RELATED]-(d:Node { uuid: $destination_id })
WITH s, rl, d
MATCH (s)-[:IS_RELATED]-(rl:Relationship {uuid: $rel_id})-[:IS_RELATED]-(d)
WITH DISTINCT s, rl, d
LIMIT 1
CREATE (s)%(r1)s(rl)
CREATE (rl)%(r2)s(d)
Expand Down Expand Up @@ -853,8 +860,6 @@ class RelationshipGetQuery(RelationshipQuery):
type: QueryType = QueryType.READ

async def query_init(self, db: InfrahubDatabase, **kwargs) -> None: # noqa: ARG002
self.params["source_id"] = self.source_id
self.params["destination_id"] = self.destination_id
self.params["name"] = self.schema.identifier
self.params["branch"] = self.branch.name

Expand All @@ -868,9 +873,12 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None: # noqa: ARG
r1 = f"{arrows.left.start}[r1:{self.rel.rel_type}]{arrows.left.end}"
r2 = f"{arrows.right.start}[r2:{self.rel.rel_type}]{arrows.right.end}"

self.add_source_match_to_query(source_branch=self.source.get_branch_based_on_support_type())
self.add_dest_match_to_query(
destination_branch=self.destination.get_branch_based_on_support_type(),
destination_id=self.destination_id or self.destination.get_id(),
)
query = """
MATCH (s:Node { uuid: $source_id })
MATCH (d:Node { uuid: $destination_id })
MATCH (s)%s(rl:Relationship { name: $name })%s(d)
WHERE %s
""" % (
Expand Down
2 changes: 1 addition & 1 deletion backend/infrahub/core/relationship/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ async def delete(self, db: InfrahubDatabase, at: Timestamp | None = None) -> Non
await update_relationships_to(rel_ids_to_update, to=delete_at, db=db)

delete_query = await RelationshipDeleteQuery.init(
db=db, rel=self, source_id=node.id, destination_id=peer.id, branch=branch, at=delete_at
db=db, rel=self, source=node, destination=peer, branch=branch, at=delete_at
)
await delete_query.execute(db=db)

Expand Down
Loading