@itwin/imodel-transformer 2.0.0-dev.72 → 2.0.0-dev.74

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.
Files changed (180) hide show
  1. package/README.md +11 -0
  2. package/lib/Algo.d.ts.map +1 -0
  3. package/lib/{cjs/Algo.js → Algo.js} +1 -4
  4. package/lib/Algo.js.map +1 -0
  5. package/lib/BigMap.d.ts.map +1 -0
  6. package/lib/{cjs/BigMap.js → BigMap.js} +1 -5
  7. package/lib/BigMap.js.map +1 -0
  8. package/lib/BranchProvenanceInitializer.d.ts.map +1 -0
  9. package/lib/{cjs/BranchProvenanceInitializer.js → BranchProvenanceInitializer.js} +34 -37
  10. package/lib/BranchProvenanceInitializer.js.map +1 -0
  11. package/lib/ChangedElementForest.d.ts.map +1 -0
  12. package/lib/{cjs/ChangedElementForest.js → ChangedElementForest.js} +12 -14
  13. package/lib/ChangedElementForest.js.map +1 -0
  14. package/lib/{cjs/ChangesetScanner.d.ts → ChangesetScanner.d.ts} +2 -2
  15. package/lib/ChangesetScanner.d.ts.map +1 -0
  16. package/lib/{cjs/ChangesetScanner.js → ChangesetScanner.js} +19 -24
  17. package/lib/ChangesetScanner.js.map +1 -0
  18. package/lib/ECReferenceTypesCache.d.ts.map +1 -0
  19. package/lib/{cjs/ECReferenceTypesCache.js → ECReferenceTypesCache.js} +32 -37
  20. package/lib/ECReferenceTypesCache.js.map +1 -0
  21. package/lib/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +1 -0
  22. package/lib/{cjs/ECSqlReaderAsyncIterableIteratorAdapter.js → ECSqlReaderAsyncIterableIteratorAdapter.js} +2 -7
  23. package/lib/ECSqlReaderAsyncIterableIteratorAdapter.js.map +1 -0
  24. package/lib/ElementAspectCleanup.d.ts.map +1 -0
  25. package/lib/{cjs/ElementAspectCleanup.js → ElementAspectCleanup.js} +9 -13
  26. package/lib/ElementAspectCleanup.js.map +1 -0
  27. package/lib/ElementAspectExportCoordinator.d.ts.map +1 -0
  28. package/lib/{cjs/ElementAspectExportCoordinator.js → ElementAspectExportCoordinator.js} +1 -5
  29. package/lib/ElementAspectExportCoordinator.js.map +1 -0
  30. package/lib/ElementAspectExportProcessor.d.ts.map +1 -0
  31. package/lib/{cjs/ElementAspectExportProcessor.js → ElementAspectExportProcessor.js} +10 -14
  32. package/lib/ElementAspectExportProcessor.js.map +1 -0
  33. package/lib/ElementBulkDelete.d.ts.map +1 -0
  34. package/lib/{cjs/ElementBulkDelete.js → ElementBulkDelete.js} +9 -12
  35. package/lib/{cjs/ElementBulkDelete.js.map → ElementBulkDelete.js.map} +1 -1
  36. package/lib/EntityExistenceCache.d.ts.map +1 -0
  37. package/lib/{cjs/EntityExistenceCache.js → EntityExistenceCache.js} +4 -8
  38. package/lib/EntityExistenceCache.js.map +1 -0
  39. package/lib/EntityUnifier.d.ts.map +1 -0
  40. package/lib/{cjs/EntityUnifier.js → EntityUnifier.js} +21 -22
  41. package/lib/EntityUnifier.js.map +1 -0
  42. package/lib/{cjs/IModelCloneContext.d.ts → IModelCloneContext.d.ts} +2 -2
  43. package/lib/IModelCloneContext.d.ts.map +1 -0
  44. package/lib/{cjs/IModelCloneContext.js → IModelCloneContext.js} +52 -56
  45. package/lib/IModelCloneContext.js.map +1 -0
  46. package/lib/{cjs/IModelExporter.d.ts → IModelExporter.d.ts} +1 -1
  47. package/lib/IModelExporter.d.ts.map +1 -0
  48. package/lib/{cjs/IModelExporter.js → IModelExporter.js} +165 -174
  49. package/lib/IModelExporter.js.map +1 -0
  50. package/lib/{cjs/IModelImporter.d.ts → IModelImporter.d.ts} +3 -3
  51. package/lib/IModelImporter.d.ts.map +1 -0
  52. package/lib/{cjs/IModelImporter.js → IModelImporter.js} +104 -109
  53. package/lib/IModelImporter.js.map +1 -0
  54. package/lib/IModelTransformContext.d.ts.map +1 -0
  55. package/lib/IModelTransformContext.js +2 -0
  56. package/lib/IModelTransformContext.js.map +1 -0
  57. package/lib/{cjs/IModelTransformer.d.ts → IModelTransformer.d.ts} +9 -6
  58. package/lib/IModelTransformer.d.ts.map +1 -0
  59. package/lib/{cjs/IModelTransformer.js → IModelTransformer.js} +297 -337
  60. package/lib/IModelTransformer.js.map +1 -0
  61. package/lib/IModelTransformerError.d.ts.map +1 -0
  62. package/lib/{cjs/IModelTransformerError.js → IModelTransformerError.js} +3 -6
  63. package/lib/IModelTransformerError.js.map +1 -0
  64. package/lib/{cjs/ProvenanceManager.d.ts → ProvenanceManager.d.ts} +3 -3
  65. package/lib/ProvenanceManager.d.ts.map +1 -0
  66. package/lib/{cjs/ProvenanceManager.js → ProvenanceManager.js} +69 -73
  67. package/lib/ProvenanceManager.js.map +1 -0
  68. package/lib/SourceClassKinds.d.ts.map +1 -0
  69. package/lib/{cjs/SourceClassKinds.js → SourceClassKinds.js} +1 -5
  70. package/lib/SourceClassKinds.js.map +1 -0
  71. package/lib/SyncTypeResolver.d.ts.map +1 -0
  72. package/lib/{cjs/SyncTypeResolver.js → SyncTypeResolver.js} +15 -19
  73. package/lib/SyncTypeResolver.js.map +1 -0
  74. package/lib/TransformerLoggerCategory.d.ts.map +1 -0
  75. package/lib/{cjs/TransformerLoggerCategory.js → TransformerLoggerCategory.js} +2 -5
  76. package/lib/TransformerLoggerCategory.js.map +1 -0
  77. package/lib/TransformerPackageMetadata.d.ts.map +1 -0
  78. package/lib/TransformerPackageMetadata.js +8 -0
  79. package/lib/TransformerPackageMetadata.js.map +1 -0
  80. package/lib/{cjs/imodel-transformer.d.ts → imodel-transformer.d.ts} +9 -9
  81. package/lib/imodel-transformer.d.ts.map +1 -0
  82. package/lib/imodel-transformer.js +88 -0
  83. package/lib/imodel-transformer.js.map +1 -0
  84. package/lib/{cjs/schema-processing → schema-processing}/DynamicSchemaUnionStrategy.d.ts +1 -1
  85. package/lib/schema-processing/DynamicSchemaUnionStrategy.d.ts.map +1 -0
  86. package/lib/{cjs/schema-processing → schema-processing}/DynamicSchemaUnionStrategy.js +16 -20
  87. package/lib/schema-processing/DynamicSchemaUnionStrategy.js.map +1 -0
  88. package/lib/{cjs/schema-processing → schema-processing}/SchemaProcessingCoordinator.d.ts +2 -2
  89. package/lib/schema-processing/SchemaProcessingCoordinator.d.ts.map +1 -0
  90. package/lib/{cjs/schema-processing → schema-processing}/SchemaProcessingCoordinator.js +15 -52
  91. package/lib/schema-processing/SchemaProcessingCoordinator.js.map +1 -0
  92. package/lib/schema-processing/SchemaProcessingStrategy.d.ts.map +1 -0
  93. package/lib/{cjs/schema-processing → schema-processing}/SchemaProcessingStrategy.js +1 -5
  94. package/lib/schema-processing/SchemaProcessingStrategy.js.map +1 -0
  95. package/lib/schema-processing.d.ts +7 -0
  96. package/lib/schema-processing.d.ts.map +1 -0
  97. package/lib/schema-processing.js +11 -0
  98. package/lib/schema-processing.js.map +1 -0
  99. package/package.json +14 -14
  100. package/lib/cjs/Algo.d.ts.map +0 -1
  101. package/lib/cjs/Algo.js.map +0 -1
  102. package/lib/cjs/BigMap.d.ts.map +0 -1
  103. package/lib/cjs/BigMap.js.map +0 -1
  104. package/lib/cjs/BranchProvenanceInitializer.d.ts.map +0 -1
  105. package/lib/cjs/BranchProvenanceInitializer.js.map +0 -1
  106. package/lib/cjs/ChangedElementForest.d.ts.map +0 -1
  107. package/lib/cjs/ChangedElementForest.js.map +0 -1
  108. package/lib/cjs/ChangesetScanner.d.ts.map +0 -1
  109. package/lib/cjs/ChangesetScanner.js.map +0 -1
  110. package/lib/cjs/ECReferenceTypesCache.d.ts.map +0 -1
  111. package/lib/cjs/ECReferenceTypesCache.js.map +0 -1
  112. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +0 -1
  113. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js.map +0 -1
  114. package/lib/cjs/ElementAspectCleanup.d.ts.map +0 -1
  115. package/lib/cjs/ElementAspectCleanup.js.map +0 -1
  116. package/lib/cjs/ElementAspectExportCoordinator.d.ts.map +0 -1
  117. package/lib/cjs/ElementAspectExportCoordinator.js.map +0 -1
  118. package/lib/cjs/ElementAspectExportProcessor.d.ts.map +0 -1
  119. package/lib/cjs/ElementAspectExportProcessor.js.map +0 -1
  120. package/lib/cjs/ElementBulkDelete.d.ts.map +0 -1
  121. package/lib/cjs/EntityExistenceCache.d.ts.map +0 -1
  122. package/lib/cjs/EntityExistenceCache.js.map +0 -1
  123. package/lib/cjs/EntityUnifier.d.ts.map +0 -1
  124. package/lib/cjs/EntityUnifier.js.map +0 -1
  125. package/lib/cjs/IModelCloneContext.d.ts.map +0 -1
  126. package/lib/cjs/IModelCloneContext.js.map +0 -1
  127. package/lib/cjs/IModelExporter.d.ts.map +0 -1
  128. package/lib/cjs/IModelExporter.js.map +0 -1
  129. package/lib/cjs/IModelImporter.d.ts.map +0 -1
  130. package/lib/cjs/IModelImporter.js.map +0 -1
  131. package/lib/cjs/IModelTransformContext.d.ts.map +0 -1
  132. package/lib/cjs/IModelTransformContext.js +0 -3
  133. package/lib/cjs/IModelTransformContext.js.map +0 -1
  134. package/lib/cjs/IModelTransformer.d.ts.map +0 -1
  135. package/lib/cjs/IModelTransformer.js.map +0 -1
  136. package/lib/cjs/IModelTransformerError.d.ts.map +0 -1
  137. package/lib/cjs/IModelTransformerError.js.map +0 -1
  138. package/lib/cjs/ProvenanceManager.d.ts.map +0 -1
  139. package/lib/cjs/ProvenanceManager.js.map +0 -1
  140. package/lib/cjs/SourceClassKinds.d.ts.map +0 -1
  141. package/lib/cjs/SourceClassKinds.js.map +0 -1
  142. package/lib/cjs/SyncTypeResolver.d.ts.map +0 -1
  143. package/lib/cjs/SyncTypeResolver.js.map +0 -1
  144. package/lib/cjs/TransformerLoggerCategory.d.ts.map +0 -1
  145. package/lib/cjs/TransformerLoggerCategory.js.map +0 -1
  146. package/lib/cjs/TransformerPackageMetadata.d.ts.map +0 -1
  147. package/lib/cjs/TransformerPackageMetadata.js +0 -47
  148. package/lib/cjs/TransformerPackageMetadata.js.map +0 -1
  149. package/lib/cjs/imodel-transformer.d.ts.map +0 -1
  150. package/lib/cjs/imodel-transformer.js +0 -125
  151. package/lib/cjs/imodel-transformer.js.map +0 -1
  152. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts.map +0 -1
  153. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js.map +0 -1
  154. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts.map +0 -1
  155. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js.map +0 -1
  156. package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts.map +0 -1
  157. package/lib/cjs/schema-processing/SchemaProcessingStrategy.js.map +0 -1
  158. package/lib/cjs/schema-processing.d.ts +0 -7
  159. package/lib/cjs/schema-processing.d.ts.map +0 -1
  160. package/lib/cjs/schema-processing.js +0 -27
  161. package/lib/cjs/schema-processing.js.map +0 -1
  162. /package/lib/{cjs/Algo.d.ts → Algo.d.ts} +0 -0
  163. /package/lib/{cjs/BigMap.d.ts → BigMap.d.ts} +0 -0
  164. /package/lib/{cjs/BranchProvenanceInitializer.d.ts → BranchProvenanceInitializer.d.ts} +0 -0
  165. /package/lib/{cjs/ChangedElementForest.d.ts → ChangedElementForest.d.ts} +0 -0
  166. /package/lib/{cjs/ECReferenceTypesCache.d.ts → ECReferenceTypesCache.d.ts} +0 -0
  167. /package/lib/{cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts → ECSqlReaderAsyncIterableIteratorAdapter.d.ts} +0 -0
  168. /package/lib/{cjs/ElementAspectCleanup.d.ts → ElementAspectCleanup.d.ts} +0 -0
  169. /package/lib/{cjs/ElementAspectExportCoordinator.d.ts → ElementAspectExportCoordinator.d.ts} +0 -0
  170. /package/lib/{cjs/ElementAspectExportProcessor.d.ts → ElementAspectExportProcessor.d.ts} +0 -0
  171. /package/lib/{cjs/ElementBulkDelete.d.ts → ElementBulkDelete.d.ts} +0 -0
  172. /package/lib/{cjs/EntityExistenceCache.d.ts → EntityExistenceCache.d.ts} +0 -0
  173. /package/lib/{cjs/EntityUnifier.d.ts → EntityUnifier.d.ts} +0 -0
  174. /package/lib/{cjs/IModelTransformContext.d.ts → IModelTransformContext.d.ts} +0 -0
  175. /package/lib/{cjs/IModelTransformerError.d.ts → IModelTransformerError.d.ts} +0 -0
  176. /package/lib/{cjs/SourceClassKinds.d.ts → SourceClassKinds.d.ts} +0 -0
  177. /package/lib/{cjs/SyncTypeResolver.d.ts → SyncTypeResolver.d.ts} +0 -0
  178. /package/lib/{cjs/TransformerLoggerCategory.d.ts → TransformerLoggerCategory.d.ts} +0 -0
  179. /package/lib/{cjs/TransformerPackageMetadata.d.ts → TransformerPackageMetadata.d.ts} +0 -0
  180. /package/lib/{cjs/schema-processing → schema-processing}/SchemaProcessingStrategy.d.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ElementBulkDelete.js","sourceRoot":"","sources":["../../src/ElementBulkDelete.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { assert, Id64Array, Id64Set, Id64String } from \"@itwin/core-bentley\";\nimport { QueryBinder } from \"@itwin/core-common\";\nimport { IModelDb } from \"@itwin/core-backend\";\n\n/** Native deletion calls needed to delete a set of element trees without a partial result.\n * @internal\n */\nexport interface BulkDeletePlan {\n /** Roots for each native deletion call, in execution order. Empty when nothing needs deleting. */\n readonly phases: readonly Id64Array[];\n /** Elements kept because an element outside the deleted trees still references them, each mapped to one such\n * referencing element. Their child elements and sub-models, and the elements whose deletion would delete them,\n * are kept too.\n */\n readonly keptReferences: ReadonlyMap<Id64String, Id64String>;\n}\n\ninterface DeletionTrees {\n /** Roots that the native API must receive. */\n readonly roots: Id64Set;\n /** Every element that deleting the roots removes, mapped to the roots whose trees contain it. */\n readonly rootsByElement: ReadonlyMap<Id64String, readonly Id64String[]>;\n}\n\n/** Plans native bulk deletion of the specified element trees.\n *\n * An element that something outside the deleted trees still references is kept, together with what it\n * needs to stay valid, and the rest is deleted. Keeping elements can leave new outside references, so the\n * plan repeats until none remain.\n *\n * Native validation checks each root against the iModel before the call, so a root is refused when its tree\n * contains a definition, such as a category or a view, that a non-definition element in the same call still\n * uses. The plan deletes those users in an earlier call than the definitions they use. Validation stays enabled\n * for every call, so a reference this plan does not know about fails loudly instead of leaving a dangling\n * reference. That includes elements outside the trees whose geometry uses a definition in them, such as a\n * geometry part: only native code can read geometry, so those uses are not checked in advance.\n * @internal\n */\nexport async function planBulkDelete(\n targetDb: IModelDb,\n elementIds: ReadonlySet<Id64String>\n): Promise<BulkDeletePlan> {\n const requestedIds = new Set(elementIds);\n const keptReferences = new Map<Id64String, Id64String>();\n for (;;) {\n const trees = await queryDeletionTrees(targetDb, requestedIds);\n if (trees.roots.size === 0) return { phases: [], keptReferences };\n\n const references = await queryReferences(\n targetDb,\n trees.rootsByElement.keys()\n );\n const blockedIds = new Set<Id64String>();\n for (const { referencingId, referencedId } of references.references) {\n if (trees.rootsByElement.has(referencingId)) continue;\n blockedIds.add(referencedId);\n if (!keptReferences.has(referencedId))\n keptReferences.set(referencedId, referencingId);\n }\n if (blockedIds.size === 0)\n return {\n phases: await planPhases(targetDb, trees, references),\n keptReferences,\n };\n\n // Every blocked element is reached from a requested element, and queryKeptElements walks back up to it,\n // so each pass removes at least one requested element and the loop ends.\n const requestedCount = requestedIds.size;\n for (const id of await queryKeptElements(targetDb, blockedIds))\n requestedIds.delete(id);\n assert(\n requestedIds.size < requestedCount,\n \"Keeping referenced elements must remove a requested element\"\n );\n }\n}\n\n/** Orders the roots of deletion trees that nothing outside them references into native calls. */\nasync function planPhases(\n targetDb: IModelDb,\n trees: DeletionTrees,\n { references, geometryDefinitionIds }: TreeReferences\n): Promise<Id64Array[]> {\n // Elements in the trees that use a definition that is also in the trees. Native validation refuses the definition while they exist.\n const usersOfDeletedDefinitions = new Set<Id64String>();\n // Roots whose trees contain such a definition. They must be deleted after its users.\n const rootsWithUsedDefinitions = new Set<Id64String>();\n const addUsedDefinition = (definitionId: Id64String) => {\n for (const rootId of trees.rootsByElement.get(definitionId) ?? [])\n rootsWithUsedDefinitions.add(rootId);\n };\n const sameCallReferences: TreeReference[] = [];\n for (const reference of references) {\n if (reference.usersFirst) {\n usersOfDeletedDefinitions.add(reference.referencingId);\n addUsedDefinition(reference.referencedId);\n } else {\n sameCallReferences.push(reference);\n }\n }\n // Only native code can tell which geometry uses a geometry part, material, texture, line style, or sub-category,\n // so every geometric element in the trees counts as a user of every such definition. Deleting the trees that\n // contain those definitions last is enough unless one of them also contains a geometric element; only then are\n // all geometric elements queried, to delete them as roots of their own.\n const geometryRoots = new Set<Id64String>();\n for (const id of geometryDefinitionIds)\n for (const rootId of trees.rootsByElement.get(id) ?? [])\n geometryRoots.add(rootId);\n if (geometryRoots.size > 0) {\n const elementsInGeometryTrees = [...trees.rootsByElement]\n .filter(([, rootIds]) => rootIds.some((id) => geometryRoots.has(id)))\n .map(([id]) => id);\n if (\n (await queryGeometricElements(targetDb, elementsInGeometryTrees)).length >\n 0\n )\n for (const id of await queryGeometricElements(\n targetDb,\n trees.rootsByElement.keys()\n ))\n usersOfDeletedDefinitions.add(id);\n for (const rootId of geometryRoots) rootsWithUsedDefinitions.add(rootId);\n }\n if (rootsWithUsedDefinitions.size === 0) return [[...trees.roots]];\n // True when a root deleted in the last call removes the element.\n const isInTreeWithUsedDefinition = (id: Id64String) =>\n (trees.rootsByElement.get(id) ?? []).some((rootId) =>\n rootsWithUsedDefinitions.has(rootId)\n );\n // True when a root deleted in the first call removes the element. An element in overlapping trees can satisfy both checks.\n const isInOtherTree = (id: Id64String) =>\n (trees.rootsByElement.get(id) ?? []).some(\n (rootId) => !rootsWithUsedDefinitions.has(rootId)\n );\n // Deleting the other roots first works unless a user shares a tree with a used definition, or an other tree\n // contains an element that an element deleted later references, such as its code scope.\n const canDeleteOtherRootsFirst =\n ![...usersOfDeletedDefinitions].some(isInTreeWithUsedDefinition) &&\n !sameCallReferences.some(\n ({ referencingId, referencedId }) =>\n isInTreeWithUsedDefinition(referencingId) && isInOtherTree(referencedId)\n );\n if (canDeleteOtherRootsFirst) {\n // There are no other roots only when every tree contains a geometry definition and nothing in the trees uses a\n // definition through a queried reference.\n const otherRoots = [...trees.roots].filter(\n (id) => !rootsWithUsedDefinitions.has(id)\n );\n return otherRoots.length > 0\n ? [otherRoots, [...rootsWithUsedDefinitions]]\n : [[...rootsWithUsedDefinitions]];\n }\n\n // Otherwise delete the users and their code dependents as roots of their own. Core refuses to delete an\n // element whose code scopes an element deleted in a later call, so the first call also takes code dependents\n // that have a parent. They are all in the trees; one outside them would have kept its code scope above.\n const userTrees = await queryDeletionTrees(\n targetDb,\n usersOfDeletedDefinitions,\n true\n );\n const remainingRoots = [...trees.roots].filter(\n (id) => !userTrees.rootsByElement.has(id)\n );\n const phases = [[...userTrees.roots]];\n if (remainingRoots.length > 0) phases.push(remainingRoots);\n return phases;\n}\n\n/** Finds the native deletion roots and every element their deletion removes.\n *\n * Native deletion already cascades through child elements and modeled contents. This query follows\n * those dependencies to find elements whose codes are scoped by an element in a deleted tree. Each\n * code-dependent element becomes another native deletion root. Only top-level code dependents are\n * included unless `includeParentedCodeDependents` is true.\n */\nasync function queryDeletionTrees(\n targetDb: IModelDb,\n elementIds: ReadonlySet<Id64String>,\n includeParentedCodeDependents = false\n): Promise<DeletionTrees> {\n const roots: Id64Set = new Set<Id64String>();\n // An element has more than one root only when requested trees overlap. UNION in the query already removes duplicate\n // (element, root) pairs, so an array holds distinct roots without allocating a Set per element.\n const rootsByElement = new Map<Id64String, Id64String[]>();\n // CascadeIds pairs each traversed element with a root that the native API must delete. The anchor\n // adds requested elements that still exist, except those whose parent or modeled element is also\n // requested: the recursion reaches them anyway, and anchoring them too would walk a nested tree once\n // per requested ancestor. Recursive branches walk child elements and modeled contents while\n // preserving DeleteRootId. An element whose code is scoped by anything already traversed becomes a\n // new root, so recursion also covers its tree and code dependents.\n const query = `\n WITH RECURSIVE CascadeIds(Id, DeleteRootId) AS (\n SELECT element.ECInstanceId, element.ECInstanceId\n FROM bis.Element element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.ECInstanceId\n WHERE (element.Parent.Id IS NULL OR element.Parent.Id NOT IN (SELECT id FROM IdSet(:elementIds)))\n AND element.Model.Id NOT IN (SELECT id FROM IdSet(:elementIds))\n UNION\n SELECT child.ECInstanceId, deletionParent.DeleteRootId\n FROM bis.Element child\n INNER JOIN CascadeIds deletionParent ON child.Parent.Id = deletionParent.Id\n UNION\n SELECT modelElement.ECInstanceId, modeledElement.DeleteRootId\n FROM bis.Element modelElement\n INNER JOIN CascadeIds modeledElement ON modelElement.Model.Id = modeledElement.Id\n UNION\n SELECT codeDependent.ECInstanceId, codeDependent.ECInstanceId\n FROM bis.Element codeDependent\n INNER JOIN CascadeIds scope ON codeDependent.CodeScope.Id = scope.Id\n ${includeParentedCodeDependents ? \"\" : \"WHERE codeDependent.Parent.Id IS NULL\"}\n )\n SELECT Id AS id, DeleteRootId AS rootId FROM CascadeIds\n `;\n const params = new QueryBinder().bindIdSet(\"elementIds\", elementIds);\n for await (const row of targetDb.createQueryReader(query, params, {\n usePrimaryConn: true,\n })) {\n roots.add(row.rootId);\n const elementRoots = rootsByElement.get(row.id);\n if (elementRoots) elementRoots.push(row.rootId);\n else rootsByElement.set(row.id, [row.rootId]);\n }\n return { roots, rootsByElement };\n}\n\n/** Finds the elements to keep so that the blocked elements stay valid: each blocked element and its child\n * elements and sub-model contents, plus every element whose deletion would delete a kept element or leave its\n * parent, model, or code scope dangling.\n *\n * The whole subtree below a blocked element is kept, even when the element is blocked only as a code scope and\n * its children could be deleted. A kept category needs its sub-categories, because the plan can't see geometry\n * outside the trees that uses them, and keeping too much is safe.\n */\nasync function queryKeptElements(\n targetDb: IModelDb,\n blockedIds: ReadonlySet<Id64String>\n): Promise<Id64Set> {\n const query = `\n WITH RECURSIVE\n Above(Id) AS (\n SELECT ids.id FROM IdSet(:blockedIds) ids\n UNION\n SELECT element.Parent.Id FROM bis.Element element\n INNER JOIN Above ON element.ECInstanceId = Above.Id\n WHERE element.Parent.Id IS NOT NULL\n UNION\n SELECT element.Model.Id FROM bis.Element element\n INNER JOIN Above ON element.ECInstanceId = Above.Id\n UNION\n SELECT element.CodeScope.Id FROM bis.Element element\n INNER JOIN Above ON element.ECInstanceId = Above.Id\n ),\n Below(Id) AS (\n SELECT ids.id FROM IdSet(:blockedIds) ids\n UNION\n SELECT element.ECInstanceId FROM bis.Element element\n INNER JOIN Below ON element.Parent.Id = Below.Id\n UNION\n SELECT element.ECInstanceId FROM bis.Element element\n INNER JOIN Below ON element.Model.Id = Below.Id\n )\n SELECT Id AS id FROM Above\n UNION\n SELECT Id FROM Below\n `;\n const keptIds: Id64Set = new Set<Id64String>();\n const params = new QueryBinder().bindIdSet(\"blockedIds\", blockedIds);\n for await (const row of targetDb.createQueryReader(query, params, {\n usePrimaryConn: true,\n }))\n keptIds.add(row.id);\n return keptIds;\n}\n\ninterface TreeReference {\n readonly referencingId: Id64String;\n readonly referencedId: Id64String;\n /** True when native validation refuses the referenced element while the referencing element exists, even when\n * both are deleted in the same call. False when deleting them in the same call is enough.\n */\n readonly usersFirst: boolean;\n}\n\ninterface TreeReferences {\n readonly references: readonly TreeReference[];\n /** Geometry parts, materials, textures, line styles, and non-default sub-categories in the trees. Geometry\n * references them, so their users can't be queried.\n */\n readonly geometryDefinitionIds: readonly Id64String[];\n}\n\n/** Finds BisCore references to the specified elements that native deletion validates and that [[queryDeletionTrees]]\n * does not follow. Parent and model references are not included because the deleted trees contain every child and\n * modeled element.\n */\nasync function queryReferences(\n targetDb: IModelDb,\n elementIds: Iterable<Id64String>\n): Promise<TreeReferences> {\n const references: TreeReference[] = [];\n const geometryDefinitionIds: Id64String[] = [];\n // Any element can be a code scope. Every other validated reference targets a definition element, so those are\n // queried only for the definitions among the elements, which are usually few or none.\n const definitionIds: Id64String[] = [];\n const firstQuery = `\n SELECT element.ECInstanceId AS referencingId, element.CodeScope.Id AS referencedId, 0 AS isDefinition\n FROM bis.Element element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.CodeScope.Id\n UNION ALL\n SELECT definition.ECInstanceId, definition.ECInstanceId, 1\n FROM bis.DefinitionElement definition\n INNER JOIN IdSet(:elementIds) ids ON ids.id = definition.ECInstanceId\n `;\n for await (const row of targetDb.createQueryReader(\n firstQuery,\n new QueryBinder().bindIdSet(\"elementIds\", elementIds),\n { usePrimaryConn: true }\n )) {\n if (row.isDefinition === 1) definitionIds.push(row.referencedId);\n else\n references.push({\n referencingId: row.referencingId,\n referencedId: row.referencedId,\n usersFirst: false,\n });\n }\n if (definitionIds.length === 0) return { references, geometryDefinitionIds };\n\n // Classes and properties added in later BisCore versions.\n const sectionReferences = await querySectionViewReferences(targetDb);\n // Kind 1: native validation refuses the definition while the referencing element exists, even in the same call.\n // Kind 0: deleting both in the same call is enough. Native validation treats a default sub-category, whose ID\n // follows its category's, as used by the category unless both are deleted.\n // Kind 2: a definition that geometry references, so its users can't be queried.\n const definitionQuery = `\n SELECT element.ECInstanceId AS referencingId, element.Category.Id AS referencedId, 1 AS kind\n FROM bis.GeometricElement3d element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.Category.Id\n UNION ALL\n SELECT element.ECInstanceId, element.Category.Id, 1\n FROM bis.GeometricElement2d element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.Category.Id\n UNION ALL\n SELECT element.ECInstanceId, element.View.Id, 1\n FROM bis.ViewAttachment element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.View.Id\n ${sectionReferences\n .map(\n ({ className, propertyName }) => `\n UNION ALL\n SELECT element.ECInstanceId, element.${propertyName}.Id, 1\n FROM bis.${className} element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.${propertyName}.Id`\n )\n .join(\"\")}\n UNION ALL\n SELECT viewDefinition.ECInstanceId, viewDefinition.DisplayStyle.Id, 0\n FROM bis.ViewDefinition viewDefinition\n INNER JOIN IdSet(:elementIds) ids ON ids.id = viewDefinition.DisplayStyle.Id\n UNION ALL\n SELECT viewDefinition.ECInstanceId, viewDefinition.CategorySelector.Id, 0\n FROM bis.ViewDefinition viewDefinition\n INNER JOIN IdSet(:elementIds) ids ON ids.id = viewDefinition.CategorySelector.Id\n UNION ALL\n SELECT viewDefinition.ECInstanceId, viewDefinition.ModelSelector.Id, 0\n FROM bis.SpatialViewDefinition viewDefinition\n INNER JOIN IdSet(:elementIds) ids ON ids.id = viewDefinition.ModelSelector.Id\n UNION ALL\n SELECT subCategory.Parent.Id, subCategory.ECInstanceId, 0\n FROM bis.SubCategory subCategory\n INNER JOIN IdSet(:elementIds) ids ON ids.id = subCategory.ECInstanceId\n WHERE CAST(subCategory.ECInstanceId AS INTEGER) = CAST(subCategory.Parent.Id AS INTEGER) + 1\n UNION ALL\n SELECT subCategory.ECInstanceId, subCategory.ECInstanceId, 2\n FROM bis.SubCategory subCategory\n INNER JOIN IdSet(:elementIds) ids ON ids.id = subCategory.ECInstanceId\n WHERE CAST(subCategory.ECInstanceId AS INTEGER) <> CAST(subCategory.Parent.Id AS INTEGER) + 1\n ${[\"GeometryPart\", \"RenderMaterial\", \"Texture\", \"LineStyle\"]\n .map(\n (className) => `\n UNION ALL\n SELECT element.ECInstanceId, element.ECInstanceId, 2\n FROM bis.${className} element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.ECInstanceId`\n )\n .join(\"\")}\n `;\n for await (const row of targetDb.createQueryReader(\n definitionQuery,\n new QueryBinder().bindIdSet(\"elementIds\", definitionIds),\n { usePrimaryConn: true }\n )) {\n if (row.kind === 2) geometryDefinitionIds.push(row.referencedId);\n else\n references.push({\n referencingId: row.referencingId,\n referencedId: row.referencedId,\n usersFirst: row.kind === 1,\n });\n }\n return { references, geometryDefinitionIds };\n}\n\n/** Finds the BisCore section classes and view properties that exist in the iModel's schema. */\nasync function querySectionViewReferences(\n targetDb: IModelDb\n): Promise<{ className: string; propertyName: string }[]> {\n const query = `\n SELECT classDef.Name AS className, propertyDef.Name AS propertyName\n FROM meta.ECPropertyDef propertyDef\n INNER JOIN meta.ECClassDef classDef ON classDef.ECInstanceId = propertyDef.Class.Id\n INNER JOIN meta.ECSchemaDef schemaDef ON schemaDef.ECInstanceId = classDef.Schema.Id\n WHERE schemaDef.Name = 'BisCore'\n AND ((classDef.Name = 'SectionDrawing' AND propertyDef.Name = 'SpatialView')\n OR (classDef.Name = 'SectionDrawingLocation' AND propertyDef.Name = 'SectionView'))\n `;\n const references: { className: string; propertyName: string }[] = [];\n for await (const row of targetDb.createQueryReader(query, undefined, {\n usePrimaryConn: true,\n }))\n references.push({\n className: row.className,\n propertyName: row.propertyName,\n });\n return references;\n}\n\n/** Finds the 2D and 3D geometric elements among the specified elements. */\nasync function queryGeometricElements(\n targetDb: IModelDb,\n elementIds: Iterable<Id64String>\n): Promise<Id64String[]> {\n // Joining the abstract bis.GeometricElement with an IdSet is quadratic, so query its 3D and 2D subclasses.\n const query = `\n SELECT element.ECInstanceId AS id\n FROM bis.GeometricElement3d element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.ECInstanceId\n UNION ALL\n SELECT element.ECInstanceId\n FROM bis.GeometricElement2d element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.ECInstanceId\n `;\n const ids: Id64String[] = [];\n const params = new QueryBinder().bindIdSet(\"elementIds\", elementIds);\n for await (const row of targetDb.createQueryReader(query, params, {\n usePrimaryConn: true,\n }))\n ids.push(row.id);\n return ids;\n}\n"]}
1
+ {"version":3,"file":"ElementBulkDelete.js","sourceRoot":"","sources":["../src/ElementBulkDelete.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,MAAM,EAAkC,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAuBjD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAkB,EAClB,UAAmC;IAEnC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,cAAc,GAAG,IAAI,GAAG,EAA0B,CAAC;IACzD,SAAS,CAAC;QACR,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC/D,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC;QAElE,MAAM,UAAU,GAAG,MAAM,eAAe,CACtC,QAAQ,EACR,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,CAC5B,CAAC;QACF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAc,CAAC;QACzC,KAAK,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;YACpE,IAAI,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,aAAa,CAAC;gBAAE,SAAS;YACtD,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC7B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC;gBACnC,cAAc,CAAC,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC;YACvB,OAAO;gBACL,MAAM,EAAE,MAAM,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC;gBACrD,cAAc;aACf,CAAC;QAEJ,wGAAwG;QACxG,yEAAyE;QACzE,MAAM,cAAc,GAAG,YAAY,CAAC,IAAI,CAAC;QACzC,KAAK,MAAM,EAAE,IAAI,MAAM,iBAAiB,CAAC,QAAQ,EAAE,UAAU,CAAC;YAC5D,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1B,MAAM,CACJ,YAAY,CAAC,IAAI,GAAG,cAAc,EAClC,6DAA6D,CAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,iGAAiG;AACjG,KAAK,UAAU,UAAU,CACvB,QAAkB,EAClB,KAAoB,EACpB,EAAE,UAAU,EAAE,qBAAqB,EAAkB;IAErD,oIAAoI;IACpI,MAAM,yBAAyB,GAAG,IAAI,GAAG,EAAc,CAAC;IACxD,qFAAqF;IACrF,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAc,CAAC;IACvD,MAAM,iBAAiB,GAAG,CAAC,YAAwB,EAAE,EAAE;QACrD,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE;YAC/D,wBAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC,CAAC;IACF,MAAM,kBAAkB,GAAoB,EAAE,CAAC;IAC/C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;YACzB,yBAAyB,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YACvD,iBAAiB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,iHAAiH;IACjH,6GAA6G;IAC7G,+GAA+G;IAC/G,wEAAwE;IACxE,MAAM,aAAa,GAAG,IAAI,GAAG,EAAc,CAAC;IAC5C,KAAK,MAAM,EAAE,IAAI,qBAAqB;QACpC,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;YACrD,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,uBAAuB,GAAG,CAAC,GAAG,KAAK,CAAC,cAAc,CAAC;aACtD,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;aACpE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QACrB,IACE,CAAC,MAAM,sBAAsB,CAAC,QAAQ,EAAE,uBAAuB,CAAC,CAAC,CAAC,MAAM;YACxE,CAAC;YAED,KAAK,MAAM,EAAE,IAAI,MAAM,sBAAsB,CAC3C,QAAQ,EACR,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,CAC5B;gBACC,yBAAyB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtC,KAAK,MAAM,MAAM,IAAI,aAAa;YAAE,wBAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,wBAAwB,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACnE,iEAAiE;IACjE,MAAM,0BAA0B,GAAG,CAAC,EAAc,EAAE,EAAE,CACpD,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CACnD,wBAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,CACrC,CAAC;IACJ,2HAA2H;IAC3H,MAAM,aAAa,GAAG,CAAC,EAAc,EAAE,EAAE,CACvC,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CACvC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,wBAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,CAClD,CAAC;IACJ,4GAA4G;IAC5G,wFAAwF;IACxF,MAAM,wBAAwB,GAC5B,CAAC,CAAC,GAAG,yBAAyB,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC;QAChE,CAAC,kBAAkB,CAAC,IAAI,CACtB,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,EAAE,CAClC,0BAA0B,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,YAAY,CAAC,CAC3E,CAAC;IACJ,IAAI,wBAAwB,EAAE,CAAC;QAC7B,+GAA+G;QAC/G,0CAA0C;QAC1C,MAAM,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CACxC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,wBAAwB,CAAC,GAAG,CAAC,EAAE,CAAC,CAC1C,CAAC;QACF,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC;YAC1B,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,GAAG,wBAAwB,CAAC,CAAC;YAC7C,CAAC,CAAC,CAAC,CAAC,GAAG,wBAAwB,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,wGAAwG;IACxG,6GAA6G;IAC7G,wGAAwG;IACxG,MAAM,SAAS,GAAG,MAAM,kBAAkB,CACxC,QAAQ,EACR,yBAAyB,EACzB,IAAI,CACL,CAAC;IACF,MAAM,cAAc,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAC5C,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAC1C,CAAC;IACF,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IACtC,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,kBAAkB,CAC/B,QAAkB,EAClB,UAAmC,EACnC,6BAA6B,GAAG,KAAK;IAErC,MAAM,KAAK,GAAY,IAAI,GAAG,EAAc,CAAC;IAC7C,oHAAoH;IACpH,gGAAgG;IAChG,MAAM,cAAc,GAAG,IAAI,GAAG,EAA4B,CAAC;IAC3D,kGAAkG;IAClG,iGAAiG;IACjG,qGAAqG;IACrG,4FAA4F;IAC5F,mGAAmG;IACnG,mEAAmE;IACnE,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;QAmBR,6BAA6B,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,uCAAuC;;;GAGjF,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACrE,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,QAAQ,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;QAChE,cAAc,EAAE,IAAI;KACrB,CAAC,EAAE,CAAC;QACH,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtB,MAAM,YAAY,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChD,IAAI,YAAY;YAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;;YAC3C,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;AACnC,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,iBAAiB,CAC9B,QAAkB,EAClB,UAAmC;IAEnC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2Bb,CAAC;IACF,MAAM,OAAO,GAAY,IAAI,GAAG,EAAc,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACrE,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,QAAQ,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;QAChE,cAAc,EAAE,IAAI;KACrB,CAAC;QACA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACtB,OAAO,OAAO,CAAC;AACjB,CAAC;AAmBD;;;GAGG;AACH,KAAK,UAAU,eAAe,CAC5B,QAAkB,EAClB,UAAgC;IAEhC,MAAM,UAAU,GAAoB,EAAE,CAAC;IACvC,MAAM,qBAAqB,GAAiB,EAAE,CAAC;IAC/C,8GAA8G;IAC9G,sFAAsF;IACtF,MAAM,aAAa,GAAiB,EAAE,CAAC;IACvC,MAAM,UAAU,GAAG;;;;;;;;GAQlB,CAAC;IACF,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,QAAQ,CAAC,iBAAiB,CAChD,UAAU,EACV,IAAI,WAAW,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,UAAU,CAAC,EACrD,EAAE,cAAc,EAAE,IAAI,EAAE,CACzB,EAAE,CAAC;QACF,IAAI,GAAG,CAAC,YAAY,KAAK,CAAC;YAAE,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;;YAE/D,UAAU,CAAC,IAAI,CAAC;gBACd,aAAa,EAAE,GAAG,CAAC,aAAa;gBAChC,YAAY,EAAE,GAAG,CAAC,YAAY;gBAC9B,UAAU,EAAE,KAAK;aAClB,CAAC,CAAC;IACP,CAAC;IACD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,CAAC;IAE7E,0DAA0D;IAC1D,MAAM,iBAAiB,GAAG,MAAM,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IACrE,gHAAgH;IAChH,8GAA8G;IAC9G,2EAA2E;IAC3E,gFAAgF;IAChF,MAAM,eAAe,GAAG;;;;;;;;;;;;MAYpB,iBAAiB;SAChB,GAAG,CACF,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;;2CAEE,YAAY;eACxC,SAAS;4DACoC,YAAY,KAAK,CACtE;SACA,IAAI,CAAC,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;MAuBT,CAAC,cAAc,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,CAAC;SACzD,GAAG,CACF,CAAC,SAAS,EAAE,EAAE,CAAC;;;eAGR,SAAS;uEAC+C,CAChE;SACA,IAAI,CAAC,EAAE,CAAC;GACZ,CAAC;IACF,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,QAAQ,CAAC,iBAAiB,CAChD,eAAe,EACf,IAAI,WAAW,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,aAAa,CAAC,EACxD,EAAE,cAAc,EAAE,IAAI,EAAE,CACzB,EAAE,CAAC;QACF,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;YAAE,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;;YAE/D,UAAU,CAAC,IAAI,CAAC;gBACd,aAAa,EAAE,GAAG,CAAC,aAAa;gBAChC,YAAY,EAAE,GAAG,CAAC,YAAY;gBAC9B,UAAU,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC;aAC3B,CAAC,CAAC;IACP,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,CAAC;AAC/C,CAAC;AAED,+FAA+F;AAC/F,KAAK,UAAU,0BAA0B,CACvC,QAAkB;IAElB,MAAM,KAAK,GAAG;;;;;;;;GAQb,CAAC;IACF,MAAM,UAAU,GAAkD,EAAE,CAAC;IACrE,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,QAAQ,CAAC,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE;QACnE,cAAc,EAAE,IAAI;KACrB,CAAC;QACA,UAAU,CAAC,IAAI,CAAC;YACd,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,YAAY,EAAE,GAAG,CAAC,YAAY;SAC/B,CAAC,CAAC;IACL,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,2EAA2E;AAC3E,KAAK,UAAU,sBAAsB,CACnC,QAAkB,EAClB,UAAgC;IAEhC,2GAA2G;IAC3G,MAAM,KAAK,GAAG;;;;;;;;GAQb,CAAC;IACF,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACrE,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,QAAQ,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;QAChE,cAAc,EAAE,IAAI;KACrB,CAAC;QACA,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACnB,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { assert, Id64Array, Id64Set, Id64String } from \"@itwin/core-bentley\";\nimport { QueryBinder } from \"@itwin/core-common\";\nimport { IModelDb } from \"@itwin/core-backend\";\n\n/** Native deletion calls needed to delete a set of element trees without a partial result.\n * @internal\n */\nexport interface BulkDeletePlan {\n /** Roots for each native deletion call, in execution order. Empty when nothing needs deleting. */\n readonly phases: readonly Id64Array[];\n /** Elements kept because an element outside the deleted trees still references them, each mapped to one such\n * referencing element. Their child elements and sub-models, and the elements whose deletion would delete them,\n * are kept too.\n */\n readonly keptReferences: ReadonlyMap<Id64String, Id64String>;\n}\n\ninterface DeletionTrees {\n /** Roots that the native API must receive. */\n readonly roots: Id64Set;\n /** Every element that deleting the roots removes, mapped to the roots whose trees contain it. */\n readonly rootsByElement: ReadonlyMap<Id64String, readonly Id64String[]>;\n}\n\n/** Plans native bulk deletion of the specified element trees.\n *\n * An element that something outside the deleted trees still references is kept, together with what it\n * needs to stay valid, and the rest is deleted. Keeping elements can leave new outside references, so the\n * plan repeats until none remain.\n *\n * Native validation checks each root against the iModel before the call, so a root is refused when its tree\n * contains a definition, such as a category or a view, that a non-definition element in the same call still\n * uses. The plan deletes those users in an earlier call than the definitions they use. Validation stays enabled\n * for every call, so a reference this plan does not know about fails loudly instead of leaving a dangling\n * reference. That includes elements outside the trees whose geometry uses a definition in them, such as a\n * geometry part: only native code can read geometry, so those uses are not checked in advance.\n * @internal\n */\nexport async function planBulkDelete(\n targetDb: IModelDb,\n elementIds: ReadonlySet<Id64String>\n): Promise<BulkDeletePlan> {\n const requestedIds = new Set(elementIds);\n const keptReferences = new Map<Id64String, Id64String>();\n for (;;) {\n const trees = await queryDeletionTrees(targetDb, requestedIds);\n if (trees.roots.size === 0) return { phases: [], keptReferences };\n\n const references = await queryReferences(\n targetDb,\n trees.rootsByElement.keys()\n );\n const blockedIds = new Set<Id64String>();\n for (const { referencingId, referencedId } of references.references) {\n if (trees.rootsByElement.has(referencingId)) continue;\n blockedIds.add(referencedId);\n if (!keptReferences.has(referencedId))\n keptReferences.set(referencedId, referencingId);\n }\n if (blockedIds.size === 0)\n return {\n phases: await planPhases(targetDb, trees, references),\n keptReferences,\n };\n\n // Every blocked element is reached from a requested element, and queryKeptElements walks back up to it,\n // so each pass removes at least one requested element and the loop ends.\n const requestedCount = requestedIds.size;\n for (const id of await queryKeptElements(targetDb, blockedIds))\n requestedIds.delete(id);\n assert(\n requestedIds.size < requestedCount,\n \"Keeping referenced elements must remove a requested element\"\n );\n }\n}\n\n/** Orders the roots of deletion trees that nothing outside them references into native calls. */\nasync function planPhases(\n targetDb: IModelDb,\n trees: DeletionTrees,\n { references, geometryDefinitionIds }: TreeReferences\n): Promise<Id64Array[]> {\n // Elements in the trees that use a definition that is also in the trees. Native validation refuses the definition while they exist.\n const usersOfDeletedDefinitions = new Set<Id64String>();\n // Roots whose trees contain such a definition. They must be deleted after its users.\n const rootsWithUsedDefinitions = new Set<Id64String>();\n const addUsedDefinition = (definitionId: Id64String) => {\n for (const rootId of trees.rootsByElement.get(definitionId) ?? [])\n rootsWithUsedDefinitions.add(rootId);\n };\n const sameCallReferences: TreeReference[] = [];\n for (const reference of references) {\n if (reference.usersFirst) {\n usersOfDeletedDefinitions.add(reference.referencingId);\n addUsedDefinition(reference.referencedId);\n } else {\n sameCallReferences.push(reference);\n }\n }\n // Only native code can tell which geometry uses a geometry part, material, texture, line style, or sub-category,\n // so every geometric element in the trees counts as a user of every such definition. Deleting the trees that\n // contain those definitions last is enough unless one of them also contains a geometric element; only then are\n // all geometric elements queried, to delete them as roots of their own.\n const geometryRoots = new Set<Id64String>();\n for (const id of geometryDefinitionIds)\n for (const rootId of trees.rootsByElement.get(id) ?? [])\n geometryRoots.add(rootId);\n if (geometryRoots.size > 0) {\n const elementsInGeometryTrees = [...trees.rootsByElement]\n .filter(([, rootIds]) => rootIds.some((id) => geometryRoots.has(id)))\n .map(([id]) => id);\n if (\n (await queryGeometricElements(targetDb, elementsInGeometryTrees)).length >\n 0\n )\n for (const id of await queryGeometricElements(\n targetDb,\n trees.rootsByElement.keys()\n ))\n usersOfDeletedDefinitions.add(id);\n for (const rootId of geometryRoots) rootsWithUsedDefinitions.add(rootId);\n }\n if (rootsWithUsedDefinitions.size === 0) return [[...trees.roots]];\n // True when a root deleted in the last call removes the element.\n const isInTreeWithUsedDefinition = (id: Id64String) =>\n (trees.rootsByElement.get(id) ?? []).some((rootId) =>\n rootsWithUsedDefinitions.has(rootId)\n );\n // True when a root deleted in the first call removes the element. An element in overlapping trees can satisfy both checks.\n const isInOtherTree = (id: Id64String) =>\n (trees.rootsByElement.get(id) ?? []).some(\n (rootId) => !rootsWithUsedDefinitions.has(rootId)\n );\n // Deleting the other roots first works unless a user shares a tree with a used definition, or an other tree\n // contains an element that an element deleted later references, such as its code scope.\n const canDeleteOtherRootsFirst =\n ![...usersOfDeletedDefinitions].some(isInTreeWithUsedDefinition) &&\n !sameCallReferences.some(\n ({ referencingId, referencedId }) =>\n isInTreeWithUsedDefinition(referencingId) && isInOtherTree(referencedId)\n );\n if (canDeleteOtherRootsFirst) {\n // There are no other roots only when every tree contains a geometry definition and nothing in the trees uses a\n // definition through a queried reference.\n const otherRoots = [...trees.roots].filter(\n (id) => !rootsWithUsedDefinitions.has(id)\n );\n return otherRoots.length > 0\n ? [otherRoots, [...rootsWithUsedDefinitions]]\n : [[...rootsWithUsedDefinitions]];\n }\n\n // Otherwise delete the users and their code dependents as roots of their own. Core refuses to delete an\n // element whose code scopes an element deleted in a later call, so the first call also takes code dependents\n // that have a parent. They are all in the trees; one outside them would have kept its code scope above.\n const userTrees = await queryDeletionTrees(\n targetDb,\n usersOfDeletedDefinitions,\n true\n );\n const remainingRoots = [...trees.roots].filter(\n (id) => !userTrees.rootsByElement.has(id)\n );\n const phases = [[...userTrees.roots]];\n if (remainingRoots.length > 0) phases.push(remainingRoots);\n return phases;\n}\n\n/** Finds the native deletion roots and every element their deletion removes.\n *\n * Native deletion already cascades through child elements and modeled contents. This query follows\n * those dependencies to find elements whose codes are scoped by an element in a deleted tree. Each\n * code-dependent element becomes another native deletion root. Only top-level code dependents are\n * included unless `includeParentedCodeDependents` is true.\n */\nasync function queryDeletionTrees(\n targetDb: IModelDb,\n elementIds: ReadonlySet<Id64String>,\n includeParentedCodeDependents = false\n): Promise<DeletionTrees> {\n const roots: Id64Set = new Set<Id64String>();\n // An element has more than one root only when requested trees overlap. UNION in the query already removes duplicate\n // (element, root) pairs, so an array holds distinct roots without allocating a Set per element.\n const rootsByElement = new Map<Id64String, Id64String[]>();\n // CascadeIds pairs each traversed element with a root that the native API must delete. The anchor\n // adds requested elements that still exist, except those whose parent or modeled element is also\n // requested: the recursion reaches them anyway, and anchoring them too would walk a nested tree once\n // per requested ancestor. Recursive branches walk child elements and modeled contents while\n // preserving DeleteRootId. An element whose code is scoped by anything already traversed becomes a\n // new root, so recursion also covers its tree and code dependents.\n const query = `\n WITH RECURSIVE CascadeIds(Id, DeleteRootId) AS (\n SELECT element.ECInstanceId, element.ECInstanceId\n FROM bis.Element element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.ECInstanceId\n WHERE (element.Parent.Id IS NULL OR element.Parent.Id NOT IN (SELECT id FROM IdSet(:elementIds)))\n AND element.Model.Id NOT IN (SELECT id FROM IdSet(:elementIds))\n UNION\n SELECT child.ECInstanceId, deletionParent.DeleteRootId\n FROM bis.Element child\n INNER JOIN CascadeIds deletionParent ON child.Parent.Id = deletionParent.Id\n UNION\n SELECT modelElement.ECInstanceId, modeledElement.DeleteRootId\n FROM bis.Element modelElement\n INNER JOIN CascadeIds modeledElement ON modelElement.Model.Id = modeledElement.Id\n UNION\n SELECT codeDependent.ECInstanceId, codeDependent.ECInstanceId\n FROM bis.Element codeDependent\n INNER JOIN CascadeIds scope ON codeDependent.CodeScope.Id = scope.Id\n ${includeParentedCodeDependents ? \"\" : \"WHERE codeDependent.Parent.Id IS NULL\"}\n )\n SELECT Id AS id, DeleteRootId AS rootId FROM CascadeIds\n `;\n const params = new QueryBinder().bindIdSet(\"elementIds\", elementIds);\n for await (const row of targetDb.createQueryReader(query, params, {\n usePrimaryConn: true,\n })) {\n roots.add(row.rootId);\n const elementRoots = rootsByElement.get(row.id);\n if (elementRoots) elementRoots.push(row.rootId);\n else rootsByElement.set(row.id, [row.rootId]);\n }\n return { roots, rootsByElement };\n}\n\n/** Finds the elements to keep so that the blocked elements stay valid: each blocked element and its child\n * elements and sub-model contents, plus every element whose deletion would delete a kept element or leave its\n * parent, model, or code scope dangling.\n *\n * The whole subtree below a blocked element is kept, even when the element is blocked only as a code scope and\n * its children could be deleted. A kept category needs its sub-categories, because the plan can't see geometry\n * outside the trees that uses them, and keeping too much is safe.\n */\nasync function queryKeptElements(\n targetDb: IModelDb,\n blockedIds: ReadonlySet<Id64String>\n): Promise<Id64Set> {\n const query = `\n WITH RECURSIVE\n Above(Id) AS (\n SELECT ids.id FROM IdSet(:blockedIds) ids\n UNION\n SELECT element.Parent.Id FROM bis.Element element\n INNER JOIN Above ON element.ECInstanceId = Above.Id\n WHERE element.Parent.Id IS NOT NULL\n UNION\n SELECT element.Model.Id FROM bis.Element element\n INNER JOIN Above ON element.ECInstanceId = Above.Id\n UNION\n SELECT element.CodeScope.Id FROM bis.Element element\n INNER JOIN Above ON element.ECInstanceId = Above.Id\n ),\n Below(Id) AS (\n SELECT ids.id FROM IdSet(:blockedIds) ids\n UNION\n SELECT element.ECInstanceId FROM bis.Element element\n INNER JOIN Below ON element.Parent.Id = Below.Id\n UNION\n SELECT element.ECInstanceId FROM bis.Element element\n INNER JOIN Below ON element.Model.Id = Below.Id\n )\n SELECT Id AS id FROM Above\n UNION\n SELECT Id FROM Below\n `;\n const keptIds: Id64Set = new Set<Id64String>();\n const params = new QueryBinder().bindIdSet(\"blockedIds\", blockedIds);\n for await (const row of targetDb.createQueryReader(query, params, {\n usePrimaryConn: true,\n }))\n keptIds.add(row.id);\n return keptIds;\n}\n\ninterface TreeReference {\n readonly referencingId: Id64String;\n readonly referencedId: Id64String;\n /** True when native validation refuses the referenced element while the referencing element exists, even when\n * both are deleted in the same call. False when deleting them in the same call is enough.\n */\n readonly usersFirst: boolean;\n}\n\ninterface TreeReferences {\n readonly references: readonly TreeReference[];\n /** Geometry parts, materials, textures, line styles, and non-default sub-categories in the trees. Geometry\n * references them, so their users can't be queried.\n */\n readonly geometryDefinitionIds: readonly Id64String[];\n}\n\n/** Finds BisCore references to the specified elements that native deletion validates and that [[queryDeletionTrees]]\n * does not follow. Parent and model references are not included because the deleted trees contain every child and\n * modeled element.\n */\nasync function queryReferences(\n targetDb: IModelDb,\n elementIds: Iterable<Id64String>\n): Promise<TreeReferences> {\n const references: TreeReference[] = [];\n const geometryDefinitionIds: Id64String[] = [];\n // Any element can be a code scope. Every other validated reference targets a definition element, so those are\n // queried only for the definitions among the elements, which are usually few or none.\n const definitionIds: Id64String[] = [];\n const firstQuery = `\n SELECT element.ECInstanceId AS referencingId, element.CodeScope.Id AS referencedId, 0 AS isDefinition\n FROM bis.Element element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.CodeScope.Id\n UNION ALL\n SELECT definition.ECInstanceId, definition.ECInstanceId, 1\n FROM bis.DefinitionElement definition\n INNER JOIN IdSet(:elementIds) ids ON ids.id = definition.ECInstanceId\n `;\n for await (const row of targetDb.createQueryReader(\n firstQuery,\n new QueryBinder().bindIdSet(\"elementIds\", elementIds),\n { usePrimaryConn: true }\n )) {\n if (row.isDefinition === 1) definitionIds.push(row.referencedId);\n else\n references.push({\n referencingId: row.referencingId,\n referencedId: row.referencedId,\n usersFirst: false,\n });\n }\n if (definitionIds.length === 0) return { references, geometryDefinitionIds };\n\n // Classes and properties added in later BisCore versions.\n const sectionReferences = await querySectionViewReferences(targetDb);\n // Kind 1: native validation refuses the definition while the referencing element exists, even in the same call.\n // Kind 0: deleting both in the same call is enough. Native validation treats a default sub-category, whose ID\n // follows its category's, as used by the category unless both are deleted.\n // Kind 2: a definition that geometry references, so its users can't be queried.\n const definitionQuery = `\n SELECT element.ECInstanceId AS referencingId, element.Category.Id AS referencedId, 1 AS kind\n FROM bis.GeometricElement3d element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.Category.Id\n UNION ALL\n SELECT element.ECInstanceId, element.Category.Id, 1\n FROM bis.GeometricElement2d element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.Category.Id\n UNION ALL\n SELECT element.ECInstanceId, element.View.Id, 1\n FROM bis.ViewAttachment element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.View.Id\n ${sectionReferences\n .map(\n ({ className, propertyName }) => `\n UNION ALL\n SELECT element.ECInstanceId, element.${propertyName}.Id, 1\n FROM bis.${className} element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.${propertyName}.Id`\n )\n .join(\"\")}\n UNION ALL\n SELECT viewDefinition.ECInstanceId, viewDefinition.DisplayStyle.Id, 0\n FROM bis.ViewDefinition viewDefinition\n INNER JOIN IdSet(:elementIds) ids ON ids.id = viewDefinition.DisplayStyle.Id\n UNION ALL\n SELECT viewDefinition.ECInstanceId, viewDefinition.CategorySelector.Id, 0\n FROM bis.ViewDefinition viewDefinition\n INNER JOIN IdSet(:elementIds) ids ON ids.id = viewDefinition.CategorySelector.Id\n UNION ALL\n SELECT viewDefinition.ECInstanceId, viewDefinition.ModelSelector.Id, 0\n FROM bis.SpatialViewDefinition viewDefinition\n INNER JOIN IdSet(:elementIds) ids ON ids.id = viewDefinition.ModelSelector.Id\n UNION ALL\n SELECT subCategory.Parent.Id, subCategory.ECInstanceId, 0\n FROM bis.SubCategory subCategory\n INNER JOIN IdSet(:elementIds) ids ON ids.id = subCategory.ECInstanceId\n WHERE CAST(subCategory.ECInstanceId AS INTEGER) = CAST(subCategory.Parent.Id AS INTEGER) + 1\n UNION ALL\n SELECT subCategory.ECInstanceId, subCategory.ECInstanceId, 2\n FROM bis.SubCategory subCategory\n INNER JOIN IdSet(:elementIds) ids ON ids.id = subCategory.ECInstanceId\n WHERE CAST(subCategory.ECInstanceId AS INTEGER) <> CAST(subCategory.Parent.Id AS INTEGER) + 1\n ${[\"GeometryPart\", \"RenderMaterial\", \"Texture\", \"LineStyle\"]\n .map(\n (className) => `\n UNION ALL\n SELECT element.ECInstanceId, element.ECInstanceId, 2\n FROM bis.${className} element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.ECInstanceId`\n )\n .join(\"\")}\n `;\n for await (const row of targetDb.createQueryReader(\n definitionQuery,\n new QueryBinder().bindIdSet(\"elementIds\", definitionIds),\n { usePrimaryConn: true }\n )) {\n if (row.kind === 2) geometryDefinitionIds.push(row.referencedId);\n else\n references.push({\n referencingId: row.referencingId,\n referencedId: row.referencedId,\n usersFirst: row.kind === 1,\n });\n }\n return { references, geometryDefinitionIds };\n}\n\n/** Finds the BisCore section classes and view properties that exist in the iModel's schema. */\nasync function querySectionViewReferences(\n targetDb: IModelDb\n): Promise<{ className: string; propertyName: string }[]> {\n const query = `\n SELECT classDef.Name AS className, propertyDef.Name AS propertyName\n FROM meta.ECPropertyDef propertyDef\n INNER JOIN meta.ECClassDef classDef ON classDef.ECInstanceId = propertyDef.Class.Id\n INNER JOIN meta.ECSchemaDef schemaDef ON schemaDef.ECInstanceId = classDef.Schema.Id\n WHERE schemaDef.Name = 'BisCore'\n AND ((classDef.Name = 'SectionDrawing' AND propertyDef.Name = 'SpatialView')\n OR (classDef.Name = 'SectionDrawingLocation' AND propertyDef.Name = 'SectionView'))\n `;\n const references: { className: string; propertyName: string }[] = [];\n for await (const row of targetDb.createQueryReader(query, undefined, {\n usePrimaryConn: true,\n }))\n references.push({\n className: row.className,\n propertyName: row.propertyName,\n });\n return references;\n}\n\n/** Finds the 2D and 3D geometric elements among the specified elements. */\nasync function queryGeometricElements(\n targetDb: IModelDb,\n elementIds: Iterable<Id64String>\n): Promise<Id64String[]> {\n // Joining the abstract bis.GeometricElement with an IdSet is quadratic, so query its 3D and 2D subclasses.\n const query = `\n SELECT element.ECInstanceId AS id\n FROM bis.GeometricElement3d element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.ECInstanceId\n UNION ALL\n SELECT element.ECInstanceId\n FROM bis.GeometricElement2d element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.ECInstanceId\n `;\n const ids: Id64String[] = [];\n const params = new QueryBinder().bindIdSet(\"elementIds\", elementIds);\n for await (const row of targetDb.createQueryReader(query, params, {\n usePrimaryConn: true,\n }))\n ids.push(row.id);\n return ids;\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityExistenceCache.d.ts","sourceRoot":"","sources":["../src/EntityExistenceCache.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,WAAW,CAA6C;IAEhE,OAAO,CAAC,QAAQ;IAShB;;OAEG;IACU,MAAM,CACjB,EAAE,EAAE,QAAQ,EACZ,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,OAAO,CAAC,CAMlB;IAED,6GAA6G;IAChG,SAAS,CACpB,EAAE,EAAE,QAAQ,EACZ,gBAAgB,EAAE,QAAQ,CAAC,eAAe,CAAC,GAC1C,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAkBvC;IAED,mFAAmF;IAC5E,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CAEtE;IAED,wFAAwF;IACjF,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CAEtE;IAED;;OAEG;IACI,OAAO,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAEjC;IAED,+BAA+B;IACxB,KAAK,IAAI,IAAI,CAEnB;CACF"}
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /*---------------------------------------------------------------------------------------------
3
2
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
3
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -6,9 +5,7 @@
6
5
  /** @packageDocumentation
7
6
  * @module Utils
8
7
  */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.EntityExistenceCache = void 0;
11
- const EntityUnifier_1 = require("./EntityUnifier");
8
+ import { EntityUnifier } from "./EntityUnifier.js";
12
9
  /** A positive-only read-through cache of entity existence checks, scoped to a single transformation run.
13
10
  *
14
11
  * Entities are created continuously as a transformation progresses, so a negative
@@ -26,7 +23,7 @@ const EntityUnifier_1 = require("./EntityUnifier");
26
23
  * disposed.
27
24
  * @internal
28
25
  */
29
- class EntityExistenceCache {
26
+ export class EntityExistenceCache {
30
27
  _existsByDb = new Map();
31
28
  getDbSet(db) {
32
29
  let set = this._existsByDb.get(db);
@@ -43,7 +40,7 @@ class EntityExistenceCache {
43
40
  const set = this.getDbSet(db);
44
41
  if (set.has(entityReference))
45
42
  return true;
46
- const found = await EntityUnifier_1.EntityUnifier.exists(db, { entityReference });
43
+ const found = await EntityUnifier.exists(db, { entityReference });
47
44
  if (found)
48
45
  set.add(entityReference);
49
46
  return found;
@@ -61,7 +58,7 @@ class EntityExistenceCache {
61
58
  }
62
59
  if (unverified.length === 0)
63
60
  return found;
64
- const queried = await EntityUnifier_1.EntityUnifier.existsAll(db, unverified);
61
+ const queried = await EntityUnifier.existsAll(db, unverified);
65
62
  for (const entityReference of queried) {
66
63
  dbSet.add(entityReference);
67
64
  found.add(entityReference);
@@ -87,5 +84,4 @@ class EntityExistenceCache {
87
84
  this._existsByDb.clear();
88
85
  }
89
86
  }
90
- exports.EntityExistenceCache = EntityExistenceCache;
91
87
  //# sourceMappingURL=EntityExistenceCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityExistenceCache.js","sourceRoot":"","sources":["../src/EntityExistenceCache.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG;;GAEG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,oBAAoB;IACvB,WAAW,GAAG,IAAI,GAAG,EAAkC,CAAC;IAExD,QAAQ,CAAC,EAAY;QAC3B,IAAI,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,MAAM,CACjB,EAAY,EACZ,eAAgC;QAEhC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC9B,IAAI,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;QAClE,IAAI,KAAK;YAAE,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,6GAA6G;IACtG,KAAK,CAAC,SAAS,CACpB,EAAY,EACZ,gBAA2C;QAE3C,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;QACzC,MAAM,UAAU,GAAsB,EAAE,CAAC;QAEzC,KAAK,MAAM,eAAe,IAAI,gBAAgB,EAAE,CAAC;YAC/C,IAAI,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;;gBACtD,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAE1C,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAC9D,KAAK,MAAM,eAAe,IAAI,OAAO,EAAE,CAAC;YACtC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC3B,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mFAAmF;IAC5E,UAAU,CAAC,EAAY,EAAE,eAAgC;QAC9D,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACzC,CAAC;IAED,wFAAwF;IACjF,UAAU,CAAC,EAAY,EAAE,eAAgC;QAC9D,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACI,OAAO,CAAC,EAAY;QACzB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,+BAA+B;IACxB,KAAK;QACV,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;CACF","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Utils\n */\n\nimport { EntityReference } from \"@itwin/core-common\";\nimport { IModelDb } from \"@itwin/core-backend\";\nimport { EntityUnifier } from \"./EntityUnifier.js\";\n\n/** A positive-only read-through cache of entity existence checks, scoped to a single transformation run.\n *\n * Entities are created continuously as a transformation progresses, so a negative\n * (\"does not exist\") result may become stale at any moment — therefore only positive\n * results are ever cached. Positive results can only be invalidated by deletes, which the\n * transformer routes through [[invalidate]] and [[clearDb]].\n *\n * The cache is keyed by [IModelDb]($core-backend) instance, so same-iModel transformations\n * (where sourceDb === targetDb) share a single set and source/target roles cannot be confused.\n *\n * [IModelImporter]($transformer) delete operations invalidate registered caches. Deletes performed\n * directly through an `EditTxn` while a transformation is active are out-of-band and must not be\n * mixed with transformer operations. A successful high-level `process()` clears the cache when the\n * transformation finalizes; low-level or failed transformations clear it when the transformer is\n * disposed.\n * @internal\n */\nexport class EntityExistenceCache {\n private _existsByDb = new Map<IModelDb, Set<EntityReference>>();\n\n private getDbSet(db: IModelDb): Set<EntityReference> {\n let set = this._existsByDb.get(db);\n if (set === undefined) {\n set = new Set();\n this._existsByDb.set(db, set);\n }\n return set;\n }\n\n /** Check whether an entity exists in `db`, consulting the cache first.\n * A `true` result is cached; a `false` result is never cached and will be re-queried.\n */\n public async exists(\n db: IModelDb,\n entityReference: EntityReference\n ): Promise<boolean> {\n const set = this.getDbSet(db);\n if (set.has(entityReference)) return true;\n const found = await EntityUnifier.exists(db, { entityReference });\n if (found) set.add(entityReference);\n return found;\n }\n\n /** Read through the cache to check which of the supplied entities exist in `db`, populating it on a miss. */\n public async existsAll(\n db: IModelDb,\n entityReferences: Iterable<EntityReference>\n ): Promise<ReadonlySet<EntityReference>> {\n const dbSet = this.getDbSet(db);\n const found = new Set<EntityReference>();\n const unverified: EntityReference[] = [];\n\n for (const entityReference of entityReferences) {\n if (dbSet.has(entityReference)) found.add(entityReference);\n else unverified.push(entityReference);\n }\n\n if (unverified.length === 0) return found;\n\n const queried = await EntityUnifier.existsAll(db, unverified);\n for (const entityReference of queried) {\n dbSet.add(entityReference);\n found.add(entityReference);\n }\n return found;\n }\n\n /** Record that an entity is known to exist in `db` (e.g. it was just imported). */\n public markExists(db: IModelDb, entityReference: EntityReference): void {\n this.getDbSet(db).add(entityReference);\n }\n\n /** Remove a single entity from the cache for `db`, forcing a re-query on next check. */\n public invalidate(db: IModelDb, entityReference: EntityReference): void {\n this._existsByDb.get(db)?.delete(entityReference);\n }\n\n /** Drop all cached results for `db`. Used when a delete may cascade to entities the\n * caller cannot enumerate (e.g. element tree deletes that remove descendants and submodels).\n */\n public clearDb(db: IModelDb): void {\n this._existsByDb.delete(db);\n }\n\n /** Drop all cached results. */\n public clear(): void {\n this._existsByDb.clear();\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityUnifier.d.ts","sourceRoot":"","sources":["../src/EntityUnifier.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,EAEL,eAAe,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EAMd,QAAQ,EAGT,MAAM,qBAAqB,CAAC;AAU7B,gBAAgB;AAChB,yBAAiB,aAAa,CAAC;IAC7B,SAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,yEAKrD;IAED,SAAsB,MAAM,CAC1B,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE;QAAE,MAAM,EAAE,cAAc,CAAA;KAAE,GAAG;QAAE,eAAe,EAAE,eAAe,CAAA;KAAE,oBAqBvE;IAED;;OAEG;IACH,SAAsB,SAAS,CAC7B,EAAE,EAAE,QAAQ,EACZ,gBAAgB,EAAE,QAAQ,CAAC,eAAe,CAAC,GAC1C,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CA8B/B;CACF"}
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /*---------------------------------------------------------------------------------------------
3
2
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
3
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -8,26 +7,26 @@
8
7
  * utilities that unify operations, especially CRUD operations, on entities
9
8
  * for entity-generic operations in the transformer
10
9
  */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.EntityUnifier = void 0;
13
- const core_common_1 = require("@itwin/core-common");
14
- const core_backend_1 = require("@itwin/core-backend");
15
- const core_bentley_1 = require("@itwin/core-bentley");
10
+ import { ConcreteEntityTypes, QueryBinder, } from "@itwin/core-common";
11
+ import {
12
+ // eslint-disable-next-line @typescript-eslint/no-redeclare
13
+ Element, ElementAspect, EntityReferences, Model, Relationship, } from "@itwin/core-backend";
14
+ import { Id64, OrderedId64Iterable } from "@itwin/core-bentley";
16
15
  const bisCoreRootClasses = {
17
- [core_common_1.ConcreteEntityTypes.Model]: core_backend_1.Model,
18
- [core_common_1.ConcreteEntityTypes.Element]: core_backend_1.Element,
19
- [core_common_1.ConcreteEntityTypes.ElementAspect]: core_backend_1.ElementAspect,
20
- [core_common_1.ConcreteEntityTypes.Relationship]: core_backend_1.Relationship,
16
+ [ConcreteEntityTypes.Model]: Model,
17
+ [ConcreteEntityTypes.Element]: Element,
18
+ [ConcreteEntityTypes.ElementAspect]: ElementAspect,
19
+ [ConcreteEntityTypes.Relationship]: Relationship,
21
20
  };
22
21
  /** @internal */
23
- var EntityUnifier;
22
+ export var EntityUnifier;
24
23
  (function (EntityUnifier) {
25
24
  function getReadableType(entity) {
26
- if (entity instanceof core_backend_1.Element)
25
+ if (entity instanceof Element)
27
26
  return "element";
28
- else if (entity instanceof core_backend_1.ElementAspect)
27
+ else if (entity instanceof ElementAspect)
29
28
  return "element aspect";
30
- else if (entity instanceof core_backend_1.Relationship)
29
+ else if (entity instanceof Relationship)
31
30
  return "relationship";
32
31
  else
33
32
  return "unknown entity type";
@@ -37,7 +36,7 @@ var EntityUnifier;
37
36
  let classFullName;
38
37
  let id;
39
38
  if ("entityReference" in arg) {
40
- const [type, entityId] = core_backend_1.EntityReferences.split(arg.entityReference);
39
+ const [type, entityId] = EntityReferences.split(arg.entityReference);
41
40
  classFullName = bisCoreRootClasses[type].classFullName;
42
41
  id = entityId;
43
42
  }
@@ -45,10 +44,10 @@ var EntityUnifier;
45
44
  classFullName = `[${arg.entity.schemaName}].[${arg.entity.className}]`;
46
45
  id = arg.entity.id;
47
46
  }
48
- if (core_bentley_1.Id64.isInvalid(id))
47
+ if (Id64.isInvalid(id))
49
48
  return false;
50
49
  const query = `SELECT 1 FROM ${classFullName} WHERE ECInstanceId=:id`;
51
- const params = new core_common_1.QueryBinder().bindId("id", id);
50
+ const params = new QueryBinder().bindId("id", id);
52
51
  const reader = db.createQueryReader(query, params, {
53
52
  usePrimaryConn: true,
54
53
  });
@@ -61,8 +60,8 @@ var EntityUnifier;
61
60
  async function existsAll(db, entityReferences) {
62
61
  const idsByType = new Map();
63
62
  for (const entityReference of entityReferences) {
64
- const [type, id] = core_backend_1.EntityReferences.split(entityReference);
65
- if (core_bentley_1.Id64.isInvalid(id))
63
+ const [type, id] = EntityReferences.split(entityReference);
64
+ if (Id64.isInvalid(id))
66
65
  continue;
67
66
  let ids = idsByType.get(type);
68
67
  if (ids === undefined) {
@@ -76,16 +75,16 @@ var EntityUnifier;
76
75
  const classFullName = bisCoreRootClasses[type].classFullName;
77
76
  // Join IdSet so SQLite looks up each id by primary key; InVirtualSet scans the whole table.
78
77
  const query = `SELECT e.ECInstanceId FROM ${classFullName} e INNER JOIN IdSet(:ids) s ON s.id = e.ECInstanceId`;
79
- const params = new core_common_1.QueryBinder().bindIdSet("ids", core_bentley_1.OrderedId64Iterable.sortArray([...ids]));
78
+ const params = new QueryBinder().bindIdSet("ids", OrderedId64Iterable.sortArray([...ids]));
80
79
  const reader = db.createQueryReader(query, params, {
81
80
  usePrimaryConn: true,
82
81
  });
83
82
  while (await reader.step()) {
84
- found.add(core_backend_1.EntityReferences.fromEntityType(reader.current[0], type));
83
+ found.add(EntityReferences.fromEntityType(reader.current[0], type));
85
84
  }
86
85
  }
87
86
  return found;
88
87
  }
89
88
  EntityUnifier.existsAll = existsAll;
90
- })(EntityUnifier || (exports.EntityUnifier = EntityUnifier = {}));
89
+ })(EntityUnifier || (EntityUnifier = {}));
91
90
  //# sourceMappingURL=EntityUnifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityUnifier.js","sourceRoot":"","sources":["../src/EntityUnifier.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG;;;;GAIG;AAEH,OAAO,EACL,mBAAmB,EAEnB,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO;AAEL,2DAA2D;AAC3D,OAAO,EACP,aAAa,EAEb,gBAAgB,EAEhB,KAAK,EACL,YAAY,GACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAc,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE5E,MAAM,kBAAkB,GAA+C;IACrE,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,KAAK;IAClC,CAAC,mBAAmB,CAAC,OAAO,CAAC,EAAE,OAAO;IACtC,CAAC,mBAAmB,CAAC,aAAa,CAAC,EAAE,aAAa;IAClD,CAAC,mBAAmB,CAAC,YAAY,CAAC,EAAE,YAAY;CACjD,CAAC;AAEF,gBAAgB;AAChB,MAAM,KAAW,aAAa,CAsE7B;AAtED,WAAiB,aAAa;IAC5B,SAAgB,eAAe,CAAC,MAAsB;QACpD,IAAI,MAAM,YAAY,OAAO;YAAE,OAAO,SAAS,CAAC;aAC3C,IAAI,MAAM,YAAY,aAAa;YAAE,OAAO,gBAAgB,CAAC;aAC7D,IAAI,MAAM,YAAY,YAAY;YAAE,OAAO,cAAc,CAAC;;YAC1D,OAAO,qBAAqB,CAAC;IACpC,CAAC;IALe,cAAA,eAAe,kBAK9B,CAAA;IAEM,KAAK,UAAU,MAAM,CAC1B,EAAY,EACZ,GAAsE;QAEtE,IAAI,aAAqB,CAAC;QAC1B,IAAI,EAAc,CAAC;QACnB,IAAI,iBAAiB,IAAI,GAAG,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACrE,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;YACvD,EAAE,GAAG,QAAQ,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC;YACvE,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACrB,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QAErC,MAAM,KAAK,GAAG,iBAAiB,aAAa,yBAAyB,CAAC;QACtE,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;YACjD,cAAc,EAAE,IAAI;SACrB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAvBqB,cAAA,MAAM,SAuB3B,CAAA;IAED;;OAEG;IACI,KAAK,UAAU,SAAS,CAC7B,EAAY,EACZ,gBAA2C;QAE3C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwC,CAAC;QAClE,KAAK,MAAM,eAAe,IAAI,gBAAgB,EAAE,CAAC;YAC/C,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YAC3D,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAAE,SAAS;YACjC,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;gBAChB,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAC3B,CAAC;YACD,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;QACzC,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC;YACpC,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;YAC7D,4FAA4F;YAC5F,MAAM,KAAK,GAAG,8BAA8B,aAAa,sDAAsD,CAAC;YAChH,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,SAAS,CACxC,KAAK,EACL,mBAAmB,CAAC,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CACxC,CAAC;YACF,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;gBACjD,cAAc,EAAE,IAAI;aACrB,CAAC,CAAC;YACH,OAAO,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC3B,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAjCqB,cAAA,SAAS,YAiC9B,CAAA;AACH,CAAC,EAtEgB,aAAa,KAAb,aAAa,QAsE7B","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Utils\n * utilities that unify operations, especially CRUD operations, on entities\n * for entity-generic operations in the transformer\n */\n\nimport {\n ConcreteEntityTypes,\n EntityReference,\n QueryBinder,\n} from \"@itwin/core-common\";\nimport {\n ConcreteEntity,\n // eslint-disable-next-line @typescript-eslint/no-redeclare\n Element,\n ElementAspect,\n Entity,\n EntityReferences,\n IModelDb,\n Model,\n Relationship,\n} from \"@itwin/core-backend\";\nimport { Id64, Id64String, OrderedId64Iterable } from \"@itwin/core-bentley\";\n\nconst bisCoreRootClasses: Record<ConcreteEntityTypes, typeof Entity> = {\n [ConcreteEntityTypes.Model]: Model,\n [ConcreteEntityTypes.Element]: Element,\n [ConcreteEntityTypes.ElementAspect]: ElementAspect,\n [ConcreteEntityTypes.Relationship]: Relationship,\n};\n\n/** @internal */\nexport namespace EntityUnifier {\n export function getReadableType(entity: ConcreteEntity) {\n if (entity instanceof Element) return \"element\";\n else if (entity instanceof ElementAspect) return \"element aspect\";\n else if (entity instanceof Relationship) return \"relationship\";\n else return \"unknown entity type\";\n }\n\n export async function exists(\n db: IModelDb,\n arg: { entity: ConcreteEntity } | { entityReference: EntityReference }\n ) {\n let classFullName: string;\n let id: Id64String;\n if (\"entityReference\" in arg) {\n const [type, entityId] = EntityReferences.split(arg.entityReference);\n classFullName = bisCoreRootClasses[type].classFullName;\n id = entityId;\n } else {\n classFullName = `[${arg.entity.schemaName}].[${arg.entity.className}]`;\n id = arg.entity.id;\n }\n\n if (Id64.isInvalid(id)) return false;\n\n const query = `SELECT 1 FROM ${classFullName} WHERE ECInstanceId=:id`;\n const params = new QueryBinder().bindId(\"id\", id);\n const reader = db.createQueryReader(query, params, {\n usePrimaryConn: true,\n });\n return reader.step();\n }\n\n /** Batched existence check: returns the subset of `entityReferences` that exist in `db`,\n * using one query per concrete entity type instead of one query per reference.\n */\n export async function existsAll(\n db: IModelDb,\n entityReferences: Iterable<EntityReference>\n ): Promise<Set<EntityReference>> {\n const idsByType = new Map<ConcreteEntityTypes, Set<Id64String>>();\n for (const entityReference of entityReferences) {\n const [type, id] = EntityReferences.split(entityReference);\n if (Id64.isInvalid(id)) continue;\n let ids = idsByType.get(type);\n if (ids === undefined) {\n ids = new Set();\n idsByType.set(type, ids);\n }\n ids.add(id);\n }\n\n const found = new Set<EntityReference>();\n for (const [type, ids] of idsByType) {\n const classFullName = bisCoreRootClasses[type].classFullName;\n // Join IdSet so SQLite looks up each id by primary key; InVirtualSet scans the whole table.\n const query = `SELECT e.ECInstanceId FROM ${classFullName} e INNER JOIN IdSet(:ids) s ON s.id = e.ECInstanceId`;\n const params = new QueryBinder().bindIdSet(\n \"ids\",\n OrderedId64Iterable.sortArray([...ids])\n );\n const reader = db.createQueryReader(query, params, {\n usePrimaryConn: true,\n });\n while (await reader.step()) {\n found.add(EntityReferences.fromEntityType(reader.current[0], type));\n }\n }\n return found;\n }\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  import { Id64String } from "@itwin/core-bentley";
2
2
  import { ElementAspectProps, ElementProps, EntityReference } from "@itwin/core-common";
3
3
  import { Element, ElementAspect, IModelElementCloneContext, IModelJsNative } from "@itwin/core-backend";
4
- import { EntityExistenceCache } from "./EntityExistenceCache";
5
- import type { IModelTransformContext } from "./IModelTransformContext";
4
+ import { EntityExistenceCache } from "./EntityExistenceCache.js";
5
+ import type { IModelTransformContext } from "./IModelTransformContext.js";
6
6
  /** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
7
7
  * @internal
8
8
  */
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IModelCloneContext.d.ts","sourceRoot":"","sources":["../src/IModelCloneContext.ts"],"names":[],"mappings":"AAQA,OAAO,EAAQ,UAAU,EAAU,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAKL,kBAAkB,EAClB,YAAY,EACZ,eAAe,EAKhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,OAAO,EACP,aAAa,EAEb,yBAAyB,EACzB,cAAc,EACf,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAI1E;;GAEG;AACH,qBAAa,kBACX,SAAQ,yBACR,YAAW,sBAAsB;IAEjC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,iBAAiB,CAA4B;IAErD;;OAEG;IACH,SAAgB,cAAc,uBAA8B;IAE5D,0HAA0H;IACpG,UAAU,kBAE/B;IAED;;OAEG;IACmB,YAAY,CAChC,aAAa,EAAE,OAAO,EACtB,YAAY,CAAC,EAAE,cAAc,CAAC,mBAAmB,GAChD,OAAO,CAAC,YAAY,CAAC,CAgFvB;IAED,uGAAuG;IAChG,kBAAkB,CACvB,cAAc,EAAE,UAAU,EAC1B,cAAc,EAAE,UAAU,GACzB,IAAI,CAEN;IAED,mEAAmE;IAC5D,mBAAmB,CAAC,cAAc,EAAE,UAAU,GAAG,IAAI,CAE3D;IAED;;OAEG;IACI,kBAAkB,CAAC,cAAc,EAAE,UAAU,GAAG,UAAU,CAEhE;IAED;;OAEG;IACU,kBAAkB,CAC7B,cAAc,EAAE,eAAe,GAC9B,OAAO,CAAC,eAAe,CAAC,CA6H1B;IAED;;OAEG;IACU,kBAAkB,CAC7B,mBAAmB,EAAE,aAAa,GACjC,OAAO,CAAC,kBAAkB,CAAC,CAqD7B;CACF"}
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.IModelCloneContext = void 0;
4
1
  /*---------------------------------------------------------------------------------------------
5
2
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
6
3
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -8,26 +5,26 @@ exports.IModelCloneContext = void 0;
8
5
  /** @packageDocumentation
9
6
  * @module iModels
10
7
  */
11
- const node_assert_1 = require("node:assert");
12
- const core_bentley_1 = require("@itwin/core-bentley");
13
- const core_common_1 = require("@itwin/core-common");
14
- const core_backend_1 = require("@itwin/core-backend");
15
- const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
16
- const ECReferenceTypesCache_1 = require("./ECReferenceTypesCache");
17
- const EntityExistenceCache_1 = require("./EntityExistenceCache");
18
- const TransformerLoggerCategory_1 = require("./TransformerLoggerCategory");
19
- const BigMap_1 = require("./BigMap");
20
- const loggerCategory = TransformerLoggerCategory_1.TransformerLoggerCategory.IModelCloneContext;
8
+ import { strict as assert } from "node:assert";
9
+ import { Id64, Logger } from "@itwin/core-bentley";
10
+ import { Code, CodeScopeSpec, ConcreteEntityTypes, ECJsNames, IModel, QueryBinder, RelatedElement, } from "@itwin/core-common";
11
+ import { EntityReferences, IModelElementCloneContext, } from "@itwin/core-backend";
12
+ import { EntityClass } from "@itwin/ecschema-metadata";
13
+ import { ECReferenceTypesCache } from "./ECReferenceTypesCache.js";
14
+ import { EntityExistenceCache } from "./EntityExistenceCache.js";
15
+ import { TransformerLoggerCategory } from "./TransformerLoggerCategory.js";
16
+ import { BigMap } from "./BigMap.js";
17
+ const loggerCategory = TransformerLoggerCategory.IModelCloneContext;
21
18
  /** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
22
19
  * @internal
23
20
  */
24
- class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
25
- _refTypesCache = new ECReferenceTypesCache_1.ECReferenceTypesCache();
26
- _aspectRemapTable = new BigMap_1.BigMap();
21
+ export class IModelCloneContext extends IModelElementCloneContext {
22
+ _refTypesCache = new ECReferenceTypesCache();
23
+ _aspectRemapTable = new BigMap();
27
24
  /** A positive-only cache of entity existence checks, scoped to the current transformation run.
28
25
  * @internal
29
26
  */
30
- existenceCache = new EntityExistenceCache_1.EntityExistenceCache();
27
+ existenceCache = new EntityExistenceCache();
31
28
  /** perform necessary initialization to use a clone context, namely caching the reference types in the source's schemas */
32
29
  async initialize() {
33
30
  await this._refTypesCache.initAllSchemasInIModel(this.sourceDb);
@@ -41,47 +38,47 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
41
38
  if (!this.isBetweenIModels &&
42
39
  this.findTargetElementId(sourceElement.id) === sourceElement.id) {
43
40
  targetElementProps.code.value = sourceElement.code.value;
44
- if (!core_bentley_1.Id64.isValidId64(targetElementProps.code.spec)) {
41
+ if (!Id64.isValidId64(targetElementProps.code.spec)) {
45
42
  const mappedCodeSpecId = this.findTargetCodeSpecId(sourceElement.code.spec);
46
- targetElementProps.code.spec = core_bentley_1.Id64.isValidId64(mappedCodeSpecId)
43
+ targetElementProps.code.spec = Id64.isValidId64(mappedCodeSpecId)
47
44
  ? mappedCodeSpecId
48
45
  : sourceElement.code.spec;
49
46
  }
50
- if (!core_bentley_1.Id64.isValidId64(targetElementProps.code.scope)) {
47
+ if (!Id64.isValidId64(targetElementProps.code.scope)) {
51
48
  const mappedCodeScopeId = this.findTargetElementId(sourceElement.code.scope);
52
- targetElementProps.code.scope = core_bentley_1.Id64.isValidId64(mappedCodeScopeId)
49
+ targetElementProps.code.scope = Id64.isValidId64(mappedCodeScopeId)
53
50
  ? mappedCodeScopeId
54
51
  : sourceElement.code.scope;
55
52
  }
56
53
  }
57
54
  // Ensure that all NavigationProperties in targetElementProps have a defined value so "clearing" changes will be part of the JSON used for update
58
- const sourceElementClass = sourceElement.iModel.schemaContext.getSchemaItemSync(sourceElement.schemaItemKey, ecschema_metadata_1.EntityClass);
59
- (0, node_assert_1.strict)(sourceElementClass !== undefined, `Cannot get metadata for ${sourceElement.classFullName}.`);
55
+ const sourceElementClass = sourceElement.iModel.schemaContext.getSchemaItemSync(sourceElement.schemaItemKey, EntityClass);
56
+ assert(sourceElementClass !== undefined, `Cannot get metadata for ${sourceElement.classFullName}.`);
60
57
  for (const property of sourceElementClass.getPropertiesSync()) {
61
58
  // Exclude custom properties because C++ has already handled them.
62
59
  if (property.customAttributes?.has("BisCore.CustomHandledProperty"))
63
60
  continue;
64
61
  const name = property.name;
65
62
  if (property.isNavigation() &&
66
- undefined === sourceElement[core_common_1.ECJsNames.toJsName(name)]) {
67
- targetElementProps[core_common_1.ECJsNames.toJsName(name)] =
68
- core_common_1.RelatedElement.none;
63
+ undefined === sourceElement[ECJsNames.toJsName(name)]) {
64
+ targetElementProps[ECJsNames.toJsName(name)] =
65
+ RelatedElement.none;
69
66
  }
70
67
  }
71
68
  if (this.isBetweenIModels) {
72
69
  // The native C++ cloneElement strips off federationGuid, want to put it back if transformation is between iModels
73
70
  targetElementProps.federationGuid = sourceElement.federationGuid;
74
71
  const targetElementCodeScopeType = this.targetDb.codeSpecs.getById(targetElementProps.code.spec).scopeType;
75
- if (core_common_1.CodeScopeSpec.Type.Repository === targetElementCodeScopeType &&
76
- targetElementProps.code.scope !== core_common_1.IModel.rootSubjectId) {
77
- core_bentley_1.Logger.logWarning(loggerCategory, `Incorrect CodeScope '${targetElementCodeScopeType}' is set for target element ${targetElementProps.id}`);
72
+ if (CodeScopeSpec.Type.Repository === targetElementCodeScopeType &&
73
+ targetElementProps.code.scope !== IModel.rootSubjectId) {
74
+ Logger.logWarning(loggerCategory, `Incorrect CodeScope '${targetElementCodeScopeType}' is set for target element ${targetElementProps.id}`);
78
75
  }
79
76
  }
80
77
  // unlike other references, code cannot be null. If it is null, use an empty code instead
81
78
  // this will be updated back later as the transformer resolves references
82
- if (targetElementProps.code.scope === core_bentley_1.Id64.invalid ||
83
- targetElementProps.code.spec === core_bentley_1.Id64.invalid) {
84
- targetElementProps.code = core_common_1.Code.createEmpty();
79
+ if (targetElementProps.code.scope === Id64.invalid ||
80
+ targetElementProps.code.spec === Id64.invalid) {
81
+ targetElementProps.code = Code.createEmpty();
85
82
  }
86
83
  const jsClass = this.sourceDb.getJsClass(sourceElement.classFullName);
87
84
  await jsClass["onCloned"](this, sourceElement.toJSON(), targetElementProps);
@@ -99,16 +96,16 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
99
96
  * @returns the target AspectId or [Id64.invalid]($bentley) if a mapping not found.
100
97
  */
101
98
  findTargetAspectId(sourceAspectId) {
102
- return this._aspectRemapTable.get(sourceAspectId) ?? core_bentley_1.Id64.invalid;
99
+ return this._aspectRemapTable.get(sourceAspectId) ?? Id64.invalid;
103
100
  }
104
101
  /** Look up a target [EntityReference]($bentley) from a source [EntityReference]($bentley)
105
102
  * @returns the target CodeSpecId or a [EntityReference]($bentley) containing [Id64.invalid]($bentley) if a mapping is not found.
106
103
  */
107
104
  async findTargetEntityId(sourceEntityId) {
108
- const [type, rawId] = core_backend_1.EntityReferences.split(sourceEntityId);
109
- if (core_bentley_1.Id64.isValid(rawId)) {
105
+ const [type, rawId] = EntityReferences.split(sourceEntityId);
106
+ if (Id64.isValid(rawId)) {
110
107
  switch (type) {
111
- case core_common_1.ConcreteEntityTypes.Model: {
108
+ case ConcreteEntityTypes.Model: {
112
109
  let targetId;
113
110
  /**
114
111
  * The repository model is a singleton container which exists in all iModels which has a modelId of 0x1.
@@ -119,8 +116,8 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
119
116
  * https://www.itwinjs.org/bis/domains/biscore.ecschema/#subject
120
117
  * Since there is a chance that the root subject is remapped to some other subject which has the same id as the repositoryModel, we need to ignore the remapping for the repository model.
121
118
  */
122
- if (rawId === core_common_1.IModel.repositoryModelId) {
123
- targetId = `m${core_common_1.IModel.repositoryModelId}`;
119
+ if (rawId === IModel.repositoryModelId) {
120
+ targetId = `m${IModel.repositoryModelId}`;
124
121
  }
125
122
  else {
126
123
  targetId = `m${this.findTargetElementId(rawId)}`;
@@ -131,11 +128,11 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
131
128
  return targetId;
132
129
  break;
133
130
  }
134
- case core_common_1.ConcreteEntityTypes.Element:
131
+ case ConcreteEntityTypes.Element:
135
132
  return `e${this.findTargetElementId(rawId)}`;
136
- case core_common_1.ConcreteEntityTypes.ElementAspect:
133
+ case ConcreteEntityTypes.ElementAspect:
137
134
  return `a${this.findTargetAspectId(rawId)}`;
138
- case core_common_1.ConcreteEntityTypes.Relationship: {
135
+ case ConcreteEntityTypes.Relationship: {
139
136
  const makeGetConcreteEntityTypeSql = (property) => `
140
137
  CASE
141
138
  WHEN [${property}] IS (BisCore.ElementUniqueAspect) OR [${property}] IS (BisCore.ElementMultiAspect)
@@ -160,7 +157,7 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
160
157
  FROM BisCore:ElementRefersToElements
161
158
  WHERE ECInstanceId=?
162
159
  `;
163
- const params = new core_common_1.QueryBinder().bindId(1, rawId);
160
+ const params = new QueryBinder().bindId(1, rawId);
164
161
  const reader = this.sourceDb.createQueryReader(sql, params, {
165
162
  usePrimaryConn: true,
166
163
  });
@@ -190,8 +187,8 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
190
187
  targetId: await this.findTargetEntityId(relInSource.targetId),
191
188
  };
192
189
  // return a null
193
- if (!core_backend_1.EntityReferences.isValid(relInTarget.sourceId) ||
194
- !core_backend_1.EntityReferences.isValid(relInTarget.targetId))
190
+ if (!EntityReferences.isValid(relInTarget.sourceId) ||
191
+ !EntityReferences.isValid(relInTarget.targetId))
195
192
  break;
196
193
  const relInTargetSql = `
197
194
  SELECT ECInstanceId
@@ -199,22 +196,22 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
199
196
  WHERE SourceECInstanceId=?
200
197
  AND TargetECInstanceId=?
201
198
  `;
202
- const relInTargetParams = new core_common_1.QueryBinder();
203
- relInTargetParams.bindId(1, core_backend_1.EntityReferences.toId64(relInTarget.sourceId));
204
- relInTargetParams.bindId(2, core_backend_1.EntityReferences.toId64(relInTarget.targetId));
199
+ const relInTargetParams = new QueryBinder();
200
+ relInTargetParams.bindId(1, EntityReferences.toId64(relInTarget.sourceId));
201
+ relInTargetParams.bindId(2, EntityReferences.toId64(relInTarget.targetId));
205
202
  const relInTargetResult = await this.targetDb
206
203
  .createQueryReader(relInTargetSql, relInTargetParams, {
207
204
  usePrimaryConn: true,
208
205
  })
209
206
  .next();
210
207
  const relInTargetId = relInTargetResult.done
211
- ? core_bentley_1.Id64.invalid
208
+ ? Id64.invalid
212
209
  : relInTargetResult.value.id;
213
210
  return `r${relInTargetId}`;
214
211
  }
215
212
  }
216
213
  }
217
- return `${type}${core_bentley_1.Id64.invalid}`;
214
+ return `${type}${Id64.invalid}`;
218
215
  }
219
216
  /** Clone the specified source Element into ElementProps for the target iModel.
220
217
  * @internal
@@ -223,18 +220,18 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
223
220
  const targetElementAspectProps = sourceElementAspect.toJSON();
224
221
  targetElementAspectProps.id = undefined;
225
222
  const targetEntityIds = [];
226
- const sourceElementAspectClass = sourceElementAspect.iModel.schemaContext.getSchemaItemSync(sourceElementAspect.schemaItemKey, ecschema_metadata_1.EntityClass);
227
- (0, node_assert_1.strict)(sourceElementAspectClass !== undefined, `Cannot get metadata for ${sourceElementAspect.classFullName}.`);
223
+ const sourceElementAspectClass = sourceElementAspect.iModel.schemaContext.getSchemaItemSync(sourceElementAspect.schemaItemKey, EntityClass);
224
+ assert(sourceElementAspectClass !== undefined, `Cannot get metadata for ${sourceElementAspect.classFullName}.`);
228
225
  for (const property of sourceElementAspectClass.getPropertiesSync()) {
229
226
  const ecName = property.name;
230
- const name = core_common_1.ECJsNames.toJsName(ecName);
227
+ const name = ECJsNames.toJsName(ecName);
231
228
  if (property.isNavigation()) {
232
229
  const sourceNavProp = sourceElementAspect.asAny[name];
233
230
  if (sourceNavProp?.id) {
234
231
  const navPropRefType = this._refTypesCache.getNavPropRefType(sourceElementAspect.schemaName, sourceElementAspect.className, name);
235
- (0, node_assert_1.strict)(navPropRefType !== undefined, `nav prop ref type for '${name}' was not in the cache, this is a bug.`);
236
- targetEntityIds.push(this.findTargetEntityId(core_backend_1.EntityReferences.fromEntityType(sourceNavProp.id, navPropRefType)).then((targetEntityReference) => {
237
- const targetEntityId = core_backend_1.EntityReferences.toId64(targetEntityReference);
232
+ assert(navPropRefType !== undefined, `nav prop ref type for '${name}' was not in the cache, this is a bug.`);
233
+ targetEntityIds.push(this.findTargetEntityId(EntityReferences.fromEntityType(sourceNavProp.id, navPropRefType)).then((targetEntityReference) => {
234
+ const targetEntityId = EntityReferences.toId64(targetEntityReference);
238
235
  // spread the property in case toJSON did not deep-clone
239
236
  targetElementAspectProps[name] = {
240
237
  ...targetElementAspectProps[name],
@@ -251,5 +248,4 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
251
248
  return targetElementAspectProps;
252
249
  }
253
250
  }
254
- exports.IModelCloneContext = IModelCloneContext;
255
251
  //# sourceMappingURL=IModelCloneContext.js.map