infrahub-server 1.2.11__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- infrahub/actions/constants.py +130 -0
- infrahub/actions/gather.py +114 -0
- infrahub/actions/models.py +243 -0
- infrahub/actions/parsers.py +104 -0
- infrahub/actions/schema.py +393 -0
- infrahub/actions/tasks.py +119 -0
- infrahub/actions/triggers.py +21 -0
- infrahub/branch/__init__.py +0 -0
- infrahub/branch/tasks.py +29 -0
- infrahub/branch/triggers.py +22 -0
- infrahub/cli/db.py +3 -4
- infrahub/computed_attribute/gather.py +3 -1
- infrahub/computed_attribute/tasks.py +23 -29
- infrahub/core/account.py +24 -47
- infrahub/core/attribute.py +13 -15
- infrahub/core/constants/__init__.py +10 -0
- infrahub/core/constants/database.py +1 -0
- infrahub/core/constants/infrahubkind.py +9 -0
- infrahub/core/constraint/node/runner.py +3 -1
- infrahub/core/convert_object_type/__init__.py +0 -0
- infrahub/core/convert_object_type/conversion.py +124 -0
- infrahub/core/convert_object_type/schema_mapping.py +56 -0
- infrahub/core/diff/coordinator.py +8 -1
- infrahub/core/diff/query/all_conflicts.py +1 -5
- infrahub/core/diff/query/artifact.py +10 -20
- infrahub/core/diff/query/delete_query.py +8 -4
- infrahub/core/diff/query/diff_get.py +3 -6
- infrahub/core/diff/query/field_specifiers.py +1 -1
- infrahub/core/diff/query/field_summary.py +2 -4
- infrahub/core/diff/query/merge.py +72 -125
- infrahub/core/diff/query/save.py +83 -68
- infrahub/core/diff/query/summary_counts_enricher.py +34 -54
- infrahub/core/diff/query/time_range_query.py +0 -1
- infrahub/core/diff/repository/repository.py +4 -0
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/manager.py +14 -11
- infrahub/core/migrations/graph/__init__.py +6 -0
- infrahub/core/migrations/graph/m003_relationship_parent_optional.py +1 -2
- infrahub/core/migrations/graph/m012_convert_account_generic.py +1 -1
- infrahub/core/migrations/graph/m013_convert_git_password_credential.py +2 -6
- infrahub/core/migrations/graph/m015_diff_format_update.py +1 -2
- infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -2
- infrahub/core/migrations/graph/m019_restore_rels_to_time.py +11 -22
- infrahub/core/migrations/graph/m020_duplicate_edges.py +3 -6
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +1 -2
- infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +2 -2
- infrahub/core/migrations/graph/m024_missing_hierarchy_backfill.py +1 -2
- infrahub/core/migrations/graph/m028_delete_diffs.py +1 -2
- infrahub/core/migrations/graph/m029_duplicates_cleanup.py +662 -0
- infrahub/core/migrations/graph/m030_illegal_edges.py +82 -0
- infrahub/core/migrations/query/attribute_add.py +14 -11
- infrahub/core/migrations/query/attribute_rename.py +6 -11
- infrahub/core/migrations/query/delete_element_in_schema.py +19 -17
- infrahub/core/migrations/query/node_duplicate.py +19 -21
- infrahub/core/migrations/query/relationship_duplicate.py +19 -18
- infrahub/core/migrations/schema/node_attribute_remove.py +4 -8
- infrahub/core/migrations/schema/node_remove.py +19 -20
- infrahub/core/models.py +29 -2
- infrahub/core/node/__init__.py +131 -28
- infrahub/core/node/base.py +1 -1
- infrahub/core/node/create.py +211 -0
- infrahub/core/node/resource_manager/number_pool.py +31 -5
- infrahub/core/node/standard.py +6 -1
- infrahub/core/path.py +15 -1
- infrahub/core/protocols.py +57 -0
- infrahub/core/protocols_base.py +3 -0
- infrahub/core/query/__init__.py +2 -2
- infrahub/core/query/delete.py +3 -3
- infrahub/core/query/diff.py +19 -32
- infrahub/core/query/ipam.py +10 -20
- infrahub/core/query/node.py +29 -47
- infrahub/core/query/relationship.py +55 -34
- infrahub/core/query/resource_manager.py +1 -2
- infrahub/core/query/standard_node.py +19 -5
- infrahub/core/query/subquery.py +2 -4
- infrahub/core/relationship/constraints/count.py +10 -9
- infrahub/core/relationship/constraints/interface.py +2 -1
- infrahub/core/relationship/constraints/peer_kind.py +2 -1
- infrahub/core/relationship/constraints/peer_parent.py +56 -0
- infrahub/core/relationship/constraints/peer_relatives.py +72 -0
- infrahub/core/relationship/constraints/profiles_kind.py +1 -1
- infrahub/core/relationship/model.py +4 -1
- infrahub/core/schema/__init__.py +2 -1
- infrahub/core/schema/attribute_parameters.py +160 -0
- infrahub/core/schema/attribute_schema.py +130 -7
- infrahub/core/schema/basenode_schema.py +27 -3
- infrahub/core/schema/definitions/core/__init__.py +29 -1
- infrahub/core/schema/definitions/core/group.py +45 -0
- infrahub/core/schema/definitions/core/resource_pool.py +9 -0
- infrahub/core/schema/definitions/internal.py +43 -5
- infrahub/core/schema/generated/attribute_schema.py +16 -3
- infrahub/core/schema/generated/relationship_schema.py +11 -1
- infrahub/core/schema/manager.py +7 -2
- infrahub/core/schema/schema_branch.py +109 -12
- infrahub/core/validators/__init__.py +15 -2
- infrahub/core/validators/attribute/choices.py +1 -3
- infrahub/core/validators/attribute/enum.py +1 -3
- infrahub/core/validators/attribute/kind.py +1 -3
- infrahub/core/validators/attribute/length.py +13 -7
- infrahub/core/validators/attribute/min_max.py +118 -0
- infrahub/core/validators/attribute/number_pool.py +106 -0
- infrahub/core/validators/attribute/optional.py +1 -4
- infrahub/core/validators/attribute/regex.py +5 -6
- infrahub/core/validators/attribute/unique.py +1 -3
- infrahub/core/validators/determiner.py +18 -2
- infrahub/core/validators/enum.py +12 -0
- infrahub/core/validators/node/hierarchy.py +3 -6
- infrahub/core/validators/query.py +1 -3
- infrahub/core/validators/relationship/count.py +6 -12
- infrahub/core/validators/relationship/optional.py +2 -4
- infrahub/core/validators/relationship/peer.py +177 -12
- infrahub/core/validators/tasks.py +1 -1
- infrahub/core/validators/uniqueness/query.py +5 -9
- infrahub/database/__init__.py +12 -4
- infrahub/database/validation.py +100 -0
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +4 -0
- infrahub/dependencies/builder/constraint/relationship_manager/peer_parent.py +8 -0
- infrahub/dependencies/builder/constraint/relationship_manager/peer_relatives.py +8 -0
- infrahub/dependencies/builder/constraint/schema/aggregated.py +2 -0
- infrahub/dependencies/builder/constraint/schema/relationship_peer.py +8 -0
- infrahub/dependencies/builder/diff/deserializer.py +1 -1
- infrahub/dependencies/registry.py +4 -0
- infrahub/events/group_action.py +1 -0
- infrahub/events/models.py +1 -1
- infrahub/git/base.py +5 -3
- infrahub/git/integrator.py +96 -5
- infrahub/git/tasks.py +1 -0
- infrahub/graphql/analyzer.py +139 -18
- infrahub/graphql/manager.py +4 -0
- infrahub/graphql/mutations/action.py +164 -0
- infrahub/graphql/mutations/convert_object_type.py +71 -0
- infrahub/graphql/mutations/main.py +25 -176
- infrahub/graphql/mutations/proposed_change.py +20 -17
- infrahub/graphql/mutations/relationship.py +32 -0
- infrahub/graphql/mutations/resource_manager.py +63 -7
- infrahub/graphql/queries/convert_object_type_mapping.py +34 -0
- infrahub/graphql/queries/resource_manager.py +7 -1
- infrahub/graphql/resolvers/many_relationship.py +1 -1
- infrahub/graphql/resolvers/resolver.py +2 -2
- infrahub/graphql/resolvers/single_relationship.py +1 -1
- infrahub/graphql/schema.py +6 -0
- infrahub/menu/menu.py +34 -2
- infrahub/message_bus/messages/__init__.py +0 -10
- infrahub/message_bus/operations/__init__.py +0 -8
- infrahub/message_bus/operations/refresh/registry.py +4 -7
- infrahub/patch/queries/delete_duplicated_edges.py +45 -39
- infrahub/pools/models.py +14 -0
- infrahub/pools/number.py +5 -3
- infrahub/pools/registration.py +22 -0
- infrahub/pools/tasks.py +126 -0
- infrahub/prefect_server/models.py +1 -19
- infrahub/proposed_change/models.py +68 -3
- infrahub/proposed_change/tasks.py +911 -34
- infrahub/schema/__init__.py +0 -0
- infrahub/schema/tasks.py +27 -0
- infrahub/schema/triggers.py +23 -0
- infrahub/task_manager/models.py +10 -6
- infrahub/trigger/catalogue.py +6 -0
- infrahub/trigger/models.py +23 -6
- infrahub/trigger/setup.py +26 -2
- infrahub/trigger/tasks.py +4 -2
- infrahub/types.py +6 -0
- infrahub/webhook/tasks.py +6 -9
- infrahub/workflows/catalogue.py +103 -1
- infrahub_sdk/client.py +43 -10
- infrahub_sdk/ctl/generator.py +4 -4
- infrahub_sdk/ctl/repository.py +1 -1
- infrahub_sdk/node/__init__.py +39 -0
- infrahub_sdk/node/attribute.py +122 -0
- infrahub_sdk/node/constants.py +21 -0
- infrahub_sdk/{node.py → node/node.py} +158 -803
- infrahub_sdk/node/parsers.py +15 -0
- infrahub_sdk/node/property.py +24 -0
- infrahub_sdk/node/related_node.py +266 -0
- infrahub_sdk/node/relationship.py +302 -0
- infrahub_sdk/protocols.py +112 -0
- infrahub_sdk/protocols_base.py +34 -2
- infrahub_sdk/pytest_plugin/items/python_transform.py +2 -1
- infrahub_sdk/query_groups.py +17 -5
- infrahub_sdk/schema/main.py +1 -0
- infrahub_sdk/schema/repository.py +16 -0
- infrahub_sdk/spec/object.py +1 -1
- infrahub_sdk/store.py +1 -1
- infrahub_sdk/testing/schemas/car_person.py +1 -0
- infrahub_sdk/utils.py +7 -20
- infrahub_sdk/yaml.py +6 -5
- {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/METADATA +5 -5
- {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/RECORD +197 -168
- {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/WHEEL +1 -1
- infrahub_testcontainers/container.py +239 -65
- infrahub_testcontainers/docker-compose-cluster.test.yml +321 -0
- infrahub_testcontainers/docker-compose.test.yml +2 -1
- infrahub_testcontainers/helpers.py +23 -3
- infrahub_testcontainers/plugin.py +9 -0
- infrahub/message_bus/messages/check_generator_run.py +0 -26
- infrahub/message_bus/messages/finalize_validator_execution.py +0 -15
- infrahub/message_bus/messages/proposed_change/base_with_diff.py +0 -16
- infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +0 -11
- infrahub/message_bus/messages/request_generatordefinition_check.py +0 -20
- infrahub/message_bus/messages/request_proposedchange_pipeline.py +0 -23
- infrahub/message_bus/operations/check/__init__.py +0 -3
- infrahub/message_bus/operations/check/generator.py +0 -156
- infrahub/message_bus/operations/finalize/__init__.py +0 -3
- infrahub/message_bus/operations/finalize/validator.py +0 -133
- infrahub/message_bus/operations/requests/__init__.py +0 -9
- infrahub/message_bus/operations/requests/generator_definition.py +0 -140
- infrahub/message_bus/operations/requests/proposed_change.py +0 -629
- infrahub/patch/queries/consolidate_duplicated_nodes.py +0 -109
- /infrahub/{message_bus/messages/proposed_change → actions}/__init__.py +0 -0
- {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Sequence
|
|
4
|
+
|
|
5
|
+
from infrahub.core.migrations.shared import GraphMigration, MigrationResult
|
|
6
|
+
from infrahub.log import get_logger
|
|
7
|
+
|
|
8
|
+
from ...query import Query, QueryType
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from infrahub.database import InfrahubDatabase
|
|
12
|
+
|
|
13
|
+
log = get_logger()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class DeletePosthumousEdges(Query):
|
|
17
|
+
name = "delete_posthumous_edges_query"
|
|
18
|
+
type = QueryType.WRITE
|
|
19
|
+
insert_return = False
|
|
20
|
+
|
|
21
|
+
async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
|
|
22
|
+
query = """
|
|
23
|
+
// ------------
|
|
24
|
+
// find deleted nodes
|
|
25
|
+
// ------------
|
|
26
|
+
MATCH (n:Node)-[e:IS_PART_OF]->(:Root)
|
|
27
|
+
WHERE e.status = "deleted" OR e.to IS NOT NULL
|
|
28
|
+
WITH DISTINCT n, e.branch AS delete_branch, e.branch_level AS delete_branch_level, CASE
|
|
29
|
+
WHEN e.status = "deleted" THEN e.from
|
|
30
|
+
ELSE e.to
|
|
31
|
+
END AS delete_time
|
|
32
|
+
// ------------
|
|
33
|
+
// find the edges added to the deleted node after the delete time
|
|
34
|
+
// ------------
|
|
35
|
+
MATCH (n)-[added_e]-(peer)
|
|
36
|
+
WHERE added_e.from > delete_time
|
|
37
|
+
AND type(added_e) <> "IS_PART_OF"
|
|
38
|
+
// if the node was deleted on a branch (delete_branch_level > 1), and then updated on main/global (added_e.branch_level = 1), we can ignore it
|
|
39
|
+
AND added_e.branch_level >= delete_branch_level
|
|
40
|
+
AND (added_e.branch = delete_branch OR delete_branch_level = 1)
|
|
41
|
+
WITH DISTINCT n, delete_branch, delete_time, added_e, peer
|
|
42
|
+
// ------------
|
|
43
|
+
// get the branched_from for the branch on which the node was deleted
|
|
44
|
+
// ------------
|
|
45
|
+
CALL (added_e) {
|
|
46
|
+
MATCH (b:Branch {name: added_e.branch})
|
|
47
|
+
RETURN b.branched_from AS added_e_branched_from
|
|
48
|
+
}
|
|
49
|
+
// ------------
|
|
50
|
+
// account for the following situations, given that the edge update time is after the node delete time
|
|
51
|
+
// - deleted on main/global, updated on branch
|
|
52
|
+
// - illegal if the delete is before branch.branched_from
|
|
53
|
+
// - deleted on branch, updated on branch
|
|
54
|
+
// - illegal
|
|
55
|
+
// ------------
|
|
56
|
+
WITH n, delete_branch, delete_time, added_e, peer
|
|
57
|
+
WHERE delete_branch = added_e.branch
|
|
58
|
+
OR delete_time < added_e_branched_from
|
|
59
|
+
DELETE added_e
|
|
60
|
+
// --------------
|
|
61
|
+
// the peer _should_ only be an Attribute, but I want to make sure we don't
|
|
62
|
+
// inadvertently delete Root or an AttributeValue or a Boolean
|
|
63
|
+
// --------------
|
|
64
|
+
WITH peer
|
|
65
|
+
WHERE "Attribute" IN labels(peer)
|
|
66
|
+
DETACH DELETE peer
|
|
67
|
+
"""
|
|
68
|
+
self.add_to_query(query)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class Migration030(GraphMigration):
|
|
72
|
+
"""
|
|
73
|
+
Edges could have been added to Nodes after the Node was deleted, so we need to hard-delete those illegal edges
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
name: str = "030_delete_illegal_edges"
|
|
77
|
+
minimum_version: int = 29
|
|
78
|
+
queries: Sequence[type[Query]] = [DeletePosthumousEdges]
|
|
79
|
+
|
|
80
|
+
async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
|
|
81
|
+
result = MigrationResult()
|
|
82
|
+
return result
|
|
@@ -61,30 +61,33 @@ class AttributeAddQuery(Query):
|
|
|
61
61
|
MERGE (is_visible_value:Boolean { value: $is_visible_default })
|
|
62
62
|
WITH av, is_protected_value, is_visible_value
|
|
63
63
|
MATCH p = (n:%(node_kind)s)
|
|
64
|
-
CALL {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
CALL (n) {
|
|
65
|
+
MATCH (:Root)<-[r:IS_PART_OF]-(n)
|
|
66
|
+
WHERE %(branch_filter)s
|
|
67
|
+
WITH n, r AS is_part_of_e
|
|
68
|
+
OPTIONAL MATCH (n)-[r:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name })
|
|
69
|
+
WHERE %(branch_filter)s
|
|
70
|
+
WITH is_part_of_e, r AS has_attr_e
|
|
71
|
+
RETURN is_part_of_e, has_attr_e
|
|
72
|
+
ORDER BY has_attr_e.branch_level DESC, has_attr_e.from ASC, is_part_of_e.branch_level DESC, is_part_of_e.from ASC
|
|
71
73
|
LIMIT 1
|
|
72
74
|
}
|
|
73
|
-
WITH
|
|
74
|
-
WHERE
|
|
75
|
+
WITH n, is_part_of_e, has_attr_e, av, is_protected_value, is_visible_value
|
|
76
|
+
WHERE is_part_of_e.status = "active" AND (has_attr_e IS NULL OR has_attr_e.status = "deleted")
|
|
75
77
|
CREATE (a:Attribute { name: $attr_name, branch_support: $branch_support })
|
|
76
78
|
CREATE (n)-[:HAS_ATTRIBUTE $rel_props ]->(a)
|
|
77
79
|
CREATE (a)-[:HAS_VALUE $rel_props ]->(av)
|
|
78
80
|
CREATE (a)-[:IS_PROTECTED $rel_props]->(is_protected_value)
|
|
79
81
|
CREATE (a)-[:IS_VISIBLE $rel_props]->(is_visible_value)
|
|
80
82
|
%(uuid_generation)s
|
|
81
|
-
FOREACH (i in CASE WHEN
|
|
82
|
-
SET
|
|
83
|
+
FOREACH (i in CASE WHEN has_attr_e.status = "deleted" THEN [1] ELSE [] END |
|
|
84
|
+
SET has_attr_e.to = $current_time
|
|
83
85
|
)
|
|
84
86
|
""" % {
|
|
85
87
|
"branch_filter": branch_filter,
|
|
86
88
|
"node_kind": self.node_kind,
|
|
87
89
|
"uuid_generation": db.render_uuid_generation(node_label="a", node_attr="uuid"),
|
|
88
90
|
}
|
|
91
|
+
|
|
89
92
|
self.add_to_query(query)
|
|
90
93
|
self.return_labels = ["n.uuid", "a.uuid"]
|
|
@@ -38,7 +38,7 @@ class AttributeRenameQuery(Query):
|
|
|
38
38
|
def render_match(self) -> str:
|
|
39
39
|
query = """
|
|
40
40
|
// Find all the active nodes
|
|
41
|
-
CALL {
|
|
41
|
+
CALL () {
|
|
42
42
|
MATCH (node:%(node_kind)s)
|
|
43
43
|
WHERE exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name }))
|
|
44
44
|
RETURN node
|
|
@@ -55,7 +55,6 @@ class AttributeRenameQuery(Query):
|
|
|
55
55
|
@staticmethod
|
|
56
56
|
def _render_sub_query_per_rel_type_update_active(rel_type: str, rel_def: FieldInfo) -> str:
|
|
57
57
|
subquery = [
|
|
58
|
-
"WITH peer_node, rb, active_attr",
|
|
59
58
|
"WITH peer_node, rb, active_attr",
|
|
60
59
|
f'WHERE type(rb) = "{rel_type}"',
|
|
61
60
|
]
|
|
@@ -72,7 +71,6 @@ class AttributeRenameQuery(Query):
|
|
|
72
71
|
@staticmethod
|
|
73
72
|
def _render_sub_query_per_rel_type_create_new(rel_type: str, rel_def: FieldInfo) -> str:
|
|
74
73
|
subquery = [
|
|
75
|
-
"WITH peer_node, rb, active_attr, new_attr",
|
|
76
74
|
"WITH peer_node, rb, active_attr, new_attr",
|
|
77
75
|
f'WHERE type(rb) = "{rel_type}"',
|
|
78
76
|
]
|
|
@@ -126,8 +124,7 @@ class AttributeRenameQuery(Query):
|
|
|
126
124
|
|
|
127
125
|
add_uuid = db.render_uuid_generation(node_label="new_attr", node_attr="uuid")
|
|
128
126
|
query = """
|
|
129
|
-
CALL {
|
|
130
|
-
WITH node
|
|
127
|
+
CALL (node) {
|
|
131
128
|
MATCH (root:Root)<-[r:IS_PART_OF]-(node)
|
|
132
129
|
WHERE %(branch_filter)s
|
|
133
130
|
RETURN node as n1, r as r1
|
|
@@ -137,8 +134,7 @@ class AttributeRenameQuery(Query):
|
|
|
137
134
|
WITH n1 as active_node, r1 as rb
|
|
138
135
|
WHERE rb.status = "active"
|
|
139
136
|
// Find all the attributes that need to be updated
|
|
140
|
-
CALL {
|
|
141
|
-
WITH active_node
|
|
137
|
+
CALL (active_node) {
|
|
142
138
|
MATCH (active_node)-[r:HAS_ATTRIBUTE]-(attr:Attribute { name: $prev_attr.name })
|
|
143
139
|
WHERE %(branch_filter)s
|
|
144
140
|
RETURN active_node as n1, r as r1, attr as attr1
|
|
@@ -151,8 +147,7 @@ class AttributeRenameQuery(Query):
|
|
|
151
147
|
%(add_uuid)s
|
|
152
148
|
WITH active_attr, new_attr
|
|
153
149
|
MATCH (active_attr)-[]-(peer)
|
|
154
|
-
CALL {
|
|
155
|
-
WITH active_attr, peer
|
|
150
|
+
CALL (active_attr, peer) {
|
|
156
151
|
MATCH (active_attr)-[r]-(peer)
|
|
157
152
|
WHERE %(branch_filter)s
|
|
158
153
|
RETURN active_attr as a1, r as r1, peer as p1
|
|
@@ -161,7 +156,7 @@ class AttributeRenameQuery(Query):
|
|
|
161
156
|
}
|
|
162
157
|
WITH a1 as active_attr, r1 as rb, p1 as peer_node, new_attr
|
|
163
158
|
WHERE rb.status = "active"
|
|
164
|
-
CALL {
|
|
159
|
+
CALL (peer_node, rb, active_attr, new_attr){
|
|
165
160
|
%(sub_query_create_all)s
|
|
166
161
|
}
|
|
167
162
|
WITH p2 as peer_node, rb, new_attr, active_attr
|
|
@@ -170,7 +165,7 @@ class AttributeRenameQuery(Query):
|
|
|
170
165
|
|
|
171
166
|
if not (self.branch.is_default or self.branch.is_global):
|
|
172
167
|
query = """
|
|
173
|
-
CALL {
|
|
168
|
+
CALL (peer_node, rb, active_attr) {
|
|
174
169
|
%(sub_query_update_all)s
|
|
175
170
|
}
|
|
176
171
|
WITH p2 as peer_node, rb, new_attr
|
|
@@ -55,7 +55,6 @@ class DeleteElementInSchemaQuery(Query):
|
|
|
55
55
|
@staticmethod
|
|
56
56
|
def _render_sub_query_per_rel_type(rel_name: str, rel_type: str, direction: GraphRelDirection) -> str:
|
|
57
57
|
subquery = [
|
|
58
|
-
f"WITH peer_node, {rel_name}, element_to_delete",
|
|
59
58
|
f"WITH peer_node, {rel_name}, element_to_delete",
|
|
60
59
|
f'WHERE type({rel_name}) = "{rel_type}"',
|
|
61
60
|
]
|
|
@@ -67,28 +66,32 @@ class DeleteElementInSchemaQuery(Query):
|
|
|
67
66
|
return "\n".join(subquery)
|
|
68
67
|
|
|
69
68
|
@classmethod
|
|
70
|
-
def _render_sub_query_out(cls) -> str:
|
|
69
|
+
def _render_sub_query_out(cls) -> tuple[str, str]:
|
|
70
|
+
rel_name = "rel_outband"
|
|
71
|
+
sub_query_out_args = f"peer_node, {rel_name}, element_to_delete"
|
|
71
72
|
sub_queries_out = [
|
|
72
73
|
cls._render_sub_query_per_rel_type(
|
|
73
|
-
rel_name=
|
|
74
|
+
rel_name=rel_name, rel_type=rel_type, direction=GraphRelDirection.OUTBOUND
|
|
74
75
|
)
|
|
75
76
|
for rel_type, rel_def in GraphNodeRelationships.model_fields.items()
|
|
76
77
|
if rel_def.default.direction in [GraphRelDirection.OUTBOUND, GraphRelDirection.EITHER]
|
|
77
78
|
]
|
|
78
79
|
sub_query_out = "\nUNION\n".join(sub_queries_out)
|
|
79
|
-
return sub_query_out
|
|
80
|
+
return sub_query_out, sub_query_out_args
|
|
80
81
|
|
|
81
82
|
@classmethod
|
|
82
|
-
def _render_sub_query_in(cls) -> str:
|
|
83
|
+
def _render_sub_query_in(cls) -> tuple[str, str]:
|
|
84
|
+
rel_name = "rel_inband"
|
|
85
|
+
sub_query_in_args = f"peer_node, {rel_name}, element_to_delete"
|
|
83
86
|
sub_queries_in = [
|
|
84
87
|
cls._render_sub_query_per_rel_type(
|
|
85
|
-
rel_name=
|
|
88
|
+
rel_name=rel_name, rel_type=rel_type, direction=GraphRelDirection.INBOUND
|
|
86
89
|
)
|
|
87
90
|
for rel_type, rel_def in GraphNodeRelationships.model_fields.items()
|
|
88
91
|
if rel_def.default.direction in [GraphRelDirection.INBOUND, GraphRelDirection.EITHER]
|
|
89
92
|
]
|
|
90
93
|
sub_query_in = "\nUNION\n".join(sub_queries_in)
|
|
91
|
-
return sub_query_in
|
|
94
|
+
return sub_query_in, sub_query_in_args
|
|
92
95
|
|
|
93
96
|
async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
|
|
94
97
|
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
|
|
@@ -108,16 +111,15 @@ class DeleteElementInSchemaQuery(Query):
|
|
|
108
111
|
"from": self.at.to_string(),
|
|
109
112
|
}
|
|
110
113
|
|
|
111
|
-
sub_query_out = self._render_sub_query_out()
|
|
112
|
-
sub_query_in = self._render_sub_query_in()
|
|
114
|
+
sub_query_out, sub_query_out_args = self._render_sub_query_out()
|
|
115
|
+
sub_query_in, sub_query_in_args = self._render_sub_query_in()
|
|
113
116
|
|
|
114
117
|
self.add_to_query(self.render_match())
|
|
115
118
|
self.add_to_query(self.render_where())
|
|
116
119
|
|
|
117
120
|
# ruff: noqa: E501
|
|
118
121
|
query = """
|
|
119
|
-
CALL {
|
|
120
|
-
WITH attr_node
|
|
122
|
+
CALL (attr_node) {
|
|
121
123
|
MATCH (root:Root)<-[r:IS_PART_OF]-(attr_node)
|
|
122
124
|
WHERE %(branch_filter)s
|
|
123
125
|
RETURN attr_node as n1, r as r1
|
|
@@ -130,8 +132,7 @@ class DeleteElementInSchemaQuery(Query):
|
|
|
130
132
|
|
|
131
133
|
// Process Outbound Relationship
|
|
132
134
|
MATCH (element_to_delete)-[]->(peer)
|
|
133
|
-
CALL {
|
|
134
|
-
WITH element_to_delete, peer
|
|
135
|
+
CALL (element_to_delete, peer) {
|
|
135
136
|
MATCH (element_to_delete)-[r]->(peer)
|
|
136
137
|
WHERE %(branch_filter)s
|
|
137
138
|
RETURN element_to_delete as n1, r as rel_outband1, peer as p1
|
|
@@ -140,7 +141,7 @@ class DeleteElementInSchemaQuery(Query):
|
|
|
140
141
|
}
|
|
141
142
|
WITH n1 as element_to_delete, rel_outband1 as rel_outband, p1 as peer_node
|
|
142
143
|
WHERE rel_outband.status = "active"
|
|
143
|
-
CALL {
|
|
144
|
+
CALL (%(sub_query_out_args)s) {
|
|
144
145
|
%(sub_query_out)s
|
|
145
146
|
}
|
|
146
147
|
WITH p2 as peer_node, rel_outband, element_to_delete
|
|
@@ -150,8 +151,7 @@ class DeleteElementInSchemaQuery(Query):
|
|
|
150
151
|
WITH DISTINCT(element_to_delete) AS element_to_delete
|
|
151
152
|
// Process Inbound Relationship
|
|
152
153
|
MATCH (element_to_delete)<-[]-(peer)
|
|
153
|
-
CALL {
|
|
154
|
-
WITH element_to_delete, peer
|
|
154
|
+
CALL (element_to_delete, peer) {
|
|
155
155
|
MATCH (element_to_delete)<-[r]-(peer)
|
|
156
156
|
WHERE %(branch_filter)s
|
|
157
157
|
RETURN element_to_delete as n1, r as rel_inband1, peer as p1
|
|
@@ -160,7 +160,7 @@ class DeleteElementInSchemaQuery(Query):
|
|
|
160
160
|
}
|
|
161
161
|
WITH n1 as element_to_delete, rel_inband1 as rel_inband, p1 as peer_node
|
|
162
162
|
WHERE rel_inband.status = "active"
|
|
163
|
-
CALL {
|
|
163
|
+
CALL (%(sub_query_in_args)s) {
|
|
164
164
|
%(sub_query_in)s
|
|
165
165
|
}
|
|
166
166
|
WITH p2 as peer_node, rel_inband, element_to_delete
|
|
@@ -172,5 +172,7 @@ class DeleteElementInSchemaQuery(Query):
|
|
|
172
172
|
"branch_filter": branch_filter,
|
|
173
173
|
"sub_query_out": sub_query_out,
|
|
174
174
|
"sub_query_in": sub_query_in,
|
|
175
|
+
"sub_query_out_args": sub_query_out_args,
|
|
176
|
+
"sub_query_in_args": sub_query_in_args,
|
|
175
177
|
}
|
|
176
178
|
self.add_to_query(query)
|
|
@@ -47,7 +47,6 @@ class NodeDuplicateQuery(Query):
|
|
|
47
47
|
@staticmethod
|
|
48
48
|
def _render_sub_query_per_rel_type(rel_name: str, rel_type: str, rel_dir: GraphRelDirection) -> str:
|
|
49
49
|
subquery = [
|
|
50
|
-
f"WITH peer_node, {rel_name}, active_node, new_node",
|
|
51
50
|
f"WITH peer_node, {rel_name}, active_node, new_node",
|
|
52
51
|
f'WHERE type({rel_name}) = "{rel_type}"',
|
|
53
52
|
]
|
|
@@ -81,28 +80,28 @@ class NodeDuplicateQuery(Query):
|
|
|
81
80
|
return "\n".join(subquery)
|
|
82
81
|
|
|
83
82
|
@classmethod
|
|
84
|
-
def _render_sub_query_out(cls) -> str:
|
|
83
|
+
def _render_sub_query_out(cls) -> tuple[str, str]:
|
|
84
|
+
rel_name = "rel_outband"
|
|
85
|
+
sub_query_out_args = f"peer_node, {rel_name}, active_node, new_node"
|
|
85
86
|
sub_queries_out = [
|
|
86
|
-
cls._render_sub_query_per_rel_type(
|
|
87
|
-
rel_name="rel_outband", rel_type=rel_type, rel_dir=GraphRelDirection.OUTBOUND
|
|
88
|
-
)
|
|
87
|
+
cls._render_sub_query_per_rel_type(rel_name=rel_name, rel_type=rel_type, rel_dir=GraphRelDirection.OUTBOUND)
|
|
89
88
|
for rel_type, field_info in GraphNodeRelationships.model_fields.items()
|
|
90
89
|
if field_info.default.direction in (GraphRelDirection.OUTBOUND, GraphRelDirection.EITHER)
|
|
91
90
|
]
|
|
92
91
|
sub_query_out = "\nUNION\n".join(sub_queries_out)
|
|
93
|
-
return sub_query_out
|
|
92
|
+
return sub_query_out, sub_query_out_args
|
|
94
93
|
|
|
95
94
|
@classmethod
|
|
96
|
-
def _render_sub_query_in(cls) -> str:
|
|
95
|
+
def _render_sub_query_in(cls) -> tuple[str, str]:
|
|
96
|
+
rel_name = "rel_inband"
|
|
97
|
+
sub_query_in_args = f"peer_node, {rel_name}, active_node, new_node"
|
|
97
98
|
sub_queries_in = [
|
|
98
|
-
cls._render_sub_query_per_rel_type(
|
|
99
|
-
rel_name="rel_inband", rel_type=rel_type, rel_dir=GraphRelDirection.INBOUND
|
|
100
|
-
)
|
|
99
|
+
cls._render_sub_query_per_rel_type(rel_name=rel_name, rel_type=rel_type, rel_dir=GraphRelDirection.INBOUND)
|
|
101
100
|
for rel_type, field_info in GraphNodeRelationships.model_fields.items()
|
|
102
101
|
if field_info.default.direction in (GraphRelDirection.INBOUND, GraphRelDirection.EITHER)
|
|
103
102
|
]
|
|
104
103
|
sub_query_in = "\nUNION\n".join(sub_queries_in)
|
|
105
|
-
return sub_query_in
|
|
104
|
+
return sub_query_in, sub_query_in_args
|
|
106
105
|
|
|
107
106
|
async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
|
|
108
107
|
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
|
|
@@ -126,15 +125,14 @@ class NodeDuplicateQuery(Query):
|
|
|
126
125
|
"from": self.at.to_string(),
|
|
127
126
|
}
|
|
128
127
|
|
|
129
|
-
sub_query_out = self._render_sub_query_out()
|
|
130
|
-
sub_query_in = self._render_sub_query_in()
|
|
128
|
+
sub_query_out, sub_query_out_args = self._render_sub_query_out()
|
|
129
|
+
sub_query_in, sub_query_in_args = self._render_sub_query_in()
|
|
131
130
|
|
|
132
131
|
self.add_to_query(self.render_match())
|
|
133
132
|
|
|
134
133
|
# ruff: noqa: E501
|
|
135
134
|
query = """
|
|
136
|
-
CALL {
|
|
137
|
-
WITH node
|
|
135
|
+
CALL (node) {
|
|
138
136
|
MATCH (root:Root)<-[r:IS_PART_OF]-(node)
|
|
139
137
|
WHERE %(branch_filter)s
|
|
140
138
|
RETURN node as n1, r as r1
|
|
@@ -147,8 +145,7 @@ class NodeDuplicateQuery(Query):
|
|
|
147
145
|
WITH active_node, new_node
|
|
148
146
|
// Process Outbound Relationship
|
|
149
147
|
MATCH (active_node)-[]->(peer)
|
|
150
|
-
CALL {
|
|
151
|
-
WITH active_node, peer
|
|
148
|
+
CALL (active_node, peer) {
|
|
152
149
|
MATCH (active_node)-[r]->(peer)
|
|
153
150
|
WHERE %(branch_filter)s
|
|
154
151
|
RETURN active_node as n1, r as rel_outband1, peer as p1
|
|
@@ -157,7 +154,7 @@ class NodeDuplicateQuery(Query):
|
|
|
157
154
|
}
|
|
158
155
|
WITH n1 as active_node, rel_outband1 as rel_outband, p1 as peer_node, new_node
|
|
159
156
|
WHERE rel_outband.status = "active" AND rel_outband.to IS NULL
|
|
160
|
-
CALL {
|
|
157
|
+
CALL (%(sub_query_out_args)s) {
|
|
161
158
|
%(sub_query_out)s
|
|
162
159
|
}
|
|
163
160
|
WITH p2 as peer_node, rel_outband, active_node, new_node
|
|
@@ -167,8 +164,7 @@ class NodeDuplicateQuery(Query):
|
|
|
167
164
|
WITH DISTINCT active_node, new_node
|
|
168
165
|
// Process Inbound Relationship
|
|
169
166
|
MATCH (active_node)<-[]-(peer)
|
|
170
|
-
CALL {
|
|
171
|
-
WITH active_node, peer
|
|
167
|
+
CALL (active_node, peer) {
|
|
172
168
|
MATCH (active_node)<-[r]-(peer)
|
|
173
169
|
WHERE %(branch_filter)s
|
|
174
170
|
RETURN active_node as n1, r as rel_inband1, peer as p1
|
|
@@ -177,7 +173,7 @@ class NodeDuplicateQuery(Query):
|
|
|
177
173
|
}
|
|
178
174
|
WITH n1 as active_node, rel_inband1 as rel_inband, p1 as peer_node, new_node
|
|
179
175
|
WHERE rel_inband.status = "active" AND rel_inband.to IS NULL
|
|
180
|
-
CALL {
|
|
176
|
+
CALL (%(sub_query_in_args)s) {
|
|
181
177
|
%(sub_query_in)s
|
|
182
178
|
}
|
|
183
179
|
WITH p2 as peer_node, rel_inband, active_node, new_node
|
|
@@ -191,5 +187,7 @@ class NodeDuplicateQuery(Query):
|
|
|
191
187
|
"labels": ":".join(self.new_node.labels),
|
|
192
188
|
"sub_query_out": sub_query_out,
|
|
193
189
|
"sub_query_in": sub_query_in,
|
|
190
|
+
"sub_query_out_args": sub_query_out_args,
|
|
191
|
+
"sub_query_in_args": sub_query_in_args,
|
|
194
192
|
}
|
|
195
193
|
self.add_to_query(query)
|
|
@@ -47,7 +47,6 @@ class RelationshipDuplicateQuery(Query):
|
|
|
47
47
|
@staticmethod
|
|
48
48
|
def _render_sub_query_per_rel_type(rel_name: str, rel_type: str, direction: GraphRelDirection) -> str:
|
|
49
49
|
subquery = [
|
|
50
|
-
f"WITH peer_node, {rel_name}, active_rel, new_rel",
|
|
51
50
|
f"WITH peer_node, {rel_name}, active_rel, new_rel",
|
|
52
51
|
f'WHERE type({rel_name}) = "{rel_type}"',
|
|
53
52
|
]
|
|
@@ -61,28 +60,32 @@ class RelationshipDuplicateQuery(Query):
|
|
|
61
60
|
return "\n".join(subquery)
|
|
62
61
|
|
|
63
62
|
@classmethod
|
|
64
|
-
def _render_sub_query_out(cls) -> str:
|
|
63
|
+
def _render_sub_query_out(cls) -> tuple[str, str]:
|
|
64
|
+
rel_name = "rel_outband"
|
|
65
|
+
sub_query_out_args = f"peer_node, {rel_name}, active_rel, new_rel"
|
|
65
66
|
sub_queries_out = [
|
|
66
67
|
cls._render_sub_query_per_rel_type(
|
|
67
|
-
rel_name=
|
|
68
|
+
rel_name=rel_name, rel_type=rel_type, direction=GraphRelDirection.OUTBOUND
|
|
68
69
|
)
|
|
69
70
|
for rel_type, rel_def in GraphRelationshipRelationships.model_fields.items()
|
|
70
71
|
if rel_def.default.direction in [GraphRelDirection.OUTBOUND, GraphRelDirection.EITHER]
|
|
71
72
|
]
|
|
72
73
|
sub_query_out = "\nUNION\n".join(sub_queries_out)
|
|
73
|
-
return sub_query_out
|
|
74
|
+
return sub_query_out, sub_query_out_args
|
|
74
75
|
|
|
75
76
|
@classmethod
|
|
76
|
-
def _render_sub_query_in(cls) -> str:
|
|
77
|
+
def _render_sub_query_in(cls) -> tuple[str, str]:
|
|
78
|
+
rel_name = "rel_inband"
|
|
79
|
+
sub_query_in_args = f"peer_node, {rel_name}, active_rel, new_rel"
|
|
77
80
|
sub_queries_in = [
|
|
78
81
|
cls._render_sub_query_per_rel_type(
|
|
79
|
-
rel_name=
|
|
82
|
+
rel_name=rel_name, rel_type=rel_type, direction=GraphRelDirection.INBOUND
|
|
80
83
|
)
|
|
81
84
|
for rel_type, rel_def in GraphRelationshipRelationships.model_fields.items()
|
|
82
85
|
if rel_def.default.direction in [GraphRelDirection.INBOUND, GraphRelDirection.EITHER]
|
|
83
86
|
]
|
|
84
87
|
sub_query_in = "\nUNION\n".join(sub_queries_in)
|
|
85
|
-
return sub_query_in
|
|
88
|
+
return sub_query_in, sub_query_in_args
|
|
86
89
|
|
|
87
90
|
async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> None: # noqa: ARG002
|
|
88
91
|
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
|
|
@@ -109,15 +112,13 @@ class RelationshipDuplicateQuery(Query):
|
|
|
109
112
|
"from": self.at.to_string(),
|
|
110
113
|
}
|
|
111
114
|
|
|
112
|
-
sub_query_out = self._render_sub_query_out()
|
|
113
|
-
sub_query_in = self._render_sub_query_in()
|
|
115
|
+
sub_query_out, sub_query_out_args = self._render_sub_query_out()
|
|
116
|
+
sub_query_in, sub_query_in_args = self._render_sub_query_in()
|
|
114
117
|
|
|
115
118
|
self.add_to_query(self.render_match())
|
|
116
119
|
|
|
117
|
-
# ruff: noqa: E501
|
|
118
120
|
query = """
|
|
119
|
-
CALL {
|
|
120
|
-
WITH source, rel, destination
|
|
121
|
+
CALL (source, rel, destination) {
|
|
121
122
|
MATCH path = (source)-[r1:IS_RELATED]-(rel)-[r2:IS_RELATED]-(destination)
|
|
122
123
|
WHERE all(r IN relationships(path) WHERE %(branch_filter)s)
|
|
123
124
|
RETURN rel as rel1, r1 as r11, r2 as r12
|
|
@@ -130,8 +131,7 @@ class RelationshipDuplicateQuery(Query):
|
|
|
130
131
|
WITH DISTINCT(active_rel) as active_rel, new_rel
|
|
131
132
|
// Process Inbound Relationship
|
|
132
133
|
MATCH (active_rel)<-[]-(peer)
|
|
133
|
-
CALL {
|
|
134
|
-
WITH active_rel, peer
|
|
134
|
+
CALL (active_rel, peer) {
|
|
135
135
|
MATCH (active_rel)<-[r]-(peer)
|
|
136
136
|
WHERE %(branch_filter)s
|
|
137
137
|
RETURN active_rel as n1, r as rel_inband1, peer as p1
|
|
@@ -140,7 +140,7 @@ class RelationshipDuplicateQuery(Query):
|
|
|
140
140
|
}
|
|
141
141
|
WITH n1 as active_rel, rel_inband1 as rel_inband, p1 as peer_node, new_rel
|
|
142
142
|
WHERE rel_inband.status = "active"
|
|
143
|
-
CALL {
|
|
143
|
+
CALL (%(sub_query_in_args)s) {
|
|
144
144
|
%(sub_query_in)s
|
|
145
145
|
}
|
|
146
146
|
WITH p2 as peer_node, rel_inband, active_rel, new_rel
|
|
@@ -150,8 +150,7 @@ class RelationshipDuplicateQuery(Query):
|
|
|
150
150
|
WITH DISTINCT(active_rel) as active_rel, new_rel
|
|
151
151
|
// Process Outbound Relationship
|
|
152
152
|
MATCH (active_rel)-[]->(peer)
|
|
153
|
-
CALL {
|
|
154
|
-
WITH active_rel, peer
|
|
153
|
+
CALL (active_rel, peer) {
|
|
155
154
|
MATCH (active_rel)-[r]->(peer)
|
|
156
155
|
WHERE %(branch_filter)s
|
|
157
156
|
RETURN active_rel as n1, r as rel_outband1, peer as p1
|
|
@@ -160,7 +159,7 @@ class RelationshipDuplicateQuery(Query):
|
|
|
160
159
|
}
|
|
161
160
|
WITH n1 as active_rel, rel_outband1 as rel_outband, p1 as peer_node, new_rel
|
|
162
161
|
WHERE rel_outband.status = "active"
|
|
163
|
-
CALL {
|
|
162
|
+
CALL (%(sub_query_out_args)s) {
|
|
164
163
|
%(sub_query_out)s
|
|
165
164
|
}
|
|
166
165
|
WITH p2 as peer_node, rel_outband, active_rel, new_rel
|
|
@@ -172,5 +171,7 @@ class RelationshipDuplicateQuery(Query):
|
|
|
172
171
|
"branch_filter": branch_filter,
|
|
173
172
|
"sub_query_out": sub_query_out,
|
|
174
173
|
"sub_query_in": sub_query_in,
|
|
174
|
+
"sub_query_in_args": sub_query_in_args,
|
|
175
|
+
"sub_query_out_args": sub_query_out_args,
|
|
175
176
|
}
|
|
176
177
|
self.add_to_query(query)
|
|
@@ -50,7 +50,6 @@ class NodeAttributeRemoveMigrationQuery01(AttributeMigrationQuery):
|
|
|
50
50
|
|
|
51
51
|
def render_sub_query_per_rel_type(rel_type: str, rel_def: FieldInfo) -> str:
|
|
52
52
|
subquery = [
|
|
53
|
-
"WITH peer_node, rb, active_attr",
|
|
54
53
|
"WITH peer_node, rb, active_attr",
|
|
55
54
|
f'WHERE type(rb) = "{rel_type}"',
|
|
56
55
|
]
|
|
@@ -75,8 +74,7 @@ class NodeAttributeRemoveMigrationQuery01(AttributeMigrationQuery):
|
|
|
75
74
|
MATCH (node:%(node_kind)s)
|
|
76
75
|
WHERE (size($kinds_to_ignore) = 0 OR NOT any(l IN labels(node) WHERE l IN $kinds_to_ignore))
|
|
77
76
|
AND exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name }))
|
|
78
|
-
CALL {
|
|
79
|
-
WITH node
|
|
77
|
+
CALL (node) {
|
|
80
78
|
MATCH (root:Root)<-[r:IS_PART_OF]-(node)
|
|
81
79
|
WHERE %(branch_filter)s
|
|
82
80
|
RETURN node as n1, r as r1
|
|
@@ -86,8 +84,7 @@ class NodeAttributeRemoveMigrationQuery01(AttributeMigrationQuery):
|
|
|
86
84
|
WITH n1 as active_node, r1 as rb
|
|
87
85
|
WHERE rb.status = "active"
|
|
88
86
|
// Find all the attributes that need to be updated
|
|
89
|
-
CALL {
|
|
90
|
-
WITH active_node
|
|
87
|
+
CALL (active_node) {
|
|
91
88
|
MATCH (active_node)-[r:HAS_ATTRIBUTE]-(attr:Attribute { name: $attr_name })
|
|
92
89
|
WHERE %(branch_filter)s
|
|
93
90
|
RETURN active_node as n1, r as r1, attr as attr1
|
|
@@ -98,8 +95,7 @@ class NodeAttributeRemoveMigrationQuery01(AttributeMigrationQuery):
|
|
|
98
95
|
WHERE rb.status = "active"
|
|
99
96
|
WITH active_attr
|
|
100
97
|
MATCH (active_attr)-[]-(peer)
|
|
101
|
-
CALL {
|
|
102
|
-
WITH active_attr, peer
|
|
98
|
+
CALL (active_attr, peer) {
|
|
103
99
|
MATCH (active_attr)-[r]-(peer)
|
|
104
100
|
WHERE %(branch_filter)s
|
|
105
101
|
RETURN active_attr as a1, r as r1, peer as p1
|
|
@@ -108,7 +104,7 @@ class NodeAttributeRemoveMigrationQuery01(AttributeMigrationQuery):
|
|
|
108
104
|
}
|
|
109
105
|
WITH a1 as active_attr, r1 as rb, p1 as peer_node
|
|
110
106
|
WHERE rb.status = "active"
|
|
111
|
-
CALL {
|
|
107
|
+
CALL (peer_node, rb, active_attr) {
|
|
112
108
|
%(sub_query_all)s
|
|
113
109
|
}
|
|
114
110
|
WITH p2 as peer_node, rb, active_attr
|