|
9 | 9 |
|
10 | 10 | if TYPE_CHECKING: |
11 | 11 | from infrahub.core.attribute import BaseAttribute |
| 12 | + from infrahub.core.branch import Branch |
12 | 13 | from infrahub.core.manager import RelationshipSchema |
13 | 14 | from infrahub.core.query.relationship import RelationshipPeerData |
14 | 15 | from infrahub.core.relationship.model import Relationship |
| 16 | + from infrahub.database import InfrahubDatabase |
15 | 17 |
|
16 | 18 |
|
17 | 19 | class PropertyChangelog(BaseModel): |
@@ -221,6 +223,11 @@ class NodeChangelog(BaseModel): |
221 | 223 | def parent(self) -> ChangelogNodeParent | None: |
222 | 224 | return self._parent |
223 | 225 |
|
| 226 | + @property |
| 227 | + def updated_fields(self) -> list[str]: |
| 228 | + """Return a list of update fields i.e. attributes and relationships""" |
| 229 | + return list(self.relationships.keys()) + list(self.attributes.keys()) |
| 230 | + |
224 | 231 | @property |
225 | 232 | def root_node_id(self) -> str: |
226 | 233 | """Return the top level node_id""" |
@@ -404,3 +411,50 @@ def changelog(self) -> RelationshipCardinalityOneChangelog | RelationshipCardina |
404 | 411 | return self.cardinality_one_relationship |
405 | 412 | case RelationshipCardinality.MANY: |
406 | 413 | return self.cardinality_many_relationship |
| 414 | + |
| 415 | + |
| 416 | +class RelationshipChangelogGetter: |
| 417 | + def __init__(self, db: InfrahubDatabase, branch: Branch) -> None: |
| 418 | + self._db = db |
| 419 | + self._branch = branch |
| 420 | + |
| 421 | + async def get_changelogs(self, primary_changelog: NodeChangelog) -> list[NodeChangelog]: |
| 422 | + """Return secondary changelogs based on this update |
| 423 | +
|
| 424 | + These will typically include updates to relationships on other nodes. |
| 425 | + """ |
| 426 | + schema_branch = self._db.schema.get_schema_branch(name=self._branch.name) |
| 427 | + node_schema = schema_branch.get(name=primary_changelog.node_kind) |
| 428 | + secondaries: list[NodeChangelog] = [] |
| 429 | + |
| 430 | + for relationship in primary_changelog.relationships.values(): |
| 431 | + rel_schema = node_schema.get_relationship(name=relationship.name) |
| 432 | + if isinstance(relationship, RelationshipCardinalityOneChangelog): |
| 433 | + # For now this code only looks at the scenario when a cardinality=one relationship |
| 434 | + # is added to a node and it has a cardinality=many relationship coming back from |
| 435 | + # another node, it will be expanded to include all variations. |
| 436 | + if relationship.peer_status == DiffAction.ADDED: |
| 437 | + peer_schema = schema_branch.get(name=str(relationship.peer_kind)) |
| 438 | + peer_relation = peer_schema.get_relationship_by_identifier( |
| 439 | + id=str(rel_schema.identifier), raise_on_error=False |
| 440 | + ) |
| 441 | + if peer_relation: |
| 442 | + node_changelog = NodeChangelog( |
| 443 | + node_id=str(relationship.peer_id), |
| 444 | + node_kind=str(relationship.peer_kind), |
| 445 | + display_label="n/a", |
| 446 | + ) |
| 447 | + if peer_relation.cardinality == RelationshipCardinality.MANY: |
| 448 | + node_changelog.relationships[peer_relation.name] = RelationshipCardinalityManyChangelog( |
| 449 | + name=peer_relation.name, |
| 450 | + peers=[ |
| 451 | + RelationshipPeerChangelog( |
| 452 | + peer_id=primary_changelog.node_id, |
| 453 | + peer_kind=primary_changelog.node_kind, |
| 454 | + peer_status=DiffAction.ADDED, |
| 455 | + ) |
| 456 | + ], |
| 457 | + ) |
| 458 | + secondaries.append(node_changelog) |
| 459 | + |
| 460 | + return secondaries |
0 commit comments