@itwin/imodel-transformer 2.0.0-dev.5 → 2.0.0-dev.50

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 (115) hide show
  1. package/README.md +13 -27
  2. package/lib/cjs/Algo.js.map +1 -1
  3. package/lib/cjs/BigMap.d.ts.map +1 -1
  4. package/lib/cjs/BigMap.js.map +1 -1
  5. package/lib/cjs/BranchProvenanceInitializer.d.ts.map +1 -1
  6. package/lib/cjs/BranchProvenanceInitializer.js +34 -36
  7. package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
  8. package/lib/cjs/ChangesetScanner.d.ts +60 -0
  9. package/lib/cjs/ChangesetScanner.d.ts.map +1 -0
  10. package/lib/cjs/ChangesetScanner.js +101 -0
  11. package/lib/cjs/ChangesetScanner.js.map +1 -0
  12. package/lib/cjs/ECReferenceTypesCache.d.ts +0 -3
  13. package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -1
  14. package/lib/cjs/ECReferenceTypesCache.js +61 -103
  15. package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
  16. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +1 -1
  17. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js.map +1 -1
  18. package/lib/cjs/ElementAspectCleanup.d.ts +16 -0
  19. package/lib/cjs/ElementAspectCleanup.d.ts.map +1 -0
  20. package/lib/cjs/ElementAspectCleanup.js +83 -0
  21. package/lib/cjs/ElementAspectCleanup.js.map +1 -0
  22. package/lib/cjs/ElementAspectExportCoordinator.d.ts +44 -0
  23. package/lib/cjs/ElementAspectExportCoordinator.d.ts.map +1 -0
  24. package/lib/cjs/ElementAspectExportCoordinator.js +148 -0
  25. package/lib/cjs/ElementAspectExportCoordinator.js.map +1 -0
  26. package/lib/cjs/ElementAspectExportProcessor.d.ts +43 -0
  27. package/lib/cjs/ElementAspectExportProcessor.d.ts.map +1 -0
  28. package/lib/cjs/ElementAspectExportProcessor.js +167 -0
  29. package/lib/cjs/ElementAspectExportProcessor.js.map +1 -0
  30. package/lib/cjs/ElementCascadingDeleter.d.ts +3 -3
  31. package/lib/cjs/ElementCascadingDeleter.d.ts.map +1 -1
  32. package/lib/cjs/ElementCascadingDeleter.js +12 -12
  33. package/lib/cjs/ElementCascadingDeleter.js.map +1 -1
  34. package/lib/cjs/EntityExistenceCache.d.ts +43 -0
  35. package/lib/cjs/EntityExistenceCache.d.ts.map +1 -0
  36. package/lib/cjs/EntityExistenceCache.js +91 -0
  37. package/lib/cjs/EntityExistenceCache.js.map +1 -0
  38. package/lib/cjs/EntityMap.d.ts.map +1 -1
  39. package/lib/cjs/EntityMap.js.map +1 -1
  40. package/lib/cjs/EntityUnifier.d.ts +8 -8
  41. package/lib/cjs/EntityUnifier.d.ts.map +1 -1
  42. package/lib/cjs/EntityUnifier.js +55 -32
  43. package/lib/cjs/EntityUnifier.js.map +1 -1
  44. package/lib/cjs/IModelCloneContext.d.ts +11 -5
  45. package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
  46. package/lib/cjs/IModelCloneContext.js +94 -58
  47. package/lib/cjs/IModelCloneContext.js.map +1 -1
  48. package/lib/cjs/IModelExporter.d.ts +108 -34
  49. package/lib/cjs/IModelExporter.d.ts.map +1 -1
  50. package/lib/cjs/IModelExporter.js +702 -208
  51. package/lib/cjs/IModelExporter.js.map +1 -1
  52. package/lib/cjs/IModelImporter.d.ts +50 -25
  53. package/lib/cjs/IModelImporter.d.ts.map +1 -1
  54. package/lib/cjs/IModelImporter.js +231 -130
  55. package/lib/cjs/IModelImporter.js.map +1 -1
  56. package/lib/cjs/IModelTransformContext.d.ts +54 -0
  57. package/lib/cjs/IModelTransformContext.d.ts.map +1 -0
  58. package/lib/cjs/IModelTransformContext.js +3 -0
  59. package/lib/cjs/IModelTransformContext.js.map +1 -0
  60. package/lib/cjs/IModelTransformer.d.ts +125 -203
  61. package/lib/cjs/IModelTransformer.d.ts.map +1 -1
  62. package/lib/cjs/IModelTransformer.js +646 -1190
  63. package/lib/cjs/IModelTransformer.js.map +1 -1
  64. package/lib/cjs/IModelTransformerError.d.ts +82 -0
  65. package/lib/cjs/IModelTransformerError.d.ts.map +1 -0
  66. package/lib/cjs/IModelTransformerError.js +91 -0
  67. package/lib/cjs/IModelTransformerError.js.map +1 -0
  68. package/lib/cjs/ProvenanceManager.d.ts +182 -0
  69. package/lib/cjs/ProvenanceManager.d.ts.map +1 -0
  70. package/lib/cjs/ProvenanceManager.js +743 -0
  71. package/lib/cjs/ProvenanceManager.js.map +1 -0
  72. package/lib/cjs/SyncTypeResolver.d.ts +34 -0
  73. package/lib/cjs/SyncTypeResolver.d.ts.map +1 -0
  74. package/lib/cjs/SyncTypeResolver.js +98 -0
  75. package/lib/cjs/SyncTypeResolver.js.map +1 -0
  76. package/lib/cjs/TransformerLoggerCategory.d.ts +1 -1
  77. package/lib/cjs/TransformerLoggerCategory.js +1 -1
  78. package/lib/cjs/TransformerLoggerCategory.js.map +1 -1
  79. package/lib/cjs/TransformerPackageMetadata.d.ts +8 -0
  80. package/lib/cjs/TransformerPackageMetadata.d.ts.map +1 -0
  81. package/lib/cjs/TransformerPackageMetadata.js +47 -0
  82. package/lib/cjs/TransformerPackageMetadata.js.map +1 -0
  83. package/lib/cjs/imodel-transformer.d.ts +19 -0
  84. package/lib/cjs/imodel-transformer.d.ts.map +1 -1
  85. package/lib/cjs/imodel-transformer.js +53 -34
  86. package/lib/cjs/imodel-transformer.js.map +1 -1
  87. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts +29 -0
  88. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts.map +1 -0
  89. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js +212 -0
  90. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js.map +1 -0
  91. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts +25 -0
  92. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts.map +1 -0
  93. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js +196 -0
  94. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js.map +1 -0
  95. package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts +59 -0
  96. package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts.map +1 -0
  97. package/lib/cjs/schema-processing/SchemaProcessingStrategy.js +28 -0
  98. package/lib/cjs/schema-processing/SchemaProcessingStrategy.js.map +1 -0
  99. package/lib/cjs/schema-processing.d.ts +7 -0
  100. package/lib/cjs/schema-processing.d.ts.map +1 -0
  101. package/lib/cjs/schema-processing.js +27 -0
  102. package/lib/cjs/schema-processing.js.map +1 -0
  103. package/package.json +65 -43
  104. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts +0 -16
  105. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +0 -1
  106. package/lib/cjs/DetachedExportElementAspectsStrategy.js +0 -106
  107. package/lib/cjs/DetachedExportElementAspectsStrategy.js.map +0 -1
  108. package/lib/cjs/ExportElementAspectsStrategy.d.ts +0 -35
  109. package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +0 -1
  110. package/lib/cjs/ExportElementAspectsStrategy.js +0 -52
  111. package/lib/cjs/ExportElementAspectsStrategy.js.map +0 -1
  112. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts +0 -12
  113. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts.map +0 -1
  114. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +0 -47
  115. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js.map +0 -1
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ /** @packageDocumentation
7
+ * @module Utils
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.EntityExistenceCache = void 0;
11
+ const EntityUnifier_1 = require("./EntityUnifier");
12
+ /** A positive-only read-through cache of entity existence checks, scoped to a single transformation run.
13
+ *
14
+ * Entities are created continuously as a transformation progresses, so a negative
15
+ * ("does not exist") result may become stale at any moment — therefore only positive
16
+ * results are ever cached. Positive results can only be invalidated by deletes, which the
17
+ * transformer routes through [[invalidate]] and [[clearDb]].
18
+ *
19
+ * The cache is keyed by [IModelDb]($core-backend) instance, so same-iModel transformations
20
+ * (where sourceDb === targetDb) share a single set and source/target roles cannot be confused.
21
+ *
22
+ * [IModelImporter]($transformer) delete operations invalidate registered caches. Deletes performed
23
+ * directly through an `EditTxn` while a transformation is active are out-of-band and must not be
24
+ * mixed with transformer operations. A successful high-level `process()` clears the cache when the
25
+ * transformation finalizes; low-level or failed transformations clear it when the transformer is
26
+ * disposed.
27
+ * @internal
28
+ */
29
+ class EntityExistenceCache {
30
+ _existsByDb = new Map();
31
+ getDbSet(db) {
32
+ let set = this._existsByDb.get(db);
33
+ if (set === undefined) {
34
+ set = new Set();
35
+ this._existsByDb.set(db, set);
36
+ }
37
+ return set;
38
+ }
39
+ /** Check whether an entity exists in `db`, consulting the cache first.
40
+ * A `true` result is cached; a `false` result is never cached and will be re-queried.
41
+ */
42
+ async exists(db, entityReference) {
43
+ const set = this.getDbSet(db);
44
+ if (set.has(entityReference))
45
+ return true;
46
+ const found = await EntityUnifier_1.EntityUnifier.exists(db, { entityReference });
47
+ if (found)
48
+ set.add(entityReference);
49
+ return found;
50
+ }
51
+ /** Read through the cache to check which of the supplied entities exist in `db`, populating it on a miss. */
52
+ async existsAll(db, entityReferences) {
53
+ const dbSet = this.getDbSet(db);
54
+ const found = new Set();
55
+ const unverified = [];
56
+ for (const entityReference of entityReferences) {
57
+ if (dbSet.has(entityReference))
58
+ found.add(entityReference);
59
+ else
60
+ unverified.push(entityReference);
61
+ }
62
+ if (unverified.length === 0)
63
+ return found;
64
+ const queried = await EntityUnifier_1.EntityUnifier.existsAll(db, unverified);
65
+ for (const entityReference of queried) {
66
+ dbSet.add(entityReference);
67
+ found.add(entityReference);
68
+ }
69
+ return found;
70
+ }
71
+ /** Record that an entity is known to exist in `db` (e.g. it was just imported). */
72
+ markExists(db, entityReference) {
73
+ this.getDbSet(db).add(entityReference);
74
+ }
75
+ /** Remove a single entity from the cache for `db`, forcing a re-query on next check. */
76
+ invalidate(db, entityReference) {
77
+ this._existsByDb.get(db)?.delete(entityReference);
78
+ }
79
+ /** Drop all cached results for `db`. Used when a delete may cascade to entities the
80
+ * caller cannot enumerate (e.g. element tree deletes that remove descendants and submodels).
81
+ */
82
+ clearDb(db) {
83
+ this._existsByDb.delete(db);
84
+ }
85
+ /** Drop all cached results. */
86
+ clear() {
87
+ this._existsByDb.clear();
88
+ }
89
+ }
90
+ exports.EntityExistenceCache = EntityExistenceCache;
91
+ //# 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,mDAAgD;AAEhD;;;;;;;;;;;;;;;;GAgBG;AACH;IACU,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,6BAAa,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,6BAAa,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\";\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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"EntityMap.d.ts","sourceRoot":"","sources":["../../src/EntityMap.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAoB,MAAM,qBAAqB,CAAC;AAGvE,gBAAgB;AAChB,MAAM,MAAM,SAAS,GAAG,eAAe,CAAC;AAExC,gBAAgB;AAChB,qBAAa,SAAS,CAAC,CAAC;IACtB,OAAO,CAAC,IAAI,CAAmB;WAEjB,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS;IAIjD,KAAK,IAAI,IAAI;IAIb,GAAG,CAAC,MAAM,EAAE,cAAc;IAI1B,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAIjD,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAK5C,GAAG,CAAC,MAAM,EAAE,cAAc,GAAG,CAAC,GAAG,SAAS;IAI1C,QAAQ,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,GAAG,SAAS;IAIrC,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO;IAIvC,WAAW,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO;IAIlC,IAAI;IAIJ,MAAM;IAIN,OAAO;IAIP,CAAC,MAAM,CAAC,QAAQ,CAAC;IAIxB,IAAW,IAAI,WAEd;CACF"}
1
+ {"version":3,"file":"EntityMap.d.ts","sourceRoot":"","sources":["../../src/EntityMap.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAoB,MAAM,qBAAqB,CAAC;AAGvE,gBAAgB;AAChB,MAAM,MAAM,SAAS,GAAG,eAAe,CAAC;AAExC,gBAAgB;AAChB,qBAAa,SAAS,CAAC,CAAC;IACtB,OAAO,CAAC,IAAI,CAAmB;IAE/B,OAAc,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CAEvD;IAEM,KAAK,IAAI,IAAI,CAEnB;IAEM,GAAG,CAAC,MAAM,EAAE,cAAc,WAEhC;IAEM,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAEvD;IAEM,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAGlD;IAEM,GAAG,CAAC,MAAM,EAAE,cAAc,GAAG,CAAC,GAAG,SAAS,CAEhD;IAEM,QAAQ,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,GAAG,SAAS,CAE3C;IAEM,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAE7C;IAEM,WAAW,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAExC;IAEM,IAAI,wBAEV;IAEM,MAAM,mBAEZ;IAEM,OAAO,6BAEb;IAEM,CAAC,MAAM,CAAC,QAAQ,CAAC,6BAEvB;IAED,IAAW,IAAI,WAEd;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"EntityMap.js","sourceRoot":"","sources":["../../src/EntityMap.ts"],"names":[],"mappings":";;;AAQA,sDAAuE;AACvE,qCAAkC;AAKlC,gBAAgB;AAChB,MAAa,SAAS;IACZ,IAAI,GAAG,IAAI,eAAM,EAAK,CAAC;IAExB,MAAM,CAAC,OAAO,CAAC,MAAsB;QAC1C,OAAO,+BAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAEM,KAAK;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAEM,GAAG,CAAC,MAAsB;QAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC;IAEM,GAAG,CAAC,MAAsB,EAAE,GAAM;QACvC,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAEM,QAAQ,CAAC,CAAY,EAAE,GAAM;QAClC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,MAAsB;QAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC;IAEM,QAAQ,CAAC,CAAY;QAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAEM,MAAM,CAAC,MAAsB;QAClC,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC;IAEM,WAAW,CAAC,CAAY;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC;IAEM,IAAI;QACT,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;IAEM,OAAO;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAEM,CAAC,MAAM,CAAC,QAAQ,CAAC;QACtB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IACtC,CAAC;IAED,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;CACF;AA3DD,8BA2DC","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 */\nimport { EntityReference } from \"@itwin/core-common\";\nimport { ConcreteEntity, EntityReferences } from \"@itwin/core-backend\";\nimport { BigMap } from \"./BigMap\";\n\n/** @internal */\nexport type EntityKey = EntityReference;\n\n/** @internal */\nexport class EntityMap<V> {\n private _map = new BigMap<V>();\n\n public static makeKey(entity: ConcreteEntity): EntityKey {\n return EntityReferences.from(entity);\n }\n\n public clear(): void {\n return this._map.clear();\n }\n\n public has(entity: ConcreteEntity) {\n return this._map.has(EntityMap.makeKey(entity));\n }\n\n public set(entity: ConcreteEntity, val: V): EntityMap<V> {\n return this.setByKey(EntityMap.makeKey(entity), val);\n }\n\n public setByKey(k: EntityKey, val: V): EntityMap<V> {\n this._map.set(k, val);\n return this;\n }\n\n public get(entity: ConcreteEntity): V | undefined {\n return this.getByKey(EntityMap.makeKey(entity));\n }\n\n public getByKey(k: EntityKey): V | undefined {\n return this._map.get(k);\n }\n\n public delete(entity: ConcreteEntity): boolean {\n return this.deleteByKey(EntityMap.makeKey(entity));\n }\n\n public deleteByKey(k: EntityKey): boolean {\n return this._map.delete(k);\n }\n\n public keys() {\n return this._map.keys();\n }\n\n public values() {\n return this._map.values();\n }\n\n public entries() {\n return this._map.entries();\n }\n\n public [Symbol.iterator]() {\n return this._map[Symbol.iterator]();\n }\n\n public get size() {\n return this._map.size;\n }\n}\n"]}
1
+ {"version":3,"file":"EntityMap.js","sourceRoot":"","sources":["../../src/EntityMap.ts"],"names":[],"mappings":";;;AAQA,sDAAuE;AACvE,qCAAkC;AAKlC,gBAAgB;AAChB;IACU,IAAI,GAAG,IAAI,eAAM,EAAK,CAAC;IAExB,MAAM,CAAC,OAAO,CAAC,MAAsB;QAC1C,OAAO,+BAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAEM,KAAK;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAEM,GAAG,CAAC,MAAsB;QAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC;IAEM,GAAG,CAAC,MAAsB,EAAE,GAAM;QACvC,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAEM,QAAQ,CAAC,CAAY,EAAE,GAAM;QAClC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,MAAsB;QAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC;IAEM,QAAQ,CAAC,CAAY;QAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAEM,MAAM,CAAC,MAAsB;QAClC,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC;IAEM,WAAW,CAAC,CAAY;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC;IAEM,IAAI;QACT,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;IAEM,OAAO;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAEM,CAAC,MAAM,CAAC,QAAQ,CAAC;QACtB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IACtC,CAAC;IAED,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB,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 */\nimport { EntityReference } from \"@itwin/core-common\";\nimport { ConcreteEntity, EntityReferences } from \"@itwin/core-backend\";\nimport { BigMap } from \"./BigMap\";\n\n/** @internal */\nexport type EntityKey = EntityReference;\n\n/** @internal */\nexport class EntityMap<V> {\n private _map = new BigMap<V>();\n\n public static makeKey(entity: ConcreteEntity): EntityKey {\n return EntityReferences.from(entity);\n }\n\n public clear(): void {\n return this._map.clear();\n }\n\n public has(entity: ConcreteEntity) {\n return this._map.has(EntityMap.makeKey(entity));\n }\n\n public set(entity: ConcreteEntity, val: V): EntityMap<V> {\n return this.setByKey(EntityMap.makeKey(entity), val);\n }\n\n public setByKey(k: EntityKey, val: V): EntityMap<V> {\n this._map.set(k, val);\n return this;\n }\n\n public get(entity: ConcreteEntity): V | undefined {\n return this.getByKey(EntityMap.makeKey(entity));\n }\n\n public getByKey(k: EntityKey): V | undefined {\n return this._map.get(k);\n }\n\n public delete(entity: ConcreteEntity): boolean {\n return this.deleteByKey(EntityMap.makeKey(entity));\n }\n\n public deleteByKey(k: EntityKey): boolean {\n return this._map.delete(k);\n }\n\n public keys() {\n return this._map.keys();\n }\n\n public values() {\n return this._map.values();\n }\n\n public entries() {\n return this._map.entries();\n }\n\n public [Symbol.iterator]() {\n return this._map[Symbol.iterator]();\n }\n\n public get size() {\n return this._map.size;\n }\n}\n"]}
@@ -4,18 +4,18 @@
4
4
  * for entity-generic operations in the transformer
5
5
  */
6
6
  import { EntityReference } from "@itwin/core-common";
7
- import { ConcreteEntity, ConcreteEntityProps, IModelDb } from "@itwin/core-backend";
7
+ import { ConcreteEntity, IModelDb } from "@itwin/core-backend";
8
8
  /** @internal */
9
9
  export declare namespace EntityUnifier {
10
- export function getReadableType(entity: ConcreteEntity): "element" | "element aspect" | "relationship" | "unknown entity type";
11
- type EntityUpdater = (entityProps: ConcreteEntityProps) => void;
12
- /** needs to return a widened type otherwise typescript complains when result is used with a narrow type */
13
- export function updaterFor(db: IModelDb, entity: ConcreteEntity): EntityUpdater;
14
- export function exists(db: IModelDb, arg: {
10
+ function getReadableType(entity: ConcreteEntity): "element" | "element aspect" | "relationship" | "unknown entity type";
11
+ function exists(db: IModelDb, arg: {
15
12
  entity: ConcreteEntity;
16
13
  } | {
17
14
  entityReference: EntityReference;
18
- }): boolean;
19
- export {};
15
+ }): Promise<boolean>;
16
+ /** Batched existence check: returns the subset of `entityReferences` that exist in `db`,
17
+ * using one query per concrete entity type instead of one query per reference.
18
+ */
19
+ function existsAll(db: IModelDb, entityReferences: Iterable<EntityReference>): Promise<Set<EntityReference>>;
20
20
  }
21
21
  //# sourceMappingURL=EntityUnifier.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EntityUnifier.d.ts","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAGH,OAAO,EAEL,eAAe,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,mBAAmB,EAKnB,QAAQ,EAET,MAAM,qBAAqB,CAAC;AAG7B,gBAAgB;AAChB,yBAAiB,aAAa,CAAC;IAC7B,MAAM,UAAU,eAAe,CAAC,MAAM,EAAE,cAAc,yEAKrD;IAED,KAAK,aAAa,GAAG,CAAC,WAAW,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAEhE,2GAA2G;IAC3G,MAAM,UAAU,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,iBAc9D;IAED,MAAM,UAAU,MAAM,CACpB,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE;QAAE,MAAM,EAAE,cAAc,CAAA;KAAE,GAAG;QAAE,eAAe,EAAE,eAAe,CAAA;KAAE,WAyBvE;;CACF"}
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,CA6B/B;CACF"}
@@ -10,10 +10,15 @@
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.EntityUnifier = void 0;
13
- const assert = require("assert");
14
13
  const core_common_1 = require("@itwin/core-common");
15
14
  const core_backend_1 = require("@itwin/core-backend");
16
15
  const core_bentley_1 = require("@itwin/core-bentley");
16
+ 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,
21
+ };
17
22
  /** @internal */
18
23
  var EntityUnifier;
19
24
  (function (EntityUnifier) {
@@ -28,40 +33,58 @@ var EntityUnifier;
28
33
  return "unknown entity type";
29
34
  }
30
35
  EntityUnifier.getReadableType = getReadableType;
31
- /** needs to return a widened type otherwise typescript complains when result is used with a narrow type */
32
- function updaterFor(db, entity) {
33
- if (entity instanceof core_backend_1.Element)
34
- return db.elements.updateElement.bind(db.elements);
35
- else if (entity instanceof core_backend_1.Relationship)
36
- return db.relationships.updateInstance.bind(db.relationships);
37
- else if (entity instanceof core_backend_1.ElementAspect)
38
- return db.elements.updateAspect.bind(db.elements);
39
- else
40
- assert(false, `unreachable; entity was '${entity.constructor.name}' not an Element, Relationship, or ElementAspect`);
41
- }
42
- EntityUnifier.updaterFor = updaterFor;
43
- function exists(db, arg) {
44
- const [type, id] = "entityReference" in arg
45
- ? core_backend_1.EntityReferences.split(arg.entityReference)
46
- : [undefined, arg.entity.id];
47
- const classFullName = "entityReference" in arg
48
- ? // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-non-null-assertion
49
- core_common_1.ConcreteEntityTypes.toBisCoreRootClassFullName(type)
50
- : `[${arg.entity.schemaName}].[${arg.entity.className}]`;
51
- if (id === undefined || core_bentley_1.Id64.isInvalid(id))
36
+ async function exists(db, arg) {
37
+ let classFullName;
38
+ let id;
39
+ if ("entityReference" in arg) {
40
+ const [type, entityId] = core_backend_1.EntityReferences.split(arg.entityReference);
41
+ classFullName = bisCoreRootClasses[type].classFullName;
42
+ id = entityId;
43
+ }
44
+ else {
45
+ classFullName = `[${arg.entity.schemaName}].[${arg.entity.className}]`;
46
+ id = arg.entity.id;
47
+ }
48
+ if (core_bentley_1.Id64.isInvalid(id))
52
49
  return false;
53
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
54
- return db.withPreparedStatement(`SELECT 1 FROM ${classFullName} WHERE ECInstanceId=?`, (stmt) => {
55
- stmt.bindId(1, id);
56
- const matchesResult = stmt.step();
57
- if (matchesResult === core_bentley_1.DbResult.BE_SQLITE_ROW)
58
- return true;
59
- if (matchesResult === core_bentley_1.DbResult.BE_SQLITE_DONE)
60
- return false;
61
- else
62
- throw new core_common_1.IModelError(matchesResult, "query failed");
50
+ const query = `SELECT 1 FROM ${classFullName} WHERE ECInstanceId=:id`;
51
+ const params = new core_common_1.QueryBinder().bindId("id", id);
52
+ const reader = db.createQueryReader(query, params, {
53
+ usePrimaryConn: true,
63
54
  });
55
+ return reader.step();
64
56
  }
65
57
  EntityUnifier.exists = exists;
58
+ /** Batched existence check: returns the subset of `entityReferences` that exist in `db`,
59
+ * using one query per concrete entity type instead of one query per reference.
60
+ */
61
+ async function existsAll(db, entityReferences) {
62
+ const idsByType = new Map();
63
+ for (const entityReference of entityReferences) {
64
+ const [type, id] = core_backend_1.EntityReferences.split(entityReference);
65
+ if (core_bentley_1.Id64.isInvalid(id))
66
+ continue;
67
+ let ids = idsByType.get(type);
68
+ if (ids === undefined) {
69
+ ids = new Set();
70
+ idsByType.set(type, ids);
71
+ }
72
+ ids.add(id);
73
+ }
74
+ const found = new Set();
75
+ for (const [type, ids] of idsByType) {
76
+ const classFullName = bisCoreRootClasses[type].classFullName;
77
+ const query = `SELECT ECInstanceId FROM ${classFullName} WHERE InVirtualSet(:ids, ECInstanceId)`;
78
+ const params = new core_common_1.QueryBinder().bindIdSet("ids", core_bentley_1.OrderedId64Iterable.sortArray([...ids]));
79
+ const reader = db.createQueryReader(query, params, {
80
+ usePrimaryConn: true,
81
+ });
82
+ while (await reader.step()) {
83
+ found.add(core_backend_1.EntityReferences.fromEntityType(reader.current[0], type));
84
+ }
85
+ }
86
+ return found;
87
+ }
88
+ EntityUnifier.existsAll = existsAll;
66
89
  })(EntityUnifier || (exports.EntityUnifier = EntityUnifier = {}));
67
90
  //# sourceMappingURL=EntityUnifier.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EntityUnifier.js","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;AAChG;;;;GAIG;;;AAEH,iCAAiC;AACjC,oDAI4B;AAC5B,sDAS6B;AAC7B,sDAAqD;AAErD,gBAAgB;AAChB,IAAiB,aAAa,CAuD7B;AAvDD,WAAiB,aAAa;IAC5B,SAAgB,eAAe,CAAC,MAAsB;QACpD,IAAI,MAAM,YAAY,sBAAO;YAAE,OAAO,SAAS,CAAC;aAC3C,IAAI,MAAM,YAAY,4BAAa;YAAE,OAAO,gBAAgB,CAAC;aAC7D,IAAI,MAAM,YAAY,2BAAY;YAAE,OAAO,cAAc,CAAC;;YAC1D,OAAO,qBAAqB,CAAC;IACpC,CAAC;IALe,6BAAe,kBAK9B,CAAA;IAID,2GAA2G;IAC3G,SAAgB,UAAU,CAAC,EAAY,EAAE,MAAsB;QAC7D,IAAI,MAAM,YAAY,sBAAO;YAC3B,OAAO,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAkB,CAAC;aACjE,IAAI,MAAM,YAAY,2BAAY;YACrC,OAAO,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,CACzC,EAAE,CAAC,aAAa,CACA,CAAC;aAChB,IAAI,MAAM,YAAY,4BAAa;YACtC,OAAO,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAkB,CAAC;;YAEnE,MAAM,CACJ,KAAK,EACL,4BAA4B,MAAM,CAAC,WAAW,CAAC,IAAI,kDAAkD,CACtG,CAAC;IACN,CAAC;IAde,wBAAU,aAczB,CAAA;IAED,SAAgB,MAAM,CACpB,EAAY,EACZ,GAAsE;QAEtE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GACd,iBAAiB,IAAI,GAAG;YACtB,CAAC,CAAC,+BAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC;YAC7C,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjC,MAAM,aAAa,GACjB,iBAAiB,IAAI,GAAG;YACtB,CAAC,CAAC,wFAAwF;gBACxF,iCAAmB,CAAC,0BAA0B,CAAC,IAAK,CAAC;YACvD,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC;QAE7D,IAAI,EAAE,KAAK,SAAS,IAAI,mBAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QAEzD,gFAAgF;QAChF,OAAO,EAAE,CAAC,qBAAqB,CAC7B,iBAAiB,aAAa,uBAAuB,EACrD,CAAC,IAAI,EAAE,EAAE;YACP,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,aAAa,KAAK,uBAAQ,CAAC,aAAa;gBAAE,OAAO,IAAI,CAAC;YAC1D,IAAI,aAAa,KAAK,uBAAQ,CAAC,cAAc;gBAAE,OAAO,KAAK,CAAC;;gBACvD,MAAM,IAAI,yBAAW,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;QAC5D,CAAC,CACF,CAAC;IACJ,CAAC;IA3Be,oBAAM,SA2BrB,CAAA;AACH,CAAC,EAvDgB,aAAa,6BAAb,aAAa,QAuD7B","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 * as assert from \"assert\";\nimport {\n ConcreteEntityTypes,\n EntityReference,\n IModelError,\n} from \"@itwin/core-common\";\nimport {\n ConcreteEntity,\n ConcreteEntityProps,\n // eslint-disable-next-line @typescript-eslint/no-redeclare\n Element,\n ElementAspect,\n EntityReferences,\n IModelDb,\n Relationship,\n} from \"@itwin/core-backend\";\nimport { DbResult, Id64 } from \"@itwin/core-bentley\";\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 type EntityUpdater = (entityProps: ConcreteEntityProps) => void;\n\n /** needs to return a widened type otherwise typescript complains when result is used with a narrow type */\n export function updaterFor(db: IModelDb, entity: ConcreteEntity) {\n if (entity instanceof Element)\n return db.elements.updateElement.bind(db.elements) as EntityUpdater;\n else if (entity instanceof Relationship)\n return db.relationships.updateInstance.bind(\n db.relationships\n ) as EntityUpdater;\n else if (entity instanceof ElementAspect)\n return db.elements.updateAspect.bind(db.elements) as EntityUpdater;\n else\n assert(\n false,\n `unreachable; entity was '${entity.constructor.name}' not an Element, Relationship, or ElementAspect`\n );\n }\n\n export function exists(\n db: IModelDb,\n arg: { entity: ConcreteEntity } | { entityReference: EntityReference }\n ) {\n const [type, id] =\n \"entityReference\" in arg\n ? EntityReferences.split(arg.entityReference)\n : [undefined, arg.entity.id];\n const classFullName =\n \"entityReference\" in arg\n ? // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-non-null-assertion\n ConcreteEntityTypes.toBisCoreRootClassFullName(type!)\n : `[${arg.entity.schemaName}].[${arg.entity.className}]`;\n\n if (id === undefined || Id64.isInvalid(id)) return false;\n\n // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated\n return db.withPreparedStatement(\n `SELECT 1 FROM ${classFullName} WHERE ECInstanceId=?`,\n (stmt) => {\n stmt.bindId(1, id);\n const matchesResult = stmt.step();\n if (matchesResult === DbResult.BE_SQLITE_ROW) return true;\n if (matchesResult === DbResult.BE_SQLITE_DONE) return false;\n else throw new IModelError(matchesResult, \"query failed\");\n }\n );\n }\n}\n"]}
1
+ {"version":3,"file":"EntityUnifier.js","sourceRoot":"","sources":["../../src/EntityUnifier.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/** @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 const query = `SELECT ECInstanceId FROM ${classFullName} WHERE InVirtualSet(:ids, 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,18 +1,24 @@
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
6
  /** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
5
- * @beta
7
+ * @internal
6
8
  */
7
- export declare class IModelCloneContext extends IModelElementCloneContext {
9
+ export declare class IModelCloneContext extends IModelElementCloneContext implements IModelTransformContext {
8
10
  private _refTypesCache;
9
11
  private _aspectRemapTable;
12
+ /** A positive-only cache of entity existence checks, scoped to the current transformation run.
13
+ * @internal
14
+ */
15
+ readonly existenceCache: EntityExistenceCache;
10
16
  /** perform necessary initialization to use a clone context, namely caching the reference types in the source's schemas */
11
17
  initialize(): Promise<void>;
12
18
  /** Clone the specified source Element into ElementProps for the target iModel.
13
19
  * @internal
14
20
  */
15
- cloneElement(sourceElement: Element, cloneOptions?: IModelJsNative.CloneElementOptions): ElementProps;
21
+ cloneElement(sourceElement: Element, cloneOptions?: IModelJsNative.CloneElementOptions): Promise<ElementProps>;
16
22
  /** Add a rule that remaps the specified source ElementAspect to the specified target ElementAspect. */
17
23
  remapElementAspect(aspectSourceId: Id64String, aspectTargetId: Id64String): void;
18
24
  /** Remove a rule that remaps the specified source ElementAspect */
@@ -24,10 +30,10 @@ export declare class IModelCloneContext extends IModelElementCloneContext {
24
30
  /** Look up a target [EntityReference]($bentley) from a source [EntityReference]($bentley)
25
31
  * @returns the target CodeSpecId or a [EntityReference]($bentley) containing [Id64.invalid]($bentley) if a mapping is not found.
26
32
  */
27
- findTargetEntityId(sourceEntityId: EntityReference): EntityReference;
33
+ findTargetEntityId(sourceEntityId: EntityReference): Promise<EntityReference>;
28
34
  /** Clone the specified source Element into ElementProps for the target iModel.
29
35
  * @internal
30
36
  */
31
- cloneElementAspect(sourceElementAspect: ElementAspect): ElementAspectProps;
37
+ cloneElementAspect(sourceElementAspect: ElementAspect): Promise<ElementAspectProps>;
32
38
  }
33
39
  //# sourceMappingURL=IModelCloneContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IModelCloneContext.d.ts","sourceRoot":"","sources":["../../src/IModelCloneContext.ts"],"names":[],"mappings":"AAQA,OAAO,EAAkB,UAAU,EAAU,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAIL,kBAAkB,EAClB,YAAY,EACZ,eAAe,EAOhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,OAAO,EACP,aAAa,EAEb,yBAAyB,EACzB,cAAc,EACf,MAAM,qBAAqB,CAAC;AAO7B;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,yBAAyB;IAC/D,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,iBAAiB,CAAqC;IAE9D,0HAA0H;IACpG,UAAU;IAIhC;;OAEG;IACa,YAAY,CAC1B,aAAa,EAAE,OAAO,EACtB,YAAY,CAAC,EAAE,cAAc,CAAC,mBAAmB,GAChD,YAAY;IA+Cf,uGAAuG;IAChG,kBAAkB,CACvB,cAAc,EAAE,UAAU,EAC1B,cAAc,EAAE,UAAU,GACzB,IAAI;IAIP,mEAAmE;IAC5D,mBAAmB,CAAC,cAAc,EAAE,UAAU,GAAG,IAAI;IAI5D;;OAEG;IACI,kBAAkB,CAAC,cAAc,EAAE,UAAU,GAAG,UAAU;IAIjE;;OAEG;IACI,kBAAkB,CAAC,cAAc,EAAE,eAAe,GAAG,eAAe;IAkI3E;;OAEG;IACI,kBAAkB,CACvB,mBAAmB,EAAE,aAAa,GACjC,kBAAkB;CAsCtB"}
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,wBAAwB,CAAC;AAG9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAIvE;;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,CA+H1B;IAED;;OAEG;IACU,kBAAkB,CAC7B,mBAAmB,EAAE,aAAa,GACjC,OAAO,CAAC,kBAAkB,CAAC,CAqD7B;CACF"}
@@ -8,20 +8,26 @@ exports.IModelCloneContext = void 0;
8
8
  /** @packageDocumentation
9
9
  * @module iModels
10
10
  */
11
- const assert = require("assert");
11
+ const node_assert_1 = require("node:assert");
12
12
  const core_bentley_1 = require("@itwin/core-bentley");
13
13
  const core_common_1 = require("@itwin/core-common");
14
14
  const core_backend_1 = require("@itwin/core-backend");
15
+ const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
15
16
  const ECReferenceTypesCache_1 = require("./ECReferenceTypesCache");
16
- const EntityUnifier_1 = require("./EntityUnifier");
17
+ const EntityExistenceCache_1 = require("./EntityExistenceCache");
17
18
  const TransformerLoggerCategory_1 = require("./TransformerLoggerCategory");
19
+ const BigMap_1 = require("./BigMap");
18
20
  const loggerCategory = TransformerLoggerCategory_1.TransformerLoggerCategory.IModelCloneContext;
19
21
  /** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
20
- * @beta
22
+ * @internal
21
23
  */
22
24
  class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
23
25
  _refTypesCache = new ECReferenceTypesCache_1.ECReferenceTypesCache();
24
- _aspectRemapTable = new Map();
26
+ _aspectRemapTable = new BigMap_1.BigMap();
27
+ /** A positive-only cache of entity existence checks, scoped to the current transformation run.
28
+ * @internal
29
+ */
30
+ existenceCache = new EntityExistenceCache_1.EntityExistenceCache();
25
31
  /** perform necessary initialization to use a clone context, namely caching the reference types in the source's schemas */
26
32
  async initialize() {
27
33
  await this._refTypesCache.initAllSchemasInIModel(this.sourceDb);
@@ -29,15 +35,39 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
29
35
  /** Clone the specified source Element into ElementProps for the target iModel.
30
36
  * @internal
31
37
  */
32
- cloneElement(sourceElement, cloneOptions) {
38
+ async cloneElement(sourceElement, cloneOptions) {
33
39
  const targetElementProps = this["_nativeContext"].cloneElement(sourceElement.id, cloneOptions);
40
+ // Native same-iModel cloning clears codes for inserts, but identity mappings are updates.
41
+ if (!this.isBetweenIModels &&
42
+ this.findTargetElementId(sourceElement.id) === sourceElement.id) {
43
+ targetElementProps.code.value = sourceElement.code.value;
44
+ if (!core_bentley_1.Id64.isValidId64(targetElementProps.code.spec)) {
45
+ const mappedCodeSpecId = this.findTargetCodeSpecId(sourceElement.code.spec);
46
+ targetElementProps.code.spec = core_bentley_1.Id64.isValidId64(mappedCodeSpecId)
47
+ ? mappedCodeSpecId
48
+ : sourceElement.code.spec;
49
+ }
50
+ if (!core_bentley_1.Id64.isValidId64(targetElementProps.code.scope)) {
51
+ const mappedCodeScopeId = this.findTargetElementId(sourceElement.code.scope);
52
+ targetElementProps.code.scope = core_bentley_1.Id64.isValidId64(mappedCodeScopeId)
53
+ ? mappedCodeScopeId
54
+ : sourceElement.code.scope;
55
+ }
56
+ }
34
57
  // Ensure that all NavigationProperties in targetElementProps have a defined value so "clearing" changes will be part of the JSON used for update
35
- sourceElement.forEachProperty((propertyName, meta) => {
36
- if (meta.isNavigation &&
37
- undefined === sourceElement[propertyName]) {
38
- targetElementProps[propertyName] = core_common_1.RelatedElement.none;
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}.`);
60
+ for (const property of sourceElementClass.getPropertiesSync()) {
61
+ // Exclude custom properties because C++ has already handled them.
62
+ if (property.customAttributes?.has("BisCore.CustomHandledProperty"))
63
+ continue;
64
+ const name = property.name;
65
+ 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;
39
69
  }
40
- }, false); // exclude custom because C++ has already handled them
70
+ }
41
71
  if (this.isBetweenIModels) {
42
72
  // The native C++ cloneElement strips off federationGuid, want to put it back if transformation is between iModels
43
73
  targetElementProps.federationGuid = sourceElement.federationGuid;
@@ -54,7 +84,7 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
54
84
  targetElementProps.code = core_common_1.Code.createEmpty();
55
85
  }
56
86
  const jsClass = this.sourceDb.getJsClass(sourceElement.classFullName);
57
- jsClass["onCloned"](this, sourceElement.toJSON(), targetElementProps);
87
+ await jsClass["onCloned"](this, sourceElement.toJSON(), targetElementProps);
58
88
  return targetElementProps;
59
89
  }
60
90
  /** Add a rule that remaps the specified source ElementAspect to the specified target ElementAspect. */
@@ -74,7 +104,7 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
74
104
  /** Look up a target [EntityReference]($bentley) from a source [EntityReference]($bentley)
75
105
  * @returns the target CodeSpecId or a [EntityReference]($bentley) containing [Id64.invalid]($bentley) if a mapping is not found.
76
106
  */
77
- findTargetEntityId(sourceEntityId) {
107
+ async findTargetEntityId(sourceEntityId) {
78
108
  const [type, rawId] = core_backend_1.EntityReferences.split(sourceEntityId);
79
109
  if (core_bentley_1.Id64.isValid(rawId)) {
80
110
  switch (type) {
@@ -97,7 +127,7 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
97
127
  }
98
128
  // Check if the model exists, `findTargetElementId` may have worked because the element exists when the model doesn't.
99
129
  // That can occur in the transformer since a submodeled element is imported before its submodel.
100
- if (EntityUnifier_1.EntityUnifier.exists(this.targetDb, { entityReference: targetId }))
130
+ if (await this.existenceCache.exists(this.targetDb, targetId))
101
131
  return targetId;
102
132
  break;
103
133
  }
@@ -121,8 +151,7 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
121
151
  ELSE 'error'
122
152
  END
123
153
  `;
124
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
125
- const relInSource = this.sourceDb.withPreparedStatement(`
154
+ const sql = `
126
155
  SELECT
127
156
  SourceECInstanceId,
128
157
  TargetECInstanceId,
@@ -130,14 +159,17 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
130
159
  (${makeGetConcreteEntityTypeSql("TargetECClassId")}) AS TargetType
131
160
  FROM BisCore:ElementRefersToElements
132
161
  WHERE ECInstanceId=?
133
- `, (stmt) => {
134
- stmt.bindId(1, rawId);
135
- let status;
136
- while ((status = stmt.step()) === core_bentley_1.DbResult.BE_SQLITE_ROW) {
137
- const sourceId = stmt.getValue(0).getId();
138
- const targetId = stmt.getValue(1).getId();
139
- const sourceType = stmt.getValue(2).getString();
140
- const targetType = stmt.getValue(3).getString();
162
+ `;
163
+ const params = new core_common_1.QueryBinder().bindId(1, rawId);
164
+ const reader = this.sourceDb.createQueryReader(sql, params, {
165
+ usePrimaryConn: true,
166
+ });
167
+ const relInSource = await (async () => {
168
+ if (await reader.step()) {
169
+ const sourceId = reader.current[0];
170
+ const targetId = reader.current[1];
171
+ const sourceType = reader.current[2];
172
+ const targetType = reader.current[3];
141
173
  if (sourceType === "error" || targetType === "error")
142
174
  throw Error("relationship end had unknown root class");
143
175
  return {
@@ -145,10 +177,8 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
145
177
  targetId: `${targetType}${targetId}`,
146
178
  };
147
179
  }
148
- if (status !== core_bentley_1.DbResult.BE_SQLITE_DONE)
149
- throw new core_common_1.IModelError(status, "unexpected query failure");
150
180
  return undefined;
151
- });
181
+ })();
152
182
  if (relInSource === undefined)
153
183
  break;
154
184
  // just in case prevent recursion
@@ -156,29 +186,30 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
156
186
  relInSource.targetId === sourceEntityId)
157
187
  throw Error("link table relationship end was resolved to itself. This should be impossible");
158
188
  const relInTarget = {
159
- sourceId: this.findTargetEntityId(relInSource.sourceId),
160
- targetId: this.findTargetEntityId(relInSource.targetId),
189
+ sourceId: await this.findTargetEntityId(relInSource.sourceId),
190
+ targetId: await this.findTargetEntityId(relInSource.targetId),
161
191
  };
162
192
  // return a null
163
193
  if (!core_backend_1.EntityReferences.isValid(relInTarget.sourceId) ||
164
194
  !core_backend_1.EntityReferences.isValid(relInTarget.targetId))
165
195
  break;
166
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
167
- const relInTargetId = this.targetDb.withPreparedStatement(`
196
+ const relInTargetSql = `
168
197
  SELECT ECInstanceId
169
198
  FROM BisCore:ElementRefersToElements
170
199
  WHERE SourceECInstanceId=?
171
200
  AND TargetECInstanceId=?
172
- `, (stmt) => {
173
- stmt.bindId(1, core_backend_1.EntityReferences.toId64(relInTarget.sourceId));
174
- stmt.bindId(2, core_backend_1.EntityReferences.toId64(relInTarget.targetId));
175
- const status = stmt.step();
176
- if (status === core_bentley_1.DbResult.BE_SQLITE_ROW)
177
- return stmt.getValue(0).getId();
178
- if (status !== core_bentley_1.DbResult.BE_SQLITE_DONE)
179
- throw new core_common_1.IModelError(status, "unexpected query failure");
180
- return core_bentley_1.Id64.invalid;
181
- });
201
+ `;
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));
205
+ const relInTargetResult = await this.targetDb
206
+ .createQueryReader(relInTargetSql, relInTargetParams, {
207
+ usePrimaryConn: true,
208
+ })
209
+ .next();
210
+ const relInTargetId = relInTargetResult.done
211
+ ? core_bentley_1.Id64.invalid
212
+ : relInTargetResult.value.id;
182
213
  return `r${relInTargetId}`;
183
214
  }
184
215
  }
@@ -188,30 +219,35 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
188
219
  /** Clone the specified source Element into ElementProps for the target iModel.
189
220
  * @internal
190
221
  */
191
- cloneElementAspect(sourceElementAspect) {
222
+ async cloneElementAspect(sourceElementAspect) {
192
223
  const targetElementAspectProps = sourceElementAspect.toJSON();
193
224
  targetElementAspectProps.id = undefined;
194
- sourceElementAspect.forEachProperty((propertyName, propertyMetaData) => {
195
- if (propertyMetaData.isNavigation) {
196
- const sourceNavProp = sourceElementAspect.asAny[propertyName];
225
+ 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}.`);
228
+ for (const property of sourceElementAspectClass.getPropertiesSync()) {
229
+ const ecName = property.name;
230
+ const name = core_common_1.ECJsNames.toJsName(ecName);
231
+ if (property.isNavigation()) {
232
+ const sourceNavProp = sourceElementAspect.asAny[name];
197
233
  if (sourceNavProp?.id) {
198
- const navPropRefType = this._refTypesCache.getNavPropRefType(sourceElementAspect.schemaName, sourceElementAspect.className, propertyName);
199
- assert(navPropRefType !== undefined, `nav prop ref type for '${propertyName}' was not in the cache, this is a bug.`);
200
- const targetEntityReference = this.findTargetEntityId(core_backend_1.EntityReferences.fromEntityType(sourceNavProp.id, navPropRefType));
201
- const targetEntityId = core_backend_1.EntityReferences.toId64(targetEntityReference);
202
- // spread the property in case toJSON did not deep-clone
203
- targetElementAspectProps[propertyName] = {
204
- ...targetElementAspectProps[propertyName],
205
- id: targetEntityId,
206
- };
234
+ 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);
238
+ // spread the property in case toJSON did not deep-clone
239
+ targetElementAspectProps[name] = {
240
+ ...targetElementAspectProps[name],
241
+ id: targetEntityId,
242
+ };
243
+ }));
207
244
  }
208
245
  }
209
- else if (core_common_1.PrimitiveTypeCode.Long === propertyMetaData.primitiveType &&
210
- "Id" === propertyMetaData.extendedType) {
211
- targetElementAspectProps[propertyName] =
212
- this.findTargetElementId(sourceElementAspect.asAny[propertyName]);
246
+ else if (property.isPrimitive() && "Id" === property.extendedTypeName) {
247
+ targetElementAspectProps[name] = this.findTargetElementId(sourceElementAspect.asAny[name]);
213
248
  }
214
- });
249
+ }
250
+ await Promise.all(targetEntityIds);
215
251
  return targetElementAspectProps;
216
252
  }
217
253
  }