@@ -203,15 +203,16 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None:
203203 }
204204 ipnetwork_prop_list = [f"{ key } : { value } " for key , value in ipnetwork_prop .items ()]
205205
206- query = """
207- MATCH (root:Root)
208- CREATE (n:Node:%(labels)s $node_prop )
209- CREATE (n)-[r:IS_PART_OF $node_branch_prop ]->(root)
206+ attrs_query = """
210207 WITH distinct n
211- FOREACH ( attr IN $attrs |
208+ UNWIND $attrs AS attr
209+ CALL {
210+ WITH n, attr
212211 CREATE (a:Attribute { uuid: attr.uuid, name: attr.name, branch_support: attr.branch_support })
213212 CREATE (n)-[:HAS_ATTRIBUTE { branch: attr.branch, branch_level: attr.branch_level, status: attr.status, from: $at }]->(a)
214213 MERGE (av:AttributeValue { value: attr.content.value, is_default: attr.content.is_default })
214+ WITH n, attr, av, a
215+ LIMIT 1
215216 CREATE (a)-[:HAS_VALUE { branch: attr.branch, branch_level: attr.branch_level, status: attr.status, from: $at }]->(av)
216217 MERGE (ip:Boolean { value: attr.is_protected })
217218 MERGE (iv:Boolean { value: attr.is_visible })
@@ -225,11 +226,19 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None:
225226 MERGE (peer:Node { uuid: prop.peer_id })
226227 CREATE (a)-[:HAS_OWNER { branch: attr.branch, branch_level: attr.branch_level, status: attr.status, from: $at }]->(peer)
227228 )
228- )
229- FOREACH ( attr IN $attrs_iphost |
229+ }"""
230+
231+ attrs_iphost_query = """
232+ WITH distinct n
233+ UNWIND $attrs_iphost AS attr_iphost
234+ CALL {
235+ WITH n, attr_iphost
236+ WITH n, attr_iphost AS attr
230237 CREATE (a:Attribute { uuid: attr.uuid, name: attr.name, branch_support: attr.branch_support })
231238 CREATE (n)-[:HAS_ATTRIBUTE { branch: attr.branch, branch_level: attr.branch_level, status: attr.status, from: $at }]->(a)
232239 MERGE (av:AttributeValue:AttributeIPHost { %(iphost_prop)s })
240+ WITH n, attr, av, a
241+ LIMIT 1
233242 CREATE (a)-[:HAS_VALUE { branch: attr.branch, branch_level: attr.branch_level, status: attr.status, from: $at }]->(av)
234243 MERGE (ip:Boolean { value: attr.is_protected })
235244 MERGE (iv:Boolean { value: attr.is_visible })
@@ -243,11 +252,20 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None:
243252 MERGE (peer:Node { uuid: prop.peer_id })
244253 CREATE (a)-[:HAS_OWNER { branch: attr.branch, branch_level: attr.branch_level, status: attr.status, from: $at }]->(peer)
245254 )
246- )
247- FOREACH ( attr IN $attrs_ipnetwork |
255+ }
256+ """ % {"iphost_prop" : ", " .join (iphost_prop_list )}
257+
258+ attrs_ipnetwork_query = """
259+ WITH distinct n
260+ UNWIND $attrs_ipnetwork AS attr_ipnetwork
261+ CALL {
262+ WITH n, attr_ipnetwork
263+ WITH n, attr_ipnetwork AS attr
248264 CREATE (a:Attribute { uuid: attr.uuid, name: attr.name, branch_support: attr.branch_support })
249265 CREATE (n)-[:HAS_ATTRIBUTE { branch: attr.branch, branch_level: attr.branch_level, status: attr.status, from: $at }]->(a)
250266 MERGE (av:AttributeValue:AttributeIPNetwork { %(ipnetwork_prop)s })
267+ WITH n, attr, av, a
268+ LIMIT 1
251269 CREATE (a)-[:HAS_VALUE { branch: attr.branch, branch_level: attr.branch_level, status: attr.status, from: $at }]->(av)
252270 MERGE (ip:Boolean { value: attr.is_protected })
253271 MERGE (iv:Boolean { value: attr.is_visible })
@@ -261,8 +279,14 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None:
261279 MERGE (peer:Node { uuid: prop.peer_id })
262280 CREATE (a)-[:HAS_OWNER { branch: attr.branch, branch_level: attr.branch_level, status: attr.status, from: $at }]->(peer)
263281 )
264- )
265- FOREACH ( rel IN $rels_bidir |
282+ }
283+ """ % {"ipnetwork_prop" : ", " .join (ipnetwork_prop_list )}
284+
285+ rels_bidir_query = """
286+ WITH distinct n
287+ UNWIND $rels_bidir AS rel
288+ CALL {
289+ WITH n, rel
266290 MERGE (d:Node { uuid: rel.destination_id })
267291 CREATE (rl:Relationship { uuid: rel.uuid, name: rel.name, branch_support: rel.branch_support })
268292 CREATE (n)-[:IS_RELATED %(rel_prop)s ]->(rl)
@@ -279,8 +303,15 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None:
279303 MERGE (peer:Node { uuid: prop.peer_id })
280304 CREATE (rl)-[:HAS_OWNER { branch: rel.branch, branch_level: rel.branch_level, status: rel.status, from: $at }]->(peer)
281305 )
282- )
283- FOREACH ( rel IN $rels_out |
306+ }
307+ """ % {"rel_prop" : rel_prop_str }
308+
309+ rels_out_query = """
310+ WITH distinct n
311+ UNWIND $rels_out AS rel_out
312+ CALL {
313+ WITH n, rel_out
314+ WITH n, rel_out as rel
284315 MERGE (d:Node { uuid: rel.destination_id })
285316 CREATE (rl:Relationship { uuid: rel.uuid, name: rel.name, branch_support: rel.branch_support })
286317 CREATE (n)-[:IS_RELATED %(rel_prop)s ]->(rl)
@@ -297,8 +328,15 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None:
297328 MERGE (peer:Node { uuid: prop.peer_id })
298329 CREATE (rl)-[:HAS_OWNER { branch: rel.branch, branch_level: rel.branch_level, status: rel.status, from: $at }]->(peer)
299330 )
300- )
301- FOREACH ( rel IN $rels_in |
331+ }
332+ """ % {"rel_prop" : rel_prop_str }
333+
334+ rels_in_query = """
335+ WITH distinct n
336+ UNWIND $rels_in AS rel_in
337+ CALL {
338+ WITH n, rel_in
339+ WITH n, rel_in AS rel
302340 MERGE (d:Node { uuid: rel.destination_id })
303341 CREATE (rl:Relationship { uuid: rel.uuid, name: rel.name, branch_support: rel.branch_support })
304342 CREATE (n)<-[:IS_RELATED %(rel_prop)s ]-(rl)
@@ -315,14 +353,23 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None:
315353 MERGE (peer:Node { uuid: prop.peer_id })
316354 CREATE (rl)-[:HAS_OWNER { branch: rel.branch, branch_level: rel.branch_level, status: rel.status, from: $at }]->(peer)
317355 )
318- )
356+ }
357+ """ % {"rel_prop" : rel_prop_str }
358+
359+ query = f"""
360+ MATCH (root:Root)
361+ CREATE (n:Node:%(labels)s $node_prop )
362+ CREATE (n)-[r:IS_PART_OF $node_branch_prop ]->(root)
363+ { attrs_query if self .params ["attrs" ] else "" }
364+ { attrs_iphost_query if self .params ["attrs_iphost" ] else "" }
365+ { attrs_ipnetwork_query if self .params ["attrs_ipnetwork" ] else "" }
366+ { rels_bidir_query if self .params ["rels_bidir" ] else "" }
367+ { rels_out_query if self .params ["rels_out" ] else "" }
368+ { rels_in_query if self .params ["rels_in" ] else "" }
319369 WITH distinct n
320370 MATCH (n)-[:HAS_ATTRIBUTE|IS_RELATED]-(rn)-[:HAS_VALUE|IS_RELATED]-(rv)
321371 """ % {
322372 "labels" : ":" .join (self .node .get_labels ()),
323- "rel_prop" : rel_prop_str ,
324- "iphost_prop" : ", " .join (iphost_prop_list ),
325- "ipnetwork_prop" : ", " .join (ipnetwork_prop_list ),
326373 }
327374
328375 self .params ["at" ] = at .to_string ()
0 commit comments