diff --git a/backend/infrahub/core/migrations/graph/m012_convert_account_generic.py b/backend/infrahub/core/migrations/graph/m012_convert_account_generic.py index cc4dc61f14..616deb5a39 100644 --- a/backend/infrahub/core/migrations/graph/m012_convert_account_generic.py +++ b/backend/infrahub/core/migrations/graph/m012_convert_account_generic.py @@ -61,11 +61,18 @@ def __init__(self, **kwargs: Any): def render_match(self) -> str: query = """ // Find all the active nodes - MATCH (node:Node) - WHERE ( "Profile%(node_kind)s" IN LABELS(node) OR "%(node_kind)s" IN LABELS(node) ) - AND exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name })) - AND NOT exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $new_attr.name })) - + CALL { + MATCH (node:%(node_kind)s) + WHERE exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name })) + AND NOT exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $new_attr.name })) + RETURN node + UNION + MATCH (node:Profile%(node_kind)s) + WHERE exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name })) + AND NOT exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $new_attr.name })) + RETURN node + } + WITH node """ % {"node_kind": self.previous_attr.node_kind} return query diff --git a/backend/infrahub/core/migrations/query/attribute_rename.py b/backend/infrahub/core/migrations/query/attribute_rename.py index e712ad7482..efca8fffbb 100644 --- a/backend/infrahub/core/migrations/query/attribute_rename.py +++ b/backend/infrahub/core/migrations/query/attribute_rename.py @@ -38,9 +38,16 @@ def __init__( def render_match(self) -> str: query = """ // Find all the active nodes - MATCH (node:Node) - WHERE ( "Profile%(node_kind)s" IN LABELS(node) OR "%(node_kind)s" IN LABELS(node) ) - AND exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name })) + CALL { + MATCH (node:%(node_kind)s) + WHERE exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name })) + RETURN node + UNION + MATCH (node:Profile%(node_kind)s) + WHERE exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name })) + RETURN node + } + WITH node """ % {"node_kind": self.previous_attr.node_kind} return query diff --git a/backend/infrahub/core/migrations/schema/node_attribute_remove.py b/backend/infrahub/core/migrations/schema/node_attribute_remove.py index f73a79cffb..0e20cfdeae 100644 --- a/backend/infrahub/core/migrations/schema/node_attribute_remove.py +++ b/backend/infrahub/core/migrations/schema/node_attribute_remove.py @@ -59,8 +59,8 @@ def render_sub_query_per_rel_type(rel_type: str, rel_def: FieldInfo) -> str: query = """ // Find all the active nodes - MATCH (node:Node) - WHERE $node_kind IN LABELS(node) AND exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name })) + MATCH (node:%(node_kind)s) + WHERE exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name })) CALL { WITH node MATCH (root:Root)<-[r:IS_PART_OF]-(node) @@ -102,7 +102,11 @@ def render_sub_query_per_rel_type(rel_type: str, rel_def: FieldInfo) -> str: SET rb.to = $current_time ) RETURN DISTINCT active_attr - """ % {"branch_filter": branch_filter, "sub_query_all": sub_query_all} + """ % { + "branch_filter": branch_filter, + "sub_query_all": sub_query_all, + "node_kind": self.migration.new_schema.kind, + } self.add_to_query(query) diff --git a/backend/infrahub/core/migrations/schema/node_remove.py b/backend/infrahub/core/migrations/schema/node_remove.py index 5867806390..223ea08bbd 100644 --- a/backend/infrahub/core/migrations/schema/node_remove.py +++ b/backend/infrahub/core/migrations/schema/node_remove.py @@ -36,7 +36,6 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string()) self.params.update(branch_params) - self.params["node_kind"] = self.migration.previous_schema.kind self.params["current_time"] = self.at.to_string() self.params["branch_name"] = self.branch.name @@ -52,8 +51,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No # ruff: noqa: E501 query = """ // Find all the active nodes - MATCH (node:Node) - WHERE $node_kind IN LABELS(node) + MATCH (node:%(node_kind)s) CALL { WITH node MATCH (root:Root)<-[r:IS_PART_OF]-(node) @@ -66,7 +64,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No WHERE rb.status = "active" %(node_remove_query)s RETURN DISTINCT active_node - """ % {"branch_filter": branch_filter, "node_remove_query": node_remove_query} + """ % { + "branch_filter": branch_filter, + "node_remove_query": node_remove_query, + "node_kind": self.migration.previous_schema.kind, + } self.add_to_query(query) def get_nbr_migrations_executed(self) -> int: diff --git a/backend/infrahub/core/query/node.py b/backend/infrahub/core/query/node.py index 125864b06f..6f12a96fa7 100644 --- a/backend/infrahub/core/query/node.py +++ b/backend/infrahub/core/query/node.py @@ -792,7 +792,6 @@ def _get_tracked_variables(self) -> list[str]: async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: self.order_by = [] - self.params["node_kind"] = self.schema.kind self.return_labels = ["n.uuid", "rb.branch", f"{db.get_id_function_name()}(rb) as rb_id"] where_clause_elements = [] @@ -803,8 +802,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: self.params.update(branch_params) query = """ - MATCH p = (n:Node) - WHERE $node_kind IN LABELS(n) + MATCH (n:%(node_kind)s) CALL { WITH n MATCH (root:Root)<-[r:IS_PART_OF]-(n) @@ -815,7 +813,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: } WITH n, r as rb WHERE rb.status = "active" - """ % {"branch_filter": branch_filter} + """ % {"branch_filter": branch_filter, "node_kind": self.schema.kind} self.add_to_query(query) use_simple = False if self.filters and "id" in self.filters: diff --git a/backend/infrahub/core/utils.py b/backend/infrahub/core/utils.py index 239d542944..00743d7506 100644 --- a/backend/infrahub/core/utils.py +++ b/backend/infrahub/core/utils.py @@ -132,12 +132,10 @@ async def count_relationships(db: InfrahubDatabase, label: Optional[str] = None) async def get_nodes(db: InfrahubDatabase, label: str) -> list[Neo4jNode]: """Return theall nodes of a given label in the database.""" query = """ - MATCH (node) - WHERE $label IN LABELS(node) + MATCH (node:%(node_kind)s) RETURN node - """ - params: dict = {"label": label} - results = await db.execute_query(query=query, params=params, name="get_nodes") + """ % {"node_kind": label} + results = await db.execute_query(query=query, name="get_nodes") return [result[0] for result in results] diff --git a/backend/infrahub/core/validators/attribute/choices.py b/backend/infrahub/core/validators/attribute/choices.py index b269723aac..3f72c9617a 100644 --- a/backend/infrahub/core/validators/attribute/choices.py +++ b/backend/infrahub/core/validators/attribute/choices.py @@ -25,14 +25,12 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string()) self.params.update(branch_params) - self.params["node_kind"] = self.node_schema.kind self.params["attr_name"] = self.attribute_schema.name self.params["allowed_values"] = [choice.name for choice in self.attribute_schema.choices] self.params["null_value"] = NULL_VALUE query = """ - MATCH p = (n:Node) - WHERE $node_kind IN LABELS(n) + MATCH p = (n:%(node_kind)s) CALL { WITH n MATCH path = (root:Root)<-[rr:IS_PART_OF]-(n)-[ra:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name } )-[rv:HAS_VALUE]-(av:AttributeValue) @@ -50,7 +48,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No AND attribute_value IS NOT NULL AND attribute_value <> $null_value AND NOT (attribute_value IN $allowed_values) - """ % {"branch_filter": branch_filter} + """ % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind} self.add_to_query(query) self.return_labels = ["node.uuid", "attribute_value", "value_relationship"] diff --git a/backend/infrahub/core/validators/attribute/enum.py b/backend/infrahub/core/validators/attribute/enum.py index 139fba2c26..8736d2b2b3 100644 --- a/backend/infrahub/core/validators/attribute/enum.py +++ b/backend/infrahub/core/validators/attribute/enum.py @@ -25,13 +25,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string()) self.params.update(branch_params) - self.params["node_kind"] = self.node_schema.kind self.params["attr_name"] = self.attribute_schema.name self.params["allowed_values"] = self.attribute_schema.enum self.params["null_value"] = NULL_VALUE query = """ - MATCH p = (n:Node) - WHERE $node_kind IN LABELS(n) + MATCH (n:%(node_kind)s) CALL { WITH n MATCH path = (root:Root)<-[rr:IS_PART_OF]-(n)-[ra:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name } )-[rv:HAS_VALUE]-(av:AttributeValue) @@ -49,7 +47,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No AND attribute_value IS NOT NULL AND attribute_value <> $null_value AND NOT (attribute_value IN $allowed_values) - """ % {"branch_filter": branch_filter} + """ % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind} self.add_to_query(query) self.return_labels = ["node.uuid", "attribute_value", "value_relationship"] diff --git a/backend/infrahub/core/validators/attribute/kind.py b/backend/infrahub/core/validators/attribute/kind.py index d00bc2f22a..d12366ec6f 100644 --- a/backend/infrahub/core/validators/attribute/kind.py +++ b/backend/infrahub/core/validators/attribute/kind.py @@ -32,13 +32,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string()) self.params.update(branch_params) - self.params["node_kind"] = self.node_schema.kind self.params["attr_name"] = self.attribute_schema.name self.params["null_value"] = NULL_VALUE query = """ - MATCH p = (n:Node) - WHERE $node_kind IN LABELS(n) + MATCH p = (n:%(node_kind)s) CALL { WITH n MATCH path = (root:Root)<-[rr:IS_PART_OF]-(n)-[ra:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name } )-[rv:HAS_VALUE]-(av:AttributeValue) @@ -55,7 +53,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No WHERE all(r in relationships(full_path) WHERE r.status = "active") AND attribute_value IS NOT NULL AND attribute_value <> $null_value - """ % {"branch_filter": branch_filter} + """ % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind} self.add_to_query(query) self.return_labels = ["node.uuid", "attribute_value", "value_relationship.branch as value_branch"] diff --git a/backend/infrahub/core/validators/attribute/length.py b/backend/infrahub/core/validators/attribute/length.py index 822b0d4dd9..3b4526e4e6 100644 --- a/backend/infrahub/core/validators/attribute/length.py +++ b/backend/infrahub/core/validators/attribute/length.py @@ -22,14 +22,12 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string()) self.params.update(branch_params) - self.params["node_kind"] = self.node_schema.kind self.params["attr_name"] = self.attribute_schema.name self.params["min_length"] = self.attribute_schema.min_length self.params["max_length"] = self.attribute_schema.max_length query = """ - MATCH p = (n:Node) - WHERE $node_kind IN LABELS(n) + MATCH (n:%(node_kind)s) CALL { WITH n MATCH path = (root:Root)<-[rr:IS_PART_OF]-(n)-[ra:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name } )-[rv:HAS_VALUE]-(av:AttributeValue) @@ -48,7 +46,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No (toInteger($min_length) IS NOT NULL AND size(attribute_value) < toInteger($min_length)) OR (toInteger($max_length) IS NOT NULL AND size(attribute_value) > toInteger($max_length)) ) - """ % {"branch_filter": branch_filter} + """ % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind} self.add_to_query(query) self.return_labels = ["node.uuid", "value_relationship", "attribute_value"] diff --git a/backend/infrahub/core/validators/attribute/optional.py b/backend/infrahub/core/validators/attribute/optional.py index 03670a42c3..5c0c46461a 100644 --- a/backend/infrahub/core/validators/attribute/optional.py +++ b/backend/infrahub/core/validators/attribute/optional.py @@ -22,13 +22,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string()) self.params.update(branch_params) - self.params["node_kind"] = self.node_schema.kind self.params["attr_name"] = self.attribute_schema.name self.params["null_value"] = NULL_VALUE query = """ - MATCH p = (n:Node) - WHERE $node_kind IN LABELS(n) + MATCH (n:%(node_kind)s) CALL { WITH n MATCH path = (root:Root)<-[rr:IS_PART_OF]-(n)-[ra:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name } )-[rv:HAS_VALUE]-(av:AttributeValue) @@ -44,7 +42,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No WITH full_path, node, attribute_value, value_relationship WHERE all(r in relationships(full_path) WHERE r.status = "active") AND (attribute_value IS NULL OR attribute_value = $null_value) - """ % {"branch_filter": branch_filter} + """ % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind} self.add_to_query(query) self.return_labels = ["node.uuid", "value_relationship"] diff --git a/backend/infrahub/core/validators/attribute/regex.py b/backend/infrahub/core/validators/attribute/regex.py index 008409050b..282b158b35 100644 --- a/backend/infrahub/core/validators/attribute/regex.py +++ b/backend/infrahub/core/validators/attribute/regex.py @@ -22,13 +22,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string()) self.params.update(branch_params) - self.params["node_kind"] = self.node_schema.kind self.params["attr_name"] = self.attribute_schema.name self.params["attr_value_regex"] = self.attribute_schema.regex self.params["null_value"] = NULL_VALUE query = """ - MATCH p = (n:Node) - WHERE $node_kind IN LABELS(n) + MATCH p = (n:%(node_kind)s) CALL { WITH n MATCH path = (root:Root)<-[rr:IS_PART_OF]-(n)-[ra:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name } )-[rv:HAS_VALUE]-(av:AttributeValue) @@ -45,7 +43,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No WHERE all(r in relationships(full_path) WHERE r.status = "active") AND attribute_value <> $null_value AND NOT attribute_value =~ $attr_value_regex - """ % {"branch_filter": branch_filter} + """ % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind} self.add_to_query(query) self.return_labels = ["node.uuid", "attribute_value", "value_relationship"] diff --git a/backend/infrahub/core/validators/node/hierarchy.py b/backend/infrahub/core/validators/node/hierarchy.py index a95a7c8f66..1ced350a97 100644 --- a/backend/infrahub/core/validators/node/hierarchy.py +++ b/backend/infrahub/core/validators/node/hierarchy.py @@ -52,7 +52,6 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string(), is_isolated=False) self.params.update(branch_params) - self.params["node_kind"] = self.node_schema.kind if hierarchy := getattr(self.node_schema, "hierarchy", None): self.params["hierarchy_kind"] = hierarchy else: @@ -61,8 +60,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No # ruff: noqa: E501 query = """ - MATCH (n:Node) - WHERE $node_kind IN LABELS(n) + MATCH (n:%(node_kind)s) CALL { WITH n MATCH path = (root:Root)<-[rroot:IS_PART_OF]-(n) @@ -117,7 +115,12 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No any(r in relationships(current_path) WHERE r.hierarchy <> $hierarchy_kind) OR NOT ($peer_kind IN labels(current_peer)) ) - """ % {"branch_filter": branch_filter, "to_children": to_children, "to_parent": to_parent} + """ % { + "branch_filter": branch_filter, + "to_children": to_children, + "to_parent": to_parent, + "node_kind": self.node_schema.kind, + } self.add_to_query(query) self.return_labels = ["start_node.uuid", "branch_name", "current_peer.uuid"] diff --git a/backend/infrahub/core/validators/relationship/optional.py b/backend/infrahub/core/validators/relationship/optional.py index 24dacb50a6..2b9c438e9f 100644 --- a/backend/infrahub/core/validators/relationship/optional.py +++ b/backend/infrahub/core/validators/relationship/optional.py @@ -24,14 +24,12 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string(), is_isolated=False) self.params.update(branch_params) - self.params["node_kind"] = self.node_schema.kind self.params["relationship_id"] = self.relationship_schema.identifier query = """ // Query all Active Nodes of type // and store their UUID in uuids_active_node - MATCH (n:Node) - WHERE $node_kind IN LABELS(n) + MATCH (n:%(node_kind)s) CALL { WITH n MATCH (root:Root)<-[r:IS_PART_OF]-(n) @@ -45,8 +43,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No WITH COLLECT(active_node.uuid) AS uuids_active_node // identifier all nodes with at least one active member for this relationship // and store their UUID in uuids_with_rel - MATCH (n:Node) - WHERE $node_kind IN LABELS(n) + MATCH (n:%(node_kind)s) CALL { WITH n, uuids_active_node MATCH path = (n)-[r:IS_RELATED]-(:Relationship { name: $relationship_id }) @@ -58,12 +55,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No WITH n1 as node_with_rel, r1 as r, uuids_active_node WHERE r.status = "active" WITH COLLECT(node_with_rel.uuid) AS uuids_with_rel, uuids_active_node - MATCH (n:Node)-[r:IS_PART_OF]->(:Root) - WHERE $node_kind IN LABELS(n) - AND n.uuid IN uuids_active_node + MATCH (n:%(node_kind)s)-[r:IS_PART_OF]->(:Root) + WHERE n.uuid IN uuids_active_node AND not n.uuid IN uuids_with_rel AND NOT exists((n)-[:IS_RELATED]-(:Relationship { name: $relationship_id })) - """ % {"branch_filter": branch_filter} + """ % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind} self.add_to_query(query) self.return_labels = ["n.uuid", "r as root_relationship"] diff --git a/backend/infrahub/core/validators/relationship/peer.py b/backend/infrahub/core/validators/relationship/peer.py index 7ff63d069f..c21d388de0 100644 --- a/backend/infrahub/core/validators/relationship/peer.py +++ b/backend/infrahub/core/validators/relationship/peer.py @@ -30,14 +30,12 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string(), is_isolated=False) self.params.update(branch_params) - self.params["node_kind"] = self.node_schema.kind self.params["relationship_id"] = self.relationship_schema.identifier self.params["allowed_peer_kinds"] = allowed_peer_kinds # ruff: noqa: E501 query = """ - MATCH (n:Node) - WHERE $node_kind IN LABELS(n) + MATCH (n:%(node_kind)s) CALL { WITH n MATCH path = (root:Root)<-[rroot:IS_PART_OF]-(n) @@ -85,7 +83,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No WITH start_node, current_peer, branch_name, current_path WHERE all(r in relationships(current_path) WHERE r.status = "active") AND NOT any(label IN LABELS(current_peer) WHERE label IN $allowed_peer_kinds) - """ % {"branch_filter": branch_filter} + """ % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind} self.add_to_query(query) self.return_labels = ["start_node.uuid", "branch_name", "current_peer.uuid"]