@itwin/imodel-transformer 2.0.0-dev.6 → 2.0.0-dev.61

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 (123) 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 -34
  7. package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
  8. package/lib/cjs/ChangedElementForest.d.ts +14 -0
  9. package/lib/cjs/ChangedElementForest.d.ts.map +1 -0
  10. package/lib/cjs/ChangedElementForest.js +86 -0
  11. package/lib/cjs/ChangedElementForest.js.map +1 -0
  12. package/lib/cjs/ChangesetScanner.d.ts +61 -0
  13. package/lib/cjs/ChangesetScanner.d.ts.map +1 -0
  14. package/lib/cjs/ChangesetScanner.js +104 -0
  15. package/lib/cjs/ChangesetScanner.js.map +1 -0
  16. package/lib/cjs/ECReferenceTypesCache.d.ts +0 -3
  17. package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -1
  18. package/lib/cjs/ECReferenceTypesCache.js +61 -104
  19. package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
  20. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +1 -1
  21. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js.map +1 -1
  22. package/lib/cjs/ElementAspectCleanup.d.ts +16 -0
  23. package/lib/cjs/ElementAspectCleanup.d.ts.map +1 -0
  24. package/lib/cjs/ElementAspectCleanup.js +87 -0
  25. package/lib/cjs/ElementAspectCleanup.js.map +1 -0
  26. package/lib/cjs/ElementAspectExportCoordinator.d.ts +44 -0
  27. package/lib/cjs/ElementAspectExportCoordinator.d.ts.map +1 -0
  28. package/lib/cjs/ElementAspectExportCoordinator.js +148 -0
  29. package/lib/cjs/ElementAspectExportCoordinator.js.map +1 -0
  30. package/lib/cjs/ElementAspectExportProcessor.d.ts +44 -0
  31. package/lib/cjs/ElementAspectExportProcessor.d.ts.map +1 -0
  32. package/lib/cjs/ElementAspectExportProcessor.js +152 -0
  33. package/lib/cjs/ElementAspectExportProcessor.js.map +1 -0
  34. package/lib/cjs/ElementBulkDelete.d.ts +30 -0
  35. package/lib/cjs/ElementBulkDelete.d.ts.map +1 -0
  36. package/lib/cjs/ElementBulkDelete.js +358 -0
  37. package/lib/cjs/ElementBulkDelete.js.map +1 -0
  38. package/lib/cjs/EntityExistenceCache.d.ts +43 -0
  39. package/lib/cjs/EntityExistenceCache.d.ts.map +1 -0
  40. package/lib/cjs/EntityExistenceCache.js +91 -0
  41. package/lib/cjs/EntityExistenceCache.js.map +1 -0
  42. package/lib/cjs/EntityMap.d.ts.map +1 -1
  43. package/lib/cjs/EntityMap.js.map +1 -1
  44. package/lib/cjs/EntityUnifier.d.ts +8 -8
  45. package/lib/cjs/EntityUnifier.d.ts.map +1 -1
  46. package/lib/cjs/EntityUnifier.js +56 -32
  47. package/lib/cjs/EntityUnifier.js.map +1 -1
  48. package/lib/cjs/IModelCloneContext.d.ts +9 -3
  49. package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
  50. package/lib/cjs/IModelCloneContext.js +66 -31
  51. package/lib/cjs/IModelCloneContext.js.map +1 -1
  52. package/lib/cjs/IModelExporter.d.ts +143 -30
  53. package/lib/cjs/IModelExporter.d.ts.map +1 -1
  54. package/lib/cjs/IModelExporter.js +893 -178
  55. package/lib/cjs/IModelExporter.js.map +1 -1
  56. package/lib/cjs/IModelImporter.d.ts +75 -30
  57. package/lib/cjs/IModelImporter.d.ts.map +1 -1
  58. package/lib/cjs/IModelImporter.js +292 -132
  59. package/lib/cjs/IModelImporter.js.map +1 -1
  60. package/lib/cjs/IModelTransformContext.d.ts +54 -0
  61. package/lib/cjs/IModelTransformContext.d.ts.map +1 -0
  62. package/lib/cjs/IModelTransformContext.js +3 -0
  63. package/lib/cjs/IModelTransformContext.js.map +1 -0
  64. package/lib/cjs/IModelTransformer.d.ts +130 -196
  65. package/lib/cjs/IModelTransformer.d.ts.map +1 -1
  66. package/lib/cjs/IModelTransformer.js +697 -1155
  67. package/lib/cjs/IModelTransformer.js.map +1 -1
  68. package/lib/cjs/IModelTransformerError.d.ts +84 -0
  69. package/lib/cjs/IModelTransformerError.d.ts.map +1 -0
  70. package/lib/cjs/IModelTransformerError.js +93 -0
  71. package/lib/cjs/IModelTransformerError.js.map +1 -0
  72. package/lib/cjs/ProvenanceManager.d.ts +177 -0
  73. package/lib/cjs/ProvenanceManager.d.ts.map +1 -0
  74. package/lib/cjs/ProvenanceManager.js +719 -0
  75. package/lib/cjs/ProvenanceManager.js.map +1 -0
  76. package/lib/cjs/SyncTypeResolver.d.ts +34 -0
  77. package/lib/cjs/SyncTypeResolver.d.ts.map +1 -0
  78. package/lib/cjs/SyncTypeResolver.js +98 -0
  79. package/lib/cjs/SyncTypeResolver.js.map +1 -0
  80. package/lib/cjs/TransformerLoggerCategory.d.ts +1 -1
  81. package/lib/cjs/TransformerLoggerCategory.js +1 -1
  82. package/lib/cjs/TransformerLoggerCategory.js.map +1 -1
  83. package/lib/cjs/TransformerPackageMetadata.d.ts +8 -0
  84. package/lib/cjs/TransformerPackageMetadata.d.ts.map +1 -0
  85. package/lib/cjs/TransformerPackageMetadata.js +47 -0
  86. package/lib/cjs/TransformerPackageMetadata.js.map +1 -0
  87. package/lib/cjs/imodel-transformer.d.ts +27 -0
  88. package/lib/cjs/imodel-transformer.d.ts.map +1 -1
  89. package/lib/cjs/imodel-transformer.js +61 -34
  90. package/lib/cjs/imodel-transformer.js.map +1 -1
  91. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts +29 -0
  92. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts.map +1 -0
  93. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js +212 -0
  94. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js.map +1 -0
  95. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts +25 -0
  96. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts.map +1 -0
  97. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js +196 -0
  98. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js.map +1 -0
  99. package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts +59 -0
  100. package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts.map +1 -0
  101. package/lib/cjs/schema-processing/SchemaProcessingStrategy.js +28 -0
  102. package/lib/cjs/schema-processing/SchemaProcessingStrategy.js.map +1 -0
  103. package/lib/cjs/schema-processing.d.ts +7 -0
  104. package/lib/cjs/schema-processing.d.ts.map +1 -0
  105. package/lib/cjs/schema-processing.js +27 -0
  106. package/lib/cjs/schema-processing.js.map +1 -0
  107. package/package.json +65 -43
  108. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts +0 -16
  109. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +0 -1
  110. package/lib/cjs/DetachedExportElementAspectsStrategy.js +0 -106
  111. package/lib/cjs/DetachedExportElementAspectsStrategy.js.map +0 -1
  112. package/lib/cjs/ElementCascadingDeleter.d.ts +0 -22
  113. package/lib/cjs/ElementCascadingDeleter.d.ts.map +0 -1
  114. package/lib/cjs/ElementCascadingDeleter.js +0 -57
  115. package/lib/cjs/ElementCascadingDeleter.js.map +0 -1
  116. package/lib/cjs/ExportElementAspectsStrategy.d.ts +0 -35
  117. package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +0 -1
  118. package/lib/cjs/ExportElementAspectsStrategy.js +0 -52
  119. package/lib/cjs/ExportElementAspectsStrategy.js.map +0 -1
  120. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts +0 -12
  121. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts.map +0 -1
  122. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +0 -47
  123. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js.map +0 -1
@@ -0,0 +1,104 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ChangesetScanner = void 0;
8
+ const core_backend_1 = require("@itwin/core-backend");
9
+ const core_bentley_1 = require("@itwin/core-bentley");
10
+ const IModelTransformerError_1 = require("./IModelTransformerError");
11
+ /**
12
+ * Reads each changeset once, unifies table changes into EC instance changes,
13
+ * normalizes overflow-only inserts and deletes to updates, writes all operations
14
+ * to [[ChangedInstanceIds]], and retains properties needed to process deletions.
15
+ * @internal
16
+ */
17
+ class ChangesetScanner {
18
+ /**
19
+ * Scans each changeset file in order with one reader and unifier per file.
20
+ * @param iModel Database used to resolve EC class names.
21
+ * @param csFileProps Ordered changeset files to scan.
22
+ * @param changedInstanceIds Aggregate updated with the unified changes unless disabled by [[options]].
23
+ * @param options Controls whether the aggregate is populated while deletion records are collected.
24
+ * @returns Deleted-instance properties needed after the scan; changed IDs are written to [[changedInstanceIds]].
25
+ */
26
+ static async scan(iModel, csFileProps, changedInstanceIds, options = {}) {
27
+ const deletionRecordsByChangeset = [];
28
+ await changedInstanceIds.addChanges(this.readChanges(iModel, csFileProps, deletionRecordsByChangeset, options));
29
+ return deletionRecordsByChangeset;
30
+ }
31
+ static *readChanges(iModel, csFileProps, deletionRecordsByChangeset, options) {
32
+ for (const csFile of csFileProps) {
33
+ const csReader = core_backend_1.ChangesetReader.openFile({
34
+ fileName: csFile.pathname,
35
+ db: iModel,
36
+ propFilter: core_backend_1.PropertyFilter.BisCoreElement,
37
+ });
38
+ const changeUnifier = new core_backend_1.PartialChangeUnifier();
39
+ try {
40
+ while (csReader.step())
41
+ changeUnifier.appendFrom(csReader);
42
+ const deletionRecords = [];
43
+ for (const change of changeUnifier.instances) {
44
+ const ecClassId = change.ECClassId;
45
+ if (ecClassId === undefined)
46
+ core_bentley_1.ITwinError.throwError({
47
+ iTwinErrorId: {
48
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
49
+ key: IModelTransformerError_1.IModelTransformerError.ChangedInstanceMetadataMissing,
50
+ },
51
+ message: `ECClassId was not found for id: ${change.ECInstanceId}! Table is : ${change.$meta.tables}`,
52
+ });
53
+ // Change is recorded at table level, not EC entity level.
54
+ // This normalizes overflow-table expansion records so they do not
55
+ // appear as element inserts or deletes.
56
+ if ((change.$meta.op === "Inserted" || change.$meta.op === "Deleted") &&
57
+ change.$meta.tables.every((table) => table.endsWith("Overflow"))) {
58
+ change.$meta.op = "Updated";
59
+ }
60
+ if (options.populateChangedInstanceIds !== false)
61
+ yield change;
62
+ if (change.$meta.op === "Deleted") {
63
+ deletionRecords.push(this.toDeletionRecord(iModel, change));
64
+ }
65
+ }
66
+ deletionRecordsByChangeset.push(deletionRecords);
67
+ }
68
+ finally {
69
+ try {
70
+ changeUnifier[Symbol.dispose]();
71
+ }
72
+ finally {
73
+ csReader[Symbol.dispose]();
74
+ }
75
+ }
76
+ }
77
+ }
78
+ static toDeletionRecord(iModel, change) {
79
+ const ecClassId = change.ECClassId;
80
+ if (ecClassId === undefined) {
81
+ core_bentley_1.ITwinError.throwError({
82
+ iTwinErrorId: {
83
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
84
+ key: IModelTransformerError_1.IModelTransformerError.ChangedInstanceMetadataMissing,
85
+ },
86
+ message: `ECClassId was not found for id: ${change.ECInstanceId}! Table is : ${change.$meta.tables}`,
87
+ });
88
+ }
89
+ return {
90
+ ecInstanceId: change.ECInstanceId,
91
+ ecClassId,
92
+ classFullName: iModel.getClassNameFromId(ecClassId),
93
+ federationGuid: change.FederationGuid,
94
+ sourceECInstanceId: change.SourceECInstanceId,
95
+ targetECInstanceId: change.TargetECInstanceId,
96
+ scopeId: change.Scope?.Id,
97
+ elementId: change.Element?.Id,
98
+ kind: change.Kind,
99
+ identifier: change.Identifier,
100
+ };
101
+ }
102
+ }
103
+ exports.ChangesetScanner = ChangesetScanner;
104
+ //# sourceMappingURL=ChangesetScanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChangesetScanner.js","sourceRoot":"","sources":["../../src/ChangesetScanner.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 {\n ChangeInstance,\n ChangesetReader,\n IModelDb,\n PartialChangeUnifier,\n PropertyFilter,\n} from \"@itwin/core-backend\";\nimport { Id64String, ITwinError } from \"@itwin/core-bentley\";\nimport { ChangesetFileProps } from \"@itwin/core-common\";\nimport type { ChangedInstanceIds } from \"./IModelExporter\";\nimport {\n IModelTransformerError,\n IModelTransformerErrorScope,\n} from \"./IModelTransformerError\";\n\n/**\n * Metadata retained from a deleted EC instance for later target remapping.\n * Properties are optional when the deleted instance did not contain that value.\n * @internal\n */\nexport interface ChangesetDeletionRecord {\n /** ID of the deleted source instance. */\n ecInstanceId: Id64String;\n /** EC class ID of the deleted source instance. */\n ecClassId: Id64String;\n /** Full EC class name resolved from [[ecClassId]]. */\n classFullName?: string;\n /** Federation GUID used to find the corresponding target element. */\n federationGuid?: string;\n /** Source endpoint of a deleted relationship. */\n sourceECInstanceId?: Id64String;\n /** Target endpoint of a deleted relationship. */\n targetECInstanceId?: Id64String;\n /** Scope of a deleted ExternalSourceAspect. */\n scopeId?: Id64String;\n /** Element owning a deleted ElementAspect. */\n elementId?: Id64String;\n /** Kind of a deleted ExternalSourceAspect. */\n kind?: string;\n /** Identifier of a deleted ExternalSourceAspect. */\n identifier?: string;\n}\n\n/**\n * Pre-delete properties grouped by changeset. [[ChangedInstanceIds]] retains\n * operation sets but not the properties needed to remap deleted instances.\n * Grouping keeps scoped ExternalSourceAspect metadata paired with deletions\n * from the same changeset.\n * @internal\n */\nexport type ChangesetDeletionRecordsByChangeset = ChangesetDeletionRecord[][];\n\n/**\n * Reads each changeset once, unifies table changes into EC instance changes,\n * normalizes overflow-only inserts and deletes to updates, writes all operations\n * to [[ChangedInstanceIds]], and retains properties needed to process deletions.\n * @internal\n */\nexport class ChangesetScanner {\n /**\n * Scans each changeset file in order with one reader and unifier per file.\n * @param iModel Database used to resolve EC class names.\n * @param csFileProps Ordered changeset files to scan.\n * @param changedInstanceIds Aggregate updated with the unified changes unless disabled by [[options]].\n * @param options Controls whether the aggregate is populated while deletion records are collected.\n * @returns Deleted-instance properties needed after the scan; changed IDs are written to [[changedInstanceIds]].\n */\n public static async scan(\n iModel: IModelDb,\n csFileProps: ChangesetFileProps[],\n changedInstanceIds: ChangedInstanceIds,\n options: { populateChangedInstanceIds?: boolean } = {}\n ): Promise<ChangesetDeletionRecordsByChangeset> {\n const deletionRecordsByChangeset: ChangesetDeletionRecord[][] = [];\n await changedInstanceIds.addChanges(\n this.readChanges(iModel, csFileProps, deletionRecordsByChangeset, options)\n );\n return deletionRecordsByChangeset;\n }\n\n private static *readChanges(\n iModel: IModelDb,\n csFileProps: ChangesetFileProps[],\n deletionRecordsByChangeset: ChangesetDeletionRecordsByChangeset,\n options: { populateChangedInstanceIds?: boolean }\n ): Generator<ChangeInstance> {\n for (const csFile of csFileProps) {\n const csReader = ChangesetReader.openFile({\n fileName: csFile.pathname,\n db: iModel,\n propFilter: PropertyFilter.BisCoreElement,\n });\n const changeUnifier = new PartialChangeUnifier();\n try {\n while (csReader.step()) changeUnifier.appendFrom(csReader);\n const deletionRecords: ChangesetDeletionRecord[] = [];\n for (const change of changeUnifier.instances) {\n const ecClassId = change.ECClassId;\n if (ecClassId === undefined)\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.ChangedInstanceMetadataMissing,\n },\n message: `ECClassId was not found for id: ${change.ECInstanceId}! Table is : ${change.$meta.tables}`,\n });\n // Change is recorded at table level, not EC entity level.\n // This normalizes overflow-table expansion records so they do not\n // appear as element inserts or deletes.\n if (\n (change.$meta.op === \"Inserted\" || change.$meta.op === \"Deleted\") &&\n change.$meta.tables.every((table) => table.endsWith(\"Overflow\"))\n ) {\n change.$meta.op = \"Updated\";\n }\n\n if (options.populateChangedInstanceIds !== false) yield change;\n if (change.$meta.op === \"Deleted\") {\n deletionRecords.push(this.toDeletionRecord(iModel, change));\n }\n }\n deletionRecordsByChangeset.push(deletionRecords);\n } finally {\n try {\n changeUnifier[Symbol.dispose]();\n } finally {\n csReader[Symbol.dispose]();\n }\n }\n }\n }\n\n private static toDeletionRecord(\n iModel: IModelDb,\n change: ChangeInstance\n ): ChangesetDeletionRecord {\n const ecClassId = change.ECClassId;\n if (ecClassId === undefined) {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.ChangedInstanceMetadataMissing,\n },\n message: `ECClassId was not found for id: ${change.ECInstanceId}! Table is : ${change.$meta.tables}`,\n });\n }\n\n return {\n ecInstanceId: change.ECInstanceId,\n ecClassId,\n classFullName: iModel.getClassNameFromId(ecClassId),\n federationGuid: change.FederationGuid,\n sourceECInstanceId: change.SourceECInstanceId,\n targetECInstanceId: change.TargetECInstanceId,\n scopeId: change.Scope?.Id,\n elementId: change.Element?.Id,\n kind: change.Kind,\n identifier: change.Identifier,\n };\n }\n}\n"]}
@@ -22,9 +22,6 @@ export declare class ECReferenceTypesCache {
22
22
  private _propQualifierToRefType;
23
23
  private _relClassNameEndToRefTypes;
24
24
  private _initedSchemas;
25
- private _rootBisClassCache;
26
- private _relationshipInfoCache;
27
- private _constraintClassCache;
28
25
  private static bisRootClassToRefType;
29
26
  private getRootBisClass;
30
27
  private getAbstractConstraintClass;
@@ -1 +1 @@
1
- {"version":3,"file":"ECReferenceTypesCache.d.ts","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAWtE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;;CAI7C;AAED;;;;;;;GAOG;AACH,qBAAa,qBAAqB;IAChC,uGAAuG;IACvG,OAAO,CAAC,uBAAuB,CAG3B;IACJ,OAAO,CAAC,0BAA0B,CAG9B;IACJ,OAAO,CAAC,cAAc,CAAgC;IAGtD,OAAO,CAAC,kBAAkB,CAA8B;IACxD,OAAO,CAAC,sBAAsB,CAA8C;IAC5E,OAAO,CAAC,qBAAqB,CAA8B;IAE3D,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAalC;YAEY,eAAe;YAmCf,0BAA0B;IAqBxC,8CAA8C;IACjC,sBAAsB,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;YAuDtD,kBAAkB;YAalB,UAAU;YA4FV,mBAAmB;IA4D1B,iBAAiB,CACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,SAAS,GAAG,mBAAmB;IAS3B,sBAAsB,CAC3B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,SAAS,GAAG,WAAW;IAQnB,KAAK;CAQb"}
1
+ {"version":3,"file":"ECReferenceTypesCache.d.ts","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAYtE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAO/C;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,cAEC;CACF;AAED;;;;;;;GAOG;AACH,qBAAa,qBAAqB;IAChC,uGAAuG;IACvG,OAAO,CAAC,uBAAuB,CAG3B;IACJ,OAAO,CAAC,0BAA0B,CAG9B;IACJ,OAAO,CAAC,cAAc,CAAgC;IAEtD,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAalC;YAEY,eAAe;YA2Bf,0BAA0B;IAaxC,8CAA8C;IACjC,sBAAsB,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BnE;YAEa,kBAAkB;YAalB,UAAU;YAoEV,mBAAmB;IA4D1B,iBAAiB,CACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,SAAS,GAAG,mBAAmB,CAOjC;IAEM,sBAAsB,CAC3B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,SAAS,GAAG,WAAW,CAMzB;IAEM,KAAK,SAIX;CACF"}
@@ -11,8 +11,9 @@ exports.ECReferenceTypesCache = exports.SchemaNotInCacheErr = void 0;
11
11
  const core_bentley_1 = require("@itwin/core-bentley");
12
12
  const core_common_1 = require("@itwin/core-common");
13
13
  const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
14
- const assert = require("assert");
14
+ const node_assert_1 = require("node:assert");
15
15
  const TransformerLoggerCategory_1 = require("./TransformerLoggerCategory");
16
+ const IModelTransformerError_1 = require("./IModelTransformerError");
16
17
  /** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
17
18
  * @internal
18
19
  */
@@ -35,10 +36,6 @@ class ECReferenceTypesCache {
35
36
  _propQualifierToRefType = new core_bentley_1.TupleKeyedMap();
36
37
  _relClassNameEndToRefTypes = new core_bentley_1.TupleKeyedMap();
37
38
  _initedSchemas = new Map();
38
- // Performance optimization caches
39
- _rootBisClassCache = new Map();
40
- _relationshipInfoCache = new Map();
41
- _constraintClassCache = new Map();
42
39
  static bisRootClassToRefType = {
43
40
  /* eslint-disable quote-props, @typescript-eslint/naming-convention */
44
41
  Element: core_common_1.ConcreteEntityTypes.Element,
@@ -51,11 +48,6 @@ class ECReferenceTypesCache {
51
48
  /* eslint-enable quote-props, @typescript-eslint/naming-convention */
52
49
  };
53
50
  async getRootBisClass(ecclass) {
54
- const cacheKey = ecclass.fullName;
55
- const cached = this._rootBisClassCache.get(cacheKey);
56
- if (cached) {
57
- return cached;
58
- }
59
51
  let bisRootForConstraint = ecclass;
60
52
  await ecclass.traverseBaseClasses((baseClass) => {
61
53
  // The depth first traversal will descend all the way to the root class before making any lateral traversal
@@ -71,68 +63,54 @@ class ECReferenceTypesCache {
71
63
  });
72
64
  // if the root class of the constraint was a mixin, use its AppliesToEntityClass
73
65
  if (bisRootForConstraint instanceof ecschema_metadata_1.Mixin) {
74
- assert(bisRootForConstraint.appliesTo !== undefined, "The referenced AppliesToEntityClass could not be found, how did it pass schema validation?");
66
+ (0, node_assert_1.strict)(bisRootForConstraint.appliesTo !== undefined, "The referenced AppliesToEntityClass could not be found, how did it pass schema validation?");
75
67
  bisRootForConstraint = await this.getRootBisClass(await bisRootForConstraint.appliesTo);
76
68
  }
77
- this._rootBisClassCache.set(cacheKey, bisRootForConstraint);
78
69
  return bisRootForConstraint;
79
70
  }
80
71
  async getAbstractConstraintClass(constraint) {
81
- const cacheKey = `${constraint.fullName}_${constraint.constraintClasses?.[0]?.fullName || "abstract"}`;
82
- const cached = this._constraintClassCache.get(cacheKey);
83
- if (cached) {
84
- return cached;
85
- }
86
72
  // constraint classes must share a base so we can get the root from any of them, just use the first
87
73
  const ecclass = await (constraint.constraintClasses?.[0] ||
88
74
  constraint.abstractConstraint);
89
- assert(ecclass !== undefined, "At least one constraint class or an abstract constraint must have been defined, the constraint is not valid");
90
- this._constraintClassCache.set(cacheKey, ecclass);
75
+ (0, node_assert_1.strict)(ecclass !== undefined, "At least one constraint class or an abstract constraint must have been defined, the constraint is not valid");
91
76
  return ecclass;
92
77
  }
93
78
  /** initialize from an imodel with metadata */
94
79
  async initAllSchemasInIModel(imodel) {
95
- let totalSchemaCount = 0;
96
- let schemaCompletedCount = 0;
97
- const initStartTime = performance.now();
98
80
  const query = `
99
81
  WITH RECURSIVE refs(SchemaId) AS (
100
82
  SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'
101
- UNION ALL
83
+ UNION
102
84
  SELECT sr.SourceECInstanceId
103
85
  FROM ECDbMeta.SchemaHasSchemaReferences sr
104
86
  JOIN refs ON sr.TargetECInstanceId = refs.SchemaId
105
87
  )
106
- SELECT DISTINCT s.Name as name
88
+ SELECT s.Name as name
107
89
  FROM refs
108
90
  JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId
109
- -- ensure schema dependency order
110
- ORDER BY s.ECInstanceId
111
91
  `;
112
- for await (const row of imodel.createQueryReader(query)) {
92
+ for await (const row of imodel.createQueryReader(query, undefined, {
93
+ usePrimaryConn: true,
94
+ })) {
113
95
  const schemaName = row.name;
114
- const startTime = performance.now();
115
- core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Loading schema: ${schemaName}`);
116
96
  const schemaItemKey = new ecschema_metadata_1.SchemaKey(schemaName);
117
97
  const schema = await imodel.schemaContext.getSchema(schemaItemKey);
118
- if (schema) {
119
- await this.considerInitSchema(schema);
120
- const endTime = performance.now();
121
- core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Completed schema: ${schemaName} in ${(endTime - startTime).toFixed(2)}ms`);
122
- schemaCompletedCount++;
123
- }
124
- else {
125
- core_bentley_1.Logger.logInfo(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Did not load schema: ${schemaName}`);
98
+ if (!schema) {
99
+ core_bentley_1.ITwinError.throwError({
100
+ iTwinErrorId: {
101
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
102
+ key: IModelTransformerError_1.IModelTransformerError.SchemaLoadFailed,
103
+ },
104
+ message: `Failed to load schema: ${schemaName}`,
105
+ });
126
106
  }
127
- totalSchemaCount++;
107
+ await this.considerInitSchema(schema);
128
108
  }
129
- const initEndTime = performance.now();
130
- core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Schemas completed out of total: ${schemaCompletedCount} / ${totalSchemaCount} in ${(initEndTime - initStartTime).toFixed(2)}ms`);
131
109
  }
132
110
  async considerInitSchema(schema) {
133
111
  if (this._initedSchemas.has(schema.name)) {
134
112
  const cachedSchemaKey = this._initedSchemas.get(schema.name);
135
- assert(cachedSchemaKey !== undefined);
113
+ (0, node_assert_1.strict)(cachedSchemaKey !== undefined);
136
114
  const incomingSchemaIsEqualOrOlder = schema.schemaKey.compareByVersion(cachedSchemaKey) <= 0;
137
115
  if (incomingSchemaIsEqualOrOlder) {
138
116
  return;
@@ -141,73 +119,55 @@ class ECReferenceTypesCache {
141
119
  return this.initSchema(schema);
142
120
  }
143
121
  async initSchema(schema) {
144
- core_bentley_1.Logger.logInfo(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Init Schema: ${schema.name}`);
122
+ core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `initSchema started for ${schema.name}`);
145
123
  const schemaNameLower = schema.name.toLowerCase();
146
- // Pre-collect all items to reduce iterator overhead
147
- const allItems = Array.from(schema.getItems());
148
- const ecClasses = [];
149
- const relationshipClasses = [];
150
- // Single pass through items with type checking
151
- for (const item of allItems) {
152
- // eslint-disable-next-line @itwin/no-internal
153
- if (!ecschema_metadata_1.ECClass.isECClass(item))
154
- continue;
155
- ecClasses.push(item);
156
- if (item instanceof ecschema_metadata_1.RelationshipClass) {
157
- relationshipClasses.push(item);
124
+ // Local dedup map — scoped to this single initSchema call, not persisted
125
+ const localRelInfoMap = new Map();
126
+ const getRelInfo = async (relClass) => {
127
+ let promise = localRelInfoMap.get(relClass.fullName);
128
+ if (!promise) {
129
+ promise = this.relInfoFromRelClass(relClass);
130
+ localRelInfoMap.set(relClass.fullName, promise);
158
131
  }
159
- }
160
- // Process relationship classes in parallel and populate global cache
161
- const relInfoPromises = relationshipClasses.map(async (relClass) => {
162
- const relInfo = await this.relInfoFromRelClass(relClass);
163
- this._relationshipInfoCache.set(relClass.fullName, relInfo);
164
- if (relInfo) {
165
- this._relClassNameEndToRefTypes.set([schemaNameLower, relClass.name.toLowerCase()], relInfo);
132
+ return promise;
133
+ };
134
+ // Process all classes concurrently
135
+ const classPromises = Array.from(schema.getItems())
136
+ .filter((item) => ecschema_metadata_1.ECClass.isECClass(item))
137
+ .map(async (ecclass) => {
138
+ // Handle relationship end types
139
+ if (ecclass instanceof ecschema_metadata_1.RelationshipClass) {
140
+ const relInfo = await getRelInfo(ecclass);
141
+ if (relInfo) {
142
+ this._relClassNameEndToRefTypes.set([schemaNameLower, ecclass.name.toLowerCase()], relInfo);
143
+ }
166
144
  }
167
- return relInfo;
168
- });
169
- // Wait for all relationship info to be cached
170
- await Promise.all(relInfoPromises);
171
- // Process navigation properties with optimized batching
172
- const propertyBatchSize = 25;
173
- for (let i = 0; i < ecClasses.length; i += propertyBatchSize) {
174
- const classBatch = ecClasses.slice(i, i + propertyBatchSize);
175
- const classPromises = classBatch.map(async (ecclass) => {
176
- const properties = await ecclass.getProperties();
177
- if (!properties)
145
+ // Handle nav props
146
+ const properties = await ecclass.getProperties();
147
+ const classNameLower = ecclass.name.toLowerCase();
148
+ const navPropPromises = Array.from(properties)
149
+ .filter((prop) => prop.isNavigation())
150
+ .map(async (prop) => {
151
+ if (!prop.isNavigation())
178
152
  return;
179
- const classNameLower = ecclass.name.toLowerCase();
180
- // Efficiently filter navigation properties
181
- const navProps = Array.from(properties).filter((prop) => prop.isNavigation());
182
- if (navProps.length === 0)
153
+ const relClass = await prop.relationshipClass;
154
+ const relInfo = await getRelInfo(relClass);
155
+ if (relInfo === undefined)
183
156
  return;
184
- const navPropPromises = navProps.map(async (prop) => {
185
- const relClass = await prop.relationshipClass;
186
- // Use cached relation info
187
- let relInfo = this._relationshipInfoCache.get(relClass.fullName);
188
- if (relInfo === undefined &&
189
- !this._relationshipInfoCache.has(relClass.fullName)) {
190
- relInfo = await this.relInfoFromRelClass(relClass);
191
- this._relationshipInfoCache.set(relClass.fullName, relInfo);
192
- }
193
- if (relInfo === undefined)
194
- return;
195
- const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward
196
- ? // eslint-disable-next-line @itwin/no-internal
197
- relInfo.target
198
- : // eslint-disable-next-line @itwin/no-internal
199
- relInfo.source;
200
- this._propQualifierToRefType.set([schemaNameLower, classNameLower, prop.name.toLowerCase()], navPropRefType);
201
- });
202
- await Promise.all(navPropPromises);
157
+ const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward
158
+ ? relInfo.target
159
+ : relInfo.source;
160
+ this._propQualifierToRefType.set([schemaNameLower, classNameLower, prop.name.toLowerCase()], navPropRefType);
203
161
  });
204
- await Promise.all(classPromises);
205
- }
162
+ await Promise.all(navPropPromises);
163
+ });
164
+ await Promise.all(classPromises);
206
165
  this._initedSchemas.set(schema.name, schema.schemaKey);
166
+ core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `initSchema completed for ${schema.name}`);
207
167
  }
208
168
  async relInfoFromRelClass(ecclass) {
209
- assert(ecclass.source.constraintClasses !== undefined);
210
- assert(ecclass.target.constraintClasses !== undefined);
169
+ (0, node_assert_1.strict)(ecclass.source.constraintClasses !== undefined);
170
+ (0, node_assert_1.strict)(ecclass.target.constraintClasses !== undefined);
211
171
  const [[sourceClass, sourceRootBisClass], [targetClass, targetRootBisClass],] = await Promise.all([
212
172
  this.getAbstractConstraintClass(ecclass.source).then(async (constraintClass) => [
213
173
  constraintClass,
@@ -236,8 +196,8 @@ class ECReferenceTypesCache {
236
196
  `the nav prop reference type cache for ${cls.fullName}.`,
237
197
  "This is a bug.",
238
198
  ].join("\n");
239
- assert(sourceType !== undefined, makeAssertMsg(sourceRootBisClass, sourceClass));
240
- assert(targetType !== undefined, makeAssertMsg(targetRootBisClass, targetClass));
199
+ (0, node_assert_1.strict)(sourceType !== undefined, makeAssertMsg(sourceRootBisClass, sourceClass));
200
+ (0, node_assert_1.strict)(targetType !== undefined, makeAssertMsg(targetRootBisClass, targetClass));
241
201
  return { source: sourceType, target: targetType };
242
202
  }
243
203
  getNavPropRefType(schemaName, className, propName) {
@@ -261,9 +221,6 @@ class ECReferenceTypesCache {
261
221
  this._initedSchemas.clear();
262
222
  this._propQualifierToRefType.clear();
263
223
  this._relClassNameEndToRefTypes.clear();
264
- this._rootBisClassCache.clear();
265
- this._relationshipInfoCache.clear();
266
- this._constraintClassCache.clear();
267
224
  }
268
225
  }
269
226
  exports.ECReferenceTypesCache = ECReferenceTypesCache;
@@ -1 +1 @@
1
- {"version":3,"file":"ECReferenceTypesCache.js","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.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 iModels\n */\n\nimport { Logger, TupleKeyedMap } from \"@itwin/core-bentley\";\nimport { ConcreteEntityTypes, RelTypeInfo } from \"@itwin/core-common\";\nimport {\n ECClass,\n Mixin,\n RelationshipClass,\n RelationshipConstraint,\n Schema,\n SchemaKey,\n StrengthDirection,\n} from \"@itwin/ecschema-metadata\";\nimport * as assert from \"assert\";\nimport { IModelDb } from \"@itwin/core-backend\";\nimport { TransformerLoggerCategory } from \"./TransformerLoggerCategory\";\n\n/** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.\n * @internal\n */\nexport class SchemaNotInCacheErr extends Error {\n public constructor() {\n super(\"Schema was not in cache, initialize that schema\");\n }\n}\n\n/**\n * A cache of the entity types referenced by navprops in ecchemas, as well as the source and target entity types of\n * The transformer needs the referenced type to determine how to resolve references.\n *\n * Using multiple of these usually performs redundant computation, for static schemas at least. A possible future optimization\n * would be to seed the computation from a global cache of non-dynamic schemas, but dynamic schemas can collide willy-nilly\n * @internal\n */\nexport class ECReferenceTypesCache {\n /** nesting based tuple map keyed by qualified property path tuple [schemaName, className, propName] */\n private _propQualifierToRefType = new TupleKeyedMap<\n [string, string, string],\n ConcreteEntityTypes\n >();\n private _relClassNameEndToRefTypes = new TupleKeyedMap<\n [string, string],\n RelTypeInfo\n >();\n private _initedSchemas = new Map<string, SchemaKey>();\n\n // Performance optimization caches\n private _rootBisClassCache = new Map<string, ECClass>();\n private _relationshipInfoCache = new Map<string, RelTypeInfo | undefined>();\n private _constraintClassCache = new Map<string, ECClass>();\n\n private static bisRootClassToRefType: Record<\n string,\n ConcreteEntityTypes | undefined\n > = {\n /* eslint-disable quote-props, @typescript-eslint/naming-convention */\n Element: ConcreteEntityTypes.Element,\n Model: ConcreteEntityTypes.Model,\n ElementAspect: ConcreteEntityTypes.ElementAspect,\n ElementRefersToElements: ConcreteEntityTypes.Relationship,\n ElementDrivesElement: ConcreteEntityTypes.Relationship,\n // code spec is technically a potential root class but it is ignored currently\n // see [ConcreteEntityTypes]($common)\n /* eslint-enable quote-props, @typescript-eslint/naming-convention */\n };\n\n private async getRootBisClass(ecclass: ECClass) {\n const cacheKey = ecclass.fullName;\n const cached = this._rootBisClassCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n let bisRootForConstraint: ECClass = ecclass;\n await ecclass.traverseBaseClasses((baseClass) => {\n // The depth first traversal will descend all the way to the root class before making any lateral traversal\n // of mixin hierarchies, (or if the constraint is a mixin, it will traverse to the root of the mixin hierarchy)\n // Once we see that we've moved laterally, we can terminate early\n const isFirstTest = bisRootForConstraint === ecclass;\n const traversalSwitchedRootPath =\n baseClass.name !== bisRootForConstraint.baseClass?.name;\n const stillTraversingRootPath = isFirstTest || !traversalSwitchedRootPath;\n if (!stillTraversingRootPath) return true; // stop traversal early\n bisRootForConstraint = baseClass;\n return false;\n });\n // if the root class of the constraint was a mixin, use its AppliesToEntityClass\n if (bisRootForConstraint instanceof Mixin) {\n assert(\n bisRootForConstraint.appliesTo !== undefined,\n \"The referenced AppliesToEntityClass could not be found, how did it pass schema validation?\"\n );\n bisRootForConstraint = await this.getRootBisClass(\n await bisRootForConstraint.appliesTo\n );\n }\n\n this._rootBisClassCache.set(cacheKey, bisRootForConstraint);\n return bisRootForConstraint;\n }\n\n private async getAbstractConstraintClass(\n constraint: RelationshipConstraint\n ): Promise<ECClass> {\n const cacheKey = `${constraint.fullName}_${constraint.constraintClasses?.[0]?.fullName || \"abstract\"}`;\n const cached = this._constraintClassCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n // constraint classes must share a base so we can get the root from any of them, just use the first\n const ecclass = await (constraint.constraintClasses?.[0] ||\n constraint.abstractConstraint);\n assert(\n ecclass !== undefined,\n \"At least one constraint class or an abstract constraint must have been defined, the constraint is not valid\"\n );\n\n this._constraintClassCache.set(cacheKey, ecclass);\n return ecclass;\n }\n\n /** initialize from an imodel with metadata */\n public async initAllSchemasInIModel(imodel: IModelDb): Promise<void> {\n let totalSchemaCount = 0;\n let schemaCompletedCount = 0;\n\n const initStartTime = performance.now();\n\n const query = `\n WITH RECURSIVE refs(SchemaId) AS (\n SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'\n UNION ALL\n SELECT sr.SourceECInstanceId\n FROM ECDbMeta.SchemaHasSchemaReferences sr\n JOIN refs ON sr.TargetECInstanceId = refs.SchemaId\n )\n SELECT DISTINCT s.Name as name\n FROM refs\n JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId\n -- ensure schema dependency order\n ORDER BY s.ECInstanceId\n `;\n\n for await (const row of imodel.createQueryReader(query)) {\n const schemaName = row.name;\n const startTime = performance.now();\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Loading schema: ${schemaName}`\n );\n const schemaItemKey = new SchemaKey(schemaName);\n const schema = await imodel.schemaContext.getSchema(schemaItemKey);\n if (schema) {\n await this.considerInitSchema(schema);\n const endTime = performance.now();\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Completed schema: ${schemaName} in ${(endTime - startTime).toFixed(2)}ms`\n );\n schemaCompletedCount++;\n } else {\n Logger.logInfo(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Did not load schema: ${schemaName}`\n );\n }\n\n totalSchemaCount++;\n }\n\n const initEndTime = performance.now();\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Schemas completed out of total: ${schemaCompletedCount} / ${totalSchemaCount} in ${(initEndTime - initStartTime).toFixed(2)}ms`\n );\n }\n\n private async considerInitSchema(schema: Schema): Promise<void> {\n if (this._initedSchemas.has(schema.name)) {\n const cachedSchemaKey = this._initedSchemas.get(schema.name);\n assert(cachedSchemaKey !== undefined);\n const incomingSchemaIsEqualOrOlder =\n schema.schemaKey.compareByVersion(cachedSchemaKey) <= 0;\n if (incomingSchemaIsEqualOrOlder) {\n return;\n }\n }\n return this.initSchema(schema);\n }\n\n private async initSchema(schema: Schema): Promise<void> {\n Logger.logInfo(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Init Schema: ${schema.name}`\n );\n const schemaNameLower = schema.name.toLowerCase();\n\n // Pre-collect all items to reduce iterator overhead\n const allItems = Array.from(schema.getItems());\n const ecClasses: ECClass[] = [];\n const relationshipClasses: RelationshipClass[] = [];\n\n // Single pass through items with type checking\n for (const item of allItems) {\n // eslint-disable-next-line @itwin/no-internal\n if (!ECClass.isECClass(item)) continue;\n ecClasses.push(item);\n if (item instanceof RelationshipClass) {\n relationshipClasses.push(item);\n }\n }\n\n // Process relationship classes in parallel and populate global cache\n const relInfoPromises = relationshipClasses.map(async (relClass) => {\n const relInfo = await this.relInfoFromRelClass(relClass);\n this._relationshipInfoCache.set(relClass.fullName, relInfo);\n if (relInfo) {\n this._relClassNameEndToRefTypes.set(\n [schemaNameLower, relClass.name.toLowerCase()],\n relInfo\n );\n }\n return relInfo;\n });\n\n // Wait for all relationship info to be cached\n await Promise.all(relInfoPromises);\n\n // Process navigation properties with optimized batching\n const propertyBatchSize = 25;\n for (let i = 0; i < ecClasses.length; i += propertyBatchSize) {\n const classBatch = ecClasses.slice(i, i + propertyBatchSize);\n\n const classPromises = classBatch.map(async (ecclass) => {\n const properties = await ecclass.getProperties();\n if (!properties) return;\n\n const classNameLower = ecclass.name.toLowerCase();\n\n // Efficiently filter navigation properties\n const navProps = Array.from(properties).filter((prop) =>\n prop.isNavigation()\n );\n if (navProps.length === 0) return;\n\n const navPropPromises = navProps.map(async (prop) => {\n const relClass = await prop.relationshipClass;\n\n // Use cached relation info\n let relInfo = this._relationshipInfoCache.get(relClass.fullName);\n if (\n relInfo === undefined &&\n !this._relationshipInfoCache.has(relClass.fullName)\n ) {\n relInfo = await this.relInfoFromRelClass(relClass);\n this._relationshipInfoCache.set(relClass.fullName, relInfo);\n }\n\n if (relInfo === undefined) return;\n\n const navPropRefType =\n prop.direction === StrengthDirection.Forward\n ? // eslint-disable-next-line @itwin/no-internal\n relInfo.target\n : // eslint-disable-next-line @itwin/no-internal\n relInfo.source;\n\n this._propQualifierToRefType.set(\n [schemaNameLower, classNameLower, prop.name.toLowerCase()],\n navPropRefType\n );\n });\n\n await Promise.all(navPropPromises);\n });\n\n await Promise.all(classPromises);\n }\n\n this._initedSchemas.set(schema.name, schema.schemaKey);\n }\n\n private async relInfoFromRelClass(\n ecclass: RelationshipClass\n ): Promise<RelTypeInfo | undefined> {\n assert(ecclass.source.constraintClasses !== undefined);\n assert(ecclass.target.constraintClasses !== undefined);\n const [\n [sourceClass, sourceRootBisClass],\n [targetClass, targetRootBisClass],\n ] = await Promise.all([\n this.getAbstractConstraintClass(ecclass.source).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n this.getAbstractConstraintClass(ecclass.target).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n ]);\n\n if (\n sourceRootBisClass.name === \"CodeSpec\" ||\n targetRootBisClass.name === \"CodeSpec\"\n )\n return undefined;\n const sourceType =\n ECReferenceTypesCache.bisRootClassToRefType[sourceRootBisClass.name];\n const targetType =\n ECReferenceTypesCache.bisRootClassToRefType[targetRootBisClass.name];\n if (\n (!sourceType &&\n sourceRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\")) ||\n (!targetType &&\n targetRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\"))\n ) {\n // ECView elements are not \"real\" data and transformer does not need to process them.\n // Relationships that point to ECView elements can only be used in ECViews so the mapping is not needed.\n return undefined;\n }\n\n const makeAssertMsg = (root: ECClass, cls: ECClass) =>\n [\n `An unknown root class '${root.fullName}' was encountered while populating`,\n `the nav prop reference type cache for ${cls.fullName}.`,\n \"This is a bug.\",\n ].join(\"\\n\");\n assert(\n sourceType !== undefined,\n makeAssertMsg(sourceRootBisClass, sourceClass)\n );\n assert(\n targetType !== undefined,\n makeAssertMsg(targetRootBisClass, targetClass)\n );\n return { source: sourceType, target: targetType };\n }\n\n public getNavPropRefType(\n schemaName: string,\n className: string,\n propName: string\n ): undefined | ConcreteEntityTypes {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._propQualifierToRefType.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n propName.toLowerCase(),\n ]);\n }\n\n public getRelationshipEndType(\n schemaName: string,\n className: string\n ): undefined | RelTypeInfo {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._relClassNameEndToRefTypes.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n ]);\n }\n\n public clear() {\n this._initedSchemas.clear();\n this._propQualifierToRefType.clear();\n this._relClassNameEndToRefTypes.clear();\n this._rootBisClassCache.clear();\n this._relationshipInfoCache.clear();\n this._constraintClassCache.clear();\n }\n}\n"]}
1
+ {"version":3,"file":"ECReferenceTypesCache.js","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.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 iModels\n */\n\nimport { ITwinError, Logger, TupleKeyedMap } from \"@itwin/core-bentley\";\nimport { ConcreteEntityTypes, RelTypeInfo } from \"@itwin/core-common\";\nimport {\n ECClass,\n Mixin,\n Property,\n RelationshipClass,\n RelationshipConstraint,\n Schema,\n SchemaKey,\n StrengthDirection,\n} from \"@itwin/ecschema-metadata\";\nimport { strict as assert } from \"node:assert\";\nimport { IModelDb } from \"@itwin/core-backend\";\nimport { TransformerLoggerCategory } from \"./TransformerLoggerCategory\";\nimport {\n IModelTransformerError,\n IModelTransformerErrorScope,\n} from \"./IModelTransformerError\";\n\n/** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.\n * @internal\n */\nexport class SchemaNotInCacheErr extends Error {\n public constructor() {\n super(\"Schema was not in cache, initialize that schema\");\n }\n}\n\n/**\n * A cache of the entity types referenced by navprops in ecchemas, as well as the source and target entity types of\n * The transformer needs the referenced type to determine how to resolve references.\n *\n * Using multiple of these usually performs redundant computation, for static schemas at least. A possible future optimization\n * would be to seed the computation from a global cache of non-dynamic schemas, but dynamic schemas can collide willy-nilly\n * @internal\n */\nexport class ECReferenceTypesCache {\n /** nesting based tuple map keyed by qualified property path tuple [schemaName, className, propName] */\n private _propQualifierToRefType = new TupleKeyedMap<\n [string, string, string],\n ConcreteEntityTypes\n >();\n private _relClassNameEndToRefTypes = new TupleKeyedMap<\n [string, string],\n RelTypeInfo\n >();\n private _initedSchemas = new Map<string, SchemaKey>();\n\n private static bisRootClassToRefType: Record<\n string,\n ConcreteEntityTypes | undefined\n > = {\n /* eslint-disable quote-props, @typescript-eslint/naming-convention */\n Element: ConcreteEntityTypes.Element,\n Model: ConcreteEntityTypes.Model,\n ElementAspect: ConcreteEntityTypes.ElementAspect,\n ElementRefersToElements: ConcreteEntityTypes.Relationship,\n ElementDrivesElement: ConcreteEntityTypes.Relationship,\n // code spec is technically a potential root class but it is ignored currently\n // see [ConcreteEntityTypes]($common)\n /* eslint-enable quote-props, @typescript-eslint/naming-convention */\n };\n\n private async getRootBisClass(ecclass: ECClass) {\n let bisRootForConstraint: ECClass = ecclass;\n await ecclass.traverseBaseClasses((baseClass) => {\n // The depth first traversal will descend all the way to the root class before making any lateral traversal\n // of mixin hierarchies, (or if the constraint is a mixin, it will traverse to the root of the mixin hierarchy)\n // Once we see that we've moved laterally, we can terminate early\n const isFirstTest = bisRootForConstraint === ecclass;\n const traversalSwitchedRootPath =\n baseClass.name !== bisRootForConstraint.baseClass?.name;\n const stillTraversingRootPath = isFirstTest || !traversalSwitchedRootPath;\n if (!stillTraversingRootPath) return true; // stop traversal early\n bisRootForConstraint = baseClass;\n return false;\n });\n // if the root class of the constraint was a mixin, use its AppliesToEntityClass\n if (bisRootForConstraint instanceof Mixin) {\n assert(\n bisRootForConstraint.appliesTo !== undefined,\n \"The referenced AppliesToEntityClass could not be found, how did it pass schema validation?\"\n );\n bisRootForConstraint = await this.getRootBisClass(\n await bisRootForConstraint.appliesTo\n );\n }\n return bisRootForConstraint;\n }\n\n private async getAbstractConstraintClass(\n constraint: RelationshipConstraint\n ): Promise<ECClass> {\n // constraint classes must share a base so we can get the root from any of them, just use the first\n const ecclass = await (constraint.constraintClasses?.[0] ||\n constraint.abstractConstraint);\n assert(\n ecclass !== undefined,\n \"At least one constraint class or an abstract constraint must have been defined, the constraint is not valid\"\n );\n return ecclass;\n }\n\n /** initialize from an imodel with metadata */\n public async initAllSchemasInIModel(imodel: IModelDb): Promise<void> {\n const query = `\n WITH RECURSIVE refs(SchemaId) AS (\n SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'\n UNION\n SELECT sr.SourceECInstanceId\n FROM ECDbMeta.SchemaHasSchemaReferences sr\n JOIN refs ON sr.TargetECInstanceId = refs.SchemaId\n )\n SELECT s.Name as name\n FROM refs\n JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId\n `;\n\n for await (const row of imodel.createQueryReader(query, undefined, {\n usePrimaryConn: true,\n })) {\n const schemaName = row.name;\n const schemaItemKey = new SchemaKey(schemaName);\n const schema = await imodel.schemaContext.getSchema(schemaItemKey);\n if (!schema) {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.SchemaLoadFailed,\n },\n message: `Failed to load schema: ${schemaName}`,\n });\n }\n await this.considerInitSchema(schema);\n }\n }\n\n private async considerInitSchema(schema: Schema): Promise<void> {\n if (this._initedSchemas.has(schema.name)) {\n const cachedSchemaKey = this._initedSchemas.get(schema.name);\n assert(cachedSchemaKey !== undefined);\n const incomingSchemaIsEqualOrOlder =\n schema.schemaKey.compareByVersion(cachedSchemaKey) <= 0;\n if (incomingSchemaIsEqualOrOlder) {\n return;\n }\n }\n return this.initSchema(schema);\n }\n\n private async initSchema(schema: Schema): Promise<void> {\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `initSchema started for ${schema.name}`\n );\n const schemaNameLower = schema.name.toLowerCase();\n\n // Local dedup map — scoped to this single initSchema call, not persisted\n const localRelInfoMap = new Map<string, Promise<RelTypeInfo | undefined>>();\n\n const getRelInfo = async (relClass: RelationshipClass) => {\n let promise = localRelInfoMap.get(relClass.fullName);\n if (!promise) {\n promise = this.relInfoFromRelClass(relClass);\n localRelInfoMap.set(relClass.fullName, promise);\n }\n return promise;\n };\n\n // Process all classes concurrently\n const classPromises = Array.from(schema.getItems())\n .filter((item): item is ECClass => ECClass.isECClass(item))\n .map(async (ecclass) => {\n // Handle relationship end types\n if (ecclass instanceof RelationshipClass) {\n const relInfo = await getRelInfo(ecclass);\n if (relInfo) {\n this._relClassNameEndToRefTypes.set(\n [schemaNameLower, ecclass.name.toLowerCase()],\n relInfo\n );\n }\n }\n\n // Handle nav props\n const properties = await ecclass.getProperties();\n const classNameLower = ecclass.name.toLowerCase();\n\n const navPropPromises = Array.from(properties)\n .filter((prop: Property) => prop.isNavigation())\n .map(async (prop: Property) => {\n if (!prop.isNavigation()) return;\n const relClass = await prop.relationshipClass;\n const relInfo = await getRelInfo(relClass);\n if (relInfo === undefined) return;\n\n const navPropRefType =\n prop.direction === StrengthDirection.Forward\n ? relInfo.target\n : relInfo.source;\n\n this._propQualifierToRefType.set(\n [schemaNameLower, classNameLower, prop.name.toLowerCase()],\n navPropRefType\n );\n });\n\n await Promise.all(navPropPromises);\n });\n\n await Promise.all(classPromises);\n this._initedSchemas.set(schema.name, schema.schemaKey);\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `initSchema completed for ${schema.name}`\n );\n }\n\n private async relInfoFromRelClass(\n ecclass: RelationshipClass\n ): Promise<RelTypeInfo | undefined> {\n assert(ecclass.source.constraintClasses !== undefined);\n assert(ecclass.target.constraintClasses !== undefined);\n const [\n [sourceClass, sourceRootBisClass],\n [targetClass, targetRootBisClass],\n ] = await Promise.all([\n this.getAbstractConstraintClass(ecclass.source).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n this.getAbstractConstraintClass(ecclass.target).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n ]);\n\n if (\n sourceRootBisClass.name === \"CodeSpec\" ||\n targetRootBisClass.name === \"CodeSpec\"\n )\n return undefined;\n const sourceType =\n ECReferenceTypesCache.bisRootClassToRefType[sourceRootBisClass.name];\n const targetType =\n ECReferenceTypesCache.bisRootClassToRefType[targetRootBisClass.name];\n if (\n (!sourceType &&\n sourceRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\")) ||\n (!targetType &&\n targetRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\"))\n ) {\n // ECView elements are not \"real\" data and transformer does not need to process them.\n // Relationships that point to ECView elements can only be used in ECViews so the mapping is not needed.\n return undefined;\n }\n\n const makeAssertMsg = (root: ECClass, cls: ECClass) =>\n [\n `An unknown root class '${root.fullName}' was encountered while populating`,\n `the nav prop reference type cache for ${cls.fullName}.`,\n \"This is a bug.\",\n ].join(\"\\n\");\n assert(\n sourceType !== undefined,\n makeAssertMsg(sourceRootBisClass, sourceClass)\n );\n assert(\n targetType !== undefined,\n makeAssertMsg(targetRootBisClass, targetClass)\n );\n return { source: sourceType, target: targetType };\n }\n\n public getNavPropRefType(\n schemaName: string,\n className: string,\n propName: string\n ): undefined | ConcreteEntityTypes {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._propQualifierToRefType.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n propName.toLowerCase(),\n ]);\n }\n\n public getRelationshipEndType(\n schemaName: string,\n className: string\n ): undefined | RelTypeInfo {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._relClassNameEndToRefTypes.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n ]);\n }\n\n public clear() {\n this._initedSchemas.clear();\n this._propQualifierToRefType.clear();\n this._relClassNameEndToRefTypes.clear();\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.d.ts","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;;;GAIG;AACH,qBAAa,uCACX,YAAW,qBAAqB,CAAC,aAAa,CAAC;IAE5B,OAAO,CAAC,YAAY;gBAAZ,YAAY,EAAE,WAAW;IAE7C,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,aAAa,CAAC;IAIxD,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;CAOjE;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,CACtD,WAAW,EACP,CAAC,WAAW,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC,GACpD,IAAI,CAAC,WAAW,EAAE,MAAM,qBAAqB,CAAC,aAAa,CAAC,CAAC,GAChE,qBAAqB,CAAC,aAAa,CAAC,CAUtC"}
1
+ {"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.d.ts","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;;;GAIG;AACH,qBAAa,uCACX,YAAW,qBAAqB,CAAC,aAAa,CAAC;IAE5B,OAAO,CAAC,YAAY;IAAvC,YAA2B,YAAY,EAAE,WAAW,EAAI;IAEjD,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,aAAa,CAAC,CAEpE;IAEY,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,CAM/D;CACF;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,CACtD,WAAW,EACP,CAAC,WAAW,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC,GACpD,IAAI,CAAC,WAAW,EAAE,MAAM,qBAAqB,CAAC,aAAa,CAAC,CAAC,GAChE,qBAAqB,CAAC,aAAa,CAAC,CAUtC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.js","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAgChG,4FAcC;AA1CD;;;;GAIG;AACH,MAAa,uCAAuC;IAGvB;IAA3B,YAA2B,YAAyB;QAAzB,iBAAY,GAAZ,YAAY,CAAa;IAAG,CAAC;IAEjD,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,OAAO;YACL,IAAI;YACJ,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO;SACjC,CAAC;IACJ,CAAC;CACF;AAhBD,0FAgBC;AAED;;;;GAIG;AACH,SAAgB,wCAAwC,CACtD,WAEiE;IAEjE,IAAI,MAAM,CAAC,aAAa,IAAI,WAAW,EAAE,CAAC;QACxC,kBAAkB;QAClB,OAAO,WAAW,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,kBAAkB;QAClB,OAAO,IAAI,uCAAuC,CAChD,WAA0B,CAC3B,CAAC;IACJ,CAAC;AACH,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 { ECSqlReader, QueryRowProxy } from \"@itwin/core-common\";\n\n/**\n * Adapter class for ECSqlReader for AsyncIterableIterator interface.\n * It allows to iterate through query results in itwin 3.x using for await() syntax like using itwin 4.x version.\n * @internal\n */\nexport class ECSqlReaderAsyncIterableIteratorAdapter\n implements AsyncIterableIterator<QueryRowProxy>\n{\n public constructor(private _ecSqlReader: ECSqlReader) {}\n\n public [Symbol.asyncIterator](): AsyncIterableIterator<QueryRowProxy> {\n return this;\n }\n\n public async next(): Promise<IteratorResult<QueryRowProxy, any>> {\n const done = !(await this._ecSqlReader.step());\n return {\n done,\n value: this._ecSqlReader.current,\n };\n }\n}\n\n/**\n * Wraps ECSqlReader with ECSqlReaderAsyncIterableIteratorAdapter if it's needed.\n * @param ecSqlReader ECSqlReader isntance from itwin 3.x or 4.x version\n * @internal\n */\nexport function ensureECSqlReaderIsAsyncIterableIterator(\n ecSqlReader:\n | (ECSqlReader & AsyncIterableIterator<QueryRowProxy>)\n | Omit<ECSqlReader, keyof AsyncIterableIterator<QueryRowProxy>>\n): AsyncIterableIterator<QueryRowProxy> {\n if (Symbol.asyncIterator in ecSqlReader) {\n // using itwin 4.x\n return ecSqlReader;\n } else {\n // using itwin 3.x\n return new ECSqlReaderAsyncIterableIteratorAdapter(\n ecSqlReader as ECSqlReader\n );\n }\n}\n"]}
1
+ {"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.js","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;;AAIhG;;;;GAIG;AACH;IAG6B,YAAY;IAAvC,YAA2B,YAAyB;4BAAzB,YAAY;IAAgB,CAAC;IAEjD,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,OAAO;YACL,IAAI;YACJ,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO;SACjC,CAAC;IACJ,CAAC;CACF;;AAED;;;;GAIG;AACH,kDACE,WAEiE;IAEjE,IAAI,MAAM,CAAC,aAAa,IAAI,WAAW,EAAE,CAAC;QACxC,kBAAkB;QAClB,OAAO,WAAW,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,kBAAkB;QAClB,OAAO,IAAI,uCAAuC,CAChD,WAA0B,CAC3B,CAAC;IACJ,CAAC;AACH,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 { ECSqlReader, QueryRowProxy } from \"@itwin/core-common\";\n\n/**\n * Adapter class for ECSqlReader for AsyncIterableIterator interface.\n * It allows to iterate through query results in itwin 3.x using for await() syntax like using itwin 4.x version.\n * @internal\n */\nexport class ECSqlReaderAsyncIterableIteratorAdapter\n implements AsyncIterableIterator<QueryRowProxy>\n{\n public constructor(private _ecSqlReader: ECSqlReader) {}\n\n public [Symbol.asyncIterator](): AsyncIterableIterator<QueryRowProxy> {\n return this;\n }\n\n public async next(): Promise<IteratorResult<QueryRowProxy, any>> {\n const done = !(await this._ecSqlReader.step());\n return {\n done,\n value: this._ecSqlReader.current,\n };\n }\n}\n\n/**\n * Wraps ECSqlReader with ECSqlReaderAsyncIterableIteratorAdapter if it's needed.\n * @param ecSqlReader ECSqlReader isntance from itwin 3.x or 4.x version\n * @internal\n */\nexport function ensureECSqlReaderIsAsyncIterableIterator(\n ecSqlReader:\n | (ECSqlReader & AsyncIterableIterator<QueryRowProxy>)\n | Omit<ECSqlReader, keyof AsyncIterableIterator<QueryRowProxy>>\n): AsyncIterableIterator<QueryRowProxy> {\n if (Symbol.asyncIterator in ecSqlReader) {\n // using itwin 4.x\n return ecSqlReader;\n } else {\n // using itwin 3.x\n return new ECSqlReaderAsyncIterableIteratorAdapter(\n ecSqlReader as ECSqlReader\n );\n }\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { EditTxn, ElementAspect, IModelDb } from "@itwin/core-backend";
2
+ import { Id64String } from "@itwin/core-bentley";
3
+ /** Deletes replaceable ElementAspects for target owners while preserving excluded classes and transformer provenance aspects.
4
+ * @internal
5
+ */
6
+ export declare class ElementAspectCleanup {
7
+ private readonly _targetDb;
8
+ private readonly _editTxn;
9
+ private readonly _deleteAspect;
10
+ constructor(_targetDb: IModelDb, _editTxn: EditTxn, _deleteAspect: (aspect: ElementAspect) => Promise<void>);
11
+ /** Deletes replaceable unique and multi-aspects owned by the supplied target elements.
12
+ * Excluded classes and transformer provenance aspects for `provenanceScopeId` are preserved. Each deletion is performed through the configured callback and requires the target `EditTxn` to be active.
13
+ */
14
+ delete(targetElementIds: ReadonlySet<Id64String>, excludedElementAspectClassFullNames: ReadonlySet<string>, provenanceScopeId?: Id64String, pageSize?: number): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=ElementAspectCleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementAspectCleanup.d.ts","sourceRoot":"","sources":["../../src/ElementAspectCleanup.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,OAAO,EACP,aAAa,EAIb,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD;;GAEG;AACH,qBAAa,oBAAoB;IAE7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAHhC,YACmB,SAAS,EAAE,QAAQ,EACnB,QAAQ,EAAE,OAAO,EACjB,aAAa,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,EACtE;IAEJ;;OAEG;IACU,MAAM,CACjB,gBAAgB,EAAE,WAAW,CAAC,UAAU,CAAC,EACzC,mCAAmC,EAAE,WAAW,CAAC,MAAM,CAAC,EACxD,iBAAiB,CAAC,EAAE,UAAU,EAC9B,QAAQ,SAAwB,GAC/B,OAAO,CAAC,IAAI,CAAC,CA8Cf;CACF"}