infrahub-server 1.2.0rc0__py3-none-any.whl → 1.2.1__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/api/dependencies.py +6 -6
- infrahub/api/diff/validation_models.py +7 -7
- infrahub/api/schema.py +1 -1
- infrahub/artifacts/models.py +5 -3
- infrahub/artifacts/tasks.py +3 -5
- infrahub/cli/__init__.py +13 -9
- infrahub/cli/constants.py +3 -0
- infrahub/cli/db.py +165 -183
- infrahub/cli/upgrade.py +146 -0
- infrahub/computed_attribute/gather.py +185 -0
- infrahub/computed_attribute/models.py +240 -12
- infrahub/computed_attribute/tasks.py +77 -441
- infrahub/computed_attribute/triggers.py +13 -47
- infrahub/config.py +43 -32
- infrahub/context.py +14 -0
- infrahub/core/account.py +4 -4
- infrahub/core/attribute.py +58 -58
- infrahub/core/branch/tasks.py +74 -22
- infrahub/core/changelog/diff.py +95 -36
- infrahub/core/changelog/models.py +217 -43
- infrahub/core/constants/__init__.py +28 -0
- infrahub/core/constants/infrahubkind.py +2 -0
- infrahub/core/constants/schema.py +2 -0
- infrahub/core/constraint/node/runner.py +9 -8
- infrahub/core/diff/branch_differ.py +10 -10
- infrahub/core/diff/enricher/cardinality_one.py +5 -0
- infrahub/core/diff/enricher/hierarchy.py +17 -4
- infrahub/core/diff/enricher/labels.py +5 -0
- infrahub/core/diff/enricher/path_identifier.py +4 -0
- infrahub/core/diff/ipam_diff_parser.py +4 -5
- infrahub/core/diff/model/diff.py +27 -27
- infrahub/core/diff/model/path.py +32 -9
- infrahub/core/diff/parent_node_adder.py +78 -0
- infrahub/core/diff/payload_builder.py +13 -2
- infrahub/core/diff/query/filters.py +2 -2
- infrahub/core/diff/query/merge.py +20 -17
- infrahub/core/diff/query/save.py +188 -182
- infrahub/core/diff/query/summary_counts_enricher.py +51 -4
- infrahub/core/diff/query_parser.py +4 -4
- infrahub/core/diff/repository/deserializer.py +8 -3
- infrahub/core/diff/repository/repository.py +156 -38
- infrahub/core/diff/tasks.py +4 -4
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/graph/index.py +3 -0
- infrahub/core/initialization.py +1 -10
- infrahub/core/ipam/constants.py +3 -4
- infrahub/core/ipam/reconciler.py +12 -12
- infrahub/core/ipam/utilization.py +10 -13
- infrahub/core/manager.py +36 -36
- infrahub/core/merge.py +7 -7
- infrahub/core/migrations/__init__.py +2 -3
- infrahub/core/migrations/graph/__init__.py +12 -3
- infrahub/core/migrations/graph/m017_add_core_profile.py +1 -5
- infrahub/core/migrations/graph/m018_uniqueness_nulls.py +4 -4
- infrahub/core/migrations/graph/m019_restore_rels_to_time.py +256 -0
- infrahub/core/migrations/graph/m020_duplicate_edges.py +160 -0
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +51 -0
- infrahub/core/migrations/graph/m022_add_generate_template_attr.py +48 -0
- infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +96 -0
- infrahub/core/migrations/query/attribute_add.py +2 -2
- infrahub/core/migrations/query/node_duplicate.py +43 -26
- infrahub/core/migrations/query/schema_attribute_update.py +2 -2
- infrahub/core/migrations/schema/models.py +19 -4
- infrahub/core/migrations/schema/node_remove.py +26 -12
- infrahub/core/migrations/schema/tasks.py +2 -2
- infrahub/core/migrations/shared.py +16 -16
- infrahub/core/models.py +15 -6
- infrahub/core/node/__init__.py +43 -39
- infrahub/core/node/base.py +2 -4
- infrahub/core/node/constraints/attribute_uniqueness.py +2 -2
- infrahub/core/node/constraints/grouped_uniqueness.py +99 -47
- infrahub/core/node/constraints/interface.py +1 -2
- infrahub/core/node/delete_validator.py +3 -5
- infrahub/core/node/ipam.py +4 -4
- infrahub/core/node/permissions.py +7 -7
- infrahub/core/node/resource_manager/ip_address_pool.py +6 -6
- infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -6
- infrahub/core/node/resource_manager/number_pool.py +3 -3
- infrahub/core/path.py +12 -12
- infrahub/core/property.py +11 -11
- infrahub/core/protocols.py +7 -0
- infrahub/core/protocols_base.py +21 -21
- infrahub/core/query/__init__.py +33 -33
- infrahub/core/query/attribute.py +6 -4
- infrahub/core/query/diff.py +3 -3
- infrahub/core/query/node.py +82 -32
- infrahub/core/query/relationship.py +228 -40
- infrahub/core/query/resource_manager.py +2 -0
- infrahub/core/query/standard_node.py +3 -3
- infrahub/core/query/subquery.py +9 -9
- infrahub/core/registry.py +13 -15
- infrahub/core/relationship/constraints/count.py +3 -4
- infrahub/core/relationship/constraints/peer_kind.py +3 -4
- infrahub/core/relationship/constraints/profiles_kind.py +2 -2
- infrahub/core/relationship/model.py +51 -59
- infrahub/core/schema/attribute_schema.py +16 -8
- infrahub/core/schema/basenode_schema.py +105 -44
- infrahub/core/schema/computed_attribute.py +3 -3
- infrahub/core/schema/definitions/core/__init__.py +147 -0
- infrahub/core/schema/definitions/core/account.py +171 -0
- infrahub/core/schema/definitions/core/artifact.py +136 -0
- infrahub/core/schema/definitions/core/builtin.py +24 -0
- infrahub/core/schema/definitions/core/check.py +68 -0
- infrahub/core/schema/definitions/core/core.py +17 -0
- infrahub/core/schema/definitions/core/generator.py +100 -0
- infrahub/core/schema/definitions/core/graphql_query.py +79 -0
- infrahub/core/schema/definitions/core/group.py +108 -0
- infrahub/core/schema/definitions/core/ipam.py +193 -0
- infrahub/core/schema/definitions/core/lineage.py +19 -0
- infrahub/core/schema/definitions/core/menu.py +48 -0
- infrahub/core/schema/definitions/core/permission.py +163 -0
- infrahub/core/schema/definitions/core/profile.py +18 -0
- infrahub/core/schema/definitions/core/propose_change.py +97 -0
- infrahub/core/schema/definitions/core/propose_change_comment.py +193 -0
- infrahub/core/schema/definitions/core/propose_change_validator.py +328 -0
- infrahub/core/schema/definitions/core/repository.py +286 -0
- infrahub/core/schema/definitions/core/resource_pool.py +170 -0
- infrahub/core/schema/definitions/core/template.py +27 -0
- infrahub/core/schema/definitions/core/transform.py +96 -0
- infrahub/core/schema/definitions/core/webhook.py +134 -0
- infrahub/core/schema/definitions/internal.py +16 -16
- infrahub/core/schema/dropdown.py +3 -4
- infrahub/core/schema/generated/attribute_schema.py +15 -18
- infrahub/core/schema/generated/base_node_schema.py +12 -14
- infrahub/core/schema/generated/node_schema.py +3 -5
- infrahub/core/schema/generated/relationship_schema.py +9 -11
- infrahub/core/schema/generic_schema.py +2 -2
- infrahub/core/schema/manager.py +20 -9
- infrahub/core/schema/node_schema.py +4 -2
- infrahub/core/schema/relationship_schema.py +14 -6
- infrahub/core/schema/schema_branch.py +292 -144
- infrahub/core/schema/schema_branch_computed.py +41 -4
- infrahub/core/task/task.py +3 -3
- infrahub/core/task/user_task.py +15 -15
- infrahub/core/timestamp.py +3 -3
- infrahub/core/utils.py +20 -18
- infrahub/core/validators/__init__.py +1 -3
- infrahub/core/validators/aggregated_checker.py +2 -2
- infrahub/core/validators/attribute/choices.py +2 -2
- infrahub/core/validators/attribute/enum.py +2 -2
- infrahub/core/validators/attribute/kind.py +2 -2
- infrahub/core/validators/attribute/length.py +2 -2
- infrahub/core/validators/attribute/optional.py +2 -2
- infrahub/core/validators/attribute/regex.py +2 -2
- infrahub/core/validators/attribute/unique.py +2 -2
- infrahub/core/validators/checks_runner.py +25 -2
- infrahub/core/validators/determiner.py +1 -3
- infrahub/core/validators/interface.py +6 -2
- infrahub/core/validators/model.py +22 -3
- infrahub/core/validators/models/validate_migration.py +17 -4
- infrahub/core/validators/node/attribute.py +2 -2
- infrahub/core/validators/node/generate_profile.py +2 -2
- infrahub/core/validators/node/hierarchy.py +3 -5
- infrahub/core/validators/node/inherit_from.py +27 -5
- infrahub/core/validators/node/relationship.py +2 -2
- infrahub/core/validators/relationship/count.py +4 -4
- infrahub/core/validators/relationship/optional.py +2 -2
- infrahub/core/validators/relationship/peer.py +2 -2
- infrahub/core/validators/shared.py +2 -2
- infrahub/core/validators/tasks.py +8 -0
- infrahub/core/validators/uniqueness/checker.py +22 -21
- infrahub/core/validators/uniqueness/index.py +2 -2
- infrahub/core/validators/uniqueness/model.py +11 -11
- infrahub/database/__init__.py +27 -22
- infrahub/database/metrics.py +7 -1
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +1 -3
- infrahub/dependencies/builder/diff/deserializer.py +3 -1
- infrahub/dependencies/builder/diff/enricher/hierarchy.py +3 -1
- infrahub/dependencies/builder/diff/parent_node_adder.py +8 -0
- infrahub/dependencies/component/registry.py +2 -2
- infrahub/events/__init__.py +25 -2
- infrahub/events/artifact_action.py +64 -0
- infrahub/events/branch_action.py +33 -22
- infrahub/events/generator.py +71 -0
- infrahub/events/group_action.py +51 -21
- infrahub/events/models.py +18 -19
- infrahub/events/node_action.py +88 -37
- infrahub/events/repository_action.py +5 -18
- infrahub/events/schema_action.py +4 -9
- infrahub/events/utils.py +16 -0
- infrahub/events/validator_action.py +55 -0
- infrahub/exceptions.py +32 -24
- infrahub/generators/models.py +2 -3
- infrahub/generators/tasks.py +24 -4
- infrahub/git/base.py +7 -7
- infrahub/git/integrator.py +48 -24
- infrahub/git/models.py +101 -9
- infrahub/git/repository.py +3 -3
- infrahub/git/tasks.py +408 -6
- infrahub/git/utils.py +48 -0
- infrahub/git/worktree.py +1 -2
- infrahub/git_credential/askpass.py +1 -2
- infrahub/graphql/analyzer.py +12 -0
- infrahub/graphql/app.py +13 -15
- infrahub/graphql/context.py +39 -0
- infrahub/graphql/initialization.py +3 -0
- infrahub/graphql/loaders/node.py +2 -12
- infrahub/graphql/loaders/peers.py +77 -0
- infrahub/graphql/loaders/shared.py +13 -0
- infrahub/graphql/manager.py +17 -19
- infrahub/graphql/mutations/artifact_definition.py +5 -5
- infrahub/graphql/mutations/branch.py +26 -1
- infrahub/graphql/mutations/computed_attribute.py +9 -5
- infrahub/graphql/mutations/diff.py +23 -11
- infrahub/graphql/mutations/diff_conflict.py +5 -0
- infrahub/graphql/mutations/generator.py +83 -0
- infrahub/graphql/mutations/graphql_query.py +5 -5
- infrahub/graphql/mutations/ipam.py +54 -74
- infrahub/graphql/mutations/main.py +195 -132
- infrahub/graphql/mutations/menu.py +7 -7
- infrahub/graphql/mutations/models.py +2 -4
- infrahub/graphql/mutations/node_getter/by_default_filter.py +10 -10
- infrahub/graphql/mutations/node_getter/by_hfid.py +1 -3
- infrahub/graphql/mutations/node_getter/by_id.py +1 -3
- infrahub/graphql/mutations/node_getter/interface.py +1 -2
- infrahub/graphql/mutations/proposed_change.py +7 -7
- infrahub/graphql/mutations/relationship.py +93 -19
- infrahub/graphql/mutations/repository.py +8 -8
- infrahub/graphql/mutations/resource_manager.py +3 -3
- infrahub/graphql/mutations/schema.py +19 -4
- infrahub/graphql/mutations/webhook.py +137 -0
- infrahub/graphql/parser.py +4 -4
- infrahub/graphql/permissions.py +1 -10
- infrahub/graphql/queries/diff/tree.py +19 -14
- infrahub/graphql/queries/event.py +5 -2
- infrahub/graphql/queries/ipam.py +2 -2
- infrahub/graphql/queries/relationship.py +2 -2
- infrahub/graphql/queries/search.py +2 -2
- infrahub/graphql/resolvers/many_relationship.py +264 -0
- infrahub/graphql/resolvers/resolver.py +13 -110
- infrahub/graphql/schema.py +2 -0
- infrahub/graphql/subscription/graphql_query.py +2 -0
- infrahub/graphql/types/context.py +12 -0
- infrahub/graphql/types/event.py +84 -17
- infrahub/graphql/types/node.py +2 -2
- infrahub/graphql/utils.py +2 -2
- infrahub/groups/ancestors.py +29 -0
- infrahub/groups/parsers.py +107 -0
- infrahub/lock.py +20 -20
- infrahub/menu/constants.py +0 -1
- infrahub/menu/generator.py +9 -21
- infrahub/menu/menu.py +17 -38
- infrahub/menu/models.py +117 -16
- infrahub/menu/repository.py +111 -0
- infrahub/menu/utils.py +5 -8
- infrahub/message_bus/__init__.py +11 -13
- infrahub/message_bus/messages/__init__.py +1 -21
- infrahub/message_bus/messages/check_generator_run.py +3 -3
- infrahub/message_bus/messages/finalize_validator_execution.py +3 -0
- infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +6 -0
- infrahub/message_bus/messages/request_generatordefinition_check.py +2 -0
- infrahub/message_bus/messages/send_echo_request.py +1 -1
- infrahub/message_bus/operations/__init__.py +1 -10
- infrahub/message_bus/operations/check/__init__.py +2 -2
- infrahub/message_bus/operations/check/generator.py +1 -0
- infrahub/message_bus/operations/event/__init__.py +2 -2
- infrahub/message_bus/operations/event/worker.py +0 -3
- infrahub/message_bus/operations/finalize/validator.py +51 -1
- infrahub/message_bus/operations/requests/__init__.py +0 -2
- infrahub/message_bus/operations/requests/generator_definition.py +21 -23
- infrahub/message_bus/operations/requests/proposed_change.py +14 -10
- infrahub/permissions/globals.py +15 -0
- infrahub/pools/number.py +2 -4
- infrahub/proposed_change/models.py +3 -0
- infrahub/proposed_change/tasks.py +58 -45
- infrahub/pytest_plugin.py +13 -10
- infrahub/server.py +2 -3
- infrahub/services/__init__.py +2 -2
- infrahub/services/adapters/cache/__init__.py +4 -6
- infrahub/services/adapters/cache/nats.py +4 -5
- infrahub/services/adapters/cache/redis.py +3 -7
- infrahub/services/adapters/event/__init__.py +1 -1
- infrahub/services/adapters/message_bus/__init__.py +3 -3
- infrahub/services/adapters/message_bus/local.py +2 -2
- infrahub/services/adapters/message_bus/nats.py +4 -4
- infrahub/services/adapters/message_bus/rabbitmq.py +4 -4
- infrahub/services/adapters/workflow/local.py +2 -2
- infrahub/services/component.py +5 -5
- infrahub/services/protocols.py +7 -7
- infrahub/services/scheduler.py +1 -3
- infrahub/task_manager/event.py +102 -9
- infrahub/task_manager/models.py +27 -7
- infrahub/tasks/artifact.py +7 -6
- infrahub/telemetry/__init__.py +0 -0
- infrahub/telemetry/constants.py +9 -0
- infrahub/telemetry/database.py +86 -0
- infrahub/telemetry/models.py +65 -0
- infrahub/telemetry/task_manager.py +77 -0
- infrahub/{tasks/telemetry.py → telemetry/tasks.py} +49 -56
- infrahub/telemetry/utils.py +11 -0
- infrahub/trace.py +4 -4
- infrahub/transformations/tasks.py +2 -2
- infrahub/trigger/catalogue.py +4 -6
- infrahub/trigger/constants.py +0 -8
- infrahub/trigger/models.py +54 -5
- infrahub/trigger/setup.py +90 -0
- infrahub/trigger/tasks.py +35 -84
- infrahub/utils.py +11 -1
- infrahub/validators/__init__.py +0 -0
- infrahub/validators/events.py +42 -0
- infrahub/validators/tasks.py +41 -0
- infrahub/webhook/gather.py +17 -0
- infrahub/webhook/models.py +176 -44
- infrahub/webhook/tasks.py +154 -155
- infrahub/webhook/triggers.py +31 -7
- infrahub/workers/infrahub_async.py +2 -2
- infrahub/workers/utils.py +2 -2
- infrahub/workflows/catalogue.py +86 -35
- infrahub/workflows/initialization.py +8 -2
- infrahub/workflows/models.py +27 -1
- infrahub/workflows/utils.py +10 -1
- infrahub_sdk/client.py +35 -8
- infrahub_sdk/config.py +3 -0
- infrahub_sdk/context.py +13 -0
- infrahub_sdk/ctl/branch.py +3 -2
- infrahub_sdk/ctl/cli_commands.py +5 -1
- infrahub_sdk/ctl/utils.py +0 -16
- infrahub_sdk/exceptions.py +12 -0
- infrahub_sdk/generator.py +4 -1
- infrahub_sdk/graphql.py +45 -13
- infrahub_sdk/node.py +71 -22
- infrahub_sdk/protocols.py +21 -8
- infrahub_sdk/protocols_base.py +32 -11
- infrahub_sdk/query_groups.py +6 -35
- infrahub_sdk/schema/__init__.py +55 -26
- infrahub_sdk/schema/main.py +8 -0
- infrahub_sdk/task/__init__.py +11 -0
- infrahub_sdk/task/constants.py +3 -0
- infrahub_sdk/task/exceptions.py +25 -0
- infrahub_sdk/task/manager.py +551 -0
- infrahub_sdk/task/models.py +74 -0
- infrahub_sdk/testing/schemas/animal.py +9 -0
- infrahub_sdk/timestamp.py +142 -33
- infrahub_sdk/utils.py +29 -1
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/METADATA +8 -6
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/RECORD +349 -293
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/entry_points.txt +1 -0
- infrahub_testcontainers/constants.py +2 -0
- infrahub_testcontainers/container.py +157 -12
- infrahub_testcontainers/docker-compose.test.yml +31 -6
- infrahub_testcontainers/helpers.py +18 -73
- infrahub_testcontainers/host.py +41 -0
- infrahub_testcontainers/measurements.py +93 -0
- infrahub_testcontainers/models.py +38 -0
- infrahub_testcontainers/performance_test.py +166 -0
- infrahub_testcontainers/plugin.py +136 -0
- infrahub_testcontainers/prometheus.yml +30 -0
- infrahub/core/schema/definitions/core.py +0 -2286
- infrahub/message_bus/messages/check_repository_checkdefinition.py +0 -20
- infrahub/message_bus/messages/check_repository_mergeconflicts.py +0 -16
- infrahub/message_bus/messages/check_repository_usercheck.py +0 -26
- infrahub/message_bus/messages/event_branch_create.py +0 -11
- infrahub/message_bus/messages/event_branch_delete.py +0 -11
- infrahub/message_bus/messages/event_branch_rebased.py +0 -9
- infrahub/message_bus/messages/event_node_mutated.py +0 -15
- infrahub/message_bus/messages/event_schema_update.py +0 -9
- infrahub/message_bus/messages/request_repository_checks.py +0 -12
- infrahub/message_bus/messages/request_repository_userchecks.py +0 -18
- infrahub/message_bus/operations/check/repository.py +0 -293
- infrahub/message_bus/operations/event/node.py +0 -20
- infrahub/message_bus/operations/event/schema.py +0 -17
- infrahub/message_bus/operations/requests/repository.py +0 -133
- infrahub/webhook/constants.py +0 -1
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.2.0rc0.dist-info → infrahub_server-1.2.1.dist-info}/WHEEL +0 -0
|
@@ -36,6 +36,7 @@ class DiffMergeQuery(Query):
|
|
|
36
36
|
"target_branch": self.target_branch.name,
|
|
37
37
|
"source_branch": self.source_branch_name,
|
|
38
38
|
}
|
|
39
|
+
# ruff: noqa: E501
|
|
39
40
|
query = """
|
|
40
41
|
UNWIND $node_diff_dicts AS node_diff_map
|
|
41
42
|
CALL {
|
|
@@ -242,9 +243,11 @@ CALL {
|
|
|
242
243
|
CASE
|
|
243
244
|
WHEN startNode(source_r_rel_2).uuid = r.uuid THEN "r"
|
|
244
245
|
ELSE "l"
|
|
245
|
-
END AS r2_dir
|
|
246
|
+
END AS r2_dir,
|
|
247
|
+
source_r_rel_1.hierarchy AS r1_hierarchy,
|
|
248
|
+
source_r_rel_2.hierarchy AS r2_hierarchy
|
|
246
249
|
}
|
|
247
|
-
WITH n, r, r1_dir, r2_dir, rel_name, rel_peer_id, related_rel_status
|
|
250
|
+
WITH n, r, r1_dir, r2_dir, r1_hierarchy, r2_hierarchy, rel_name, rel_peer_id, related_rel_status
|
|
248
251
|
CALL {
|
|
249
252
|
WITH n, rel_name, rel_peer_id, related_rel_status
|
|
250
253
|
OPTIONAL MATCH (n)
|
|
@@ -258,12 +261,12 @@ CALL {
|
|
|
258
261
|
SET target_r_rel_1.to = $at
|
|
259
262
|
SET target_r_rel_2.to = $at
|
|
260
263
|
}
|
|
261
|
-
WITH n, r, r1_dir, r2_dir, rel_name, rel_peer_id, related_rel_status
|
|
264
|
+
WITH n, r, r1_dir, r2_dir, r1_hierarchy, r2_hierarchy, rel_name, rel_peer_id, related_rel_status
|
|
262
265
|
// ------------------------------
|
|
263
266
|
// conditionally create new IS_RELATED relationships on target_branch, if necessary
|
|
264
267
|
// ------------------------------
|
|
265
268
|
CALL {
|
|
266
|
-
WITH n, r, r1_dir, r2_dir, rel_name, rel_peer_id, related_rel_status
|
|
269
|
+
WITH n, r, r1_dir, r2_dir, r1_hierarchy, r2_hierarchy, rel_name, rel_peer_id, related_rel_status
|
|
267
270
|
MATCH (p:Node {uuid: rel_peer_id})
|
|
268
271
|
OPTIONAL MATCH (n)
|
|
269
272
|
-[r_rel_1:IS_RELATED {branch: $target_branch, status: related_rel_status}]
|
|
@@ -274,42 +277,42 @@ CALL {
|
|
|
274
277
|
AND (r_rel_1.to >= $at OR r_rel_1.to IS NULL)
|
|
275
278
|
AND r_rel_2.from <= $at
|
|
276
279
|
AND (r_rel_2.to >= $at OR r_rel_2.to IS NULL)
|
|
277
|
-
WITH n, r, r1_dir, r2_dir, p, related_rel_status, r_rel_1, r_rel_2
|
|
280
|
+
WITH n, r, r1_dir, r2_dir, r1_hierarchy, r2_hierarchy, p, related_rel_status, r_rel_1, r_rel_2
|
|
278
281
|
WHERE r_rel_1 IS NULL
|
|
279
282
|
AND r_rel_2 IS NULL
|
|
280
283
|
// ------------------------------
|
|
281
284
|
// create IS_RELATED relationships with directions maintained from source
|
|
282
285
|
// ------------------------------
|
|
283
286
|
CALL {
|
|
284
|
-
WITH n, r, r1_dir, related_rel_status
|
|
285
|
-
WITH n, r, r1_dir, related_rel_status
|
|
287
|
+
WITH n, r, r1_dir, r1_hierarchy, related_rel_status
|
|
288
|
+
WITH n, r, r1_dir, r1_hierarchy, related_rel_status
|
|
286
289
|
WHERE r1_dir = "r"
|
|
287
290
|
CREATE (n)
|
|
288
|
-
-[:IS_RELATED {branch: $target_branch, branch_level: $branch_level, from: $at, status: related_rel_status}]
|
|
291
|
+
-[:IS_RELATED {branch: $target_branch, branch_level: $branch_level, from: $at, status: related_rel_status, hierarchy: r1_hierarchy}]
|
|
289
292
|
->(r)
|
|
290
293
|
}
|
|
291
294
|
CALL {
|
|
292
|
-
WITH n, r, r1_dir, related_rel_status
|
|
293
|
-
WITH n, r, r1_dir, related_rel_status
|
|
295
|
+
WITH n, r, r1_dir, r1_hierarchy, related_rel_status
|
|
296
|
+
WITH n, r, r1_dir, r1_hierarchy, related_rel_status
|
|
294
297
|
WHERE r1_dir = "l"
|
|
295
298
|
CREATE (n)
|
|
296
|
-
<-[:IS_RELATED {branch: $target_branch, branch_level: $branch_level, from: $at, status: related_rel_status}]
|
|
299
|
+
<-[:IS_RELATED {branch: $target_branch, branch_level: $branch_level, from: $at, status: related_rel_status, hierarchy: r1_hierarchy}]
|
|
297
300
|
-(r)
|
|
298
301
|
}
|
|
299
302
|
CALL {
|
|
300
|
-
WITH r, p, r2_dir, related_rel_status
|
|
301
|
-
WITH r, p, r2_dir, related_rel_status
|
|
303
|
+
WITH r, p, r2_dir, r2_hierarchy, related_rel_status
|
|
304
|
+
WITH r, p, r2_dir, r2_hierarchy, related_rel_status
|
|
302
305
|
WHERE r2_dir = "r"
|
|
303
306
|
CREATE (r)
|
|
304
|
-
-[:IS_RELATED {branch: $target_branch, branch_level: $branch_level, from: $at, status: related_rel_status}]
|
|
307
|
+
-[:IS_RELATED {branch: $target_branch, branch_level: $branch_level, from: $at, status: related_rel_status, hierarchy: r2_hierarchy}]
|
|
305
308
|
->(p)
|
|
306
309
|
}
|
|
307
310
|
CALL {
|
|
308
|
-
WITH r, p, r2_dir, related_rel_status
|
|
309
|
-
WITH r, p, r2_dir, related_rel_status
|
|
311
|
+
WITH r, p, r2_dir, r2_hierarchy, related_rel_status
|
|
312
|
+
WITH r, p, r2_dir, r2_hierarchy, related_rel_status
|
|
310
313
|
WHERE r2_dir = "l"
|
|
311
314
|
CREATE (r)
|
|
312
|
-
<-[:IS_RELATED {branch: $target_branch, branch_level: $branch_level, from: $at, status: related_rel_status}]
|
|
315
|
+
<-[:IS_RELATED {branch: $target_branch, branch_level: $branch_level, from: $at, status: related_rel_status, hierarchy: r2_hierarchy}]
|
|
313
316
|
-(p)
|
|
314
317
|
}
|
|
315
318
|
}
|
infrahub/core/diff/query/save.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any
|
|
1
|
+
from typing import Any, Iterable
|
|
2
2
|
|
|
3
3
|
from infrahub.core.query import Query, QueryType
|
|
4
4
|
from infrahub.database import InfrahubDatabase
|
|
@@ -42,6 +42,7 @@ CALL {
|
|
|
42
42
|
}
|
|
43
43
|
WITH DISTINCT diff_root AS diff_root
|
|
44
44
|
WITH collect(diff_root) AS diff_roots
|
|
45
|
+
WHERE SIZE(diff_roots) = 2
|
|
45
46
|
CALL {
|
|
46
47
|
WITH diff_roots
|
|
47
48
|
WITH diff_roots[0] AS base_diff_node, diff_roots[1] AS branch_diff_node
|
|
@@ -81,34 +82,59 @@ class EnrichedNodeBatchCreateQuery(Query):
|
|
|
81
82
|
self.params = self._build_node_batch_params()
|
|
82
83
|
query = """
|
|
83
84
|
UNWIND $node_details_list AS node_details
|
|
84
|
-
WITH
|
|
85
|
+
WITH
|
|
86
|
+
node_details.root_uuid AS root_uuid,
|
|
87
|
+
node_details.node_map AS node_map,
|
|
88
|
+
toString(node_details.node_map.node_properties.uuid) AS node_uuid
|
|
89
|
+
MERGE (diff_root:DiffRoot {uuid: root_uuid})
|
|
90
|
+
MERGE (diff_root)-[:DIFF_HAS_NODE]->(diff_node:DiffNode {uuid: node_uuid})
|
|
91
|
+
WITH root_uuid, node_map, diff_node, (node_map.conflict_params IS NOT NULL) AS has_node_conflict
|
|
92
|
+
SET
|
|
93
|
+
diff_node.kind = node_map.node_properties.kind,
|
|
94
|
+
diff_node.label = node_map.node_properties.label,
|
|
95
|
+
diff_node.changed_at = node_map.node_properties.changed_at,
|
|
96
|
+
diff_node.action = node_map.node_properties.action,
|
|
97
|
+
diff_node.path_identifier = node_map.node_properties.path_identifier
|
|
98
|
+
WITH root_uuid, node_map, diff_node, has_node_conflict
|
|
85
99
|
CALL {
|
|
86
|
-
WITH root_uuid, node_map
|
|
87
|
-
MATCH (diff_root {uuid: root_uuid})
|
|
88
|
-
MERGE (diff_root)-[:DIFF_HAS_NODE]->(diff_node:DiffNode {uuid: node_map.node_properties.uuid})
|
|
89
|
-
SET
|
|
90
|
-
diff_node.kind = node_map.node_properties.kind,
|
|
91
|
-
diff_node.label = node_map.node_properties.label,
|
|
92
|
-
diff_node.changed_at = node_map.node_properties.changed_at,
|
|
93
|
-
diff_node.action = node_map.node_properties.action,
|
|
94
|
-
diff_node.path_identifier = node_map.node_properties.path_identifier
|
|
95
100
|
// -------------------------
|
|
96
|
-
//
|
|
101
|
+
// delete parent-child relationships for included nodes, they will be added in EnrichedNodesLinkQuery
|
|
97
102
|
// -------------------------
|
|
98
|
-
WITH diff_node
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
WITH diff_node
|
|
104
|
+
MATCH (diff_node)-[:DIFF_HAS_RELATIONSHIP]->(:DiffRelationship)-[parent_rel:DIFF_HAS_NODE]->(:DiffNode)
|
|
105
|
+
DELETE parent_rel
|
|
106
|
+
}
|
|
107
|
+
OPTIONAL MATCH (diff_node)-[:DIFF_HAS_CONFLICT]->(current_node_conflict:DiffConflict)
|
|
108
|
+
CALL {
|
|
109
|
+
// -------------------------
|
|
110
|
+
// create a node-level conflict, if necessary
|
|
111
|
+
// -------------------------
|
|
112
|
+
WITH diff_node, current_node_conflict, has_node_conflict
|
|
113
|
+
WITH diff_node, current_node_conflict, has_node_conflict
|
|
114
|
+
WHERE current_node_conflict IS NULL AND has_node_conflict = TRUE
|
|
115
|
+
CREATE (diff_node)-[:DIFF_HAS_CONFLICT]->(:DiffConflict)
|
|
116
|
+
}
|
|
117
|
+
CALL {
|
|
118
|
+
// -------------------------
|
|
119
|
+
// delete a node-level conflict, if necessary
|
|
120
|
+
// -------------------------
|
|
121
|
+
WITH current_node_conflict, has_node_conflict
|
|
122
|
+
WITH current_node_conflict, has_node_conflict
|
|
123
|
+
WHERE current_node_conflict IS NOT NULL AND has_node_conflict = FALSE
|
|
124
|
+
DETACH DELETE current_node_conflict
|
|
125
|
+
}
|
|
126
|
+
WITH root_uuid, node_map, diff_node, has_node_conflict, node_map.conflict_params AS node_conflict_params
|
|
127
|
+
CALL {
|
|
128
|
+
// -------------------------
|
|
129
|
+
// set the properties of the node-level conflict, if necessary
|
|
130
|
+
// -------------------------
|
|
131
|
+
WITH diff_node, has_node_conflict, node_conflict_params
|
|
132
|
+
WITH diff_node, has_node_conflict, node_conflict_params
|
|
133
|
+
WHERE has_node_conflict = TRUE
|
|
134
|
+
OPTIONAL MATCH (diff_node)-[:DIFF_HAS_CONFLICT]->(node_conflict:DiffConflict)
|
|
135
|
+
SET node_conflict = node_conflict_params
|
|
108
136
|
}
|
|
109
137
|
CALL {
|
|
110
|
-
WITH root_uuid, node_map
|
|
111
|
-
MATCH (diff_root {uuid: root_uuid})-[:DIFF_HAS_NODE]->(diff_node:DiffNode {uuid: node_map.node_properties.uuid})
|
|
112
138
|
// -------------------------
|
|
113
139
|
// remove stale attributes for this node
|
|
114
140
|
// -------------------------
|
|
@@ -125,138 +151,131 @@ CALL {
|
|
|
125
151
|
// -------------------------
|
|
126
152
|
// add attributes for this node
|
|
127
153
|
// -------------------------
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
MERGE (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(diff_attribute:DiffAttribute {name: node_attribute.node_properties.name})
|
|
132
|
-
SET diff_attribute = node_attribute.node_properties
|
|
133
|
-
// -------------------------
|
|
134
|
-
// add properties for this attribute
|
|
135
|
-
// -------------------------
|
|
136
|
-
WITH diff_attribute, node_attribute
|
|
137
|
-
// -------------------------
|
|
138
|
-
// remove stale properties for this attribute
|
|
139
|
-
// -------------------------
|
|
140
|
-
CALL {
|
|
141
|
-
WITH diff_attribute, node_attribute
|
|
142
|
-
WITH diff_attribute, %(attr_props_list_comp)s AS prop_types
|
|
143
|
-
OPTIONAL MATCH (diff_attribute)-[:DIFF_HAS_PROPERTY]->(prop_to_delete:DiffProperty)
|
|
144
|
-
WHERE NOT (prop_to_delete.property_type IN prop_types)
|
|
145
|
-
OPTIONAL MATCH (prop_to_delete)-[*..4]->(next_to_delete)
|
|
146
|
-
DETACH DELETE next_to_delete
|
|
147
|
-
DETACH DELETE prop_to_delete
|
|
148
|
-
}
|
|
149
|
-
UNWIND node_attribute.properties AS attr_property
|
|
150
|
-
MERGE (diff_attribute)-[:DIFF_HAS_PROPERTY]->(diff_attr_prop:DiffProperty {property_type: attr_property.node_properties.property_type})
|
|
151
|
-
SET diff_attr_prop = attr_property.node_properties
|
|
152
|
-
// -------------------------
|
|
153
|
-
// add/remove conflict for this property
|
|
154
|
-
// -------------------------
|
|
155
|
-
WITH diff_attr_prop, attr_property
|
|
156
|
-
OPTIONAL MATCH (diff_attr_prop)-[:DIFF_HAS_CONFLICT]->(current_attr_prop_conflict:DiffConflict)
|
|
157
|
-
WITH diff_attr_prop, attr_property, current_attr_prop_conflict, (attr_property.conflict_params IS NOT NULL) AS has_prop_conflict
|
|
158
|
-
FOREACH (i in CASE WHEN has_prop_conflict = FALSE THEN [1] ELSE [] END |
|
|
159
|
-
DETACH DELETE current_attr_prop_conflict
|
|
160
|
-
)
|
|
161
|
-
FOREACH (i in CASE WHEN has_prop_conflict = TRUE THEN [1] ELSE [] END |
|
|
162
|
-
MERGE (diff_attr_prop)-[:DIFF_HAS_CONFLICT]->(diff_attr_prop_conflict:DiffConflict)
|
|
163
|
-
SET diff_attr_prop_conflict = attr_property.conflict_params
|
|
164
|
-
)
|
|
165
|
-
}
|
|
154
|
+
UNWIND node_map.attributes AS node_attribute
|
|
155
|
+
MERGE (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(diff_attribute:DiffAttribute {name: node_attribute.node_properties.name})
|
|
156
|
+
SET diff_attribute = node_attribute.node_properties
|
|
166
157
|
// -------------------------
|
|
167
|
-
//
|
|
158
|
+
// add properties for this attribute
|
|
159
|
+
// -------------------------
|
|
160
|
+
WITH diff_attribute, node_attribute
|
|
161
|
+
// -------------------------
|
|
162
|
+
// remove stale properties for this attribute
|
|
168
163
|
// -------------------------
|
|
169
|
-
WITH diff_node, node_map
|
|
170
164
|
CALL {
|
|
171
|
-
WITH
|
|
172
|
-
WITH
|
|
173
|
-
OPTIONAL MATCH (
|
|
174
|
-
WHERE NOT (
|
|
175
|
-
OPTIONAL MATCH (
|
|
165
|
+
WITH diff_attribute, node_attribute
|
|
166
|
+
WITH diff_attribute, %(attr_props_list_comp)s AS prop_types
|
|
167
|
+
OPTIONAL MATCH (diff_attribute)-[:DIFF_HAS_PROPERTY]->(prop_to_delete:DiffProperty)
|
|
168
|
+
WHERE NOT (prop_to_delete.property_type IN prop_types)
|
|
169
|
+
OPTIONAL MATCH (prop_to_delete)-[*..4]->(next_to_delete)
|
|
176
170
|
DETACH DELETE next_to_delete
|
|
177
|
-
DETACH DELETE
|
|
171
|
+
DETACH DELETE prop_to_delete
|
|
178
172
|
}
|
|
173
|
+
UNWIND node_attribute.properties AS attr_property
|
|
174
|
+
MERGE (diff_attribute)-[:DIFF_HAS_PROPERTY]->(diff_attr_prop:DiffProperty {property_type: attr_property.node_properties.property_type})
|
|
175
|
+
SET diff_attr_prop = attr_property.node_properties
|
|
179
176
|
// -------------------------
|
|
180
|
-
// add
|
|
177
|
+
// add/remove conflict for this property
|
|
181
178
|
// -------------------------
|
|
179
|
+
WITH diff_attr_prop, attr_property
|
|
180
|
+
OPTIONAL MATCH (diff_attr_prop)-[:DIFF_HAS_CONFLICT]->(current_attr_prop_conflict:DiffConflict)
|
|
181
|
+
WITH diff_attr_prop, attr_property, current_attr_prop_conflict, (attr_property.conflict_params IS NOT NULL) AS has_prop_conflict
|
|
182
|
+
FOREACH (i in CASE WHEN has_prop_conflict = FALSE THEN [1] ELSE [] END |
|
|
183
|
+
DETACH DELETE current_attr_prop_conflict
|
|
184
|
+
)
|
|
185
|
+
FOREACH (i in CASE WHEN has_prop_conflict = TRUE THEN [1] ELSE [] END |
|
|
186
|
+
MERGE (diff_attr_prop)-[:DIFF_HAS_CONFLICT]->(diff_attr_prop_conflict:DiffConflict)
|
|
187
|
+
SET diff_attr_prop_conflict = attr_property.conflict_params
|
|
188
|
+
)
|
|
189
|
+
}
|
|
190
|
+
// -------------------------
|
|
191
|
+
// remove stale relationships for this node
|
|
192
|
+
// -------------------------
|
|
193
|
+
CALL {
|
|
182
194
|
WITH diff_node, node_map
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
// remove stale elements for this relationship group
|
|
190
|
-
// -------------------------
|
|
191
|
-
WITH diff_relationship, node_relationship
|
|
192
|
-
CALL {
|
|
193
|
-
WITH diff_relationship, node_relationship
|
|
194
|
-
WITH diff_relationship, %(rel_peers_list_comp)s AS rel_peers
|
|
195
|
-
OPTIONAL MATCH (diff_relationship)-[:DIFF_HAS_ELEMENT]->(element_to_delete:DiffRelationshipElement)
|
|
196
|
-
WHERE NOT (element_to_delete.peer_id IN rel_peers)
|
|
197
|
-
OPTIONAL MATCH (element_to_delete)-[*..6]->(next_to_delete)
|
|
198
|
-
DETACH DELETE next_to_delete
|
|
199
|
-
DETACH DELETE element_to_delete
|
|
200
|
-
}
|
|
201
|
-
// -------------------------
|
|
202
|
-
// add elements for this relationship group
|
|
203
|
-
// -------------------------
|
|
204
|
-
WITH diff_relationship, node_relationship
|
|
205
|
-
UNWIND node_relationship.relationships as node_single_relationship
|
|
206
|
-
MERGE (diff_relationship)-[:DIFF_HAS_ELEMENT]
|
|
207
|
-
->(diff_relationship_element:DiffRelationshipElement {peer_id: node_single_relationship.node_properties.peer_id})
|
|
208
|
-
SET diff_relationship_element = node_single_relationship.node_properties
|
|
209
|
-
// -------------------------
|
|
210
|
-
// add/remove conflict for this relationship element
|
|
211
|
-
// -------------------------
|
|
212
|
-
WITH diff_relationship_element, node_single_relationship
|
|
213
|
-
OPTIONAL MATCH (diff_relationship_element)-[:DIFF_HAS_CONFLICT]->(current_element_conflict:DiffConflict)
|
|
214
|
-
WITH diff_relationship_element, node_single_relationship, current_element_conflict,
|
|
215
|
-
(node_single_relationship.conflict_params IS NOT NULL) AS has_element_conflict
|
|
216
|
-
FOREACH (i in CASE WHEN has_element_conflict = FALSE THEN [1] ELSE [] END |
|
|
217
|
-
DETACH DELETE current_element_conflict
|
|
218
|
-
)
|
|
219
|
-
FOREACH (i in CASE WHEN has_element_conflict = TRUE THEN [1] ELSE [] END |
|
|
220
|
-
MERGE (diff_relationship_element)-[:DIFF_HAS_CONFLICT]->(element_conflict:DiffConflict)
|
|
221
|
-
SET element_conflict = node_single_relationship.conflict_params
|
|
222
|
-
)
|
|
223
|
-
// -------------------------
|
|
224
|
-
// remove stale properties for this relationship element
|
|
225
|
-
// -------------------------
|
|
226
|
-
WITH diff_relationship_element, node_single_relationship
|
|
227
|
-
CALL {
|
|
228
|
-
WITH diff_relationship_element, node_single_relationship
|
|
229
|
-
WITH diff_relationship_element, %(element_props_list_comp)s AS element_props
|
|
230
|
-
OPTIONAL MATCH (diff_relationship_element)-[:DIFF_HAS_PROPERTY]->(property_to_delete:DiffProperty)
|
|
231
|
-
WHERE NOT (property_to_delete.property_type IN element_props)
|
|
232
|
-
OPTIONAL MATCH (property_to_delete)-[*..4]->(next_to_delete)
|
|
233
|
-
DETACH DELETE next_to_delete
|
|
234
|
-
DETACH DELETE property_to_delete
|
|
235
|
-
}
|
|
236
|
-
// -------------------------
|
|
237
|
-
// add properties for this relationship element
|
|
238
|
-
// -------------------------
|
|
239
|
-
WITH diff_relationship_element, node_single_relationship
|
|
240
|
-
UNWIND node_single_relationship.properties as node_relationship_property
|
|
241
|
-
MERGE (diff_relationship_element)-[:DIFF_HAS_PROPERTY]
|
|
242
|
-
->(diff_relationship_property:DiffProperty {property_type: node_relationship_property.node_properties.property_type})
|
|
243
|
-
SET diff_relationship_property = node_relationship_property.node_properties
|
|
244
|
-
// -------------------------
|
|
245
|
-
// add conflict for this relationship element
|
|
246
|
-
// -------------------------
|
|
247
|
-
WITH diff_relationship_property, node_relationship_property
|
|
248
|
-
OPTIONAL MATCH (diff_relationship_property)-[:DIFF_HAS_CONFLICT]->(diff_relationship_property_conflict:DiffConflict)
|
|
249
|
-
WITH diff_relationship_property, node_relationship_property, diff_relationship_property_conflict,
|
|
250
|
-
(node_relationship_property.conflict_params IS NOT NULL) AS has_property_conflict
|
|
251
|
-
FOREACH (i in CASE WHEN has_property_conflict = FALSE THEN [1] ELSE [] END |
|
|
252
|
-
DETACH DELETE diff_relationship_property_conflict
|
|
253
|
-
)
|
|
254
|
-
FOREACH (i in CASE WHEN has_property_conflict = TRUE THEN [1] ELSE [] END |
|
|
255
|
-
MERGE (diff_relationship_property)-[:DIFF_HAS_CONFLICT]->(property_conflict:DiffConflict)
|
|
256
|
-
SET property_conflict = node_relationship_property.conflict_params
|
|
257
|
-
)
|
|
258
|
-
}
|
|
195
|
+
WITH diff_node, %(rel_name_list_comp)s AS rel_names
|
|
196
|
+
OPTIONAL MATCH (diff_node)-[:DIFF_HAS_RELATIONSHIP]->(rel_to_delete:DiffRelationship)
|
|
197
|
+
WHERE NOT (rel_to_delete.name IN rel_names)
|
|
198
|
+
OPTIONAL MATCH (rel_to_delete)-[*..8]->(next_to_delete)
|
|
199
|
+
DETACH DELETE next_to_delete
|
|
200
|
+
DETACH DELETE rel_to_delete
|
|
259
201
|
}
|
|
202
|
+
// -------------------------
|
|
203
|
+
// add relationships for this node
|
|
204
|
+
// -------------------------
|
|
205
|
+
WITH diff_node, node_map
|
|
206
|
+
UNWIND node_map.relationships as node_relationship
|
|
207
|
+
MERGE (diff_node)-[:DIFF_HAS_RELATIONSHIP]->(diff_relationship:DiffRelationship {name: node_relationship.node_properties.name})
|
|
208
|
+
SET diff_relationship = node_relationship.node_properties
|
|
209
|
+
// -------------------------
|
|
210
|
+
// remove stale elements for this relationship group
|
|
211
|
+
// -------------------------
|
|
212
|
+
WITH diff_relationship, node_relationship
|
|
213
|
+
CALL {
|
|
214
|
+
WITH diff_relationship, node_relationship
|
|
215
|
+
WITH diff_relationship, %(rel_peers_list_comp)s AS rel_peers
|
|
216
|
+
OPTIONAL MATCH (diff_relationship)-[:DIFF_HAS_ELEMENT]->(element_to_delete:DiffRelationshipElement)
|
|
217
|
+
WHERE NOT (element_to_delete.peer_id IN rel_peers)
|
|
218
|
+
OPTIONAL MATCH (element_to_delete)-[*..6]->(next_to_delete)
|
|
219
|
+
DETACH DELETE next_to_delete
|
|
220
|
+
DETACH DELETE element_to_delete
|
|
221
|
+
}
|
|
222
|
+
// -------------------------
|
|
223
|
+
// add elements for this relationship group
|
|
224
|
+
// -------------------------
|
|
225
|
+
WITH diff_relationship, node_relationship
|
|
226
|
+
UNWIND node_relationship.relationships as node_single_relationship
|
|
227
|
+
MERGE (diff_relationship)-[:DIFF_HAS_ELEMENT]
|
|
228
|
+
->(diff_relationship_element:DiffRelationshipElement {peer_id: node_single_relationship.node_properties.peer_id})
|
|
229
|
+
SET diff_relationship_element = node_single_relationship.node_properties
|
|
230
|
+
// -------------------------
|
|
231
|
+
// add/remove conflict for this relationship element
|
|
232
|
+
// -------------------------
|
|
233
|
+
WITH diff_relationship_element, node_single_relationship
|
|
234
|
+
OPTIONAL MATCH (diff_relationship_element)-[:DIFF_HAS_CONFLICT]->(current_element_conflict:DiffConflict)
|
|
235
|
+
WITH diff_relationship_element, node_single_relationship, current_element_conflict,
|
|
236
|
+
(node_single_relationship.conflict_params IS NOT NULL) AS has_element_conflict
|
|
237
|
+
FOREACH (i in CASE WHEN has_element_conflict = FALSE THEN [1] ELSE [] END |
|
|
238
|
+
DETACH DELETE current_element_conflict
|
|
239
|
+
)
|
|
240
|
+
FOREACH (i in CASE WHEN has_element_conflict = TRUE THEN [1] ELSE [] END |
|
|
241
|
+
MERGE (diff_relationship_element)-[:DIFF_HAS_CONFLICT]->(element_conflict:DiffConflict)
|
|
242
|
+
SET element_conflict = node_single_relationship.conflict_params
|
|
243
|
+
)
|
|
244
|
+
// -------------------------
|
|
245
|
+
// remove stale properties for this relationship element
|
|
246
|
+
// -------------------------
|
|
247
|
+
WITH diff_relationship_element, node_single_relationship
|
|
248
|
+
CALL {
|
|
249
|
+
WITH diff_relationship_element, node_single_relationship
|
|
250
|
+
WITH diff_relationship_element, %(element_props_list_comp)s AS element_props
|
|
251
|
+
OPTIONAL MATCH (diff_relationship_element)-[:DIFF_HAS_PROPERTY]->(property_to_delete:DiffProperty)
|
|
252
|
+
WHERE NOT (property_to_delete.property_type IN element_props)
|
|
253
|
+
OPTIONAL MATCH (property_to_delete)-[*..4]->(next_to_delete)
|
|
254
|
+
DETACH DELETE next_to_delete
|
|
255
|
+
DETACH DELETE property_to_delete
|
|
256
|
+
}
|
|
257
|
+
// -------------------------
|
|
258
|
+
// add properties for this relationship element
|
|
259
|
+
// -------------------------
|
|
260
|
+
WITH diff_relationship_element, node_single_relationship
|
|
261
|
+
UNWIND node_single_relationship.properties as node_relationship_property
|
|
262
|
+
MERGE (diff_relationship_element)-[:DIFF_HAS_PROPERTY]
|
|
263
|
+
->(diff_relationship_property:DiffProperty {property_type: node_relationship_property.node_properties.property_type})
|
|
264
|
+
SET diff_relationship_property = node_relationship_property.node_properties
|
|
265
|
+
// -------------------------
|
|
266
|
+
// add conflict for this relationship element
|
|
267
|
+
// -------------------------
|
|
268
|
+
WITH diff_relationship_property, node_relationship_property
|
|
269
|
+
OPTIONAL MATCH (diff_relationship_property)-[:DIFF_HAS_CONFLICT]->(diff_relationship_property_conflict:DiffConflict)
|
|
270
|
+
WITH diff_relationship_property, node_relationship_property, diff_relationship_property_conflict,
|
|
271
|
+
(node_relationship_property.conflict_params IS NOT NULL) AS has_property_conflict
|
|
272
|
+
FOREACH (i in CASE WHEN has_property_conflict = FALSE THEN [1] ELSE [] END |
|
|
273
|
+
DETACH DELETE diff_relationship_property_conflict
|
|
274
|
+
)
|
|
275
|
+
FOREACH (i in CASE WHEN has_property_conflict = TRUE THEN [1] ELSE [] END |
|
|
276
|
+
MERGE (diff_relationship_property)-[:DIFF_HAS_CONFLICT]->(property_conflict:DiffConflict)
|
|
277
|
+
SET property_conflict = node_relationship_property.conflict_params
|
|
278
|
+
)
|
|
260
279
|
""" % {
|
|
261
280
|
"attr_name_list_comp": db.render_list_comprehension(
|
|
262
281
|
items="node_map.attributes", item_name="node_properties.name"
|
|
@@ -409,47 +428,34 @@ class EnrichedNodesLinkQuery(Query):
|
|
|
409
428
|
type = QueryType.WRITE
|
|
410
429
|
insert_return = False
|
|
411
430
|
|
|
412
|
-
def __init__(self,
|
|
431
|
+
def __init__(self, diff_root_uuid: str, diff_nodes: Iterable[EnrichedDiffNode], **kwargs: Any) -> None:
|
|
413
432
|
super().__init__(**kwargs)
|
|
414
|
-
self.
|
|
433
|
+
self.diff_root_uuid = diff_root_uuid
|
|
434
|
+
self.diff_nodes = diff_nodes
|
|
415
435
|
|
|
416
436
|
async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
|
|
417
|
-
|
|
418
|
-
for
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
437
|
+
parent_node_map: dict[str, dict[str, str]] = {}
|
|
438
|
+
for diff_node in self.diff_nodes:
|
|
439
|
+
if diff_node.uuid not in parent_node_map:
|
|
440
|
+
parent_node_map[diff_node.uuid] = {}
|
|
441
|
+
for relationship in diff_node.relationships:
|
|
442
|
+
for parent_node in relationship.nodes:
|
|
443
|
+
parent_node_map[diff_node.uuid][relationship.name] = parent_node.uuid
|
|
444
|
+
self.params = {"root_uuid": self.diff_root_uuid, "parent_node_map": parent_node_map}
|
|
422
445
|
query = """
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
node_link_details.child_uuid AS child_uuid,
|
|
428
|
-
node_link_details.relationship_name AS relationship_name
|
|
446
|
+
WITH keys($parent_node_map) AS child_node_uuids
|
|
447
|
+
MATCH (diff_root:DiffRoot {uuid: $root_uuid})
|
|
448
|
+
MATCH (diff_root)-[:DIFF_HAS_NODE]->(child_node:DiffNode)
|
|
449
|
+
WHERE child_node.uuid IN child_node_uuids
|
|
429
450
|
CALL {
|
|
430
|
-
WITH
|
|
431
|
-
|
|
451
|
+
WITH diff_root, child_node
|
|
452
|
+
WITH diff_root, child_node, $parent_node_map[child_node.uuid] AS sub_map
|
|
453
|
+
WITH diff_root, child_node, sub_map, keys(sub_map) AS relationship_names
|
|
454
|
+
MATCH (child_node)-[:DIFF_HAS_RELATIONSHIP]->(diff_rel_group:DiffRelationship)
|
|
455
|
+
WHERE diff_rel_group.name IN relationship_names
|
|
456
|
+
WITH diff_root, diff_rel_group, toString(sub_map[diff_rel_group.name]) AS parent_uuid
|
|
432
457
|
MATCH (diff_root)-[:DIFF_HAS_NODE]->(parent_node:DiffNode {uuid: parent_uuid})
|
|
433
|
-
|
|
434
|
-
MATCH (diff_root)-[:DIFF_HAS_NODE]->(child_node:DiffNode {uuid: child_uuid})
|
|
435
|
-
MERGE (diff_rel_group)-[:DIFF_HAS_NODE]->(child_node)
|
|
458
|
+
MERGE (diff_rel_group)-[:DIFF_HAS_NODE]->(parent_node)
|
|
436
459
|
}
|
|
437
460
|
"""
|
|
438
461
|
self.add_to_query(query)
|
|
439
|
-
|
|
440
|
-
def _build_node_parent_links(self, enriched_node: EnrichedDiffNode, root_uuid: str) -> list[dict[str, str]]:
|
|
441
|
-
if not enriched_node.relationships:
|
|
442
|
-
return []
|
|
443
|
-
parent_links = []
|
|
444
|
-
for relationship in enriched_node.relationships:
|
|
445
|
-
for child_node in relationship.nodes:
|
|
446
|
-
parent_links.append(
|
|
447
|
-
{
|
|
448
|
-
"parent_uuid": enriched_node.uuid,
|
|
449
|
-
"relationship_name": relationship.name,
|
|
450
|
-
"child_uuid": child_node.uuid,
|
|
451
|
-
"root_uuid": root_uuid,
|
|
452
|
-
}
|
|
453
|
-
)
|
|
454
|
-
parent_links.extend(self._build_node_parent_links(enriched_node=child_node, root_uuid=root_uuid))
|
|
455
|
-
return parent_links
|
|
@@ -6,10 +6,10 @@ from infrahub.database import InfrahubDatabase
|
|
|
6
6
|
from ..model.path import TrackingId
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class
|
|
10
|
-
"""Update summary counters for a
|
|
9
|
+
class DiffFieldsSummaryCountsEnricherQuery(Query):
|
|
10
|
+
"""Update summary counters for the attributes and relationshipsin in a diff"""
|
|
11
11
|
|
|
12
|
-
name = "
|
|
12
|
+
name = "diff_fields_summary_count_enricher"
|
|
13
13
|
type = QueryType.WRITE
|
|
14
14
|
insert_return = False
|
|
15
15
|
|
|
@@ -23,7 +23,9 @@ class DiffSummaryCountsEnricherQuery(Query):
|
|
|
23
23
|
) -> None:
|
|
24
24
|
super().__init__(**kwargs)
|
|
25
25
|
if (diff_id is None and tracking_id is None) or (diff_id and tracking_id):
|
|
26
|
-
raise ValueError(
|
|
26
|
+
raise ValueError(
|
|
27
|
+
"DiffFieldsSummaryCountsEnricherQuery requires one and only one of `tracking_id` or `diff_id`"
|
|
28
|
+
)
|
|
27
29
|
self.diff_branch_name = diff_branch_name
|
|
28
30
|
self.tracking_id = tracking_id
|
|
29
31
|
self.diff_id = diff_id
|
|
@@ -138,6 +140,51 @@ CALL {
|
|
|
138
140
|
SET dr.num_removed = num_removed
|
|
139
141
|
}
|
|
140
142
|
}
|
|
143
|
+
"""
|
|
144
|
+
self.add_to_query(query)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class DiffNodesSummaryCountsEnricherQuery(Query):
|
|
148
|
+
"""Update summary counters for the nodes and root in a diff"""
|
|
149
|
+
|
|
150
|
+
name = "diff_nodes_summary_count_enricher"
|
|
151
|
+
type = QueryType.WRITE
|
|
152
|
+
insert_return = False
|
|
153
|
+
|
|
154
|
+
def __init__(
|
|
155
|
+
self,
|
|
156
|
+
diff_branch_name: str,
|
|
157
|
+
tracking_id: TrackingId | None = None,
|
|
158
|
+
diff_id: str | None = None,
|
|
159
|
+
node_uuids: list[str] | None = None,
|
|
160
|
+
**kwargs: Any,
|
|
161
|
+
) -> None:
|
|
162
|
+
super().__init__(**kwargs)
|
|
163
|
+
if (diff_id is None and tracking_id is None) or (diff_id and tracking_id):
|
|
164
|
+
raise ValueError(
|
|
165
|
+
"DiffNodesSummaryCountsEnricherQuery requires one and only one of `tracking_id` or `diff_id`"
|
|
166
|
+
)
|
|
167
|
+
self.diff_branch_name = diff_branch_name
|
|
168
|
+
self.tracking_id = tracking_id
|
|
169
|
+
self.diff_id = diff_id
|
|
170
|
+
if self.tracking_id is None and self.diff_id is None:
|
|
171
|
+
raise RuntimeError("tracking_id or diff_id is required")
|
|
172
|
+
self.node_uuids = node_uuids
|
|
173
|
+
|
|
174
|
+
async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
|
|
175
|
+
self.params = {
|
|
176
|
+
"diff_branch_name": self.diff_branch_name,
|
|
177
|
+
"diff_id": self.diff_id,
|
|
178
|
+
"tracking_id": self.tracking_id.serialize() if self.tracking_id else None,
|
|
179
|
+
"node_uuids": self.node_uuids,
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
query = """
|
|
183
|
+
MATCH (root:DiffRoot)
|
|
184
|
+
WHERE ($diff_id IS NOT NULL AND root.uuid = $diff_id)
|
|
185
|
+
OR ($tracking_id IS NOT NULL AND root.tracking_id = $tracking_id AND root.diff_branch = $diff_branch_name)
|
|
186
|
+
MATCH (root)-[:DIFF_HAS_NODE]->(dn:DiffNode)
|
|
187
|
+
WHERE $node_uuids IS NULL OR dn.uuid IN $node_uuids
|
|
141
188
|
// ----------------------
|
|
142
189
|
// handle node count updates
|
|
143
190
|
// ----------------------
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import TYPE_CHECKING, Any
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
6
|
from uuid import uuid4
|
|
7
7
|
|
|
8
8
|
from infrahub.core.constants import (
|
|
@@ -99,7 +99,7 @@ class DiffPropertyIntermediate:
|
|
|
99
99
|
return self._ordered_values
|
|
100
100
|
|
|
101
101
|
@property
|
|
102
|
-
def earliest_diff_value(self) ->
|
|
102
|
+
def earliest_diff_value(self) -> DiffValueIntermediate | None:
|
|
103
103
|
ordered_values = self.get_ordered_values_asc()
|
|
104
104
|
if not ordered_values:
|
|
105
105
|
return None
|
|
@@ -461,7 +461,7 @@ class DiffQueryParser:
|
|
|
461
461
|
diff_branch: Branch,
|
|
462
462
|
schema_manager: SchemaManager,
|
|
463
463
|
from_time: Timestamp,
|
|
464
|
-
to_time:
|
|
464
|
+
to_time: Timestamp | None = None,
|
|
465
465
|
previous_node_field_specifiers: dict[str, set[str]] | None = None,
|
|
466
466
|
) -> None:
|
|
467
467
|
self.base_branch_name = base_branch.name
|
|
@@ -733,7 +733,7 @@ class DiffQueryParser:
|
|
|
733
733
|
base_property_set = base_diff_relationship.properties_by_db_id.get(db_id)
|
|
734
734
|
if not base_property_set:
|
|
735
735
|
continue
|
|
736
|
-
base_diff_property_by_type: dict[DatabaseEdgeType,
|
|
736
|
+
base_diff_property_by_type: dict[DatabaseEdgeType, DiffRelationshipPropertyIntermediate | None] = {
|
|
737
737
|
DatabaseEdgeType(p.property_type): None for p in property_set
|
|
738
738
|
}
|
|
739
739
|
base_diff_property_by_type[DatabaseEdgeType.IS_RELATED] = None
|