@itwin/imodel-transformer 2.0.0-dev.4 → 2.0.0-dev.40

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 (88) hide show
  1. package/README.md +12 -26
  2. package/lib/cjs/BranchProvenanceInitializer.d.ts.map +1 -1
  3. package/lib/cjs/BranchProvenanceInitializer.js +35 -30
  4. package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
  5. package/lib/cjs/ChangesetScanner.d.ts +60 -0
  6. package/lib/cjs/ChangesetScanner.d.ts.map +1 -0
  7. package/lib/cjs/ChangesetScanner.js +101 -0
  8. package/lib/cjs/ChangesetScanner.js.map +1 -0
  9. package/lib/cjs/ECReferenceTypesCache.d.ts +0 -3
  10. package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -1
  11. package/lib/cjs/ECReferenceTypesCache.js +61 -103
  12. package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
  13. package/lib/cjs/ElementAspectCleanup.d.ts +16 -0
  14. package/lib/cjs/ElementAspectCleanup.d.ts.map +1 -0
  15. package/lib/cjs/ElementAspectCleanup.js +83 -0
  16. package/lib/cjs/ElementAspectCleanup.js.map +1 -0
  17. package/lib/cjs/ElementAspectExportCoordinator.d.ts +44 -0
  18. package/lib/cjs/ElementAspectExportCoordinator.d.ts.map +1 -0
  19. package/lib/cjs/ElementAspectExportCoordinator.js +148 -0
  20. package/lib/cjs/ElementAspectExportCoordinator.js.map +1 -0
  21. package/lib/cjs/ElementAspectExportProcessor.d.ts +55 -0
  22. package/lib/cjs/ElementAspectExportProcessor.d.ts.map +1 -0
  23. package/lib/cjs/ElementAspectExportProcessor.js +186 -0
  24. package/lib/cjs/ElementAspectExportProcessor.js.map +1 -0
  25. package/lib/cjs/ElementCascadingDeleter.d.ts +3 -3
  26. package/lib/cjs/ElementCascadingDeleter.d.ts.map +1 -1
  27. package/lib/cjs/ElementCascadingDeleter.js +12 -12
  28. package/lib/cjs/ElementCascadingDeleter.js.map +1 -1
  29. package/lib/cjs/EntityUnifier.d.ts +4 -8
  30. package/lib/cjs/EntityUnifier.d.ts.map +1 -1
  31. package/lib/cjs/EntityUnifier.js +6 -24
  32. package/lib/cjs/EntityUnifier.js.map +1 -1
  33. package/lib/cjs/IModelCloneContext.d.ts +6 -5
  34. package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
  35. package/lib/cjs/IModelCloneContext.js +74 -57
  36. package/lib/cjs/IModelCloneContext.js.map +1 -1
  37. package/lib/cjs/IModelExporter.d.ts +80 -32
  38. package/lib/cjs/IModelExporter.d.ts.map +1 -1
  39. package/lib/cjs/IModelExporter.js +563 -188
  40. package/lib/cjs/IModelExporter.js.map +1 -1
  41. package/lib/cjs/IModelImporter.d.ts +38 -24
  42. package/lib/cjs/IModelImporter.d.ts.map +1 -1
  43. package/lib/cjs/IModelImporter.js +210 -129
  44. package/lib/cjs/IModelImporter.js.map +1 -1
  45. package/lib/cjs/IModelTransformContext.d.ts +54 -0
  46. package/lib/cjs/IModelTransformContext.d.ts.map +1 -0
  47. package/lib/cjs/IModelTransformContext.js +3 -0
  48. package/lib/cjs/IModelTransformContext.js.map +1 -0
  49. package/lib/cjs/IModelTransformer.d.ts +101 -189
  50. package/lib/cjs/IModelTransformer.d.ts.map +1 -1
  51. package/lib/cjs/IModelTransformer.js +558 -1104
  52. package/lib/cjs/IModelTransformer.js.map +1 -1
  53. package/lib/cjs/IModelTransformerError.d.ts +76 -0
  54. package/lib/cjs/IModelTransformerError.d.ts.map +1 -0
  55. package/lib/cjs/IModelTransformerError.js +85 -0
  56. package/lib/cjs/IModelTransformerError.js.map +1 -0
  57. package/lib/cjs/ProvenanceManager.d.ts +170 -0
  58. package/lib/cjs/ProvenanceManager.d.ts.map +1 -0
  59. package/lib/cjs/ProvenanceManager.js +735 -0
  60. package/lib/cjs/ProvenanceManager.js.map +1 -0
  61. package/lib/cjs/SyncTypeResolver.d.ts +34 -0
  62. package/lib/cjs/SyncTypeResolver.d.ts.map +1 -0
  63. package/lib/cjs/SyncTypeResolver.js +98 -0
  64. package/lib/cjs/SyncTypeResolver.js.map +1 -0
  65. package/lib/cjs/TransformerLoggerCategory.d.ts +1 -1
  66. package/lib/cjs/TransformerLoggerCategory.js +1 -1
  67. package/lib/cjs/TransformerLoggerCategory.js.map +1 -1
  68. package/lib/cjs/TransformerPackageMetadata.d.ts +8 -0
  69. package/lib/cjs/TransformerPackageMetadata.d.ts.map +1 -0
  70. package/lib/cjs/TransformerPackageMetadata.js +14 -0
  71. package/lib/cjs/TransformerPackageMetadata.js.map +1 -0
  72. package/lib/cjs/imodel-transformer.d.ts +18 -0
  73. package/lib/cjs/imodel-transformer.d.ts.map +1 -1
  74. package/lib/cjs/imodel-transformer.js +29 -33
  75. package/lib/cjs/imodel-transformer.js.map +1 -1
  76. package/package.json +27 -39
  77. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts +0 -16
  78. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +0 -1
  79. package/lib/cjs/DetachedExportElementAspectsStrategy.js +0 -106
  80. package/lib/cjs/DetachedExportElementAspectsStrategy.js.map +0 -1
  81. package/lib/cjs/ExportElementAspectsStrategy.d.ts +0 -35
  82. package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +0 -1
  83. package/lib/cjs/ExportElementAspectsStrategy.js +0 -52
  84. package/lib/cjs/ExportElementAspectsStrategy.js.map +0 -1
  85. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts +0 -12
  86. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts.map +0 -1
  87. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +0 -47
  88. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js.map +0 -1
@@ -0,0 +1,148 @@
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.ElementAspectExportCoordinator = void 0;
8
+ /** Coordinates scoped batches of accepted ElementAspect owners, including preparation before aspect export.
9
+ * @internal
10
+ */
11
+ class ElementAspectExportCoordinator {
12
+ _defaultBatchSize;
13
+ _excludedClassFullNames;
14
+ _exportAspects;
15
+ _resetCaches;
16
+ _acceptedOwnerIds = new Set();
17
+ _processedOwnerIds = new Set();
18
+ _batchSize;
19
+ _depth = 0;
20
+ _prepare;
21
+ constructor(_defaultBatchSize, _excludedClassFullNames, _exportAspects, _resetCaches = () => { }) {
22
+ this._defaultBatchSize = _defaultBatchSize;
23
+ this._excludedClassFullNames = _excludedClassFullNames;
24
+ this._exportAspects = _exportAspects;
25
+ this._resetCaches = _resetCaches;
26
+ this._batchSize = _defaultBatchSize;
27
+ }
28
+ /** Whether an accepted-owner collection scope is active. */
29
+ get isActive() {
30
+ return this._depth > 0;
31
+ }
32
+ /** Sets the callback that prepares each accepted-owner group before its aspects are exported. */
33
+ setPreparation(prepare) {
34
+ this._prepare = prepare;
35
+ }
36
+ /** Begins an accepted-owner collection scope.
37
+ * Nested scopes share the outer scope's state and batch size.
38
+ */
39
+ begin(batchSize = this._defaultBatchSize) {
40
+ if (this._depth === 0) {
41
+ this.resetScopeState();
42
+ this._resetCaches();
43
+ this._batchSize = batchSize;
44
+ }
45
+ this._depth++;
46
+ }
47
+ /** Ends an accepted-owner collection scope.
48
+ * Ending the outermost scope exports pending owners and resets all scope state.
49
+ */
50
+ async end() {
51
+ if (this._depth === 0) {
52
+ throw new Error("No scoped element export is active.");
53
+ }
54
+ this._depth--;
55
+ if (this._depth > 0)
56
+ return;
57
+ try {
58
+ if (this._acceptedOwnerIds.size > 0) {
59
+ await this.flush();
60
+ }
61
+ }
62
+ finally {
63
+ this.reset();
64
+ }
65
+ }
66
+ /** Discards the active scope and its pending owner state without exporting it. */
67
+ abort() {
68
+ this.reset();
69
+ }
70
+ /** Runs element export within an accepted-owner collection scope.
71
+ * A scope created by this call is aborted if element export fails; an existing outer scope remains responsible for its own failure handling.
72
+ */
73
+ async run(exportElements) {
74
+ if (this.isActive) {
75
+ await exportElements();
76
+ return;
77
+ }
78
+ this.begin();
79
+ try {
80
+ await exportElements();
81
+ }
82
+ catch (error) {
83
+ this.abort();
84
+ throw error;
85
+ }
86
+ await this.end();
87
+ }
88
+ /** Adds an accepted source owner to the current group and exports the group when it reaches the configured batch size. */
89
+ async addAcceptedOwner(elementId) {
90
+ if (!this.isActive || this._processedOwnerIds.has(elementId))
91
+ return;
92
+ this._acceptedOwnerIds.add(elementId);
93
+ if (this._acceptedOwnerIds.size >= this._batchSize) {
94
+ await this.flush();
95
+ }
96
+ }
97
+ /** Runs preparation and aspect export for an explicit owner set in bounded groups. */
98
+ async exportOwners(ownerElementIds) {
99
+ let ownerIds = ownerElementIds;
100
+ if (this.isActive && ownerElementIds.size > 0) {
101
+ const unprocessedOwnerIds = new Set();
102
+ for (const elementId of ownerElementIds) {
103
+ if (!this._processedOwnerIds.has(elementId)) {
104
+ unprocessedOwnerIds.add(elementId);
105
+ this._processedOwnerIds.add(elementId);
106
+ }
107
+ }
108
+ if (unprocessedOwnerIds.size === 0)
109
+ return;
110
+ ownerIds = unprocessedOwnerIds;
111
+ }
112
+ if (ownerIds.size <= this._defaultBatchSize) {
113
+ await this.exportOwnerBatch(ownerIds);
114
+ return;
115
+ }
116
+ let ownerBatch = new Set();
117
+ for (const elementId of ownerIds) {
118
+ ownerBatch.add(elementId);
119
+ if (ownerBatch.size === this._defaultBatchSize) {
120
+ await this.exportOwnerBatch(ownerBatch);
121
+ ownerBatch = new Set();
122
+ }
123
+ }
124
+ if (ownerBatch.size > 0) {
125
+ await this.exportOwnerBatch(ownerBatch);
126
+ }
127
+ }
128
+ async exportOwnerBatch(ownerElementIds) {
129
+ await this._prepare?.(this._excludedClassFullNames(), ownerElementIds);
130
+ await this._exportAspects(ownerElementIds);
131
+ }
132
+ async flush() {
133
+ const ownerElementIds = new Set(this._acceptedOwnerIds);
134
+ this._acceptedOwnerIds.clear();
135
+ await this.exportOwners(ownerElementIds);
136
+ }
137
+ resetScopeState() {
138
+ this._acceptedOwnerIds.clear();
139
+ this._processedOwnerIds.clear();
140
+ }
141
+ reset() {
142
+ this._depth = 0;
143
+ this.resetScopeState();
144
+ this._batchSize = this._defaultBatchSize;
145
+ }
146
+ }
147
+ exports.ElementAspectExportCoordinator = ElementAspectExportCoordinator;
148
+ //# sourceMappingURL=ElementAspectExportCoordinator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementAspectExportCoordinator.js","sourceRoot":"","sources":["../../src/ElementAspectExportCoordinator.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 { Id64String } from \"@itwin/core-bentley\";\n\nexport type ElementAspectExportPreparation = (\n excludedElementAspectClassFullNames: ReadonlySet<string>,\n ownerElementIds: ReadonlySet<Id64String>\n) => Promise<void>;\n\n/** Coordinates scoped batches of accepted ElementAspect owners, including preparation before aspect export.\n * @internal\n */\nexport class ElementAspectExportCoordinator {\n private readonly _acceptedOwnerIds = new Set<Id64String>();\n private readonly _processedOwnerIds = new Set<Id64String>();\n private _batchSize: number;\n private _depth = 0;\n private _prepare?: ElementAspectExportPreparation;\n\n public constructor(\n private readonly _defaultBatchSize: number,\n private readonly _excludedClassFullNames: () => ReadonlySet<string>,\n private readonly _exportAspects: (\n ownerElementIds: ReadonlySet<Id64String>\n ) => Promise<void>,\n private readonly _resetCaches: () => void = () => {}\n ) {\n this._batchSize = _defaultBatchSize;\n }\n\n /** Whether an accepted-owner collection scope is active. */\n public get isActive(): boolean {\n return this._depth > 0;\n }\n\n /** Sets the callback that prepares each accepted-owner group before its aspects are exported. */\n public setPreparation(prepare: ElementAspectExportPreparation): void {\n this._prepare = prepare;\n }\n\n /** Begins an accepted-owner collection scope.\n * Nested scopes share the outer scope's state and batch size.\n */\n public begin(batchSize = this._defaultBatchSize): void {\n if (this._depth === 0) {\n this.resetScopeState();\n this._resetCaches();\n this._batchSize = batchSize;\n }\n this._depth++;\n }\n\n /** Ends an accepted-owner collection scope.\n * Ending the outermost scope exports pending owners and resets all scope state.\n */\n public async end(): Promise<void> {\n if (this._depth === 0) {\n throw new Error(\"No scoped element export is active.\");\n }\n\n this._depth--;\n if (this._depth > 0) return;\n\n try {\n if (this._acceptedOwnerIds.size > 0) {\n await this.flush();\n }\n } finally {\n this.reset();\n }\n }\n\n /** Discards the active scope and its pending owner state without exporting it. */\n public abort(): void {\n this.reset();\n }\n\n /** Runs element export within an accepted-owner collection scope.\n * A scope created by this call is aborted if element export fails; an existing outer scope remains responsible for its own failure handling.\n */\n public async run(exportElements: () => Promise<void>): Promise<void> {\n if (this.isActive) {\n await exportElements();\n return;\n }\n\n this.begin();\n try {\n await exportElements();\n } catch (error) {\n this.abort();\n throw error;\n }\n await this.end();\n }\n\n /** Adds an accepted source owner to the current group and exports the group when it reaches the configured batch size. */\n public async addAcceptedOwner(elementId: Id64String): Promise<void> {\n if (!this.isActive || this._processedOwnerIds.has(elementId)) return;\n\n this._acceptedOwnerIds.add(elementId);\n if (this._acceptedOwnerIds.size >= this._batchSize) {\n await this.flush();\n }\n }\n\n /** Runs preparation and aspect export for an explicit owner set in bounded groups. */\n public async exportOwners(\n ownerElementIds: ReadonlySet<Id64String>\n ): Promise<void> {\n let ownerIds = ownerElementIds;\n if (this.isActive && ownerElementIds.size > 0) {\n const unprocessedOwnerIds = new Set<Id64String>();\n for (const elementId of ownerElementIds) {\n if (!this._processedOwnerIds.has(elementId)) {\n unprocessedOwnerIds.add(elementId);\n this._processedOwnerIds.add(elementId);\n }\n }\n if (unprocessedOwnerIds.size === 0) return;\n ownerIds = unprocessedOwnerIds;\n }\n\n if (ownerIds.size <= this._defaultBatchSize) {\n await this.exportOwnerBatch(ownerIds);\n return;\n }\n\n let ownerBatch = new Set<Id64String>();\n for (const elementId of ownerIds) {\n ownerBatch.add(elementId);\n if (ownerBatch.size === this._defaultBatchSize) {\n await this.exportOwnerBatch(ownerBatch);\n ownerBatch = new Set<Id64String>();\n }\n }\n if (ownerBatch.size > 0) {\n await this.exportOwnerBatch(ownerBatch);\n }\n }\n\n private async exportOwnerBatch(\n ownerElementIds: ReadonlySet<Id64String>\n ): Promise<void> {\n await this._prepare?.(this._excludedClassFullNames(), ownerElementIds);\n await this._exportAspects(ownerElementIds);\n }\n\n private async flush(): Promise<void> {\n const ownerElementIds = new Set(this._acceptedOwnerIds);\n this._acceptedOwnerIds.clear();\n await this.exportOwners(ownerElementIds);\n }\n\n private resetScopeState(): void {\n this._acceptedOwnerIds.clear();\n this._processedOwnerIds.clear();\n }\n\n private reset(): void {\n this._depth = 0;\n this.resetScopeState();\n this._batchSize = this._defaultBatchSize;\n }\n}\n"]}
@@ -0,0 +1,55 @@
1
+ import { ElementAspect, ElementMultiAspect, ElementUniqueAspect, IModelDb } from "@itwin/core-backend";
2
+ import { Id64String } from "@itwin/core-bentley";
3
+ interface AspectChanges {
4
+ readonly insertIds: ReadonlySet<Id64String>;
5
+ readonly updateIds: ReadonlySet<Id64String>;
6
+ }
7
+ export interface ElementAspectExportProcessorHandler {
8
+ shouldExportElementAspect(aspect: ElementAspect): Promise<boolean>;
9
+ onExportElementUniqueAspect(uniqueAspect: ElementUniqueAspect, isUpdate?: boolean | undefined): Promise<void>;
10
+ onExportElementMultiAspects(multiAspects: ElementMultiAspect[]): Promise<void>;
11
+ trackProgress: () => Promise<void>;
12
+ }
13
+ /** Queries and exports ElementAspects for accepted source owners, applying class and handler filters and grouping multi-aspects by owner.
14
+ * @internal
15
+ */
16
+ export declare class ElementAspectExportProcessor {
17
+ private readonly _aspectClasses;
18
+ /** ElementAspect classes excluded from source queries. */
19
+ private readonly _excludedElementAspectClassFullNames;
20
+ /** ECClassIds excluded from source queries: every excluded class plus all of its
21
+ * declared subclasses.
22
+ */
23
+ private _excludedClassIds;
24
+ private _aspectChanges;
25
+ /** ElementAspect class names excluded from source queries. */
26
+ get excludedElementAspectClassFullNames(): ReadonlySet<string>;
27
+ private readonly _sourceDb;
28
+ private readonly _handler;
29
+ constructor(sourceDb: IModelDb, handler: ElementAspectExportProcessorHandler);
30
+ /** Exports ElementAspects owned by the supplied elements.
31
+ * Multi-aspects are emitted in one callback group per owner.
32
+ */
33
+ exportAllElementAspects(ownerElementIds: ReadonlySet<Id64String>): Promise<void>;
34
+ /** Sets the aspect changes used to distinguish inserted and updated unique aspects during change export. */
35
+ setAspectChanges(aspectChanges?: AspectChanges): void;
36
+ /** Clears source schema and content caches at an outer export-scope boundary. */
37
+ resetCaches(): void;
38
+ /** Excludes an ElementAspect class from subsequent queries and export callbacks. */
39
+ excludeElementAspectClass(classFullName: string): void;
40
+ private exportAspectsLoop;
41
+ private queryAspects;
42
+ private getAspectClasses;
43
+ private queryAspectClasses;
44
+ private getExcludedClassIds;
45
+ /** Resolves every excluded class full name to the full set of ECClassIds it covers:
46
+ * the class itself plus every declared subclass. Reuses the same
47
+ * ECDbMeta.ClassHasAllBaseClasses shape as {@link queryAspectClasses}, rooted at
48
+ * each excluded class instead of at ElementUniqueAspect/ElementMultiAspect.
49
+ */
50
+ private queryExcludedClassIds;
51
+ /** Scans which concrete subclasses of the given base aspect class have rows for the supplied owners. */
52
+ private queryPopulatedAspectClassIds;
53
+ }
54
+ export {};
55
+ //# sourceMappingURL=ElementAspectExportProcessor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementAspectExportProcessor.d.ts","sourceRoot":"","sources":["../../src/ElementAspectExportProcessor.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAW,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAQ1D,UAAU,aAAa;IACrB,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,mCAAmC;IAClD,yBAAyB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnE,2BAA2B,CACzB,YAAY,EAAE,mBAAmB,EACjC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,GAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,2BAA2B,CACzB,YAAY,EAAE,kBAAkB,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,qBAAa,4BAA4B;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAG3B;IACJ,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,oCAAoC,CAAqB;IAC1E;;OAEG;IACH,OAAO,CAAC,iBAAiB,CAA+C;IACxE,OAAO,CAAC,cAAc,CAA4B;IAElD,8DAA8D;IAC9D,IAAW,mCAAmC,IAAI,WAAW,CAAC,MAAM,CAAC,CAEpE;IACD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;gBAG7D,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,mCAAmC;IAM9C;;OAEG;IACU,uBAAuB,CAClC,eAAe,EAAE,WAAW,CAAC,UAAU,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC;IAqChB,4GAA4G;IACrG,gBAAgB,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI;IAI5D,iFAAiF;IAC1E,WAAW,IAAI,IAAI;IAK1B,oFAAoF;IAC7E,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;YAK/C,iBAAiB;YAgBhB,YAAY;YAgDb,gBAAgB;YAahB,kBAAkB;YAqClB,mBAAmB;IAOjC;;;;OAIG;YACW,qBAAqB;IAsBnC,wGAAwG;YAC1F,4BAA4B;CAqB3C"}
@@ -0,0 +1,186 @@
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.ElementAspectExportProcessor = void 0;
8
+ const core_backend_1 = require("@itwin/core-backend");
9
+ const ECSqlReaderAsyncIterableIteratorAdapter_1 = require("./ECSqlReaderAsyncIterableIteratorAdapter");
10
+ const core_common_1 = require("@itwin/core-common");
11
+ /** Queries and exports ElementAspects for accepted source owners, applying class and handler filters and grouping multi-aspects by owner.
12
+ * @internal
13
+ */
14
+ class ElementAspectExportProcessor {
15
+ _aspectClasses = new Map();
16
+ /** ElementAspect classes excluded from source queries. */
17
+ _excludedElementAspectClassFullNames = new Set();
18
+ /** ECClassIds excluded from source queries: every excluded class plus all of its
19
+ * declared subclasses.
20
+ */
21
+ _excludedClassIds;
22
+ _aspectChanges;
23
+ /** ElementAspect class names excluded from source queries. */
24
+ get excludedElementAspectClassFullNames() {
25
+ return this._excludedElementAspectClassFullNames;
26
+ }
27
+ _sourceDb;
28
+ _handler;
29
+ constructor(sourceDb, handler) {
30
+ this._sourceDb = sourceDb;
31
+ this._handler = handler;
32
+ }
33
+ /** Exports ElementAspects owned by the supplied elements.
34
+ * Multi-aspects are emitted in one callback group per owner.
35
+ */
36
+ async exportAllElementAspects(ownerElementIds) {
37
+ if (ownerElementIds.size === 0)
38
+ return;
39
+ await this.exportAspectsLoop(core_backend_1.ElementUniqueAspect.classFullName, async (uniqueAspect) => {
40
+ const isUpdate = this._aspectChanges?.updateIds.has(uniqueAspect.id)
41
+ ? true
42
+ : this._aspectChanges?.insertIds.has(uniqueAspect.id)
43
+ ? false
44
+ : undefined;
45
+ await this._handler.onExportElementUniqueAspect(uniqueAspect, isUpdate);
46
+ await this._handler.trackProgress();
47
+ }, ownerElementIds);
48
+ const multiAspectsByOwner = new Map();
49
+ await this.exportAspectsLoop(core_backend_1.ElementMultiAspect.classFullName, async (multiAspect) => {
50
+ const ownerAspects = multiAspectsByOwner.get(multiAspect.element.id);
51
+ if (ownerAspects === undefined) {
52
+ multiAspectsByOwner.set(multiAspect.element.id, [multiAspect]);
53
+ }
54
+ else {
55
+ ownerAspects.push(multiAspect);
56
+ }
57
+ }, ownerElementIds);
58
+ for (const multiAspects of multiAspectsByOwner.values()) {
59
+ await this._handler.onExportElementMultiAspects(multiAspects);
60
+ await this._handler.trackProgress();
61
+ }
62
+ }
63
+ /** Sets the aspect changes used to distinguish inserted and updated unique aspects during change export. */
64
+ setAspectChanges(aspectChanges) {
65
+ this._aspectChanges = aspectChanges;
66
+ }
67
+ /** Clears source schema and content caches at an outer export-scope boundary. */
68
+ resetCaches() {
69
+ this._aspectClasses.clear();
70
+ this._excludedClassIds = undefined;
71
+ }
72
+ /** Excludes an ElementAspect class from subsequent queries and export callbacks. */
73
+ excludeElementAspectClass(classFullName) {
74
+ this._excludedElementAspectClassFullNames.add(classFullName);
75
+ this._excludedClassIds = undefined;
76
+ }
77
+ async exportAspectsLoop(baseAspectClass, exportAspect, ownerElementIds) {
78
+ for await (const aspect of this.queryAspects(baseAspectClass, ownerElementIds)) {
79
+ if (!(await this._handler.shouldExportElementAspect(aspect))) {
80
+ continue;
81
+ }
82
+ await exportAspect(aspect);
83
+ }
84
+ }
85
+ async *queryAspects(baseElementAspectClassFullName, ownerElementIds) {
86
+ const queryOwnerElementIds = new Set(ownerElementIds);
87
+ const populatedClassIds = await this.queryPopulatedAspectClassIds(baseElementAspectClassFullName, queryOwnerElementIds);
88
+ if (populatedClassIds.size === 0)
89
+ return;
90
+ const aspectClassNameIdMap = await this.getAspectClasses(baseElementAspectClassFullName);
91
+ const excludedClassIds = await this.getExcludedClassIds();
92
+ for (const [classId, { schemaName, className }] of aspectClassNameIdMap) {
93
+ // Skip classes with no rows in the current owner scope: most schemas declare
94
+ // far more concrete aspect subclasses than a batch actually populates.
95
+ if (!populatedClassIds.has(classId))
96
+ continue;
97
+ // excludedClassIds is the excluded class plus every declared subclass.
98
+ if (excludedClassIds.has(classId))
99
+ continue;
100
+ const classFullName = `${schemaName}:${className}`;
101
+ const queryParams = new core_common_1.QueryBinder()
102
+ .bindId("classId", classId)
103
+ .bindIdSet("ownerElementIds", queryOwnerElementIds);
104
+ const aspectQueryReader = this._sourceDb.createQueryReader(`SELECT aspect.* FROM [${schemaName}]:[${className}] aspect
105
+ INNER JOIN IdSet(:ownerElementIds) ids ON ids.id = aspect.Element.Id
106
+ WHERE aspect.ECClassId = :classId
107
+ ORDER BY aspect.Element.Id, aspect.ECInstanceId OPTIONS ENABLE_EXPERIMENTAL_FEATURES`, queryParams,
108
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
109
+ { rowFormat: core_common_1.QueryRowFormat.UseJsPropertyNames, usePrimaryConn: true });
110
+ for await (const rowProxy of (0, ECSqlReaderAsyncIterableIteratorAdapter_1.ensureECSqlReaderIsAsyncIterableIterator)(aspectQueryReader)) {
111
+ const { className: _className, ...aspectProps } = rowProxy.toRow();
112
+ aspectProps.classFullName = classFullName;
113
+ yield this._sourceDb.constructEntity(aspectProps);
114
+ }
115
+ }
116
+ }
117
+ async getAspectClasses(baseElementAspectClassFullName) {
118
+ let aspectClasses = this._aspectClasses.get(baseElementAspectClassFullName);
119
+ if (aspectClasses === undefined) {
120
+ aspectClasses = this.queryAspectClasses(baseElementAspectClassFullName);
121
+ this._aspectClasses.set(baseElementAspectClassFullName, aspectClasses);
122
+ }
123
+ return aspectClasses;
124
+ }
125
+ async queryAspectClasses(baseElementAspectClassFullName) {
126
+ const aspectClassNameIdMap = new Map();
127
+ const aspectClassesQueryReader = this._sourceDb.createQueryReader(`
128
+ SELECT c.ECInstanceId as classId,
129
+ (ec_className(c.ECInstanceId, 's')) as schemaName,
130
+ (ec_className(c.ECInstanceId, 'c')) as className
131
+ FROM ECDbMeta.ClassHasAllBaseClasses r
132
+ JOIN ECDbMeta.ECClassDef c ON c.ECInstanceId = r.SourceECInstanceId
133
+ WHERE r.TargetECInstanceId = ec_classId(:baseClassName)
134
+ ORDER BY schemaName, className
135
+ `, new core_common_1.QueryBinder().bindString("baseClassName", baseElementAspectClassFullName), { usePrimaryConn: true });
136
+ for await (const rowProxy of (0, ECSqlReaderAsyncIterableIteratorAdapter_1.ensureECSqlReaderIsAsyncIterableIterator)(aspectClassesQueryReader)) {
137
+ const row = rowProxy.toRow();
138
+ aspectClassNameIdMap.set(row.classId, {
139
+ schemaName: row.schemaName,
140
+ className: row.className,
141
+ });
142
+ }
143
+ return aspectClassNameIdMap;
144
+ }
145
+ async getExcludedClassIds() {
146
+ if (this._excludedClassIds === undefined) {
147
+ this._excludedClassIds = this.queryExcludedClassIds();
148
+ }
149
+ return this._excludedClassIds;
150
+ }
151
+ /** Resolves every excluded class full name to the full set of ECClassIds it covers:
152
+ * the class itself plus every declared subclass. Reuses the same
153
+ * ECDbMeta.ClassHasAllBaseClasses shape as {@link queryAspectClasses}, rooted at
154
+ * each excluded class instead of at ElementUniqueAspect/ElementMultiAspect.
155
+ */
156
+ async queryExcludedClassIds() {
157
+ const excludedClassIds = new Set();
158
+ for (const classFullName of this._excludedElementAspectClassFullNames) {
159
+ const excludedClassesQueryReader = this._sourceDb.createQueryReader(`
160
+ SELECT c.ECInstanceId as classId
161
+ FROM ECDbMeta.ClassHasAllBaseClasses r
162
+ JOIN ECDbMeta.ECClassDef c ON c.ECInstanceId = r.SourceECInstanceId
163
+ WHERE r.TargetECInstanceId = ec_classId(:excludedClassName)
164
+ `, new core_common_1.QueryBinder().bindString("excludedClassName", classFullName), { usePrimaryConn: true });
165
+ for await (const rowProxy of (0, ECSqlReaderAsyncIterableIteratorAdapter_1.ensureECSqlReaderIsAsyncIterableIterator)(excludedClassesQueryReader)) {
166
+ excludedClassIds.add(rowProxy.toRow().classId);
167
+ }
168
+ }
169
+ return excludedClassIds;
170
+ }
171
+ /** Scans which concrete subclasses of the given base aspect class have rows for the supplied owners. */
172
+ async queryPopulatedAspectClassIds(baseElementAspectClassFullName, ownerElementIds) {
173
+ const [schemaName, className] = baseElementAspectClassFullName.split(":");
174
+ const populatedClassIds = new Set();
175
+ const populatedClassesQueryReader = this._sourceDb.createQueryReader(`SELECT DISTINCT aspect.ECClassId as classId
176
+ FROM [${schemaName}]:[${className}] aspect
177
+ INNER JOIN IdSet(:ownerElementIds) ids ON ids.id = aspect.Element.Id
178
+ OPTIONS ENABLE_EXPERIMENTAL_FEATURES`, new core_common_1.QueryBinder().bindIdSet("ownerElementIds", ownerElementIds), { usePrimaryConn: true });
179
+ for await (const rowProxy of (0, ECSqlReaderAsyncIterableIteratorAdapter_1.ensureECSqlReaderIsAsyncIterableIterator)(populatedClassesQueryReader)) {
180
+ populatedClassIds.add(rowProxy.toRow().classId);
181
+ }
182
+ return populatedClassIds;
183
+ }
184
+ }
185
+ exports.ElementAspectExportProcessor = ElementAspectExportProcessor;
186
+ //# sourceMappingURL=ElementAspectExportProcessor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementAspectExportProcessor.js","sourceRoot":"","sources":["../../src/ElementAspectExportProcessor.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 ElementAspect,\n ElementMultiAspect,\n ElementUniqueAspect,\n IModelDb,\n} from \"@itwin/core-backend\";\nimport { Id64Set, Id64String } from \"@itwin/core-bentley\";\nimport { ensureECSqlReaderIsAsyncIterableIterator } from \"./ECSqlReaderAsyncIterableIteratorAdapter\";\nimport {\n ElementAspectProps,\n QueryBinder,\n QueryRowFormat,\n} from \"@itwin/core-common\";\n\ninterface AspectChanges {\n readonly insertIds: ReadonlySet<Id64String>;\n readonly updateIds: ReadonlySet<Id64String>;\n}\n\nexport interface ElementAspectExportProcessorHandler {\n shouldExportElementAspect(aspect: ElementAspect): Promise<boolean>;\n onExportElementUniqueAspect(\n uniqueAspect: ElementUniqueAspect,\n isUpdate?: boolean | undefined\n ): Promise<void>;\n onExportElementMultiAspects(\n multiAspects: ElementMultiAspect[]\n ): Promise<void>;\n trackProgress: () => Promise<void>;\n}\n\n/** Queries and exports ElementAspects for accepted source owners, applying class and handler filters and grouping multi-aspects by owner.\n * @internal\n */\nexport class ElementAspectExportProcessor {\n private readonly _aspectClasses = new Map<\n string,\n Promise<ReadonlyMap<Id64String, { schemaName: string; className: string }>>\n >();\n /** ElementAspect classes excluded from source queries. */\n private readonly _excludedElementAspectClassFullNames = new Set<string>();\n /** ECClassIds excluded from source queries: every excluded class plus all of its\n * declared subclasses.\n */\n private _excludedClassIds: Promise<ReadonlySet<Id64String>> | undefined;\n private _aspectChanges: AspectChanges | undefined;\n\n /** ElementAspect class names excluded from source queries. */\n public get excludedElementAspectClassFullNames(): ReadonlySet<string> {\n return this._excludedElementAspectClassFullNames;\n }\n private readonly _sourceDb: IModelDb;\n private readonly _handler: ElementAspectExportProcessorHandler;\n\n public constructor(\n sourceDb: IModelDb,\n handler: ElementAspectExportProcessorHandler\n ) {\n this._sourceDb = sourceDb;\n this._handler = handler;\n }\n\n /** Exports ElementAspects owned by the supplied elements.\n * Multi-aspects are emitted in one callback group per owner.\n */\n public async exportAllElementAspects(\n ownerElementIds: ReadonlySet<Id64String>\n ): Promise<void> {\n if (ownerElementIds.size === 0) return;\n\n await this.exportAspectsLoop<ElementUniqueAspect>(\n ElementUniqueAspect.classFullName,\n async (uniqueAspect) => {\n const isUpdate = this._aspectChanges?.updateIds.has(uniqueAspect.id)\n ? true\n : this._aspectChanges?.insertIds.has(uniqueAspect.id)\n ? false\n : undefined;\n await this._handler.onExportElementUniqueAspect(uniqueAspect, isUpdate);\n await this._handler.trackProgress();\n },\n ownerElementIds\n );\n\n const multiAspectsByOwner = new Map<Id64String, ElementMultiAspect[]>();\n await this.exportAspectsLoop<ElementMultiAspect>(\n ElementMultiAspect.classFullName,\n async (multiAspect) => {\n const ownerAspects = multiAspectsByOwner.get(multiAspect.element.id);\n if (ownerAspects === undefined) {\n multiAspectsByOwner.set(multiAspect.element.id, [multiAspect]);\n } else {\n ownerAspects.push(multiAspect);\n }\n },\n ownerElementIds\n );\n\n for (const multiAspects of multiAspectsByOwner.values()) {\n await this._handler.onExportElementMultiAspects(multiAspects);\n await this._handler.trackProgress();\n }\n }\n\n /** Sets the aspect changes used to distinguish inserted and updated unique aspects during change export. */\n public setAspectChanges(aspectChanges?: AspectChanges): void {\n this._aspectChanges = aspectChanges;\n }\n\n /** Clears source schema and content caches at an outer export-scope boundary. */\n public resetCaches(): void {\n this._aspectClasses.clear();\n this._excludedClassIds = undefined;\n }\n\n /** Excludes an ElementAspect class from subsequent queries and export callbacks. */\n public excludeElementAspectClass(classFullName: string): void {\n this._excludedElementAspectClassFullNames.add(classFullName);\n this._excludedClassIds = undefined;\n }\n\n private async exportAspectsLoop<T extends ElementAspect>(\n baseAspectClass: string,\n exportAspect: (aspect: T) => Promise<void>,\n ownerElementIds: ReadonlySet<Id64String>\n ): Promise<void> {\n for await (const aspect of this.queryAspects<T>(\n baseAspectClass,\n ownerElementIds\n )) {\n if (!(await this._handler.shouldExportElementAspect(aspect))) {\n continue;\n }\n await exportAspect(aspect);\n }\n }\n\n private async *queryAspects<T extends ElementAspect>(\n baseElementAspectClassFullName: string,\n ownerElementIds: ReadonlySet<Id64String>\n ) {\n const queryOwnerElementIds = new Set(ownerElementIds) as Id64Set;\n const populatedClassIds = await this.queryPopulatedAspectClassIds(\n baseElementAspectClassFullName,\n queryOwnerElementIds\n );\n if (populatedClassIds.size === 0) return;\n\n const aspectClassNameIdMap = await this.getAspectClasses(\n baseElementAspectClassFullName\n );\n const excludedClassIds = await this.getExcludedClassIds();\n for (const [classId, { schemaName, className }] of aspectClassNameIdMap) {\n // Skip classes with no rows in the current owner scope: most schemas declare\n // far more concrete aspect subclasses than a batch actually populates.\n if (!populatedClassIds.has(classId)) continue;\n // excludedClassIds is the excluded class plus every declared subclass.\n if (excludedClassIds.has(classId)) continue;\n\n const classFullName = `${schemaName}:${className}`;\n const queryParams = new QueryBinder()\n .bindId(\"classId\", classId)\n .bindIdSet(\"ownerElementIds\", queryOwnerElementIds);\n const aspectQueryReader = this._sourceDb.createQueryReader(\n `SELECT aspect.* FROM [${schemaName}]:[${className}] aspect\n INNER JOIN IdSet(:ownerElementIds) ids ON ids.id = aspect.Element.Id\n WHERE aspect.ECClassId = :classId\n ORDER BY aspect.Element.Id, aspect.ECInstanceId OPTIONS ENABLE_EXPERIMENTAL_FEATURES`,\n queryParams,\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n { rowFormat: QueryRowFormat.UseJsPropertyNames, usePrimaryConn: true }\n );\n for await (const rowProxy of ensureECSqlReaderIsAsyncIterableIterator(\n aspectQueryReader\n )) {\n const { className: _className, ...aspectProps } =\n rowProxy.toRow() as ElementAspectProps & {\n className?: string;\n };\n aspectProps.classFullName = classFullName;\n yield this._sourceDb.constructEntity<T>(aspectProps);\n }\n }\n }\n\n private async getAspectClasses(\n baseElementAspectClassFullName: string\n ): Promise<\n ReadonlyMap<Id64String, { schemaName: string; className: string }>\n > {\n let aspectClasses = this._aspectClasses.get(baseElementAspectClassFullName);\n if (aspectClasses === undefined) {\n aspectClasses = this.queryAspectClasses(baseElementAspectClassFullName);\n this._aspectClasses.set(baseElementAspectClassFullName, aspectClasses);\n }\n return aspectClasses;\n }\n\n private async queryAspectClasses(\n baseElementAspectClassFullName: string\n ): Promise<\n ReadonlyMap<Id64String, { schemaName: string; className: string }>\n > {\n const aspectClassNameIdMap = new Map<\n Id64String,\n { schemaName: string; className: string }\n >();\n const aspectClassesQueryReader = this._sourceDb.createQueryReader(\n `\n SELECT c.ECInstanceId as classId,\n (ec_className(c.ECInstanceId, 's')) as schemaName,\n (ec_className(c.ECInstanceId, 'c')) as className\n FROM ECDbMeta.ClassHasAllBaseClasses r\n JOIN ECDbMeta.ECClassDef c ON c.ECInstanceId = r.SourceECInstanceId\n WHERE r.TargetECInstanceId = ec_classId(:baseClassName)\n ORDER BY schemaName, className\n `,\n new QueryBinder().bindString(\n \"baseClassName\",\n baseElementAspectClassFullName\n ),\n { usePrimaryConn: true }\n );\n for await (const rowProxy of ensureECSqlReaderIsAsyncIterableIterator(\n aspectClassesQueryReader\n )) {\n const row = rowProxy.toRow();\n aspectClassNameIdMap.set(row.classId, {\n schemaName: row.schemaName,\n className: row.className,\n });\n }\n return aspectClassNameIdMap;\n }\n\n private async getExcludedClassIds(): Promise<ReadonlySet<Id64String>> {\n if (this._excludedClassIds === undefined) {\n this._excludedClassIds = this.queryExcludedClassIds();\n }\n return this._excludedClassIds;\n }\n\n /** Resolves every excluded class full name to the full set of ECClassIds it covers:\n * the class itself plus every declared subclass. Reuses the same\n * ECDbMeta.ClassHasAllBaseClasses shape as {@link queryAspectClasses}, rooted at\n * each excluded class instead of at ElementUniqueAspect/ElementMultiAspect.\n */\n private async queryExcludedClassIds(): Promise<ReadonlySet<Id64String>> {\n const excludedClassIds = new Set<Id64String>();\n for (const classFullName of this._excludedElementAspectClassFullNames) {\n const excludedClassesQueryReader = this._sourceDb.createQueryReader(\n `\n SELECT c.ECInstanceId as classId\n FROM ECDbMeta.ClassHasAllBaseClasses r\n JOIN ECDbMeta.ECClassDef c ON c.ECInstanceId = r.SourceECInstanceId\n WHERE r.TargetECInstanceId = ec_classId(:excludedClassName)\n `,\n new QueryBinder().bindString(\"excludedClassName\", classFullName),\n { usePrimaryConn: true }\n );\n for await (const rowProxy of ensureECSqlReaderIsAsyncIterableIterator(\n excludedClassesQueryReader\n )) {\n excludedClassIds.add(rowProxy.toRow().classId);\n }\n }\n return excludedClassIds;\n }\n\n /** Scans which concrete subclasses of the given base aspect class have rows for the supplied owners. */\n private async queryPopulatedAspectClassIds(\n baseElementAspectClassFullName: string,\n ownerElementIds: Id64Set\n ): Promise<ReadonlySet<Id64String>> {\n const [schemaName, className] = baseElementAspectClassFullName.split(\":\");\n const populatedClassIds = new Set<Id64String>();\n const populatedClassesQueryReader = this._sourceDb.createQueryReader(\n `SELECT DISTINCT aspect.ECClassId as classId\n FROM [${schemaName}]:[${className}] aspect\n INNER JOIN IdSet(:ownerElementIds) ids ON ids.id = aspect.Element.Id\n OPTIONS ENABLE_EXPERIMENTAL_FEATURES`,\n new QueryBinder().bindIdSet(\"ownerElementIds\", ownerElementIds),\n { usePrimaryConn: true }\n );\n for await (const rowProxy of ensureECSqlReaderIsAsyncIterableIterator(\n populatedClassesQueryReader\n )) {\n populatedClassIds.add(rowProxy.toRow().classId);\n }\n return populatedClassIds;\n }\n}\n"]}
@@ -1,13 +1,13 @@
1
1
  /** @packageDocumentation
2
2
  * @module iModels
3
3
  */
4
- import { ElementTreeDeleter, ElementTreeWalkerScope, IModelDb } from "@itwin/core-backend";
4
+ import { EditTxn, ElementTreeDeleter, ElementTreeWalkerScope } from "@itwin/core-backend";
5
5
  import { Id64String } from "@itwin/core-bentley";
6
6
  /** Deletes an element tree and code scope references starting with the specified top element. The top element is also deleted. Uses ElementCascadeDeleter.
7
- * @param iModel The iModel
7
+ * @param editTxn The active EditTxn for the iModel
8
8
  * @param topElement The parent of the sub-tree
9
9
  */
10
- export declare function deleteElementTreeCascade(iModel: IModelDb, topElement: Id64String): void;
10
+ export declare function deleteElementTreeCascade(editTxn: EditTxn, topElement: Id64String): void;
11
11
  /** Deletes an entire element tree, including sub-models, child elements and code scope references.
12
12
  * Items are deleted in bottom-up order. Definitions and Subjects are deleted after normal elements.
13
13
  * Call deleteNormalElements on each tree. Then call deleteSpecialElements.
@@ -1 +1 @@
1
- {"version":3,"file":"ElementCascadingDeleter.d.ts","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAY,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,QAAQ,EAChB,UAAU,EAAE,UAAU,GACrB,IAAI,CAIN;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,kBAAkB;IAC7D,SAAS,CAAC,qBAAqB,CAC7B,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,sBAAsB;IAKhC,qCAAqC;cAClB,kBAAkB,CACnC,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,sBAAsB,GAC5B,IAAI;IAMP,oCAAoC;IACpC,OAAO,CAAC,kBAAkB;CAsB3B"}
1
+ {"version":3,"file":"ElementCascadingDeleter.d.ts","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,OAAO,EACL,OAAO,EACP,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,GACrB,IAAI,CAIN;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,kBAAkB;IAC7D,SAAS,CAAC,qBAAqB,CAC7B,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,sBAAsB;IAKhC,qCAAqC;cAClB,kBAAkB,CACnC,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,sBAAsB,GAC5B,IAAI;IAMP,oCAAoC;IACpC,OAAO,CAAC,kBAAkB;CAyB3B"}
@@ -10,13 +10,13 @@ exports.deleteElementTreeCascade = deleteElementTreeCascade;
10
10
  * @module iModels
11
11
  */
12
12
  const core_backend_1 = require("@itwin/core-backend");
13
- const core_bentley_1 = require("@itwin/core-bentley");
13
+ const core_common_1 = require("@itwin/core-common");
14
14
  /** Deletes an element tree and code scope references starting with the specified top element. The top element is also deleted. Uses ElementCascadeDeleter.
15
- * @param iModel The iModel
15
+ * @param editTxn The active EditTxn for the iModel
16
16
  * @param topElement The parent of the sub-tree
17
17
  */
18
- function deleteElementTreeCascade(iModel, topElement) {
19
- const del = new ElementCascadingDeleter(iModel);
18
+ function deleteElementTreeCascade(editTxn, topElement) {
19
+ const del = new ElementCascadingDeleter(editTxn);
20
20
  del.deleteNormalElements(topElement);
21
21
  del.deleteSpecialElements();
22
22
  }
@@ -38,19 +38,19 @@ class ElementCascadingDeleter extends core_backend_1.ElementTreeDeleter {
38
38
  /** Process code scope references */
39
39
  _processCodeScopes(element, scope) {
40
40
  const newScope = new core_backend_1.ElementTreeWalkerScope(scope, element);
41
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
42
- this._iModel.withPreparedStatement(`
41
+ const query = `
43
42
  SELECT ECInstanceId
44
43
  FROM bis.Element
45
- WHERE CodeScope.id=?
44
+ WHERE CodeScope.id=:scopeId
46
45
  AND Parent.id IS NULL
47
- `, (stmt) => {
48
- stmt.bindId(1, element);
49
- while (stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW) {
50
- const elementId = stmt.getValue(0).getId();
46
+ `;
47
+ const params = new core_common_1.QueryBinder().bindId("scopeId", element);
48
+ this.txn.iModel.withQueryReader(query, (reader) => {
49
+ for (const row of reader) {
50
+ const elementId = row[0];
51
51
  this.processElementTree(elementId, newScope);
52
52
  }
53
- });
53
+ }, params);
54
54
  }
55
55
  }
56
56
  exports.ElementCascadingDeleter = ElementCascadingDeleter;
@@ -1 +1 @@
1
- {"version":3,"file":"ElementCascadingDeleter.js","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":";;;AAkBA,4DAOC;AAzBD;;;gGAGgG;AAChG;;GAEG;AACH,sDAI6B;AAC7B,sDAA2D;AAE3D;;;GAGG;AACH,SAAgB,wBAAwB,CACtC,MAAgB,EAChB,UAAsB;IAEtB,MAAM,GAAG,GAAG,IAAI,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChD,GAAG,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACrC,GAAG,CAAC,qBAAqB,EAAE,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAa,uBAAwB,SAAQ,iCAAkB;IACnD,qBAAqB,CAC7B,UAAsB,EACtB,MAA8B;QAE9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IAClB,kBAAkB,CACnC,OAAmB,EACnB,KAA6B;QAE7B,IAAI,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IACD,oCAAoC;IAC5B,kBAAkB,CACxB,OAAmB,EACnB,KAA6B;QAE7B,MAAM,QAAQ,GAAG,IAAI,qCAAsB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5D,gFAAgF;QAChF,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAChC;;;;;KAKD,EACC,CAAC,IAAI,EAAE,EAAE;YACP,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACxB,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,uBAAQ,CAAC,aAAa,EAAE,CAAC;gBAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;gBAC3C,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;CACF;AAzCD,0DAyCC","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 */\nimport {\n ElementTreeDeleter,\n ElementTreeWalkerScope,\n IModelDb,\n} from \"@itwin/core-backend\";\nimport { DbResult, Id64String } from \"@itwin/core-bentley\";\n\n/** Deletes an element tree and code scope references starting with the specified top element. The top element is also deleted. Uses ElementCascadeDeleter.\n * @param iModel The iModel\n * @param topElement The parent of the sub-tree\n */\nexport function deleteElementTreeCascade(\n iModel: IModelDb,\n topElement: Id64String\n): void {\n const del = new ElementCascadingDeleter(iModel);\n del.deleteNormalElements(topElement);\n del.deleteSpecialElements();\n}\n\n/** Deletes an entire element tree, including sub-models, child elements and code scope references.\n * Items are deleted in bottom-up order. Definitions and Subjects are deleted after normal elements.\n * Call deleteNormalElements on each tree. Then call deleteSpecialElements.\n */\nexport class ElementCascadingDeleter extends ElementTreeDeleter {\n protected shouldVisitCodeScopes(\n _elementId: Id64String,\n _scope: ElementTreeWalkerScope\n ) {\n return true;\n }\n\n /** The main tree-walking function */\n protected override processElementTree(\n element: Id64String,\n scope: ElementTreeWalkerScope\n ): void {\n if (this.shouldVisitCodeScopes(element, scope)) {\n this._processCodeScopes(element, scope);\n }\n super.processElementTree(element, scope);\n }\n /** Process code scope references */\n private _processCodeScopes(\n element: Id64String,\n scope: ElementTreeWalkerScope\n ) {\n const newScope = new ElementTreeWalkerScope(scope, element);\n // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated\n this._iModel.withPreparedStatement(\n `\n SELECT ECInstanceId\n FROM bis.Element\n WHERE CodeScope.id=?\n AND Parent.id IS NULL\n `,\n (stmt) => {\n stmt.bindId(1, element);\n while (stmt.step() === DbResult.BE_SQLITE_ROW) {\n const elementId = stmt.getValue(0).getId();\n this.processElementTree(elementId, newScope);\n }\n }\n );\n }\n}\n"]}
1
+ {"version":3,"file":"ElementCascadingDeleter.js","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":";;;AAmBA,4DAOC;AA1BD;;;gGAGgG;AAChG;;GAEG;AACH,sDAI6B;AAE7B,oDAAiD;AAEjD;;;GAGG;AACH,SAAgB,wBAAwB,CACtC,OAAgB,EAChB,UAAsB;IAEtB,MAAM,GAAG,GAAG,IAAI,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjD,GAAG,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACrC,GAAG,CAAC,qBAAqB,EAAE,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAa,uBAAwB,SAAQ,iCAAkB;IACnD,qBAAqB,CAC7B,UAAsB,EACtB,MAA8B;QAE9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IAClB,kBAAkB,CACnC,OAAmB,EACnB,KAA6B;QAE7B,IAAI,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IACD,oCAAoC;IAC5B,kBAAkB,CACxB,OAAmB,EACnB,KAA6B;QAE7B,MAAM,QAAQ,GAAG,IAAI,qCAAsB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG;;;;;KAKb,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,yBAAW,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAE5D,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAC7B,KAAK,EACL,CAAC,MAAM,EAAE,EAAE;YACT,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;gBACzB,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,CAAe,CAAC;gBACvC,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC,EACD,MAAM,CACP,CAAC;IACJ,CAAC;CACF;AA5CD,0DA4CC","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 */\nimport {\n EditTxn,\n ElementTreeDeleter,\n ElementTreeWalkerScope,\n} from \"@itwin/core-backend\";\nimport { Id64String } from \"@itwin/core-bentley\";\nimport { QueryBinder } from \"@itwin/core-common\";\n\n/** Deletes an element tree and code scope references starting with the specified top element. The top element is also deleted. Uses ElementCascadeDeleter.\n * @param editTxn The active EditTxn for the iModel\n * @param topElement The parent of the sub-tree\n */\nexport function deleteElementTreeCascade(\n editTxn: EditTxn,\n topElement: Id64String\n): void {\n const del = new ElementCascadingDeleter(editTxn);\n del.deleteNormalElements(topElement);\n del.deleteSpecialElements();\n}\n\n/** Deletes an entire element tree, including sub-models, child elements and code scope references.\n * Items are deleted in bottom-up order. Definitions and Subjects are deleted after normal elements.\n * Call deleteNormalElements on each tree. Then call deleteSpecialElements.\n */\nexport class ElementCascadingDeleter extends ElementTreeDeleter {\n protected shouldVisitCodeScopes(\n _elementId: Id64String,\n _scope: ElementTreeWalkerScope\n ) {\n return true;\n }\n\n /** The main tree-walking function */\n protected override processElementTree(\n element: Id64String,\n scope: ElementTreeWalkerScope\n ): void {\n if (this.shouldVisitCodeScopes(element, scope)) {\n this._processCodeScopes(element, scope);\n }\n super.processElementTree(element, scope);\n }\n /** Process code scope references */\n private _processCodeScopes(\n element: Id64String,\n scope: ElementTreeWalkerScope\n ) {\n const newScope = new ElementTreeWalkerScope(scope, element);\n const query = `\n SELECT ECInstanceId\n FROM bis.Element\n WHERE CodeScope.id=:scopeId\n AND Parent.id IS NULL\n `;\n\n const params = new QueryBinder().bindId(\"scopeId\", element);\n\n this.txn.iModel.withQueryReader(\n query,\n (reader) => {\n for (const row of reader) {\n const elementId = row[0] as Id64String;\n this.processElementTree(elementId, newScope);\n }\n },\n params\n );\n }\n}\n"]}
@@ -4,18 +4,14 @@
4
4
  * for entity-generic operations in the transformer
5
5
  */
6
6
  import { EntityReference } from "@itwin/core-common";
7
- import { ConcreteEntity, ConcreteEntityProps, IModelDb } from "@itwin/core-backend";
7
+ import { ConcreteEntity, IModelDb } from "@itwin/core-backend";
8
8
  /** @internal */
9
9
  export declare namespace EntityUnifier {
10
- export function getReadableType(entity: ConcreteEntity): "element" | "element aspect" | "relationship" | "unknown entity type";
11
- type EntityUpdater = (entityProps: ConcreteEntityProps) => void;
12
- /** needs to return a widened type otherwise typescript complains when result is used with a narrow type */
13
- export function updaterFor(db: IModelDb, entity: ConcreteEntity): EntityUpdater;
14
- export function exists(db: IModelDb, arg: {
10
+ function getReadableType(entity: ConcreteEntity): "element" | "element aspect" | "relationship" | "unknown entity type";
11
+ function exists(db: IModelDb, arg: {
15
12
  entity: ConcreteEntity;
16
13
  } | {
17
14
  entityReference: EntityReference;
18
- }): boolean;
19
- export {};
15
+ }): Promise<boolean>;
20
16
  }
21
17
  //# sourceMappingURL=EntityUnifier.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EntityUnifier.d.ts","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAGH,OAAO,EAEL,eAAe,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,mBAAmB,EAKnB,QAAQ,EAET,MAAM,qBAAqB,CAAC;AAG7B,gBAAgB;AAChB,yBAAiB,aAAa,CAAC;IAC7B,MAAM,UAAU,eAAe,CAAC,MAAM,EAAE,cAAc,yEAKrD;IAED,KAAK,aAAa,GAAG,CAAC,WAAW,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAEhE,2GAA2G;IAC3G,MAAM,UAAU,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,iBAc9D;IAED,MAAM,UAAU,MAAM,CACpB,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE;QAAE,MAAM,EAAE,cAAc,CAAA;KAAE,GAAG;QAAE,eAAe,EAAE,eAAe,CAAA;KAAE,WAyBvE;;CACF"}
1
+ {"version":3,"file":"EntityUnifier.d.ts","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,EAEL,eAAe,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EAKd,QAAQ,EAET,MAAM,qBAAqB,CAAC;AAG7B,gBAAgB;AAChB,yBAAiB,aAAa,CAAC;IAC7B,SAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,yEAKrD;IAED,SAAsB,MAAM,CAC1B,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE;QAAE,MAAM,EAAE,cAAc,CAAA;KAAE,GAAG;QAAE,eAAe,EAAE,eAAe,CAAA;KAAE,oBAoBvE;CACF"}
@@ -10,7 +10,6 @@
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.EntityUnifier = void 0;
13
- const assert = require("assert");
14
13
  const core_common_1 = require("@itwin/core-common");
15
14
  const core_backend_1 = require("@itwin/core-backend");
16
15
  const core_bentley_1 = require("@itwin/core-bentley");
@@ -28,19 +27,7 @@ var EntityUnifier;
28
27
  return "unknown entity type";
29
28
  }
30
29
  EntityUnifier.getReadableType = getReadableType;
31
- /** needs to return a widened type otherwise typescript complains when result is used with a narrow type */
32
- function updaterFor(db, entity) {
33
- if (entity instanceof core_backend_1.Element)
34
- return db.elements.updateElement.bind(db.elements);
35
- else if (entity instanceof core_backend_1.Relationship)
36
- return db.relationships.updateInstance.bind(db.relationships);
37
- else if (entity instanceof core_backend_1.ElementAspect)
38
- return db.elements.updateAspect.bind(db.elements);
39
- else
40
- assert(false, `unreachable; entity was '${entity.constructor.name}' not an Element, Relationship, or ElementAspect`);
41
- }
42
- EntityUnifier.updaterFor = updaterFor;
43
- function exists(db, arg) {
30
+ async function exists(db, arg) {
44
31
  const [type, id] = "entityReference" in arg
45
32
  ? core_backend_1.EntityReferences.split(arg.entityReference)
46
33
  : [undefined, arg.entity.id];
@@ -50,17 +37,12 @@ var EntityUnifier;
50
37
  : `[${arg.entity.schemaName}].[${arg.entity.className}]`;
51
38
  if (id === undefined || core_bentley_1.Id64.isInvalid(id))
52
39
  return false;
53
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
54
- return db.withPreparedStatement(`SELECT 1 FROM ${classFullName} WHERE ECInstanceId=?`, (stmt) => {
55
- stmt.bindId(1, id);
56
- const matchesResult = stmt.step();
57
- if (matchesResult === core_bentley_1.DbResult.BE_SQLITE_ROW)
58
- return true;
59
- if (matchesResult === core_bentley_1.DbResult.BE_SQLITE_DONE)
60
- return false;
61
- else
62
- throw new core_common_1.IModelError(matchesResult, "query failed");
40
+ const query = `SELECT 1 FROM ${classFullName} WHERE ECInstanceId=:id`;
41
+ const params = new core_common_1.QueryBinder().bindId("id", id);
42
+ const reader = db.createQueryReader(query, params, {
43
+ usePrimaryConn: true,
63
44
  });
45
+ return reader.step();
64
46
  }
65
47
  EntityUnifier.exists = exists;
66
48
  })(EntityUnifier || (exports.EntityUnifier = EntityUnifier = {}));