@@ -80,6 +80,7 @@ def __init__(self, node_create_batch: list[EnrichedNodeCreateRequest], **kwargs:
8080
8181 async def query_init (self , db : InfrahubDatabase , ** kwargs : Any ) -> None : # noqa: ARG002
8282 self .params = self ._build_node_batch_params ()
83+
8384 query = """
8485UNWIND $node_details_list AS node_details
8586WITH
@@ -136,65 +137,82 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa
136137 OPTIONAL MATCH (diff_node)-[:DIFF_HAS_CONFLICT]->(node_conflict:DiffConflict)
137138 SET node_conflict = node_conflict_params
138139}
140+ // -------------------------
141+ // resetting the UNWIND and starting over here reduces memory usage
142+ // -------------------------
143+ WITH root_uuid LIMIT 1
144+ UNWIND $node_details_list AS node_details
145+ WITH
146+ node_details.root_uuid AS root_uuid,
147+ node_details.node_map AS node_map,
148+ toString(node_details.node_map.node_properties.uuid) AS node_uuid,
149+ node_details.node_map.node_properties.db_id AS node_db_id
150+ MATCH (:DiffRoot {uuid: root_uuid})-[:DIFF_HAS_NODE]->(diff_node:DiffNode {uuid: node_uuid, db_id: node_db_id})
151+ WITH diff_node, node_map, %(attr_name_list_comp)s AS attr_names
152+ OPTIONAL MATCH (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(attr_to_delete:DiffAttribute)
153+ WHERE NOT (attr_to_delete.name IN attr_names)
154+ OPTIONAL MATCH (attr_to_delete)-[*..6]->(next_to_delete)
155+ DETACH DELETE next_to_delete
156+ DETACH DELETE attr_to_delete
157+ // -------------------------
158+ // add attributes for this node
159+ // -------------------------
160+ WITH DISTINCT diff_node, node_map
139161CALL {
140- // -------------------------
141- // remove stale attributes for this node
142- // -------------------------
143162 WITH diff_node, node_map
144- CALL {
145- WITH diff_node, node_map
146- WITH diff_node, %(attr_name_list_comp)s AS attr_names
147- OPTIONAL MATCH (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(attr_to_delete:DiffAttribute)
148- WHERE NOT (attr_to_delete.name IN attr_names)
149- OPTIONAL MATCH (attr_to_delete)-[*..6]->(next_to_delete)
150- DETACH DELETE next_to_delete
151- DETACH DELETE attr_to_delete
152- }
153- // -------------------------
154- // add attributes for this node
155- // -------------------------
156163 UNWIND node_map.attributes AS node_attribute
157164 MERGE (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(diff_attribute:DiffAttribute {name: node_attribute.node_properties.name})
158165 SET diff_attribute = node_attribute.node_properties
159166 // -------------------------
160- // add properties for this attribute
167+ // remove stale properties for this attribute
161168 // -------------------------
162- WITH diff_attribute, node_attribute
169+ WITH diff_attribute, node_attribute, %(attr_props_list_comp)s AS prop_types
170+ OPTIONAL MATCH (diff_attribute)-[:DIFF_HAS_PROPERTY]->(prop_to_delete:DiffProperty)
171+ WHERE NOT (prop_to_delete.property_type IN prop_types)
172+ OPTIONAL MATCH (prop_to_delete)-[*..4]->(next_to_delete)
173+ DETACH DELETE next_to_delete
174+ DETACH DELETE prop_to_delete
163175 // -------------------------
164- // remove stale properties for this attribute
176+ // set attribute property values
165177 // -------------------------
166- CALL {
167- WITH diff_attribute, node_attribute
168- WITH diff_attribute, %(attr_props_list_comp)s AS prop_types
169- OPTIONAL MATCH (diff_attribute)-[:DIFF_HAS_PROPERTY]->(prop_to_delete:DiffProperty)
170- WHERE NOT (prop_to_delete.property_type IN prop_types)
171- OPTIONAL MATCH (prop_to_delete)-[*..4]->(next_to_delete)
172- DETACH DELETE next_to_delete
173- DETACH DELETE prop_to_delete
174- }
178+ WITH DISTINCT diff_attribute, node_attribute
175179 UNWIND node_attribute.properties AS attr_property
176180 MERGE (diff_attribute)-[:DIFF_HAS_PROPERTY]->(diff_attr_prop:DiffProperty {property_type: attr_property.node_properties.property_type})
177181 SET diff_attr_prop = attr_property.node_properties
178- // -------------------------
179- // add/remove conflict for this property
180- // -------------------------
181182 WITH diff_attr_prop, attr_property
182183 OPTIONAL MATCH (diff_attr_prop)-[:DIFF_HAS_CONFLICT]->(current_attr_prop_conflict:DiffConflict)
183184 WITH diff_attr_prop, attr_property, current_attr_prop_conflict, (attr_property.conflict_params IS NOT NULL) AS has_prop_conflict
184- FOREACH (i in CASE WHEN has_prop_conflict = FALSE THEN [1] ELSE [] END |
185+ CALL {
186+ WITH has_prop_conflict, current_attr_prop_conflict
187+ WITH has_prop_conflict, current_attr_prop_conflict
188+ WHERE has_prop_conflict = FALSE AND current_attr_prop_conflict IS NOT NULL
185189 DETACH DELETE current_attr_prop_conflict
186- )
187- FOREACH (i in CASE WHEN has_prop_conflict = TRUE THEN [1] ELSE [] END |
190+ }
191+ CALL {
192+ WITH has_prop_conflict, diff_attr_prop, attr_property
193+ WITH has_prop_conflict, diff_attr_prop, attr_property
194+ WHERE has_prop_conflict = TRUE
188195 MERGE (diff_attr_prop)-[:DIFF_HAS_CONFLICT]->(diff_attr_prop_conflict:DiffConflict)
189196 SET diff_attr_prop_conflict = attr_property.conflict_params
190- )
197+ }
191198}
192199// -------------------------
200+ // resetting the UNWIND and starting over here reduces memory usage
201+ // -------------------------
202+ WITH 1 AS resetting LIMIT 1
203+ UNWIND $node_details_list AS node_details
204+ WITH
205+ node_details.root_uuid AS root_uuid,
206+ node_details.node_map AS node_map,
207+ toString(node_details.node_map.node_properties.uuid) AS node_uuid,
208+ node_details.node_map.node_properties.db_id AS node_db_id
209+ MATCH (:DiffRoot {uuid: root_uuid})-[:DIFF_HAS_NODE]->(diff_node:DiffNode {uuid: node_uuid, db_id: node_db_id})
210+ // -------------------------
193211// remove stale relationships for this node
194212// -------------------------
195213CALL {
196214 WITH diff_node, node_map
197- WITH diff_node, %(rel_name_list_comp)s AS rel_names
215+ WITH diff_node, node_map, %(rel_name_list_comp)s AS rel_names
198216 OPTIONAL MATCH (diff_node)-[:DIFF_HAS_RELATIONSHIP]->(rel_to_delete:DiffRelationship)
199217 WHERE NOT (rel_to_delete.name IN rel_names)
200218 OPTIONAL MATCH (rel_to_delete)-[*..8]->(next_to_delete)
@@ -214,7 +232,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa
214232WITH diff_relationship, node_relationship
215233CALL {
216234 WITH diff_relationship, node_relationship
217- WITH diff_relationship, %(rel_peers_list_comp)s AS rel_peers
235+ WITH diff_relationship, node_relationship, %(rel_peers_list_comp)s AS rel_peers
218236 OPTIONAL MATCH (diff_relationship)-[:DIFF_HAS_ELEMENT]->(element_to_delete:DiffRelationshipElement)
219237 WHERE NOT (element_to_delete.peer_id IN rel_peers)
220238 OPTIONAL MATCH (element_to_delete)-[*..6]->(next_to_delete)
@@ -236,20 +254,26 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa
236254OPTIONAL MATCH (diff_relationship_element)-[:DIFF_HAS_CONFLICT]->(current_element_conflict:DiffConflict)
237255WITH diff_relationship_element, node_single_relationship, current_element_conflict,
238256 (node_single_relationship.conflict_params IS NOT NULL) AS has_element_conflict
239- FOREACH (i in CASE WHEN has_element_conflict = FALSE THEN [1] ELSE [] END |
257+ CALL {
258+ WITH has_element_conflict, current_element_conflict
259+ WITH has_element_conflict, current_element_conflict
260+ WHERE has_element_conflict = FALSE
240261 DETACH DELETE current_element_conflict
241- )
242- FOREACH (i in CASE WHEN has_element_conflict = TRUE THEN [1] ELSE [] END |
262+ }
263+ CALL {
264+ WITH has_element_conflict, diff_relationship_element, node_single_relationship
265+ WITH has_element_conflict, diff_relationship_element, node_single_relationship
266+ WHERE has_element_conflict = TRUE
243267 MERGE (diff_relationship_element)-[:DIFF_HAS_CONFLICT]->(element_conflict:DiffConflict)
244268 SET element_conflict = node_single_relationship.conflict_params
245- )
269+ }
246270// -------------------------
247271// remove stale properties for this relationship element
248272// -------------------------
249273WITH diff_relationship_element, node_single_relationship
250274CALL {
251275 WITH diff_relationship_element, node_single_relationship
252- WITH diff_relationship_element, %(element_props_list_comp)s AS element_props
276+ WITH diff_relationship_element, node_single_relationship, %(element_props_list_comp)s AS element_props
253277 OPTIONAL MATCH (diff_relationship_element)-[:DIFF_HAS_PROPERTY]->(property_to_delete:DiffProperty)
254278 WHERE NOT (property_to_delete.property_type IN element_props)
255279 OPTIONAL MATCH (property_to_delete)-[*..4]->(next_to_delete)
@@ -271,13 +295,19 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa
271295OPTIONAL MATCH (diff_relationship_property)-[:DIFF_HAS_CONFLICT]->(diff_relationship_property_conflict:DiffConflict)
272296WITH diff_relationship_property, node_relationship_property, diff_relationship_property_conflict,
273297 (node_relationship_property.conflict_params IS NOT NULL) AS has_property_conflict
274- FOREACH (i in CASE WHEN has_property_conflict = FALSE THEN [1] ELSE [] END |
298+ CALL {
299+ WITH has_property_conflict, diff_relationship_property_conflict
300+ WITH has_property_conflict, diff_relationship_property_conflict
301+ WHERE has_property_conflict = FALSE
275302 DETACH DELETE diff_relationship_property_conflict
276- )
277- FOREACH (i in CASE WHEN has_property_conflict = TRUE THEN [1] ELSE [] END |
303+ }
304+ CALL {
305+ WITH has_property_conflict, diff_relationship_property, node_relationship_property
306+ WITH has_property_conflict, diff_relationship_property, node_relationship_property
307+ WHERE has_property_conflict = TRUE
278308 MERGE (diff_relationship_property)-[:DIFF_HAS_CONFLICT]->(property_conflict:DiffConflict)
279309 SET property_conflict = node_relationship_property.conflict_params
280- )
310+ }
281311 """ % {
282312 "attr_name_list_comp" : db .render_list_comprehension (
283313 items = "node_map.attributes" , item_name = "node_properties.name"
0 commit comments