@itwin/imodel-transformer 2.0.0-dev.8 → 2.0.0-experimental.0

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 (128) hide show
  1. package/README.md +13 -27
  2. package/lib/cjs/Algo.d.ts +0 -4
  3. package/lib/cjs/Algo.d.ts.map +1 -1
  4. package/lib/cjs/Algo.js +0 -11
  5. package/lib/cjs/Algo.js.map +1 -1
  6. package/lib/cjs/BigMap.d.ts.map +1 -1
  7. package/lib/cjs/BigMap.js.map +1 -1
  8. package/lib/cjs/BranchProvenanceInitializer.d.ts.map +1 -1
  9. package/lib/cjs/BranchProvenanceInitializer.js +26 -26
  10. package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
  11. package/lib/cjs/ChangedElementForest.d.ts +14 -0
  12. package/lib/cjs/ChangedElementForest.d.ts.map +1 -0
  13. package/lib/cjs/ChangedElementForest.js +86 -0
  14. package/lib/cjs/ChangedElementForest.js.map +1 -0
  15. package/lib/cjs/ChangesetScanner.d.ts +61 -0
  16. package/lib/cjs/ChangesetScanner.d.ts.map +1 -0
  17. package/lib/cjs/ChangesetScanner.js +104 -0
  18. package/lib/cjs/ChangesetScanner.js.map +1 -0
  19. package/lib/cjs/ECReferenceTypesCache.d.ts +0 -4
  20. package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -1
  21. package/lib/cjs/ECReferenceTypesCache.js +54 -102
  22. package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
  23. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +1 -1
  24. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js.map +1 -1
  25. package/lib/cjs/ElementAspectCleanup.d.ts +56 -0
  26. package/lib/cjs/ElementAspectCleanup.d.ts.map +1 -0
  27. package/lib/cjs/ElementAspectCleanup.js +175 -0
  28. package/lib/cjs/ElementAspectCleanup.js.map +1 -0
  29. package/lib/cjs/ElementAspectExportCoordinator.d.ts +47 -0
  30. package/lib/cjs/ElementAspectExportCoordinator.d.ts.map +1 -0
  31. package/lib/cjs/ElementAspectExportCoordinator.js +160 -0
  32. package/lib/cjs/ElementAspectExportCoordinator.js.map +1 -0
  33. package/lib/cjs/ElementAspectExportProcessor.d.ts +44 -0
  34. package/lib/cjs/ElementAspectExportProcessor.d.ts.map +1 -0
  35. package/lib/cjs/ElementAspectExportProcessor.js +152 -0
  36. package/lib/cjs/ElementAspectExportProcessor.js.map +1 -0
  37. package/lib/cjs/ElementBulkDelete.d.ts +30 -0
  38. package/lib/cjs/ElementBulkDelete.d.ts.map +1 -0
  39. package/lib/cjs/ElementBulkDelete.js +358 -0
  40. package/lib/cjs/ElementBulkDelete.js.map +1 -0
  41. package/lib/cjs/EntityExistenceCache.d.ts +43 -0
  42. package/lib/cjs/EntityExistenceCache.d.ts.map +1 -0
  43. package/lib/cjs/EntityExistenceCache.js +91 -0
  44. package/lib/cjs/EntityExistenceCache.js.map +1 -0
  45. package/lib/cjs/EntityUnifier.d.ts +7 -7
  46. package/lib/cjs/EntityUnifier.d.ts.map +1 -1
  47. package/lib/cjs/EntityUnifier.js +55 -24
  48. package/lib/cjs/EntityUnifier.js.map +1 -1
  49. package/lib/cjs/IModelCloneContext.d.ts +8 -2
  50. package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
  51. package/lib/cjs/IModelCloneContext.js +42 -12
  52. package/lib/cjs/IModelCloneContext.js.map +1 -1
  53. package/lib/cjs/IModelExporter.d.ts +143 -30
  54. package/lib/cjs/IModelExporter.d.ts.map +1 -1
  55. package/lib/cjs/IModelExporter.js +871 -172
  56. package/lib/cjs/IModelExporter.js.map +1 -1
  57. package/lib/cjs/IModelImporter.d.ts +87 -31
  58. package/lib/cjs/IModelImporter.d.ts.map +1 -1
  59. package/lib/cjs/IModelImporter.js +361 -139
  60. package/lib/cjs/IModelImporter.js.map +1 -1
  61. package/lib/cjs/IModelTransformContext.d.ts +54 -0
  62. package/lib/cjs/IModelTransformContext.d.ts.map +1 -0
  63. package/lib/cjs/IModelTransformContext.js +3 -0
  64. package/lib/cjs/IModelTransformContext.js.map +1 -0
  65. package/lib/cjs/IModelTransformer.d.ts +132 -174
  66. package/lib/cjs/IModelTransformer.d.ts.map +1 -1
  67. package/lib/cjs/IModelTransformer.js +679 -1025
  68. package/lib/cjs/IModelTransformer.js.map +1 -1
  69. package/lib/cjs/IModelTransformerError.d.ts +84 -0
  70. package/lib/cjs/IModelTransformerError.d.ts.map +1 -0
  71. package/lib/cjs/IModelTransformerError.js +93 -0
  72. package/lib/cjs/IModelTransformerError.js.map +1 -0
  73. package/lib/cjs/ProvenanceManager.d.ts +194 -0
  74. package/lib/cjs/ProvenanceManager.d.ts.map +1 -0
  75. package/lib/cjs/ProvenanceManager.js +771 -0
  76. package/lib/cjs/ProvenanceManager.js.map +1 -0
  77. package/lib/cjs/SyncTypeResolver.d.ts +32 -0
  78. package/lib/cjs/SyncTypeResolver.d.ts.map +1 -0
  79. package/lib/cjs/SyncTypeResolver.js +92 -0
  80. package/lib/cjs/SyncTypeResolver.js.map +1 -0
  81. package/lib/cjs/TransformerLoggerCategory.d.ts +1 -1
  82. package/lib/cjs/TransformerLoggerCategory.js +1 -1
  83. package/lib/cjs/TransformerLoggerCategory.js.map +1 -1
  84. package/lib/cjs/TransformerPackageMetadata.d.ts +8 -0
  85. package/lib/cjs/TransformerPackageMetadata.d.ts.map +1 -0
  86. package/lib/cjs/TransformerPackageMetadata.js +47 -0
  87. package/lib/cjs/TransformerPackageMetadata.js.map +1 -0
  88. package/lib/cjs/imodel-transformer.d.ts +27 -0
  89. package/lib/cjs/imodel-transformer.d.ts.map +1 -1
  90. package/lib/cjs/imodel-transformer.js +61 -34
  91. package/lib/cjs/imodel-transformer.js.map +1 -1
  92. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts +29 -0
  93. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts.map +1 -0
  94. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js +212 -0
  95. package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js.map +1 -0
  96. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts +25 -0
  97. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts.map +1 -0
  98. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js +196 -0
  99. package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js.map +1 -0
  100. package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts +59 -0
  101. package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts.map +1 -0
  102. package/lib/cjs/schema-processing/SchemaProcessingStrategy.js +28 -0
  103. package/lib/cjs/schema-processing/SchemaProcessingStrategy.js.map +1 -0
  104. package/lib/cjs/schema-processing.d.ts +7 -0
  105. package/lib/cjs/schema-processing.d.ts.map +1 -0
  106. package/lib/cjs/schema-processing.js +27 -0
  107. package/lib/cjs/schema-processing.js.map +1 -0
  108. package/package.json +70 -57
  109. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts +0 -16
  110. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +0 -1
  111. package/lib/cjs/DetachedExportElementAspectsStrategy.js +0 -106
  112. package/lib/cjs/DetachedExportElementAspectsStrategy.js.map +0 -1
  113. package/lib/cjs/ElementCascadingDeleter.d.ts +0 -22
  114. package/lib/cjs/ElementCascadingDeleter.d.ts.map +0 -1
  115. package/lib/cjs/ElementCascadingDeleter.js +0 -57
  116. package/lib/cjs/ElementCascadingDeleter.js.map +0 -1
  117. package/lib/cjs/EntityMap.d.ts +0 -26
  118. package/lib/cjs/EntityMap.d.ts.map +0 -1
  119. package/lib/cjs/EntityMap.js +0 -54
  120. package/lib/cjs/EntityMap.js.map +0 -1
  121. package/lib/cjs/ExportElementAspectsStrategy.d.ts +0 -35
  122. package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +0 -1
  123. package/lib/cjs/ExportElementAspectsStrategy.js +0 -52
  124. package/lib/cjs/ExportElementAspectsStrategy.js.map +0 -1
  125. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts +0 -12
  126. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts.map +0 -1
  127. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +0 -47
  128. 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;
@@ -35,6 +32,5 @@ export declare class ECReferenceTypesCache {
35
32
  private relInfoFromRelClass;
36
33
  getNavPropRefType(schemaName: string, className: string, propName: string): undefined | ConcreteEntityTypes;
37
34
  getRelationshipEndType(schemaName: string, className: string): undefined | RelTypeInfo;
38
- clear(): void;
39
35
  }
40
36
  //# sourceMappingURL=ECReferenceTypesCache.d.ts.map
@@ -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;YAkDtD,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,CAWlC;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;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,12 +36,7 @@ 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
- /* eslint-disable quote-props, @typescript-eslint/naming-convention */
44
40
  Element: core_common_1.ConcreteEntityTypes.Element,
45
41
  Model: core_common_1.ConcreteEntityTypes.Model,
46
42
  ElementAspect: core_common_1.ConcreteEntityTypes.ElementAspect,
@@ -48,14 +44,8 @@ class ECReferenceTypesCache {
48
44
  ElementDrivesElement: core_common_1.ConcreteEntityTypes.Relationship,
49
45
  // code spec is technically a potential root class but it is ignored currently
50
46
  // see [ConcreteEntityTypes]($common)
51
- /* eslint-enable quote-props, @typescript-eslint/naming-convention */
52
47
  };
53
48
  async getRootBisClass(ecclass) {
54
- const cacheKey = ecclass.fullName;
55
- const cached = this._rootBisClassCache.get(cacheKey);
56
- if (cached) {
57
- return cached;
58
- }
59
49
  let bisRootForConstraint = ecclass;
60
50
  await ecclass.traverseBaseClasses((baseClass) => {
61
51
  // The depth first traversal will descend all the way to the root class before making any lateral traversal
@@ -71,29 +61,20 @@ class ECReferenceTypesCache {
71
61
  });
72
62
  // if the root class of the constraint was a mixin, use its AppliesToEntityClass
73
63
  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?");
64
+ (0, node_assert_1.strict)(bisRootForConstraint.appliesTo !== undefined, "The referenced AppliesToEntityClass could not be found, how did it pass schema validation?");
75
65
  bisRootForConstraint = await this.getRootBisClass(await bisRootForConstraint.appliesTo);
76
66
  }
77
- this._rootBisClassCache.set(cacheKey, bisRootForConstraint);
78
67
  return bisRootForConstraint;
79
68
  }
80
69
  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
70
  // constraint classes must share a base so we can get the root from any of them, just use the first
87
71
  const ecclass = await (constraint.constraintClasses?.[0] ||
88
72
  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);
73
+ (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
74
  return ecclass;
92
75
  }
93
76
  /** initialize from an imodel with metadata */
94
77
  async initAllSchemasInIModel(imodel) {
95
- let schemaCount = 0;
96
- const initStartTime = performance.now();
97
78
  const query = `
98
79
  WITH RECURSIVE refs(SchemaId) AS (
99
80
  SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'
@@ -105,32 +86,29 @@ class ECReferenceTypesCache {
105
86
  SELECT s.Name as name
106
87
  FROM refs
107
88
  JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId
108
- -- ensure schema dependency order
109
- ORDER BY s.ECInstanceId
110
89
  `;
111
90
  for await (const row of imodel.createQueryReader(query, undefined, {
112
91
  usePrimaryConn: true,
113
92
  })) {
114
93
  const schemaName = row.name;
115
- const startTime = performance.now();
116
- core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Loading schema: ${schemaName}`);
117
94
  const schemaItemKey = new ecschema_metadata_1.SchemaKey(schemaName);
118
95
  const schema = await imodel.schemaContext.getSchema(schemaItemKey);
119
96
  if (!schema) {
120
- throw new Error(`Failed to load schema: ${schemaName}`);
97
+ core_bentley_1.ITwinError.throwError({
98
+ iTwinErrorId: {
99
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
100
+ key: IModelTransformerError_1.IModelTransformerError.SchemaLoadFailed,
101
+ },
102
+ message: `Failed to load schema: ${schemaName}`,
103
+ });
121
104
  }
122
105
  await this.considerInitSchema(schema);
123
- const endTime = performance.now();
124
- core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Completed schema: ${schemaName} in ${(endTime - startTime).toFixed(2)}ms`);
125
- schemaCount++;
126
106
  }
127
- const initEndTime = performance.now();
128
- core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Completed ${schemaCount} schemas in ${(initEndTime - initStartTime).toFixed(2)}ms`);
129
107
  }
130
108
  async considerInitSchema(schema) {
131
109
  if (this._initedSchemas.has(schema.name)) {
132
110
  const cachedSchemaKey = this._initedSchemas.get(schema.name);
133
- assert(cachedSchemaKey !== undefined);
111
+ (0, node_assert_1.strict)(cachedSchemaKey !== undefined);
134
112
  const incomingSchemaIsEqualOrOlder = schema.schemaKey.compareByVersion(cachedSchemaKey) <= 0;
135
113
  if (incomingSchemaIsEqualOrOlder) {
136
114
  return;
@@ -139,73 +117,55 @@ class ECReferenceTypesCache {
139
117
  return this.initSchema(schema);
140
118
  }
141
119
  async initSchema(schema) {
142
- core_bentley_1.Logger.logInfo(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Init Schema: ${schema.name}`);
120
+ core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `initSchema started for ${schema.name}`);
143
121
  const schemaNameLower = schema.name.toLowerCase();
144
- // Pre-collect all items to reduce iterator overhead
145
- const allItems = Array.from(schema.getItems());
146
- const ecClasses = [];
147
- const relationshipClasses = [];
148
- // Single pass through items with type checking
149
- for (const item of allItems) {
150
- // eslint-disable-next-line @itwin/no-internal
151
- if (!ecschema_metadata_1.ECClass.isECClass(item))
152
- continue;
153
- ecClasses.push(item);
154
- if (item instanceof ecschema_metadata_1.RelationshipClass) {
155
- relationshipClasses.push(item);
122
+ // Local dedup map — scoped to this single initSchema call, not persisted
123
+ const localRelInfoMap = new Map();
124
+ const getRelInfo = async (relClass) => {
125
+ let promise = localRelInfoMap.get(relClass.fullName);
126
+ if (!promise) {
127
+ promise = this.relInfoFromRelClass(relClass);
128
+ localRelInfoMap.set(relClass.fullName, promise);
156
129
  }
157
- }
158
- // Process relationship classes in parallel and populate global cache
159
- const relInfoPromises = relationshipClasses.map(async (relClass) => {
160
- const relInfo = await this.relInfoFromRelClass(relClass);
161
- this._relationshipInfoCache.set(relClass.fullName, relInfo);
162
- if (relInfo) {
163
- this._relClassNameEndToRefTypes.set([schemaNameLower, relClass.name.toLowerCase()], relInfo);
130
+ return promise;
131
+ };
132
+ // Process all classes concurrently
133
+ const classPromises = Array.from(schema.getItems())
134
+ .filter((item) => ecschema_metadata_1.ECClass.isECClass(item))
135
+ .map(async (ecclass) => {
136
+ // Handle relationship end types
137
+ if (ecclass instanceof ecschema_metadata_1.RelationshipClass) {
138
+ const relInfo = await getRelInfo(ecclass);
139
+ if (relInfo) {
140
+ this._relClassNameEndToRefTypes.set([schemaNameLower, ecclass.name.toLowerCase()], relInfo);
141
+ }
164
142
  }
165
- return relInfo;
166
- });
167
- // Wait for all relationship info to be cached
168
- await Promise.all(relInfoPromises);
169
- // Process navigation properties with optimized batching
170
- const propertyBatchSize = 25;
171
- for (let i = 0; i < ecClasses.length; i += propertyBatchSize) {
172
- const classBatch = ecClasses.slice(i, i + propertyBatchSize);
173
- const classPromises = classBatch.map(async (ecclass) => {
174
- const properties = await ecclass.getProperties();
175
- if (!properties)
143
+ // Handle nav props
144
+ const properties = await ecclass.getProperties();
145
+ const classNameLower = ecclass.name.toLowerCase();
146
+ const navPropPromises = Array.from(properties)
147
+ .filter((prop) => prop.isNavigation())
148
+ .map(async (prop) => {
149
+ if (!prop.isNavigation())
176
150
  return;
177
- const classNameLower = ecclass.name.toLowerCase();
178
- // Efficiently filter navigation properties
179
- const navProps = Array.from(properties).filter((prop) => prop.isNavigation());
180
- if (navProps.length === 0)
151
+ const relClass = await prop.relationshipClass;
152
+ const relInfo = await getRelInfo(relClass);
153
+ if (relInfo === undefined)
181
154
  return;
182
- const navPropPromises = navProps.map(async (prop) => {
183
- const relClass = await prop.relationshipClass;
184
- // Use cached relation info
185
- let relInfo = this._relationshipInfoCache.get(relClass.fullName);
186
- if (relInfo === undefined &&
187
- !this._relationshipInfoCache.has(relClass.fullName)) {
188
- relInfo = await this.relInfoFromRelClass(relClass);
189
- this._relationshipInfoCache.set(relClass.fullName, relInfo);
190
- }
191
- if (relInfo === undefined)
192
- return;
193
- const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward
194
- ? // eslint-disable-next-line @itwin/no-internal
195
- relInfo.target
196
- : // eslint-disable-next-line @itwin/no-internal
197
- relInfo.source;
198
- this._propQualifierToRefType.set([schemaNameLower, classNameLower, prop.name.toLowerCase()], navPropRefType);
199
- });
200
- await Promise.all(navPropPromises);
155
+ const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward
156
+ ? relInfo.target
157
+ : relInfo.source;
158
+ this._propQualifierToRefType.set([schemaNameLower, classNameLower, prop.name.toLowerCase()], navPropRefType);
201
159
  });
202
- await Promise.all(classPromises);
203
- }
160
+ await Promise.all(navPropPromises);
161
+ });
162
+ await Promise.all(classPromises);
204
163
  this._initedSchemas.set(schema.name, schema.schemaKey);
164
+ core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `initSchema completed for ${schema.name}`);
205
165
  }
206
166
  async relInfoFromRelClass(ecclass) {
207
- assert(ecclass.source.constraintClasses !== undefined);
208
- assert(ecclass.target.constraintClasses !== undefined);
167
+ (0, node_assert_1.strict)(ecclass.source.constraintClasses !== undefined);
168
+ (0, node_assert_1.strict)(ecclass.target.constraintClasses !== undefined);
209
169
  const [[sourceClass, sourceRootBisClass], [targetClass, targetRootBisClass],] = await Promise.all([
210
170
  this.getAbstractConstraintClass(ecclass.source).then(async (constraintClass) => [
211
171
  constraintClass,
@@ -234,8 +194,8 @@ class ECReferenceTypesCache {
234
194
  `the nav prop reference type cache for ${cls.fullName}.`,
235
195
  "This is a bug.",
236
196
  ].join("\n");
237
- assert(sourceType !== undefined, makeAssertMsg(sourceRootBisClass, sourceClass));
238
- assert(targetType !== undefined, makeAssertMsg(targetRootBisClass, targetClass));
197
+ (0, node_assert_1.strict)(sourceType !== undefined, makeAssertMsg(sourceRootBisClass, sourceClass));
198
+ (0, node_assert_1.strict)(targetType !== undefined, makeAssertMsg(targetRootBisClass, targetClass));
239
199
  return { source: sourceType, target: targetType };
240
200
  }
241
201
  getNavPropRefType(schemaName, className, propName) {
@@ -255,14 +215,6 @@ class ECReferenceTypesCache {
255
215
  className.toLowerCase(),
256
216
  ]);
257
217
  }
258
- clear() {
259
- this._initedSchemas.clear();
260
- this._propQualifierToRefType.clear();
261
- this._relClassNameEndToRefTypes.clear();
262
- this._rootBisClassCache.clear();
263
- this._relationshipInfoCache.clear();
264
- this._constraintClassCache.clear();
265
- }
266
218
  }
267
219
  exports.ECReferenceTypesCache = ECReferenceTypesCache;
268
220
  //# sourceMappingURL=ECReferenceTypesCache.js.map
@@ -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 schemaCount = 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\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 -- ensure schema dependency order\n ORDER BY 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 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 throw new Error(`Failed to load schema: ${schemaName}`);\n }\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 schemaCount++;\n }\n\n const initEndTime = performance.now();\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Completed ${schemaCount} schemas 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 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 };\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"]}
@@ -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,56 @@
1
+ import { EditTxn, ElementAspect, IModelDb } from "@itwin/core-backend";
2
+ import { Id64String } from "@itwin/core-bentley";
3
+ /** Deletes replaceable ElementAspects of target owners that an owner batch did not reuse, while preserving excluded classes and aspects the caller protects, such as transformer provenance.
4
+ *
5
+ * Usage per owner batch: [[collect]] the aspects the owners have before import, let the importer [[retain]] each aspect it reuses or deletes itself, then [[deleteUnretained]] to delete the rest, or [[discard]] the batch if its export failed.
6
+ * While a batch is active, [[getAspects]] answers target aspect reads for its owners from the aspects loaded by [[collect]], so the importer doesn't query each owner separately.
7
+ * The importer brackets its own aspect writes with [[beforeWrite]] and [[afterWrite]]. If anything else writes to the target during the batch, including direct `EditTxn` calls, the loaded aspects are dropped and reads go to the target for the rest of the batch.
8
+ * @internal
9
+ */
10
+ export declare class ElementAspectCleanup {
11
+ private readonly _targetDb;
12
+ private readonly _editTxn;
13
+ private readonly _deleteAspect;
14
+ /** IDs of the batch owners' replaceable target aspects that the importer has not yet reused or deleted. [[collect]] fills it, [[retain]] removes from it, and [[deleteUnretained]] deletes what is left. */
15
+ private _candidateIds;
16
+ /** Every target aspect of each batch owner that has not been written since [[collect]], keyed by owner. */
17
+ private _aspectsByOwner;
18
+ /** The target connection's change count after [[collect]] or the importer's last write; undefined when no aspects are loaded. */
19
+ private _expectedChangeCount?;
20
+ constructor(_targetDb: IModelDb, _editTxn: EditTxn, _deleteAspect: (aspect: ElementAspect) => Promise<void>);
21
+ /** Records the replaceable unique and multi-aspects owned by the supplied target elements as deletion candidates, replacing any previous candidates.
22
+ * Aspects of excluded classes, and aspects for which `isProtected` returns true, are never candidates.
23
+ */
24
+ collect(targetElementIds: ReadonlySet<Id64String>, excludedElementAspectClassFullNames: ReadonlySet<string>, isProtected?: (aspect: ElementAspect) => boolean): Promise<void>;
25
+ /** Returns the owner's target aspects of exactly `classFullName`, or all of them when it is omitted, in ECInstanceId order, from the aspects loaded by [[collect]].
26
+ * Returns undefined when the owner is not in the active batch or has been written since [[collect]]; the caller must then read the target.
27
+ */
28
+ getAspects(elementId: Id64String, classFullName?: string): ElementAspect[] | undefined;
29
+ /** Call right before the importer writes an aspect of `elementId`. Later reads for that owner go to the target. */
30
+ beforeWrite(elementId: Id64String): void;
31
+ /** Call right after the importer's write so that it isn't mistaken for a write made elsewhere. */
32
+ afterWrite(): void;
33
+ /** Discards the batch without deleting anything. */
34
+ discard(): void;
35
+ /** Drops all loaded aspects if the target changed since [[collect]] or the importer's last write, which means code other than the importer wrote to it. */
36
+ private dropLoadedAspectsIfChangedElsewhere;
37
+ /** SQLite's count of rows inserted, updated, or deleted on the target connection since it opened. Reads don't change it. */
38
+ private targetChangeCount;
39
+ /** Removes an aspect from the deletion candidates because the importer reused or already deleted it. */
40
+ retain(aspectId: Id64String): void;
41
+ /** Deletes the remaining candidates through the configured callback and clears them.
42
+ * Requires the target `EditTxn` to be active when there is anything to delete.
43
+ */
44
+ deleteUnretained(): Promise<void>;
45
+ }
46
+ /** Whether an aspect is exactly of class `classFullName`, which may use either `:` or `.` as the separator.
47
+ * @internal
48
+ */
49
+ export declare function isSameClass(aspect: {
50
+ readonly classFullName: string;
51
+ }, classFullName: string): boolean;
52
+ /** Returns the aspect, or undefined if it no longer exists.
53
+ * @internal
54
+ */
55
+ export declare function tryGetAspect(db: IModelDb, aspectId: Id64String): ElementAspect | undefined;
56
+ //# 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,EAGb,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAgB,MAAM,qBAAqB,CAAC;AAG/D;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAS7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAVhC,4MAA4M;IAC5M,OAAO,CAAC,aAAa,CAAyB;IAC9C,2GAA2G;IAC3G,OAAO,CAAC,eAAe,CAA0C;IACjE,iIAAiI;IACjI,OAAO,CAAC,oBAAoB,CAAC,CAAS;IAEtC,YACmB,SAAS,EAAE,QAAQ,EACnB,QAAQ,EAAE,OAAO,EACjB,aAAa,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,EACtE;IAEJ;;OAEG;IACU,OAAO,CAClB,gBAAgB,EAAE,WAAW,CAAC,UAAU,CAAC,EACzC,mCAAmC,EAAE,WAAW,CAAC,MAAM,CAAC,EACxD,WAAW,GAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAqB,GAC5D,OAAO,CAAC,IAAI,CAAC,CA0Cf;IAED;;OAEG;IACI,UAAU,CACf,SAAS,EAAE,UAAU,EACrB,aAAa,CAAC,EAAE,MAAM,GACrB,aAAa,EAAE,GAAG,SAAS,CAK7B;IAED,mHAAmH;IAC5G,WAAW,CAAC,SAAS,EAAE,UAAU,GAAG,IAAI,CAG9C;IAED,kGAAkG;IAC3F,UAAU,IAAI,IAAI,CAGxB;IAED,oDAAoD;IAC7C,OAAO,IAAI,IAAI,CAIrB;IAED,2JAA2J;IAC3J,OAAO,CAAC,mCAAmC;IAU3C,4HAA4H;IAC5H,OAAO,CAAC,iBAAiB;IAUzB,wGAAwG;IACjG,MAAM,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI,CAExC;IAED;;OAEG;IACU,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgB7C;CACF;AAoBD;;GAEG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE;IAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE,EAC1C,aAAa,EAAE,MAAM,GACpB,OAAO,CAKT;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,EACZ,QAAQ,EAAE,UAAU,GACnB,aAAa,GAAG,SAAS,CAW3B"}