@itwin/imodel-transformer 2.0.0-dev.74 → 2.0.0-dev.76
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.
- package/lib/ElementAspectExportCoordinator.d.ts +17 -2
- package/lib/ElementAspectExportCoordinator.d.ts.map +1 -1
- package/lib/ElementAspectExportCoordinator.js +34 -7
- package/lib/ElementAspectExportCoordinator.js.map +1 -1
- package/lib/EntityExistenceCache.d.ts +14 -1
- package/lib/EntityExistenceCache.d.ts.map +1 -1
- package/lib/EntityExistenceCache.js +30 -13
- package/lib/EntityExistenceCache.js.map +1 -1
- package/lib/IModelExporter.d.ts.map +1 -1
- package/lib/IModelExporter.js +5 -3
- package/lib/IModelExporter.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { Id64String } from "@itwin/core-bentley";
|
|
2
2
|
export type ElementAspectExportPreparation = (excludedElementAspectClassFullNames: ReadonlySet<string>, ownerElementIds: ReadonlySet<Id64String>) => Promise<void>;
|
|
3
3
|
/** Coordinates scoped batches of accepted ElementAspect owners, including preparation before aspect export.
|
|
4
|
+
*
|
|
5
|
+
* Owner deduplication within a scope is bounded: the main element traversal visits each element once, so its owners
|
|
6
|
+
* are not remembered. Only owners exported out of order are remembered: those accepted while a handler callback
|
|
7
|
+
* is running (see [[runHandlerCallback]]), such as required references that `IModelTransformer.preExportElement`
|
|
8
|
+
* exports early, and owners passed explicitly to [[exportOwners]]. When the traversal reaches such an owner again,
|
|
9
|
+
* its aspects are not exported a second time. An owner that the traversal finished before a handler callback
|
|
10
|
+
* re-exports it does have its aspects exported again.
|
|
4
11
|
* @internal
|
|
5
12
|
*/
|
|
6
13
|
export declare class ElementAspectExportCoordinator {
|
|
@@ -9,9 +16,10 @@ export declare class ElementAspectExportCoordinator {
|
|
|
9
16
|
private readonly _exportAspects;
|
|
10
17
|
private readonly _resetCaches;
|
|
11
18
|
private readonly _acceptedOwnerIds;
|
|
12
|
-
private readonly
|
|
19
|
+
private readonly _outOfOrderOwnerIds;
|
|
13
20
|
private _batchSize;
|
|
14
21
|
private _depth;
|
|
22
|
+
private _handlerCallbackDepth;
|
|
15
23
|
private _prepare?;
|
|
16
24
|
constructor(_defaultBatchSize: number, _excludedClassFullNames: () => ReadonlySet<string>, _exportAspects: (ownerElementIds: ReadonlySet<Id64String>) => Promise<void>, _resetCaches?: () => void);
|
|
17
25
|
/** Whether an accepted-owner collection scope is active. */
|
|
@@ -32,10 +40,17 @@ export declare class ElementAspectExportCoordinator {
|
|
|
32
40
|
* A scope created by this call is aborted if element export fails; an existing outer scope remains responsible for its own failure handling.
|
|
33
41
|
*/
|
|
34
42
|
run(exportElements: () => Promise<void>): Promise<void>;
|
|
43
|
+
/** Runs an export handler callback. Owners accepted while it runs were exported out of traversal order
|
|
44
|
+
* (e.g. a required reference exported by the callback), so they are remembered for the rest of the scope.
|
|
45
|
+
*/
|
|
46
|
+
runHandlerCallback<T>(callback: () => Promise<T>): Promise<T>;
|
|
35
47
|
/** Adds an accepted source owner to the current group and exports the group when it reaches the configured batch size. */
|
|
36
48
|
addAcceptedOwner(elementId: Id64String): Promise<void>;
|
|
37
|
-
/** Runs preparation and aspect export for an explicit owner set in bounded groups.
|
|
49
|
+
/** Runs preparation and aspect export for an explicit owner set in bounded groups.
|
|
50
|
+
* While a scope is active, owners already remembered in the scope are skipped and the rest are remembered.
|
|
51
|
+
*/
|
|
38
52
|
exportOwners(ownerElementIds: ReadonlySet<Id64String>): Promise<void>;
|
|
53
|
+
private exportOwnerBatches;
|
|
39
54
|
private exportOwnerBatch;
|
|
40
55
|
private flush;
|
|
41
56
|
private resetScopeState;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElementAspectExportCoordinator.d.ts","sourceRoot":"","sources":["../src/ElementAspectExportCoordinator.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,MAAM,8BAA8B,GAAG,CAC3C,mCAAmC,EAAE,WAAW,CAAC,MAAM,CAAC,EACxD,eAAe,EAAE,WAAW,CAAC,UAAU,CAAC,KACrC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB
|
|
1
|
+
{"version":3,"file":"ElementAspectExportCoordinator.d.ts","sourceRoot":"","sources":["../src/ElementAspectExportCoordinator.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,MAAM,8BAA8B,GAAG,CAC3C,mCAAmC,EAAE,WAAW,CAAC,MAAM,CAAC,EACxD,eAAe,EAAE,WAAW,CAAC,UAAU,CAAC,KACrC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB;;;;;;;;;GASG;AACH,qBAAa,8BAA8B;IASvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAG/B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAb/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAyB;IAC3D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAyB;IAC7D,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,qBAAqB,CAAK;IAClC,OAAO,CAAC,QAAQ,CAAC,CAAiC;IAElD,YACmB,iBAAiB,EAAE,MAAM,EACzB,uBAAuB,EAAE,MAAM,WAAW,CAAC,MAAM,CAAC,EAClD,cAAc,EAAE,CAC/B,eAAe,EAAE,WAAW,CAAC,UAAU,CAAC,KACrC,OAAO,CAAC,IAAI,CAAC,EACD,YAAY,GAAE,MAAM,IAAe,EAGrD;IAED,4DAA4D;IAC5D,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,iGAAiG;IAC1F,cAAc,CAAC,OAAO,EAAE,8BAA8B,GAAG,IAAI,CAEnE;IAED;;OAEG;IACI,KAAK,CAAC,SAAS,SAAyB,GAAG,IAAI,CAOrD;IAED;;OAEG;IACU,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAehC;IAED,kFAAkF;IAC3E,KAAK,IAAI,IAAI,CAEnB;IAED;;OAEG;IACU,GAAG,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAcnE;IAED;;OAEG;IACU,kBAAkB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAOzE;IAED,0HAA0H;IAC7G,gBAAgB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAQlE;IAED;;OAEG;IACU,YAAY,CACvB,eAAe,EAAE,WAAW,CAAC,UAAU,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC,CAef;YAEa,kBAAkB;YAqBlB,gBAAgB;YAOhB,KAAK;IAMnB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,KAAK;CAKd"}
|
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
/** Coordinates scoped batches of accepted ElementAspect owners, including preparation before aspect export.
|
|
6
|
+
*
|
|
7
|
+
* Owner deduplication within a scope is bounded: the main element traversal visits each element once, so its owners
|
|
8
|
+
* are not remembered. Only owners exported out of order are remembered: those accepted while a handler callback
|
|
9
|
+
* is running (see [[runHandlerCallback]]), such as required references that `IModelTransformer.preExportElement`
|
|
10
|
+
* exports early, and owners passed explicitly to [[exportOwners]]. When the traversal reaches such an owner again,
|
|
11
|
+
* its aspects are not exported a second time. An owner that the traversal finished before a handler callback
|
|
12
|
+
* re-exports it does have its aspects exported again.
|
|
6
13
|
* @internal
|
|
7
14
|
*/
|
|
8
15
|
export class ElementAspectExportCoordinator {
|
|
@@ -11,9 +18,10 @@ export class ElementAspectExportCoordinator {
|
|
|
11
18
|
_exportAspects;
|
|
12
19
|
_resetCaches;
|
|
13
20
|
_acceptedOwnerIds = new Set();
|
|
14
|
-
|
|
21
|
+
_outOfOrderOwnerIds = new Set();
|
|
15
22
|
_batchSize;
|
|
16
23
|
_depth = 0;
|
|
24
|
+
_handlerCallbackDepth = 0;
|
|
17
25
|
_prepare;
|
|
18
26
|
constructor(_defaultBatchSize, _excludedClassFullNames, _exportAspects, _resetCaches = () => { }) {
|
|
19
27
|
this._defaultBatchSize = _defaultBatchSize;
|
|
@@ -82,30 +90,49 @@ export class ElementAspectExportCoordinator {
|
|
|
82
90
|
}
|
|
83
91
|
await this.end();
|
|
84
92
|
}
|
|
93
|
+
/** Runs an export handler callback. Owners accepted while it runs were exported out of traversal order
|
|
94
|
+
* (e.g. a required reference exported by the callback), so they are remembered for the rest of the scope.
|
|
95
|
+
*/
|
|
96
|
+
async runHandlerCallback(callback) {
|
|
97
|
+
this._handlerCallbackDepth++;
|
|
98
|
+
try {
|
|
99
|
+
return await callback();
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
this._handlerCallbackDepth--;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
85
105
|
/** Adds an accepted source owner to the current group and exports the group when it reaches the configured batch size. */
|
|
86
106
|
async addAcceptedOwner(elementId) {
|
|
87
|
-
if (!this.isActive || this.
|
|
107
|
+
if (!this.isActive || this._outOfOrderOwnerIds.has(elementId))
|
|
88
108
|
return;
|
|
109
|
+
if (this._handlerCallbackDepth > 0)
|
|
110
|
+
this._outOfOrderOwnerIds.add(elementId);
|
|
89
111
|
this._acceptedOwnerIds.add(elementId);
|
|
90
112
|
if (this._acceptedOwnerIds.size >= this._batchSize) {
|
|
91
113
|
await this.flush();
|
|
92
114
|
}
|
|
93
115
|
}
|
|
94
|
-
/** Runs preparation and aspect export for an explicit owner set in bounded groups.
|
|
116
|
+
/** Runs preparation and aspect export for an explicit owner set in bounded groups.
|
|
117
|
+
* While a scope is active, owners already remembered in the scope are skipped and the rest are remembered.
|
|
118
|
+
*/
|
|
95
119
|
async exportOwners(ownerElementIds) {
|
|
96
120
|
let ownerIds = ownerElementIds;
|
|
97
121
|
if (this.isActive && ownerElementIds.size > 0) {
|
|
98
122
|
const unprocessedOwnerIds = new Set();
|
|
99
123
|
for (const elementId of ownerElementIds) {
|
|
100
|
-
if (!this.
|
|
124
|
+
if (!this._outOfOrderOwnerIds.has(elementId)) {
|
|
101
125
|
unprocessedOwnerIds.add(elementId);
|
|
102
|
-
this.
|
|
126
|
+
this._outOfOrderOwnerIds.add(elementId);
|
|
103
127
|
}
|
|
104
128
|
}
|
|
105
129
|
if (unprocessedOwnerIds.size === 0)
|
|
106
130
|
return;
|
|
107
131
|
ownerIds = unprocessedOwnerIds;
|
|
108
132
|
}
|
|
133
|
+
await this.exportOwnerBatches(ownerIds);
|
|
134
|
+
}
|
|
135
|
+
async exportOwnerBatches(ownerIds) {
|
|
109
136
|
if (ownerIds.size <= this._defaultBatchSize) {
|
|
110
137
|
await this.exportOwnerBatch(ownerIds);
|
|
111
138
|
return;
|
|
@@ -129,11 +156,11 @@ export class ElementAspectExportCoordinator {
|
|
|
129
156
|
async flush() {
|
|
130
157
|
const ownerElementIds = new Set(this._acceptedOwnerIds);
|
|
131
158
|
this._acceptedOwnerIds.clear();
|
|
132
|
-
await this.
|
|
159
|
+
await this.exportOwnerBatches(ownerElementIds);
|
|
133
160
|
}
|
|
134
161
|
resetScopeState() {
|
|
135
162
|
this._acceptedOwnerIds.clear();
|
|
136
|
-
this.
|
|
163
|
+
this._outOfOrderOwnerIds.clear();
|
|
137
164
|
}
|
|
138
165
|
reset() {
|
|
139
166
|
this._depth = 0;
|
|
@@ -1 +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"]}
|
|
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 *\n * Owner deduplication within a scope is bounded: the main element traversal visits each element once, so its owners\n * are not remembered. Only owners exported out of order are remembered: those accepted while a handler callback\n * is running (see [[runHandlerCallback]]), such as required references that `IModelTransformer.preExportElement`\n * exports early, and owners passed explicitly to [[exportOwners]]. When the traversal reaches such an owner again,\n * its aspects are not exported a second time. An owner that the traversal finished before a handler callback\n * re-exports it does have its aspects exported again.\n * @internal\n */\nexport class ElementAspectExportCoordinator {\n private readonly _acceptedOwnerIds = new Set<Id64String>();\n private readonly _outOfOrderOwnerIds = new Set<Id64String>();\n private _batchSize: number;\n private _depth = 0;\n private _handlerCallbackDepth = 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 /** Runs an export handler callback. Owners accepted while it runs were exported out of traversal order\n * (e.g. a required reference exported by the callback), so they are remembered for the rest of the scope.\n */\n public async runHandlerCallback<T>(callback: () => Promise<T>): Promise<T> {\n this._handlerCallbackDepth++;\n try {\n return await callback();\n } finally {\n this._handlerCallbackDepth--;\n }\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._outOfOrderOwnerIds.has(elementId)) return;\n\n if (this._handlerCallbackDepth > 0) this._outOfOrderOwnerIds.add(elementId);\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 * While a scope is active, owners already remembered in the scope are skipped and the rest are remembered.\n */\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._outOfOrderOwnerIds.has(elementId)) {\n unprocessedOwnerIds.add(elementId);\n this._outOfOrderOwnerIds.add(elementId);\n }\n }\n if (unprocessedOwnerIds.size === 0) return;\n ownerIds = unprocessedOwnerIds;\n }\n\n await this.exportOwnerBatches(ownerIds);\n }\n\n private async exportOwnerBatches(\n ownerIds: ReadonlySet<Id64String>\n ): Promise<void> {\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.exportOwnerBatches(ownerElementIds);\n }\n\n private resetScopeState(): void {\n this._acceptedOwnerIds.clear();\n this._outOfOrderOwnerIds.clear();\n }\n\n private reset(): void {\n this._depth = 0;\n this.resetScopeState();\n this._batchSize = this._defaultBatchSize;\n }\n}\n"]}
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { EntityReference } from "@itwin/core-common";
|
|
5
5
|
import { IModelDb } from "@itwin/core-backend";
|
|
6
|
+
/** Default maximum number of cached entities per [IModelDb]($core-backend) in an [[EntityExistenceCache]].
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare const DEFAULT_ENTITY_EXISTENCE_CACHE_LIMIT = 1000000;
|
|
6
10
|
/** A positive-only read-through cache of entity existence checks, scoped to a single transformation run.
|
|
7
11
|
*
|
|
8
12
|
* Entities are created continuously as a transformation progresses, so a negative
|
|
@@ -18,11 +22,20 @@ import { IModelDb } from "@itwin/core-backend";
|
|
|
18
22
|
* mixed with transformer operations. A successful high-level `process()` clears the cache when the
|
|
19
23
|
* transformation finalizes; low-level or failed transformations clear it when the transformer is
|
|
20
24
|
* disposed.
|
|
25
|
+
*
|
|
26
|
+
* Each db's entries are held in a least-recently-used [LRUMap]($core-bentley) bounded by `limit`, so memory does not
|
|
27
|
+
* grow with iModel size (and stays below V8's ~16.7 million entry `Map`/`Set` limit). A cache hit marks the entry as
|
|
28
|
+
* recently used, which keeps frequently referenced entities (models, categories, code scopes, recent parents) cached.
|
|
29
|
+
* Evicting an entry only costs one more existence query. The default limit is much larger than core's element and
|
|
30
|
+
* model props caches because each entry is only a key, and a transformation is a long-running batch operation.
|
|
21
31
|
* @internal
|
|
22
32
|
*/
|
|
23
33
|
export declare class EntityExistenceCache {
|
|
34
|
+
private readonly _limit;
|
|
24
35
|
private _existsByDb;
|
|
25
|
-
|
|
36
|
+
/** @param limit maximum number of cached entities per db */
|
|
37
|
+
constructor(_limit?: number);
|
|
38
|
+
private getDbCache;
|
|
26
39
|
/** Check whether an entity exists in `db`, consulting the cache first.
|
|
27
40
|
* A `true` result is cached; a `false` result is never cached and will be re-queried.
|
|
28
41
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityExistenceCache.d.ts","sourceRoot":"","sources":["../src/EntityExistenceCache.ts"],"names":[],"mappings":"AAIA;;GAEG;
|
|
1
|
+
{"version":3,"file":"EntityExistenceCache.d.ts","sourceRoot":"","sources":["../src/EntityExistenceCache.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C;;GAEG;AACH,eAAO,MAAM,oCAAoC,UAAY,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,oBAAoB;IAK7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJzB,OAAO,CAAC,WAAW,CAAsD;IAEzE,4DAA4D;IAC5D,YACmB,MAAM,SAAuC,EAC5D;IAEJ,OAAO,CAAC,UAAU;IASlB;;OAEG;IACU,MAAM,CACjB,EAAE,EAAE,QAAQ,EACZ,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,OAAO,CAAC,CAOlB;IAED,6GAA6G;IAChG,SAAS,CACpB,EAAE,EAAE,QAAQ,EACZ,gBAAgB,EAAE,QAAQ,CAAC,eAAe,CAAC,GAC1C,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAkBvC;IAED,mFAAmF;IAC5E,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CAEtE;IAED,wFAAwF;IACjF,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CAEtE;IAED;;OAEG;IACI,OAAO,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAEjC;IAED,+BAA+B;IACxB,KAAK,IAAI,IAAI,CAEnB;CACF"}
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
/** @packageDocumentation
|
|
6
6
|
* @module Utils
|
|
7
7
|
*/
|
|
8
|
+
import { LRUMap } from "@itwin/core-bentley";
|
|
8
9
|
import { EntityUnifier } from "./EntityUnifier.js";
|
|
10
|
+
/** Default maximum number of cached entities per [IModelDb]($core-backend) in an [[EntityExistenceCache]].
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export const DEFAULT_ENTITY_EXISTENCE_CACHE_LIMIT = 1_000_000;
|
|
9
14
|
/** A positive-only read-through cache of entity existence checks, scoped to a single transformation run.
|
|
10
15
|
*
|
|
11
16
|
* Entities are created continuously as a transformation progresses, so a negative
|
|
@@ -21,37 +26,49 @@ import { EntityUnifier } from "./EntityUnifier.js";
|
|
|
21
26
|
* mixed with transformer operations. A successful high-level `process()` clears the cache when the
|
|
22
27
|
* transformation finalizes; low-level or failed transformations clear it when the transformer is
|
|
23
28
|
* disposed.
|
|
29
|
+
*
|
|
30
|
+
* Each db's entries are held in a least-recently-used [LRUMap]($core-bentley) bounded by `limit`, so memory does not
|
|
31
|
+
* grow with iModel size (and stays below V8's ~16.7 million entry `Map`/`Set` limit). A cache hit marks the entry as
|
|
32
|
+
* recently used, which keeps frequently referenced entities (models, categories, code scopes, recent parents) cached.
|
|
33
|
+
* Evicting an entry only costs one more existence query. The default limit is much larger than core's element and
|
|
34
|
+
* model props caches because each entry is only a key, and a transformation is a long-running batch operation.
|
|
24
35
|
* @internal
|
|
25
36
|
*/
|
|
26
37
|
export class EntityExistenceCache {
|
|
38
|
+
_limit;
|
|
27
39
|
_existsByDb = new Map();
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
/** @param limit maximum number of cached entities per db */
|
|
41
|
+
constructor(_limit = DEFAULT_ENTITY_EXISTENCE_CACHE_LIMIT) {
|
|
42
|
+
this._limit = _limit;
|
|
43
|
+
}
|
|
44
|
+
getDbCache(db) {
|
|
45
|
+
let cache = this._existsByDb.get(db);
|
|
46
|
+
if (cache === undefined) {
|
|
47
|
+
cache = new LRUMap(this._limit);
|
|
48
|
+
this._existsByDb.set(db, cache);
|
|
33
49
|
}
|
|
34
|
-
return
|
|
50
|
+
return cache;
|
|
35
51
|
}
|
|
36
52
|
/** Check whether an entity exists in `db`, consulting the cache first.
|
|
37
53
|
* A `true` result is cached; a `false` result is never cached and will be re-queried.
|
|
38
54
|
*/
|
|
39
55
|
async exists(db, entityReference) {
|
|
40
|
-
const
|
|
41
|
-
|
|
56
|
+
const cache = this.getDbCache(db);
|
|
57
|
+
// `get` (unlike `has`) marks the entry as recently used.
|
|
58
|
+
if (cache.get(entityReference))
|
|
42
59
|
return true;
|
|
43
60
|
const found = await EntityUnifier.exists(db, { entityReference });
|
|
44
61
|
if (found)
|
|
45
|
-
set
|
|
62
|
+
cache.set(entityReference, true);
|
|
46
63
|
return found;
|
|
47
64
|
}
|
|
48
65
|
/** Read through the cache to check which of the supplied entities exist in `db`, populating it on a miss. */
|
|
49
66
|
async existsAll(db, entityReferences) {
|
|
50
|
-
const
|
|
67
|
+
const cache = this.getDbCache(db);
|
|
51
68
|
const found = new Set();
|
|
52
69
|
const unverified = [];
|
|
53
70
|
for (const entityReference of entityReferences) {
|
|
54
|
-
if (
|
|
71
|
+
if (cache.get(entityReference))
|
|
55
72
|
found.add(entityReference);
|
|
56
73
|
else
|
|
57
74
|
unverified.push(entityReference);
|
|
@@ -60,14 +77,14 @@ export class EntityExistenceCache {
|
|
|
60
77
|
return found;
|
|
61
78
|
const queried = await EntityUnifier.existsAll(db, unverified);
|
|
62
79
|
for (const entityReference of queried) {
|
|
63
|
-
|
|
80
|
+
cache.set(entityReference, true);
|
|
64
81
|
found.add(entityReference);
|
|
65
82
|
}
|
|
66
83
|
return found;
|
|
67
84
|
}
|
|
68
85
|
/** Record that an entity is known to exist in `db` (e.g. it was just imported). */
|
|
69
86
|
markExists(db, entityReference) {
|
|
70
|
-
this.
|
|
87
|
+
this.getDbCache(db).set(entityReference, true);
|
|
71
88
|
}
|
|
72
89
|
/** Remove a single entity from the cache for `db`, forcing a re-query on next check. */
|
|
73
90
|
invalidate(db, entityReference) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityExistenceCache.js","sourceRoot":"","sources":["../src/EntityExistenceCache.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG;;GAEG;
|
|
1
|
+
{"version":3,"file":"EntityExistenceCache.js","sourceRoot":"","sources":["../src/EntityExistenceCache.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Utils\n */\n\nimport { LRUMap } from \"@itwin/core-bentley\";\nimport { EntityReference } from \"@itwin/core-common\";\nimport { IModelDb } from \"@itwin/core-backend\";\nimport { EntityUnifier } from \"./EntityUnifier.js\";\n\n/** Default maximum number of cached entities per [IModelDb]($core-backend) in an [[EntityExistenceCache]].\n * @internal\n */\nexport const DEFAULT_ENTITY_EXISTENCE_CACHE_LIMIT = 1_000_000;\n\n/** A positive-only read-through cache of entity existence checks, scoped to a single transformation run.\n *\n * Entities are created continuously as a transformation progresses, so a negative\n * (\"does not exist\") result may become stale at any moment — therefore only positive\n * results are ever cached. Positive results can only be invalidated by deletes, which the\n * transformer routes through [[invalidate]] and [[clearDb]].\n *\n * The cache is keyed by [IModelDb]($core-backend) instance, so same-iModel transformations\n * (where sourceDb === targetDb) share a single set and source/target roles cannot be confused.\n *\n * [IModelImporter]($transformer) delete operations invalidate registered caches. Deletes performed\n * directly through an `EditTxn` while a transformation is active are out-of-band and must not be\n * mixed with transformer operations. A successful high-level `process()` clears the cache when the\n * transformation finalizes; low-level or failed transformations clear it when the transformer is\n * disposed.\n *\n * Each db's entries are held in a least-recently-used [LRUMap]($core-bentley) bounded by `limit`, so memory does not\n * grow with iModel size (and stays below V8's ~16.7 million entry `Map`/`Set` limit). A cache hit marks the entry as\n * recently used, which keeps frequently referenced entities (models, categories, code scopes, recent parents) cached.\n * Evicting an entry only costs one more existence query. The default limit is much larger than core's element and\n * model props caches because each entry is only a key, and a transformation is a long-running batch operation.\n * @internal\n */\nexport class EntityExistenceCache {\n private _existsByDb = new Map<IModelDb, LRUMap<EntityReference, true>>();\n\n /** @param limit maximum number of cached entities per db */\n public constructor(\n private readonly _limit = DEFAULT_ENTITY_EXISTENCE_CACHE_LIMIT\n ) {}\n\n private getDbCache(db: IModelDb): LRUMap<EntityReference, true> {\n let cache = this._existsByDb.get(db);\n if (cache === undefined) {\n cache = new LRUMap(this._limit);\n this._existsByDb.set(db, cache);\n }\n return cache;\n }\n\n /** Check whether an entity exists in `db`, consulting the cache first.\n * A `true` result is cached; a `false` result is never cached and will be re-queried.\n */\n public async exists(\n db: IModelDb,\n entityReference: EntityReference\n ): Promise<boolean> {\n const cache = this.getDbCache(db);\n // `get` (unlike `has`) marks the entry as recently used.\n if (cache.get(entityReference)) return true;\n const found = await EntityUnifier.exists(db, { entityReference });\n if (found) cache.set(entityReference, true);\n return found;\n }\n\n /** Read through the cache to check which of the supplied entities exist in `db`, populating it on a miss. */\n public async existsAll(\n db: IModelDb,\n entityReferences: Iterable<EntityReference>\n ): Promise<ReadonlySet<EntityReference>> {\n const cache = this.getDbCache(db);\n const found = new Set<EntityReference>();\n const unverified: EntityReference[] = [];\n\n for (const entityReference of entityReferences) {\n if (cache.get(entityReference)) found.add(entityReference);\n else unverified.push(entityReference);\n }\n\n if (unverified.length === 0) return found;\n\n const queried = await EntityUnifier.existsAll(db, unverified);\n for (const entityReference of queried) {\n cache.set(entityReference, true);\n found.add(entityReference);\n }\n return found;\n }\n\n /** Record that an entity is known to exist in `db` (e.g. it was just imported). */\n public markExists(db: IModelDb, entityReference: EntityReference): void {\n this.getDbCache(db).set(entityReference, true);\n }\n\n /** Remove a single entity from the cache for `db`, forcing a re-query on next check. */\n public invalidate(db: IModelDb, entityReference: EntityReference): void {\n this._existsByDb.get(db)?.delete(entityReference);\n }\n\n /** Drop all cached results for `db`. Used when a delete may cascade to entities the\n * caller cannot enumerate (e.g. element tree deletes that remove descendants and submodels).\n */\n public clearDb(db: IModelDb): void {\n this._existsByDb.delete(db);\n }\n\n /** Drop all cached results. */\n public clear(): void {\n this._existsByDb.clear();\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IModelExporter.d.ts","sourceRoot":"","sources":["../src/IModelExporter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"IModelExporter.d.ts","sourceRoot":"","sources":["../src/IModelExporter.ts"],"names":[],"mappings":"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"}
|
package/lib/IModelExporter.js
CHANGED
|
@@ -595,7 +595,7 @@ export class IModelExporter {
|
|
|
595
595
|
return; // not in changeset, don't export
|
|
596
596
|
}
|
|
597
597
|
}
|
|
598
|
-
await this.handler.onExportModel(model, isUpdate);
|
|
598
|
+
await this._elementAspectExportCoordinator.runHandlerCallback(async () => this.handler.onExportModel(model, isUpdate));
|
|
599
599
|
return this.trackProgress();
|
|
600
600
|
}
|
|
601
601
|
_yieldManager = new YieldManager();
|
|
@@ -848,8 +848,10 @@ export class IModelExporter {
|
|
|
848
848
|
Logger.logTrace(loggerCategory, `exportElement(${element.id}, "${element.getDisplayLabel()}")${this.getChangeOpSuffix(isUpdate)}`);
|
|
849
849
|
// the order and `await`ing of calls beyond here is depended upon by the IModelTransformer for a current bug workaround
|
|
850
850
|
if (await this.shouldExportElement(element)) {
|
|
851
|
-
await this.
|
|
852
|
-
|
|
851
|
+
await this._elementAspectExportCoordinator.runHandlerCallback(async () => {
|
|
852
|
+
await this.handler.preExportElement(element);
|
|
853
|
+
await this.handler.onExportElement(element, isUpdate);
|
|
854
|
+
});
|
|
853
855
|
await this.trackProgress();
|
|
854
856
|
await this._elementAspectExportCoordinator.addAcceptedOwner(elementId);
|
|
855
857
|
return "visit";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IModelExporter.js","sourceRoot":"","sources":["../src/IModelExporter.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 {\n BriefcaseDb,\n BriefcaseManager,\n ChangeInstance,\n DefinitionModel,\n // eslint-disable-next-line @typescript-eslint/no-redeclare\n Element,\n ElementAspect,\n ElementMultiAspect,\n ElementRefersToElements,\n ElementUniqueAspect,\n GeometricElement,\n IModelDb,\n IModelJsNative,\n Model,\n RecipeDefinitionElement,\n Relationship,\n SqliteChangeOp,\n} from \"@itwin/core-backend\";\nimport {\n assert,\n GuidString,\n Id64,\n Id64Arg,\n Id64Set,\n Id64String,\n IModelStatus,\n ITwinError,\n JsonUtils,\n Logger,\n YieldManager,\n} from \"@itwin/core-bentley\";\nimport {\n Base64EncodedString,\n ChangesetFileProps,\n CodeSpec,\n ECJsNames,\n FontFamilyDescriptor,\n FontId,\n FontProps,\n IModel,\n IModelError,\n QueryBinder,\n RelationshipProps,\n} from \"@itwin/core-common\";\nimport { ECVersion, Schema, SchemaKey } from \"@itwin/ecschema-metadata\";\nimport { TransformerLoggerCategory } from \"./TransformerLoggerCategory.js\";\nimport { strict as nodeAssert } from \"node:assert\";\nimport { ElementAspectExportProcessor } from \"./ElementAspectExportProcessor.js\";\nimport { ElementAspectExportCoordinator } from \"./ElementAspectExportCoordinator.js\";\nimport {\n IModelTransformerError,\n IModelTransformerErrorScope,\n} from \"./IModelTransformerError.js\";\nimport { ChangesetScanner } from \"./ChangesetScanner.js\";\nimport { SourceClassKinds } from \"./SourceClassKinds.js\";\nimport { ChangedElementForest } from \"./ChangedElementForest.js\";\n\nconst loggerCategory = TransformerLoggerCategory.IModelExporter;\n\ninterface AspectElementFact {\n id: Id64String;\n parentId?: Id64String;\n modelId: Id64String;\n classFullName: string;\n categoryId?: Id64String;\n}\n\ninterface AspectModelFact {\n id: Id64String;\n parentModelId?: Id64String;\n isTemplate: boolean;\n}\n\n/**\n * @beta\n * The (optional) result of [[IModelExportHandler.onExportSchema]]\n */\nexport interface ExportSchemaResult {\n /** set this property to notify subclasses where you wrote a schema for later import */\n schemaPath?: string;\n}\n\n/**\n * Arguments for [[IModelExporter.initialize]], usually in case you want to query changedata early\n * such as in the case of the IModelTransformer\n * @beta\n */\nexport type ExporterInitOptions = ExportChangesOptions;\n\n/**\n * Arguments for [[IModelExporter.exportChanges]]\n * @public\n */\nexport type ExportChangesOptions = {\n skipPropagateChangesToRootElements?: boolean;\n} /**\n * an array of ChangesetFileProps which are used to read the changesets and populate the ChangedInstanceIds using [[ChangedInstanceIds.initialize]] in [[IModelExporter.exportChanges]]\n * @note mutually exclusive with @see changesetRanges, @see startChangeset and @see changedInstanceIds, so define one of the four, never more\n */ & (\n | { csFileProps: ChangesetFileProps[] }\n /**\n * Class instance that contains modified elements between 2 versions of an iModel.\n * If this parameter is not provided, then [[ChangedInstanceIds.initialize]] in [[IModelExporter.exportChanges]]\n * will be called to discover changed elements.\n * @note mutually exclusive with @see changesetRanges, @see csFileProps and @see startChangeset, so define one of the four, never more\n */\n | { changedInstanceIds: ChangedInstanceIds }\n /**\n * An ordered array of changeset index ranges, e.g. [[2,2], [4,5]] is [2,4,5]\n * @note mutually exclusive with @see changedInstanceIds, @see csFileProps and @see startChangeset, so define one of the four, never more\n */\n | { changesetRanges: [number, number][] }\n /**\n * Include changes from this changeset up through and including the current changeset.\n * @note To form a range of versions to process, set `startChangeset` for the start (inclusive)\n * of the desired range and open the source iModel as of the end (inclusive) of the desired range.\n * @default the current changeset of the sourceDb, if undefined\n */\n | { startChangeset: { id?: string; index?: number } }\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n | {}\n);\n\n/** The FederationGuids of a relationship's source and target elements, read by [[IModelExporter]] while it reads the relationship.\n * A missing property means that endpoint element has no FederationGuid.\n * @see [[IModelExportHandler.onExportRelationship]]\n * @beta\n */\nexport interface RelationshipEndpointFederationGuids {\n /** The FederationGuid of the relationship's source element. */\n source?: GuidString;\n /** The FederationGuid of the relationship's target element. */\n target?: GuidString;\n}\n\n/** Handles the events generated by IModelExporter.\n * @note Change information is available when `IModelExportHandler` methods are invoked via [IModelExporter.exportChanges]($transformer), but not available when invoked via [IModelExporter.exportAll]($transformer).\n * @note The handler is intended to be owned by (registered with) and called from the IModelExporter exclusively\n * @see [iModel Transformation and Data Exchange]($docs/learning/transformer/index.md), [IModelExporter]($transformer)\n * @beta\n */\nexport abstract class IModelExportHandler {\n /** If `true` is returned, then the CodeSpec will be exported.\n * @note This method can optionally be overridden to exclude an individual CodeSpec from the export. The base implementation always returns `true`.\n */\n public async shouldExportCodeSpec(_codeSpec: CodeSpec): Promise<boolean> {\n return true;\n }\n\n /** Called when a CodeSpec should be exported.\n * @param codeSpec The CodeSpec to export\n * @param isUpdate If defined, then `true` indicates an UPDATE operation while `false` indicates an INSERT operation. If not defined, then INSERT vs. UPDATE is not known.\n * @note This should be overridden to actually do the export.\n */\n public async onExportCodeSpec(\n _codeSpec: CodeSpec,\n _isUpdate: boolean | undefined\n ): Promise<void> {}\n\n /** Called when a font should be exported.\n * @param font The font to export\n * @param isUpdate If defined, then `true` indicates an UPDATE operation while `false` indicates an INSERT operation. If not defined, then INSERT vs. UPDATE is not known.\n * @note This should be overridden to actually do the export.\n */\n public async onExportFont(\n _font: FontProps,\n _isUpdate: boolean | undefined\n ): Promise<void> {}\n\n /** Called when a model should be exported.\n * @param model The model to export\n * @param isUpdate If defined, then `true` indicates an UPDATE operation while `false` indicates an INSERT operation. If not defined, then INSERT vs. UPDATE is not known.\n * @note This should be overridden to actually do the export.\n */\n public async onExportModel(\n _model: Model,\n _isUpdate: boolean | undefined\n ): Promise<void> {}\n\n /** Called when a model should be deleted. */\n public async onDeleteModel(_modelId: Id64String): Promise<void> {}\n\n /** If `true` is returned, then the element will be exported.\n * @note This method can optionally be overridden to exclude an individual Element (and its children and ElementAspects) from the export. The base implementation always returns `true`.\n * @note During [IModelExporter.exportChanges]($transformer), this method is also called once for each unchanged ancestor of a changed element, so that a rejected ancestor excludes its changed descendants.\n */\n public async shouldExportElement(_element: Element): Promise<boolean> {\n return true;\n }\n\n /** Called when element is skipped instead of exported.\n * @note When an element is skipped, exporter will not export any of its child elements. Because of this, [[onSkipElement]] will not be invoked for any children of a \"skipped\" element.\n * @note During [IModelExporter.exportChanges]($transformer), an unchanged ancestor is filtered only when a changed descendant is reached. An element excluded by ID below it may therefore receive [[onSkipElement]] before the ancestor is rejected.\n */\n public async onSkipElement(_elementId: Id64String): Promise<void> {}\n\n /** Called when an element should be exported.\n * @param element The element to export\n * @param isUpdate If defined, then `true` indicates an UPDATE operation while `false` indicates an INSERT operation. If not defined, then INSERT vs. UPDATE is not known.\n * @note This should be overridden to actually do the export.\n */\n public async onExportElement(\n _element: Element,\n _isUpdate: boolean | undefined\n ): Promise<void> {}\n\n /**\n * Do any asynchronous actions before exporting an element\n * @note Do not implement this handler manually, it is internal, it will be removed.\n * This will become a part of onExportElement once that becomes async\n * @internal\n */\n public async preExportElement(_element: Element): Promise<void> {}\n\n /** Called once with the source IDs of all elements deleted by the exported changes. */\n public async onDeleteElements(\n _elementIds: ReadonlySet<Id64String>\n ): Promise<void> {}\n\n /** If `true` is returned, then the ElementAspect will be exported.\n * @note This method can optionally be overridden to exclude an individual ElementAspect from the export. The base implementation always returns `true`.\n */\n public async shouldExportElementAspect(\n _aspect: ElementAspect\n ): Promise<boolean> {\n return true;\n }\n\n /** Called when an ElementUniqueAspect should be exported.\n * @param aspect The ElementUniqueAspect to export\n * @param isUpdate If defined, then `true` indicates an UPDATE operation while `false` indicates an INSERT operation. If not defined, then INSERT vs. UPDATE is not known.\n * @note This should be overridden to actually do the export.\n */\n public async onExportElementUniqueAspect(\n _aspect: ElementUniqueAspect,\n _isUpdate: boolean | undefined\n ): Promise<void> {}\n\n /** Called when ElementMultiAspects should be exported.\n * @note This should be overridden to actually do the export.\n */\n public async onExportElementMultiAspects(\n _aspects: ElementMultiAspect[]\n ): Promise<void> {}\n\n /** If `true` is returned, then the relationship will be exported.\n * @note This method can optionally be overridden to exclude an individual CodeSpec from the export. The base implementation always returns `true`.\n */\n public async shouldExportRelationship(\n _relationship: Relationship\n ): Promise<boolean> {\n return true;\n }\n\n /** Called when a Relationship should be exported.\n * @param relationship The Relationship to export\n * @param isUpdate If defined, then `true` indicates an UPDATE operation while `false` indicates an INSERT operation. If not defined, then INSERT vs. UPDATE is not known.\n * @param endpointFedGuids The FederationGuids of the relationship's source and target elements. [[IModelExporter]] always supplies them. `undefined` means the caller did not supply them.\n * @note This should be overridden to actually do the export.\n */\n public async onExportRelationship(\n _relationship: Relationship,\n _isUpdate: boolean | undefined,\n _endpointFedGuids?: RelationshipEndpointFederationGuids\n ): Promise<void> {}\n\n /** Called when a relationship should be deleted. */\n public async onDeleteRelationship(\n _relInstanceId: Id64String\n ): Promise<void> {}\n\n /** If `true` is returned, then the schema will be exported.\n * @note This method can optionally be overridden to exclude an individual schema from the export. The base implementation always returns `true`.\n */\n public async shouldExportSchema(_schemaKey: SchemaKey): Promise<boolean> {\n return true;\n }\n\n /** Called when a schema should be exported.\n * @param schema The schema to export\n * @note This should be overridden to actually do the export.\n * @note return an [[ExportSchemaResult]] with a `schemaPath` property to notify overrides that call `super`\n * where a schema was written for import.\n */\n public async onExportSchema(\n _schema: Schema\n ): Promise<void | ExportSchemaResult> {}\n\n /** This method is called when IModelExporter has made incremental progress based on the [[IModelExporter.progressInterval]] setting.\n * This method is `async` to make it easier to integrate with asynchronous status and health reporting services.\n * @note A subclass may override this method to report custom progress. The base implementation does nothing.\n */\n public async onProgress(): Promise<void> {}\n}\n\n/** Base class for exporting data from an iModel.\n * @note Most uses cases will not require a custom subclass of `IModelExporter`. Instead, it is more typical to subclass/customize [IModelExportHandler]($transformer).\n * ElementAspects are exported separately from element callbacks in bounded,\n * owner-scoped groups. Aspect callbacks are not guaranteed to be adjacent to\n * callbacks for their owners.\n * @see [iModel Transformation and Data Exchange]($docs/learning/transformer/index.md), [[registerHandler]], [IModelTransformer]($transformer), [IModelImporter]($transformer)\n * @beta\n */\nexport class IModelExporter {\n private static readonly _elementAspectOwnerBatchSize = 1000;\n /** The read-only source iModel. */\n public readonly sourceDb: IModelDb;\n /** A flag that indicates whether element GeometryStreams are loaded or not.\n * @note As an optimization, exporters that don't need geometry can set this flag to `false`. The default is `true`.\n * @note The transformer by default sets this to `false` as an optimization.\n * @note This implies the `wantBRepData` option when loading elements.\n * @see [ElementLoadProps.wantGeometry]($common)\n */\n public wantGeometry: boolean = true;\n /** A flag that indicates whether template models should be exported or not. The default is `true`.\n * @note If only exporting *instances* then template models can be skipped since they are just definitions that are cloned to create new instances.\n * @see [Model.isTemplate]($backend)\n */\n public wantTemplateModels: boolean = true;\n /** A flag that indicates whether *system* schemas should be exported or not. The default is `true` (previously false).\n * This can be set to false for the legacy default behavior, but it may cause errors during schema processing in some cases.\n * @see [[exportSchemas]]\n */\n public wantSystemSchemas: boolean = true;\n /** A flag that determines whether this IModelExporter should visit Elements or not. The default is `true`.\n * @note This flag is available as an optimization when the exporter doesn't need to visit elements, so can skip loading them.\n */\n public visitElements: boolean = true;\n /** A flag that determines whether this IModelExporter should visit Relationships or not. The default is `true`.\n * @note This flag is available as an optimization when the exporter doesn't need to visit relationships, so can skip loading them.\n */\n public visitRelationships: boolean = true;\n /** The number of entities exported before incremental progress should be reported via the [[onProgress]] callback. */\n public progressInterval: number = 1000;\n /** Tracks the current total number of entities exported. */\n private _progressCounter: number = 0;\n /** Optionally cached entity change information */\n private _sourceDbChanges?: ChangedInstanceIds;\n /** State shared by nested calls in one change-processing element traversal. */\n private _changedElementTraversal?: {\n forest?: Promise<ChangedElementForest | undefined>;\n useForest: boolean;\n };\n /** Unchanged elements on the current change-processing path. Each is filtered only when a changed descendant is reached. */\n private readonly _unchangedAncestors: {\n elementId: Id64String;\n accepted?: boolean;\n }[] = [];\n /** Bounds the additional hierarchy retained by the sparse changed-element path. */\n private readonly _changedElementForestElementLimit = 100_000;\n\n /**\n * Retrieve the cached entity change information.\n * @note This will only be initialized after [IModelExporter.exportChanges] is invoked or [IModelExporter.initialize] is called.\n */\n public get sourceDbChanges(): ChangedInstanceIds | undefined {\n return this._sourceDbChanges;\n }\n /** The handler called by this IModelExporter. */\n private _handler: IModelExportHandler | undefined;\n /** The handler called by this IModelExporter. */\n protected get handler(): IModelExportHandler {\n if (undefined === this._handler) {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.ExportHandlerNotRegistered,\n },\n message: \"IModelExportHandler not registered\",\n });\n }\n\n return this._handler;\n }\n\n /** The set of CodeSpecs to exclude from the export. */\n private _excludedCodeSpecNames = new Set<string>();\n /** The set of specific Elements to exclude from the export. */\n private _excludedElementIds = new Set<Id64String>();\n /** The set of Categories where Elements in that Category will be excluded from transformation to the target iModel. */\n private _excludedElementCategoryIds = new Set<Id64String>();\n /** The set of classes of Elements that will be excluded (polymorphically) from transformation to the target iModel. */\n private _excludedElementClasses = new Set<typeof Element>();\n /** The set of classes of Relationships that will be excluded (polymorphically) from transformation to the target iModel. */\n private _excludedRelationshipClasses = new Set<typeof Relationship>();\n\n /** Exports ElementAspects for accepted owner groups. */\n private _elementAspectExportProcessor: ElementAspectExportProcessor;\n /** Coordinates accepted-owner scopes and bounded group processing. */\n private readonly _elementAspectExportCoordinator: ElementAspectExportCoordinator;\n\n /** Coordinates accepted ElementAspect owners and bounded group processing.\n * @internal\n */\n public get elementAspectExportCoordinator(): ElementAspectExportCoordinator {\n return this._elementAspectExportCoordinator;\n }\n /** Whether change traversal skips root-owned entities. */\n private _skipPropagateChangesToRootElements = false;\n private readonly _rootElementIds = new Set<Id64String>([\n IModel.rootSubjectId,\n IModel.repositoryModelId,\n IModel.dictionaryId,\n \"0xe\", // The reality-data-sources modelId, skipped with root propagation.\n ]);\n\n /** Construct a new IModelExporter\n * @param sourceDb The source IModelDb\n * @see registerHandler\n */\n public constructor(sourceDb: IModelDb) {\n this.sourceDb = sourceDb;\n this._elementAspectExportProcessor = new ElementAspectExportProcessor(\n this.sourceDb,\n {\n onExportElementMultiAspects: async (aspects) =>\n this.handler.onExportElementMultiAspects(aspects),\n onExportElementUniqueAspect: async (aspect, isUpdate) =>\n this.handler.onExportElementUniqueAspect(aspect, isUpdate),\n shouldExportElementAspect: async (aspect) =>\n this.handler.shouldExportElementAspect(aspect),\n trackProgress: async () => this.trackProgress(),\n }\n );\n this._elementAspectExportCoordinator = new ElementAspectExportCoordinator(\n IModelExporter._elementAspectOwnerBatchSize,\n () =>\n this._elementAspectExportProcessor.excludedElementAspectClassFullNames,\n async (elementIds) =>\n this._elementAspectExportProcessor.exportAllElementAspects(elementIds),\n () => this._elementAspectExportProcessor.resetCaches()\n );\n }\n\n /**\n * Initialize prerequisites of exporting. This is implicitly done by any `export*` calls that need initialization\n * which is currently just `exportChanges`.\n * Prefer to not call this explicitly (e.g. just call [[IModelExporter.exportChanges]])\n * @note that if you do call this explicitly, you must do so with the same options that\n * you pass to [[IModelExporter.exportChanges]]\n */\n public async initialize(options: ExporterInitOptions): Promise<void> {\n if (!this.sourceDb.isBriefcaseDb() || this._sourceDbChanges) return;\n\n this._sourceDbChanges = await ChangedInstanceIds.initialize({\n iModel: this.sourceDb,\n ...options,\n });\n if (this._sourceDbChanges === undefined) return;\n\n this._elementAspectExportProcessor.setAspectChanges(\n this._sourceDbChanges.aspect\n );\n }\n\n /** Register the handler that will be called by IModelExporter. */\n public registerHandler(handler: IModelExportHandler): void {\n this._handler = handler;\n }\n\n /** Add a rule to exclude a CodeSpec */\n public excludeCodeSpec(codeSpecName: string): void {\n this._excludedCodeSpecNames.add(codeSpecName);\n }\n\n /** Add a rule to exclude a specific Element.\n * @note Configure exclusions before starting an export operation. Changing exclusions while an export is in progress is unsupported.\n */\n public excludeElement(elementId: Id64String): void {\n this._excludedElementIds.add(elementId);\n }\n\n /** Add a rule to exclude all Elements in a specified Category. */\n public excludeElementsInCategory(categoryId: Id64String): void {\n this._excludedElementCategoryIds.add(categoryId);\n }\n\n /** Add a rule to exclude all Elements of a specified class. */\n public excludeElementClass(classFullName: string): void {\n this._excludedElementClasses.add(\n this.sourceDb.getJsClass<typeof Element>(classFullName)\n );\n }\n\n /** Add a rule to exclude all ElementAspects of a specified class. */\n public excludeElementAspectClass(classFullName: string): void {\n this._elementAspectExportProcessor.excludeElementAspectClass(classFullName);\n }\n\n /** Add a rule to exclude all Relationships of a specified class. */\n public excludeRelationshipClass(classFullName: string): void {\n this._excludedRelationshipClasses.add(\n this.sourceDb.getJsClass<typeof Relationship>(classFullName)\n );\n }\n\n /** Export all entity instance types from the source iModel.\n * @note [[exportSchemas]] must be called separately.\n */\n public async exportAll(): Promise<void> {\n await this.initialize({});\n\n await this.exportCodeSpecs();\n await this.exportFonts();\n await this._elementAspectExportCoordinator.run(async () =>\n this.exportModel(IModel.repositoryModelId)\n );\n await this.exportRelationships(ElementRefersToElements.classFullName);\n }\n\n /** Export changes from the source iModel.\n * Inserts, updates, and deletes are determined by inspecting the changeset(s).\n * @throws [[ITwinError]] with scope `@itwin/imodel-transformer` and key `no-changesets` if the source iModel has no changesets and no custom changes. Call [[exportAll]] to export all content.\n * @note To form a range of versions to process, set `startChangesetId` for the start (inclusive) of the desired\n * range and open the source iModel as of the end (inclusive) of the desired range.\n * @note the changedInstanceIds are just for this call to exportChanges, so you must continue to pass it in\n * for consecutive calls\n */\n public async exportChanges(args?: ExportChangesOptions): Promise<void> {\n if (!this.sourceDb.isBriefcaseDb())\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.ExportChangesRequiresBriefcase,\n },\n message: \"Must be a briefcase to export changes\",\n });\n\n let initOpts: ExporterInitOptions = args ?? {};\n const hasExplicitChangeSource =\n \"csFileProps\" in initOpts ||\n \"changedInstanceIds\" in initOpts ||\n \"changesetRanges\" in initOpts ||\n \"startChangeset\" in initOpts;\n const currentChangesetId = this.sourceDb.changeset.id;\n\n if (!hasExplicitChangeSource && currentChangesetId !== \"\") {\n initOpts = {\n ...initOpts,\n startChangeset: { id: currentChangesetId },\n };\n }\n\n await this.initialize(initOpts);\n\n if (currentChangesetId === \"\" && !this.sourceDbChanges?.hasChanges) {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.NoChangesets,\n },\n message:\n \"Cannot export changes because the source iModel has no changesets or custom changes. Call exportAll() to export all content.\",\n });\n }\n\n this._skipPropagateChangesToRootElements =\n initOpts.skipPropagateChangesToRootElements ?? false;\n // _sourceDbChanges are initialized in this.initialize\n nodeAssert(\n this._sourceDbChanges !== undefined,\n \"sourceDbChanges must be initialized.\"\n );\n\n await this.exportCodeSpecs();\n await this.exportFonts();\n nodeAssert(\n this.beginChangedElementTraversalScope(),\n \"exportChanges must own its changed-element traversal scope\"\n );\n try {\n await this._elementAspectExportCoordinator.run(async () => {\n if (initOpts.skipPropagateChangesToRootElements) {\n // The root Subject is in the RepositoryModel. Traverse its children\n // separately, then export other top-level repository elements while\n // excluding the root so no element is visited twice.\n await this.exportChildElements(IModel.rootSubjectId);\n await this.exportModelContents(\n IModel.repositoryModelId,\n Element.classFullName,\n true\n );\n await this.exportSubModels(IModel.repositoryModelId);\n } else {\n await this.exportModel(IModel.repositoryModelId);\n }\n });\n\n const aspectOnlyOwnerElementIds = new Set(\n this._sourceDbChanges.aspectOwnerElementIds\n );\n for (const elementId of this._sourceDbChanges.element.insertIds) {\n aspectOnlyOwnerElementIds.delete(elementId);\n }\n for (const elementId of this._sourceDbChanges.element.updateIds) {\n aspectOnlyOwnerElementIds.delete(elementId);\n }\n await this.exportAspectsForOwners(\n await this.filterOwnerElementIdsForAspectExport(\n aspectOnlyOwnerElementIds\n )\n );\n } finally {\n this.endChangedElementTraversalScope();\n }\n await this.exportRelationships(ElementRefersToElements.classFullName);\n\n // handle deletes\n if (this.visitElements) {\n // must delete models first since they have a constraint on the submodeling element which may also be deleted\n for (const modelId of this._sourceDbChanges.model.deleteIds) {\n await this.handler.onDeleteModel(modelId);\n }\n if (this._sourceDbChanges.element.deleteIds.size > 0) {\n await this.handler.onDeleteElements(\n new Set(this._sourceDbChanges.element.deleteIds)\n );\n }\n }\n\n if (this.visitRelationships) {\n for (const relInstanceId of this._sourceDbChanges.relationship\n .deleteIds) {\n await this.handler.onDeleteRelationship(relInstanceId);\n }\n }\n\n // Enable consecutive exportChanges runs without the need to re-instantiate the exporter.\n // You can counteract the obvious impact of losing this expensive data by always calling\n // exportChanges with the [[ExportChangesOptions.changedInstanceIds]] option set to\n // whatever you want\n if (this._resetChangeDataOnExport) {\n this._sourceDbChanges = undefined;\n this._elementAspectExportProcessor.setAspectChanges(undefined);\n }\n }\n\n private _resetChangeDataOnExport = true;\n\n /** Enumerate schemas from the source iModel in database order.\n * @note Override this method to customize schema discovery for both direct exports and transformer schema processing.\n * @beta\n */\n public async *enumerateSchemas(): AsyncIterable<Schema> {\n const sql = `\n SELECT s.Name, s.VersionMajor, s.VersionWrite, s.VersionMinor\n FROM ECDbMeta.ECSchemaDef s\n ${\n this.wantSystemSchemas\n ? \"\"\n : `\n WHERE ECInstanceId >= (SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore')\n `\n }\n ORDER BY ECInstanceId\n `;\n for await (const row of this.sourceDb.createQueryReader(sql, undefined, {\n usePrimaryConn: true,\n })) {\n const schemaKey = new SchemaKey(\n row[0],\n new ECVersion(row[1], row[2], row[3])\n );\n const schema = await this.sourceDb.schemaContext.getSchema(schemaKey);\n if (!schema) {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.SchemaLoadFailed,\n },\n message: `Failed to load schema: ${schemaKey.name}`,\n });\n }\n yield schema;\n }\n }\n\n /** Export schemas from the source iModel.\n * @note This must be called separately from [[exportAll]] or [[exportChanges]].\n */\n public async exportSchemas(): Promise<void> {\n const schemasToExport: Schema[] = [];\n for await (const schema of this.enumerateSchemas()) {\n if (await this.handler.shouldExportSchema(schema.schemaKey)) {\n schemasToExport.push(schema);\n }\n }\n\n await Promise.all(\n schemasToExport.map(async (schema) => {\n Logger.logTrace(loggerCategory, `exportSchema(${schema.name})`);\n return this.handler.onExportSchema(schema);\n })\n );\n }\n\n /** For logging, indicate the change type if known. */\n private getChangeOpSuffix(isUpdate: boolean | undefined): string {\n return isUpdate ? \" UPDATE\" : undefined === isUpdate ? \"\" : \" INSERT\";\n }\n\n /** Export all CodeSpecs from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportCodeSpecs(): Promise<void> {\n Logger.logTrace(loggerCategory, \"exportCodeSpecs()\");\n const sql = \"SELECT Name FROM BisCore:CodeSpec ORDER BY ECInstanceId\";\n for await (const row of this.sourceDb.createQueryReader(sql, undefined, {\n usePrimaryConn: true,\n })) {\n await this.exportCodeSpecByName(row[0]);\n }\n }\n\n /** Export a single CodeSpec from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportCodeSpecByName(codeSpecName: string): Promise<void> {\n const codeSpec: CodeSpec = this.sourceDb.codeSpecs.getByName(codeSpecName);\n let isUpdate: boolean | undefined;\n if (undefined !== this._sourceDbChanges) {\n // is changeset information available?\n if (this._sourceDbChanges.codeSpec.insertIds.has(codeSpec.id)) {\n isUpdate = false;\n } else if (this._sourceDbChanges.codeSpec.updateIds.has(codeSpec.id)) {\n isUpdate = true;\n } else {\n return; // not in changeset, don't export\n }\n }\n // passed changeset test, now apply standard exclusion rules\n if (this._excludedCodeSpecNames.has(codeSpec.name)) {\n Logger.logInfo(loggerCategory, `Excluding CodeSpec: ${codeSpec.name}`);\n return;\n }\n // CodeSpec has passed standard exclusion rules, now give handler a chance to accept/reject export\n if (await this.handler.shouldExportCodeSpec(codeSpec)) {\n Logger.logTrace(\n loggerCategory,\n `exportCodeSpec(${codeSpecName})${this.getChangeOpSuffix(isUpdate)}`\n );\n await this.handler.onExportCodeSpec(codeSpec, isUpdate);\n return this.trackProgress();\n }\n }\n\n /** Export a single CodeSpec from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportCodeSpecById(codeSpecId: Id64String): Promise<void> {\n const codeSpec: CodeSpec = this.sourceDb.codeSpecs.getById(codeSpecId);\n return this.exportCodeSpecByName(codeSpec.name);\n }\n\n /** Export all fonts from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportFonts(): Promise<void> {\n Logger.logTrace(loggerCategory, \"exportFonts()\");\n for (const font of this.sourceDb.fonts.queryMappedFamilies()) {\n await this.exportFontByFontProps(font);\n }\n }\n\n /** Export a single font from the source iModel.\n * @note multiple fonts can have the same font name, if a font with a specific type is needed use exportFontByFontFamilyDescriptor.\n * If not this will only export the first font with this type in the db.\n */\n public async exportFontByName(fontName: string): Promise<void> {\n Logger.logTrace(loggerCategory, `exportFontByName(${fontName})`);\n const fontId: FontId | undefined = this.sourceDb.fonts.findId({\n name: fontName,\n });\n if (undefined !== fontId) {\n await this.exportFontByNumber(fontId);\n }\n }\n\n /** Export a single font from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportFontByFontProps(fontProps: FontProps): Promise<void> {\n Logger.logTrace(\n loggerCategory,\n `exportFontByFamily(${fontProps.name}, ${fontProps.type})`\n );\n await this.handler.onExportFont(fontProps, true);\n return this.trackProgress();\n }\n\n /** Export a single font from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportFontByFontFamilyDescriptor(\n fontFamily: FontFamilyDescriptor\n ): Promise<void> {\n Logger.logTrace(\n loggerCategory,\n `exportFontByFamilyDescriptor(${fontFamily.name}, ${fontFamily.type})`\n );\n const fontId: FontId | undefined =\n await this.sourceDb.fonts.acquireId(fontFamily);\n if (undefined !== fontId) {\n await this.exportFontByFontProps({ ...fontFamily, id: fontId });\n }\n }\n\n /** Export a single font from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportFontByNumber(fontNumber: number): Promise<void> {\n /** ChangedInstanceIds contains EC-mapped changes, but the font table is not EC-mapped.\n * Always export fonts because their changes are therefore absent from sourceDbChanges.\n * It is very rare and even problematic for the font table to reach a large size, so it is not a bottleneck in transforming changes.\n * See https://github.com/iTwin/imodel-transformer/pull/135 for removed code.\n */\n Logger.logTrace(loggerCategory, `exportFontById(${fontNumber})`);\n const font: FontFamilyDescriptor | undefined =\n this.sourceDb.fonts.findDescriptor(fontNumber);\n if (undefined !== font) {\n await this.exportFontByFontFamilyDescriptor(font);\n }\n }\n\n /** Export the model container, contents, and sub-models from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportModel(modeledElementId: Id64String): Promise<void> {\n return this.runScopedElementExport(async () =>\n this.exportModelImpl(modeledElementId)\n );\n }\n\n private async exportModelImpl(modeledElementId: Id64String): Promise<void> {\n const model: Model = this.sourceDb.models.getModel(modeledElementId);\n if (model.isTemplate && !this.wantTemplateModels) {\n return;\n }\n const modeledElement: Element = this.sourceDb.elements.getElement({\n id: modeledElementId,\n wantGeometry: this.wantGeometry,\n wantBRepData: this.wantGeometry,\n });\n Logger.logTrace(loggerCategory, `exportModel(${modeledElementId})`);\n if (await this.shouldExportElement(modeledElement)) {\n await this.exportModelContainer(model);\n if (this.visitElements) {\n await this.exportModelContents(modeledElementId);\n }\n await this.exportSubModels(modeledElementId);\n }\n }\n\n /** Export the model (the container only) from the source iModel. */\n private async exportModelContainer(model: Model): Promise<void> {\n let isUpdate: boolean | undefined;\n if (undefined !== this._sourceDbChanges) {\n // is changeset information available?\n if (this._sourceDbChanges.model.insertIds.has(model.id)) {\n isUpdate = false;\n } else if (this._sourceDbChanges.model.updateIds.has(model.id)) {\n isUpdate = true;\n } else {\n return; // not in changeset, don't export\n }\n }\n await this.handler.onExportModel(model, isUpdate);\n return this.trackProgress();\n }\n\n private _yieldManager = new YieldManager();\n\n /** Export the model contents.\n * @param modelId The only required parameter\n * @param elementClassFullName Can be optionally specified if the goal is to export a subset of the model contents\n * @param skipRootSubject Decides whether or not to export the root Subject. It is normally left undefined except for internal implementation purposes.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportModelContents(\n modelId: Id64String,\n elementClassFullName: string = Element.classFullName,\n skipRootSubject?: boolean\n ): Promise<void> {\n return this.runScopedElementExport(async () =>\n this.exportModelContentsImpl(\n modelId,\n elementClassFullName,\n skipRootSubject\n )\n );\n }\n\n private async exportModelContentsImpl(\n modelId: Id64String,\n elementClassFullName: string,\n skipRootSubject?: boolean\n ): Promise<void> {\n if (skipRootSubject) {\n // NOTE: IModelTransformer.processAll should skip the root Subject since it is specific to the individual iModel and is not part of the changes that need to be synchronized\n // NOTE: IModelExporter.exportAll should not skip the root Subject since the goal is to export everything\n assert(modelId === IModel.repositoryModelId); // flag is only relevant when processing the RepositoryModel\n }\n if (!this.visitElements) {\n Logger.logTrace(\n loggerCategory,\n `visitElements=false, skipping exportModelContents(${modelId})`\n );\n return;\n }\n if (undefined !== this._sourceDbChanges) {\n // is changeset information available?\n if (\n !this._sourceDbChanges.model.insertIds.has(modelId) &&\n !this._sourceDbChanges.model.updateIds.has(modelId)\n ) {\n return; // this optimization assumes that the Model changes (LastMod) any time an Element in the Model changes\n }\n if (\n this.canUseChangedElementForest() &&\n elementClassFullName === Element.classFullName\n ) {\n const forest = await this.getChangedElementForest();\n if (forest !== undefined) {\n Logger.logTrace(\n loggerCategory,\n `exportModelContents(${modelId}) via changed-element index`\n );\n for (const rootId of forest.getModelRoots(modelId)) {\n if (skipRootSubject && rootId === IModel.rootSubjectId) continue;\n await this.exportElement(rootId);\n await this._yieldManager.allowYield();\n }\n return;\n }\n }\n }\n Logger.logTrace(loggerCategory, `exportModelContents(${modelId})`);\n const rootFilter = skipRootSubject\n ? \"e.Parent.Id IS NULL AND e.Model.Id=:modelId AND e.ECInstanceId!=:rootSubjectId\"\n : \"e.Parent.Id IS NULL AND e.Model.Id=:modelId\";\n const params = new QueryBinder().bindId(\"modelId\", modelId);\n if (skipRootSubject) {\n params.bindId(\"rootSubjectId\", IModel.rootSubjectId);\n }\n if (this.canUseSetBasedTraversal()) {\n return this.exportElementTreesStreamed(\n `SELECT e.ECInstanceId, 0 FROM ${elementClassFullName} e WHERE ${rootFilter}`,\n params\n );\n }\n const sql = `SELECT e.ECInstanceId FROM ${elementClassFullName} e WHERE ${rootFilter} ORDER BY e.ECInstanceId`;\n for await (const row of this.sourceDb.createQueryReader(sql, params, {\n usePrimaryConn: true,\n })) {\n await this.exportElement(row.id);\n await this._yieldManager.allowYield();\n }\n }\n\n /** Whether the public element traversal methods still have their base implementations. */\n private hasDefaultElementTraversal(): boolean {\n // The optimized helpers bypass these public overridable methods. Compare function\n // identity so subclass, bound, wrapped, or instrumented methods retain legacy dispatch.\n return (\n this.exportElement === IModelExporter.prototype.exportElement &&\n this.exportChildElements === IModelExporter.prototype.exportChildElements\n );\n }\n\n /** Whether hierarchy traversal can use the streamed query.\n * Changes mode and overrides of the public traversal methods require legacy dispatch.\n */\n private canUseSetBasedTraversal(): boolean {\n return (\n this._sourceDbChanges === undefined && this.hasDefaultElementTraversal()\n );\n }\n\n /** Stream element trees in the legacy depth-first order with one recursive ECSQL query.\n * Rejected subtrees are skipped in the exporter without loading their descendants.\n * @param anchorSelect a SELECT producing `(ECInstanceId, 0)` rows for the tree roots\n */\n private async exportElementTreesStreamed(\n anchorSelect: string,\n params: QueryBinder\n ): Promise<void> {\n // The anchor seeds roots at depth 0; the recursive term follows parent links.\n // SQLite's documented recursive-CTE queue behavior makes this ORDER BY a\n // depth-first priority queue, with ascending IDs breaking ties. Supported\n // iModel databases use SQLite, so the outer SELECT intentionally consumes\n // the CTE rows in this queue order.\n const sql = `\n WITH RECURSIVE ElementTree (ECInstanceId, Depth) AS (\n ${anchorSelect}\n UNION ALL\n SELECT c.ECInstanceId, t.Depth + 1 FROM ${Element.classFullName} c\n JOIN ElementTree t ON c.Parent.Id = t.ECInstanceId\n ORDER BY 2 DESC, 1 ASC\n )\n SELECT ECInstanceId, Depth FROM ElementTree`;\n let pruneDepth: number | undefined;\n for await (const row of this.sourceDb.createQueryReader(sql, params, {\n usePrimaryConn: true,\n })) {\n const elementId: Id64String = row[0];\n const depth: number = row[1];\n const isPruned = pruneDepth !== undefined && depth > pruneDepth;\n if (!isPruned) {\n pruneDepth = undefined;\n if ((await this.exportElementShallow(elementId)) === \"skip\")\n pruneDepth = depth;\n }\n // Keep the streamed loop responsive, including while consuming a rejected subtree.\n await this._yieldManager.allowYield();\n }\n }\n\n /** Export the sub-models directly below the specified model.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportSubModels(parentModelId: Id64String): Promise<void> {\n return this.runScopedElementExport(async () =>\n this.exportSubModelsImpl(parentModelId)\n );\n }\n\n private async exportSubModelsImpl(parentModelId: Id64String): Promise<void> {\n Logger.logTrace(loggerCategory, `exportSubModels(${parentModelId})`);\n // Export DefinitionModels before other Models, each in ECInstanceId order.\n // Classifying in ECSQL avoids loading every sub-model here and again in exportModel.\n // Partition in JS: sorting on the classification in ECSQL raised peak native memory on many-model iModels.\n const sql = `\n SELECT ECInstanceId, IIF(ECClassId IS (${DefinitionModel.classFullName}), 1, 0) isDefinitionModel\n FROM ${Model.classFullName}\n WHERE ParentModel.Id=:parentModelId\n ORDER BY ECInstanceId`;\n const params = new QueryBinder().bindId(\"parentModelId\", parentModelId);\n const definitionModelIds: Id64String[] = [];\n const otherModelIds: Id64String[] = [];\n for await (const row of this.sourceDb.createQueryReader(sql, params, {\n usePrimaryConn: true,\n })) {\n (row.isDefinitionModel ? definitionModelIds : otherModelIds).push(row.id);\n }\n for (const subModelId of [...definitionModelIds, ...otherModelIds]) {\n await this.exportModel(subModelId);\n }\n }\n\n /** Returns true if the specified element should be exported.\n * This considers the standard IModelExporter exclusion rules plus calls [IModelExportHandler.shouldExportElement]($transformer) for any custom exclusion rules.\n * @note This method is called from within [[exportChanges]] and [[exportAll]], so usually does not need to be called directly.\n */\n public async shouldExportElement(element: Element): Promise<boolean> {\n if (this._excludedElementIds.has(element.id)) {\n Logger.logInfo(loggerCategory, `Excluded element ${element.id} by Id`);\n return false;\n }\n if (\n element instanceof GeometricElement &&\n this._excludedElementCategoryIds.has(element.category)\n ) {\n Logger.logInfo(\n loggerCategory,\n `Excluded element ${element.id} by Category`\n );\n return false;\n }\n if (\n !this.wantTemplateModels &&\n element instanceof RecipeDefinitionElement\n ) {\n Logger.logInfo(\n loggerCategory,\n `Excluded RecipeDefinitionElement ${element.id} because wantTemplate=false`\n );\n return false;\n }\n for (const excludedElementClass of this._excludedElementClasses) {\n if (element instanceof excludedElementClass) {\n Logger.logInfo(\n loggerCategory,\n `Excluded element ${element.id} by class: ${excludedElementClass.classFullName}`\n );\n return false;\n }\n }\n // element has passed standard exclusion rules, now give handler a chance to accept/reject\n if (!(await this.handler.shouldExportElement(element))) {\n return false;\n }\n return true;\n }\n\n /** Export the specified element and its child elements (if applicable).\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n * @note ElementAspects are exported separately in owner-scoped groups, so their callbacks are not guaranteed to follow this element callback.\n */\n public async exportElement(elementId: Id64String): Promise<void> {\n return this.runScopedElementExport(async () =>\n this.exportElementImpl(elementId)\n );\n }\n\n private async exportElementImpl(elementId: Id64String): Promise<void> {\n if (!this.visitElements) {\n Logger.logTrace(\n loggerCategory,\n `visitElements=false, skipping exportElement(${elementId})`\n );\n return;\n }\n\n const childVisit = await this.exportElementShallow(elementId);\n if (childVisit === \"visit\") return this.exportChildElements(elementId);\n if (childVisit === \"passThrough\") {\n // The element's own filter result is decided later, if a changed descendant is reached.\n this._unchangedAncestors.push({ elementId });\n try {\n await this.exportChildElements(elementId);\n } finally {\n this._unchangedAncestors.pop();\n }\n }\n }\n\n /** Returns the filter result for an unchanged ancestor on the current change-processing path, or `undefined` if it has not been filtered.\n * @internal\n */\n public getUnchangedAncestorFilterResult(\n elementId: Id64String\n ): boolean | undefined {\n return this._unchangedAncestors.find(\n (ancestor) => ancestor.elementId === elementId\n )?.accepted;\n }\n\n /** Filters the unchanged ancestors of a changed element, top-down, once each.\n * @returns `false` if an ancestor is rejected.\n */\n private async acceptUnchangedAncestors(): Promise<boolean> {\n for (const ancestor of this._unchangedAncestors) {\n if (ancestor.accepted === undefined) {\n const element = this.sourceDb.elements.getElement({\n id: ancestor.elementId,\n wantGeometry: this.wantGeometry,\n wantBRepData: this.wantGeometry,\n });\n ancestor.accepted = await this.shouldExportElement(element);\n if (!ancestor.accepted)\n await this.handler.onSkipElement(ancestor.elementId);\n }\n if (!ancestor.accepted) return false;\n }\n return true;\n }\n\n /** Runs the export callbacks for a single element without visiting its children.\n * @returns how to continue with the element's children: skip them, visit them, or pass through an unchanged element to reach changed descendants.\n */\n private async exportElementShallow(\n elementId: Id64String\n ): Promise<\"skip\" | \"visit\" | \"passThrough\"> {\n // Descendants of a rejected unchanged ancestor are skipped, as in a full export.\n if (\n this._unchangedAncestors.some((ancestor) => ancestor.accepted === false)\n )\n return \"skip\";\n\n // Return early if the elementId is already excluded so it does not need to be loaded.\n if (this._excludedElementIds.has(elementId)) {\n Logger.logInfo(loggerCategory, `Excluded element ${elementId} by Id`);\n await this.handler.onSkipElement(elementId);\n return \"skip\";\n }\n\n const isUpdate = this._sourceDbChanges?.element.insertIds.has(elementId)\n ? false\n : this._sourceDbChanges?.element.updateIds.has(elementId)\n ? true\n : undefined;\n\n // An unchanged element may still connect a changed descendant to its model root.\n if (this._sourceDbChanges !== undefined && isUpdate === undefined)\n return \"passThrough\";\n\n if (!(await this.acceptUnchangedAncestors())) return \"skip\";\n\n const element = this.sourceDb.elements.getElement({\n id: elementId,\n wantGeometry: this.wantGeometry,\n wantBRepData: this.wantGeometry,\n });\n Logger.logTrace(\n loggerCategory,\n `exportElement(${\n element.id\n }, \"${element.getDisplayLabel()}\")${this.getChangeOpSuffix(isUpdate)}`\n );\n // the order and `await`ing of calls beyond here is depended upon by the IModelTransformer for a current bug workaround\n if (await this.shouldExportElement(element)) {\n await this.handler.preExportElement(element);\n await this.handler.onExportElement(element, isUpdate);\n await this.trackProgress();\n await this._elementAspectExportCoordinator.addAcceptedOwner(elementId);\n return \"visit\";\n }\n await this.handler.onSkipElement(element.id);\n return \"skip\";\n }\n\n /** Export the child elements of the specified element from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportChildElements(elementId: Id64String): Promise<void> {\n return this.runScopedElementExport(async () =>\n this.exportChildElementsImpl(elementId)\n );\n }\n\n private async exportChildElementsImpl(elementId: Id64String): Promise<void> {\n if (!this.visitElements) {\n Logger.logTrace(\n loggerCategory,\n `visitElements=false, skipping exportChildElements(${elementId})`\n );\n return;\n }\n if (this.canUseSetBasedTraversal()) {\n Logger.logTrace(loggerCategory, `exportChildElements(${elementId})`);\n // Seed the stream with direct children; the helper adds their descendants.\n return this.exportElementTreesStreamed(\n `SELECT e.ECInstanceId, 0 FROM ${Element.classFullName} e WHERE e.Parent.Id=:parentId`,\n new QueryBinder().bindId(\"parentId\", elementId)\n );\n }\n\n let childElementIds: readonly Id64String[] | undefined;\n if (this.canUseChangedElementForest()) {\n const forest = await this.getChangedElementForest();\n if (forest !== undefined) {\n Logger.logTrace(\n loggerCategory,\n `exportChildElements(${elementId}) via changed-element index`\n );\n childElementIds = forest.getChildren(elementId);\n }\n }\n childElementIds ??= this.sourceDb.elements.queryChildren(elementId);\n\n if (childElementIds.length > 0) {\n Logger.logTrace(loggerCategory, `exportChildElements(${elementId})`);\n for (const childElementId of childElementIds) {\n await this.exportElement(childElementId);\n }\n }\n }\n\n /** Whether change processing may use the sparse hierarchy as the child-id source.\n * Custom traversal overrides retain the previous full element dispatch.\n */\n private canUseChangedElementForest(): boolean {\n return (\n this._sourceDbChanges !== undefined &&\n this._changedElementTraversal?.useForest === true &&\n this.hasDefaultElementTraversal()\n );\n }\n\n private getOverriddenElementTraversalMethods(): string[] {\n const methods: string[] = [];\n if (this.exportElement !== IModelExporter.prototype.exportElement)\n methods.push(\"exportElement\");\n if (\n this.exportChildElements !== IModelExporter.prototype.exportChildElements\n )\n methods.push(\"exportChildElements\");\n return methods;\n }\n\n private disableChangedElementForest(reason: string): void {\n if (!this._changedElementTraversal?.useForest) return;\n this._changedElementTraversal.useForest = false;\n Logger.logInfo(\n loggerCategory,\n `Using full element traversal for change processing because ${reason}.`\n );\n }\n\n private async createChangedElementForest(): Promise<\n ChangedElementForest | undefined\n > {\n nodeAssert(\n this._sourceDbChanges !== undefined,\n \"changed-element traversal requires sourceDbChanges\"\n );\n const excludedElementIds = this._excludedElementIds;\n const candidateCountUpperBound =\n this._sourceDbChanges.element.insertIds.size +\n this._sourceDbChanges.element.updateIds.size +\n excludedElementIds.size;\n if (candidateCountUpperBound > this._changedElementForestElementLimit) {\n this.disableChangedElementForest(\n `${candidateCountUpperBound} candidate element references exceed the ${this._changedElementForestElementLimit}-element in-memory index limit`\n );\n return undefined;\n }\n\n const forest = await ChangedElementForest.create(\n this.sourceDb,\n [\n ...this._sourceDbChanges.element.insertIds,\n ...this._sourceDbChanges.element.updateIds,\n ...excludedElementIds,\n ],\n this._changedElementForestElementLimit\n );\n if (forest === undefined) {\n this.disableChangedElementForest(\n `the required parent hierarchy exceeds the ${this._changedElementForestElementLimit}-element in-memory index limit`\n );\n }\n return forest;\n }\n\n private async getChangedElementForest(): Promise<\n ChangedElementForest | undefined\n > {\n const traversal = this._changedElementTraversal;\n nodeAssert(\n traversal !== undefined,\n \"changed-element index requires an active traversal scope\"\n );\n return (traversal.forest ??= this.createChangedElementForest());\n }\n\n /** Exports all aspects owned by the supplied elements. */\n private async exportAspectsForOwners(\n ownerElementIds: ReadonlySet<Id64String>\n ): Promise<void> {\n return this._elementAspectExportCoordinator.exportOwners(ownerElementIds);\n }\n\n private async filterOwnerElementIdsForAspectExport(\n ownerElementIds: ReadonlySet<Id64String>\n ): Promise<ReadonlySet<Id64String>> {\n if (ownerElementIds.size === 0) return new Set<Id64String>();\n\n const elementFacts =\n await this.queryAspectElementHierarchyFacts(ownerElementIds);\n const modelFacts = await this.queryAspectModelHierarchyFacts(\n new Set(\n [...elementFacts.values()].map((elementFact) => elementFact.modelId)\n )\n );\n await this.queryAspectElementFacts(\n new Set(modelFacts.keys()),\n elementFacts\n );\n\n const elementIds = new Set<Id64String>();\n for (const elementId of ownerElementIds) {\n if (\n this._skipPropagateChangesToRootElements &&\n this._rootElementIds.has(elementId)\n ) {\n continue;\n }\n if (\n await this.shouldExportElementHierarchyForAspect(\n elementId,\n elementFacts,\n modelFacts\n )\n ) {\n elementIds.add(elementId);\n }\n }\n return elementIds;\n }\n\n private async shouldExportElementHierarchyForAspect(\n elementId: Id64String,\n elementFacts: ReadonlyMap<Id64String, AspectElementFact>,\n modelFacts: ReadonlyMap<Id64String, AspectModelFact>\n ): Promise<boolean> {\n let elementFact = elementFacts.get(elementId);\n while (elementFact !== undefined) {\n if (\n !(await this.shouldExportElementForAspect(elementFact.id, elementFact))\n )\n return false;\n if (\n !(await this.shouldExportModelForAspect(\n elementFact.modelId,\n elementFacts,\n modelFacts\n ))\n ) {\n return false;\n }\n const parentId = elementFact.parentId;\n if (\n parentId === undefined ||\n (this._skipPropagateChangesToRootElements &&\n parentId === IModel.rootSubjectId)\n ) {\n return true;\n }\n elementFact = elementFacts.get(parentId);\n }\n return false;\n }\n\n private async shouldExportModelForAspect(\n modelId: Id64String,\n elementFacts: ReadonlyMap<Id64String, AspectElementFact>,\n modelFacts: ReadonlyMap<Id64String, AspectModelFact>\n ): Promise<boolean> {\n const modelFact = modelFacts.get(modelId);\n if (modelFact === undefined) {\n this.sourceDb.models.getModel(modelId);\n return false;\n }\n if (modelFact.isTemplate && !this.wantTemplateModels) return false;\n if (\n modelFact.id !== IModel.repositoryModelId &&\n modelFact.id !== IModel.dictionaryId &&\n modelFact.id !== \"0xe\" &&\n !(await this.shouldExportElementForAspect(\n modelFact.id,\n elementFacts.get(modelFact.id)\n ))\n ) {\n return false;\n }\n if (\n modelFact.parentModelId === undefined ||\n modelFact.parentModelId === modelFact.id\n ) {\n return true;\n }\n return this.shouldExportModelForAspect(\n modelFact.parentModelId,\n elementFacts,\n modelFacts\n );\n }\n\n private beginChangedElementTraversalScope(): boolean {\n if (\n this._sourceDbChanges === undefined ||\n this._changedElementTraversal !== undefined\n ) {\n return false;\n }\n\n this._changedElementTraversal = { useForest: true };\n\n const overriddenMethods = this.getOverriddenElementTraversalMethods();\n if (this.visitElements && overriddenMethods.length > 0) {\n this.disableChangedElementForest(\n `${overriddenMethods.join(\" and \")} ${overriddenMethods.length === 1 ? \"is\" : \"are\"} overridden by the exporter subclass`\n );\n }\n return true;\n }\n\n private endChangedElementTraversalScope(): void {\n this._changedElementTraversal = undefined;\n }\n\n private async runScopedElementExport(\n exportElements: () => Promise<void>\n ): Promise<void> {\n const ownsChangedElementTraversal =\n this.beginChangedElementTraversalScope();\n try {\n await this._elementAspectExportCoordinator.run(exportElements);\n } finally {\n if (ownsChangedElementTraversal) this.endChangedElementTraversalScope();\n }\n }\n\n /** Apply the element export filter when deciding whether to process an aspect owner. @internal */\n private async shouldExportElementForAspect(\n elementId: Id64String,\n elementFact?: AspectElementFact\n ): Promise<boolean> {\n if (!this.visitElements) return false;\n\n if (\n this.shouldExportElement ===\n IModelExporter.prototype.shouldExportElement &&\n elementFact !== undefined &&\n !this.shouldExportElementFact(elementFact)\n ) {\n return false;\n }\n\n const element = this.sourceDb.elements.getElement({\n id: elementId,\n wantGeometry: false,\n wantBRepData: false,\n });\n return this.shouldExportElement(element);\n }\n\n private shouldExportElementFact(elementFact: AspectElementFact): boolean {\n if (this._excludedElementIds.has(elementFact.id)) {\n Logger.logInfo(\n loggerCategory,\n `Excluded element ${elementFact.id} by Id`\n );\n return false;\n }\n\n const elementClass = this.sourceDb.getJsClass<typeof Element>(\n elementFact.classFullName\n );\n if (\n (elementFact.classFullName === GeometricElement.classFullName ||\n elementClass.prototype instanceof GeometricElement) &&\n elementFact.categoryId !== undefined &&\n this._excludedElementCategoryIds.has(elementFact.categoryId)\n ) {\n Logger.logInfo(\n loggerCategory,\n `Excluded element ${elementFact.id} by Category`\n );\n return false;\n }\n if (\n !this.wantTemplateModels &&\n (elementFact.classFullName === RecipeDefinitionElement.classFullName ||\n elementClass.prototype instanceof RecipeDefinitionElement)\n ) {\n Logger.logInfo(\n loggerCategory,\n `Excluded RecipeDefinitionElement ${elementFact.id} because wantTemplate=false`\n );\n return false;\n }\n for (const excludedElementClass of this._excludedElementClasses) {\n if (\n elementFact.classFullName === excludedElementClass.classFullName ||\n elementClass.prototype instanceof excludedElementClass\n ) {\n Logger.logInfo(\n loggerCategory,\n `Excluded element ${elementFact.id} by class: ${excludedElementClass.classFullName}`\n );\n return false;\n }\n }\n return true;\n }\n\n private async queryAspectElementHierarchyFacts(\n elementIds: ReadonlySet<Id64String>\n ): Promise<Map<Id64String, AspectElementFact>> {\n const elementFacts = new Map<Id64String, AspectElementFact>();\n const queriedElementIds = new Set<Id64String>();\n let pendingElementIds = new Set(elementIds);\n while (pendingElementIds.size > 0) {\n const currentElementIds = pendingElementIds;\n pendingElementIds = new Set<Id64String>();\n await this.queryAspectElementFacts(currentElementIds, elementFacts);\n for (const elementId of currentElementIds)\n queriedElementIds.add(elementId);\n for (const elementId of currentElementIds) {\n const parentId = elementFacts.get(elementId)?.parentId;\n if (\n parentId !== undefined &&\n !queriedElementIds.has(parentId) &&\n !elementFacts.has(parentId)\n ) {\n pendingElementIds.add(parentId);\n }\n }\n }\n return elementFacts;\n }\n\n private async queryAspectElementFacts(\n elementIds: ReadonlySet<Id64String>,\n elementFacts: Map<Id64String, AspectElementFact>\n ): Promise<void> {\n const unqueriedElementIds = new Set(\n [...elementIds].filter((elementId) => !elementFacts.has(elementId))\n );\n if (unqueriedElementIds.size === 0) return;\n\n for (const elementIdBatch of this.getAspectOwnerIdBatches(\n unqueriedElementIds\n )) {\n const queryParams = new QueryBinder().bindIdSet(\n \"elementIds\",\n elementIdBatch\n );\n for await (const row of this.sourceDb.createQueryReader(\n `SELECT e.ECInstanceId id, e.Parent.Id parentId, e.Model.Id modelId,\n ec_className(e.ECClassId, 's') schemaName,\n ec_className(e.ECClassId, 'c') className\n FROM bis.Element e\n INNER JOIN IdSet(:elementIds) ids ON ids.id = e.ECInstanceId`,\n queryParams,\n { usePrimaryConn: true }\n )) {\n elementFacts.set(row.id, {\n id: row.id,\n parentId: row.parentId ?? undefined,\n modelId: row.modelId,\n classFullName: `${row.schemaName}:${row.className}`,\n });\n }\n if (this._excludedElementCategoryIds.size > 0) {\n const categoryQueryParams = new QueryBinder().bindIdSet(\n \"elementIds\",\n elementIdBatch\n );\n for await (const row of this.sourceDb.createQueryReader(\n `SELECT g.ECInstanceId id, g.Category.Id categoryId\n FROM bis.GeometricElement g\n INNER JOIN IdSet(:elementIds) ids ON ids.id = g.ECInstanceId`,\n categoryQueryParams,\n { usePrimaryConn: true }\n )) {\n const elementFact = elementFacts.get(row.id);\n if (elementFact !== undefined) {\n elementFact.categoryId = row.categoryId;\n }\n }\n }\n }\n }\n\n private async queryAspectModelHierarchyFacts(\n modelIds: ReadonlySet<Id64String>\n ): Promise<Map<Id64String, AspectModelFact>> {\n const modelFacts = new Map<Id64String, AspectModelFact>();\n const queriedModelIds = new Set<Id64String>();\n let pendingModelIds = new Set(modelIds);\n while (pendingModelIds.size > 0) {\n const currentModelIds = pendingModelIds;\n pendingModelIds = new Set<Id64String>();\n for (const modelIdBatch of this.getAspectOwnerIdBatches(\n currentModelIds\n )) {\n const queryParams = new QueryBinder().bindIdSet(\n \"modelIds\",\n modelIdBatch\n );\n for await (const row of this.sourceDb.createQueryReader(\n `SELECT model.ECInstanceId id, model.ParentModel.Id parentModelId, model.IsTemplate isTemplate\n FROM bis.Model model\n INNER JOIN IdSet(:modelIds) ids ON ids.id = model.ECInstanceId`,\n queryParams,\n { usePrimaryConn: true }\n )) {\n modelFacts.set(row.id, {\n id: row.id,\n parentModelId: row.parentModelId ?? undefined,\n isTemplate: row.isTemplate === true || row.isTemplate === 1,\n });\n }\n }\n for (const modelId of currentModelIds) queriedModelIds.add(modelId);\n for (const modelId of currentModelIds) {\n const parentModelId = modelFacts.get(modelId)?.parentModelId;\n if (\n parentModelId !== undefined &&\n !queriedModelIds.has(parentModelId) &&\n !modelFacts.has(parentModelId)\n ) {\n pendingModelIds.add(parentModelId);\n }\n }\n }\n return modelFacts;\n }\n\n private *getAspectOwnerIdBatches(\n ids: ReadonlySet<Id64String>\n ): Iterable<Id64Set> {\n let batch = new Set<Id64String>();\n for (const id of ids) {\n batch.add(id);\n if (batch.size === IModelExporter._elementAspectOwnerBatchSize) {\n yield batch;\n batch = new Set<Id64String>();\n }\n }\n if (batch.size > 0) yield batch;\n }\n\n /** Exports all relationships that subclass from the specified base class.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n * @note This is the bulk traversal path. It hydrates relationships with one streaming query and calls [[exportRelationshipInstance]] directly; it does not call [[exportRelationship]] once per row.\n */\n public async exportRelationships(\n baseRelClassFullName: string\n ): Promise<void> {\n if (!this.visitRelationships) {\n Logger.logTrace(\n loggerCategory,\n \"visitRelationships=false, skipping exportRelationships()\"\n );\n return;\n }\n Logger.logTrace(\n loggerCategory,\n `exportRelationships(${baseRelClassFullName})`\n );\n\n const changedRelationshipIds =\n this._sourceDbChanges === undefined\n ? undefined\n : new Set<Id64String>([\n ...this._sourceDbChanges.relationship.insertIds,\n ...this._sourceDbChanges.relationship.updateIds,\n ]);\n if (changedRelationshipIds?.size === 0) {\n // Deleted relationships are handled by exportChanges after this traversal; they are no\n // longer present in the source iModel and must not cause a full relationship scan here.\n Logger.logTrace(\n loggerCategory,\n \"No inserted or updated relationships, skipping exportRelationships()\"\n );\n return;\n }\n\n const changedRelationshipJoin =\n changedRelationshipIds === undefined\n ? undefined\n : \"INNER JOIN IdSet(:changedRelationshipIds) changed ON changed.id = r.ECInstanceId\";\n const relationshipWhereClause =\n \"s.ECInstanceId IS NOT NULL AND t.ECInstanceId IS NOT NULL\";\n // Bound the async reader's retained raw rows while preserving batched query throughput.\n // Keyset pagination avoids rescanning rows returned by earlier batches.\n const relationshipQueryBatchSize = 1000;\n let lastRelationshipId: Id64String | undefined;\n while (true) {\n let rowsRead = 0;\n const whereClause =\n lastRelationshipId === undefined\n ? relationshipWhereClause\n : `${relationshipWhereClause} AND r.ECInstanceId > :lastRelationshipId`;\n // QueryBinder parameters are immutable after binding a name. Recreate the binder for each\n // keyset page so the changing boundary can be bound without redefining a property.\n const queryParams =\n changedRelationshipIds === undefined && lastRelationshipId === undefined\n ? undefined\n : new QueryBinder();\n if (queryParams !== undefined) {\n if (changedRelationshipIds !== undefined) {\n queryParams.bindIdSet(\n \"changedRelationshipIds\",\n changedRelationshipIds\n );\n }\n if (lastRelationshipId !== undefined) {\n queryParams.bindId(\"lastRelationshipId\", lastRelationshipId);\n }\n }\n const reader = this.sourceDb.createQueryReader(\n this.getRelationshipQuery(\n baseRelClassFullName,\n \"JOIN\",\n whereClause,\n changedRelationshipJoin\n ),\n queryParams,\n {\n usePrimaryConn: true,\n limit: { count: relationshipQueryBatchSize },\n }\n );\n for await (const row of reader) {\n rowsRead++;\n const relInstanceId: Id64String = row.relInstanceId;\n lastRelationshipId = relInstanceId;\n const changesetFilter =\n this.checkRelationshipChangesetFilter(relInstanceId);\n if (changesetFilter.skip) {\n await this._yieldManager.allowYield();\n continue;\n }\n await this.exportHydratedRelationship(\n row.rawInstance,\n row.sourceFedGuid,\n row.targetFedGuid,\n changesetFilter.isUpdate\n );\n await this._yieldManager.allowYield();\n }\n if (rowsRead < relationshipQueryBatchSize) break;\n }\n }\n\n /** Builds the raw relationship query used by the bulk and targeted export paths. */\n private getRelationshipQuery(\n relClassFullName: string,\n endpointJoin: \"JOIN\" | \"LEFT JOIN\",\n whereClause: string,\n relationshipJoin?: string\n ): string {\n return `SELECT r.$ AS rawInstance, r.ECInstanceId AS relInstanceId, s.FederationGuid AS sourceFedGuid, t.FederationGuid AS targetFedGuid FROM ${relClassFullName} r\n ${relationshipJoin ?? \"\"}\n ${endpointJoin} bis.Element s ON s.ECInstanceId = r.SourceECInstanceId\n ${endpointJoin} bis.Element t ON t.ECInstanceId = r.TargetECInstanceId\n WHERE ${whereClause}\n ORDER BY r.ECInstanceId\n OPTIONS USE_JS_PROP_NAMES DO_NOT_TRUNCATE_BLOB`;\n }\n\n /** Applies the changeset filter (when exporting changes) to a relationship instance id.\n * @returns whether to skip the relationship, and whether the export is an update.\n */\n private checkRelationshipChangesetFilter(relInstanceId: Id64String): {\n skip: boolean;\n isUpdate: boolean | undefined;\n } {\n if (undefined === this._sourceDbChanges)\n return { skip: false, isUpdate: undefined };\n if (this._sourceDbChanges.relationship.insertIds.has(relInstanceId))\n return { skip: false, isUpdate: false };\n if (this._sourceDbChanges.relationship.updateIds.has(relInstanceId))\n return { skip: false, isUpdate: true };\n return { skip: true, isUpdate: undefined }; // not in changeset, don't export\n }\n\n /** Converts a raw `$` instance-access row into [RelationshipProps]($common). */\n private getRelationshipProps(rawInstance: unknown): RelationshipProps {\n const parsedRow: unknown =\n typeof rawInstance === \"string\"\n ? JSON.parse(rawInstance, Base64EncodedString.reviver)\n : rawInstance;\n if (!JsonUtils.isObject(parsedRow))\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.InvalidRelationshipData,\n },\n message: \"Expected a Relationship instance query to return an object\",\n });\n\n const row: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(parsedRow)) {\n const ecPropertyName =\n key.length === 0 ? key : key[0].toUpperCase() + key.substring(1);\n row[ECJsNames.toJsName(ecPropertyName)] = value;\n }\n\n const className = row.className;\n if (typeof className !== \"string\")\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.InvalidRelationshipData,\n },\n message: \"Expected a Relationship instance query to return a className\",\n });\n\n row.classFullName = className.replace(\".\", \":\");\n delete row.className;\n delete row.sourceClassName;\n delete row.targetClassName;\n return row as unknown as RelationshipProps;\n }\n\n /** Export one specified relationship from the source iModel.\n * @note This targeted path is separate from [[exportRelationships]], which traverses a class hierarchy. It uses the same raw instance query and passes endpoint FederationGuids to the handler.\n */\n public async exportRelationship(\n relClassFullName: string,\n relInstanceId: Id64String\n ): Promise<void> {\n if (!this.visitRelationships) {\n Logger.logTrace(\n loggerCategory,\n `visitRelationships=false, skipping exportRelationship(${relClassFullName}, ${relInstanceId})`\n );\n return;\n }\n const changesetFilter =\n this.checkRelationshipChangesetFilter(relInstanceId);\n if (changesetFilter.skip) return;\n\n const queryParams = new QueryBinder().bindId(\n \"relInstanceId\",\n relInstanceId\n );\n const reader = this.sourceDb.createQueryReader(\n this.getRelationshipQuery(\n relClassFullName,\n \"LEFT JOIN\",\n \"r.ECInstanceId = :relInstanceId\"\n ),\n queryParams,\n { usePrimaryConn: true }\n );\n if (await reader.step()) {\n const row = reader.current;\n await this.exportHydratedRelationship(\n row.rawInstance,\n row.sourceFedGuid,\n row.targetFedGuid,\n changesetFilter.isUpdate\n );\n return;\n }\n\n // The LEFT JOIN query only returns no row when the relationship doesn't exist, so this throws core's not-found error.\n this.sourceDb.relationships.getInstance(relClassFullName, relInstanceId);\n }\n\n /** Hydrates a relationship query row and runs the common export pipeline. */\n private async exportHydratedRelationship(\n rawInstance: unknown,\n sourceFedGuid: GuidString | null | undefined,\n targetFedGuid: GuidString | null | undefined,\n isUpdate: boolean | undefined\n ): Promise<void> {\n const relationship = this.sourceDb.constructEntity<Relationship>(\n this.getRelationshipProps(rawInstance)\n );\n await this.exportRelationshipInstance(relationship, isUpdate, {\n source: sourceFedGuid ?? undefined,\n target: targetFedGuid ?? undefined,\n });\n }\n\n /** Applies exclusion rules and handler callbacks to an already-hydrated relationship instance.\n * @param endpointFedGuids The FederationGuids of the relationship's source and target elements, passed to [[IModelExportHandler.onExportRelationship]].\n * @note This is the common protected hook used by both [[exportRelationship]] and [[exportRelationships]]. Most consumers should customize [[IModelExportHandler]] instead.\n */\n protected async exportRelationshipInstance(\n relationship: Relationship,\n isUpdate: boolean | undefined,\n endpointFedGuids?: RelationshipEndpointFederationGuids\n ): Promise<void> {\n // passed changeset test, now apply standard exclusion rules\n Logger.logTrace(\n loggerCategory,\n `exportRelationship(${relationship.classFullName}, ${relationship.id})`\n );\n for (const excludedRelationshipClass of this._excludedRelationshipClasses) {\n if (relationship instanceof excludedRelationshipClass) {\n Logger.logInfo(\n loggerCategory,\n `Excluded relationship by class: ${excludedRelationshipClass.classFullName}`\n );\n return;\n }\n }\n // relationship has passed standard exclusion rules, now give handler a chance to accept/reject export\n if (await this.handler.shouldExportRelationship(relationship)) {\n await this.handler.onExportRelationship(\n relationship,\n isUpdate,\n endpointFedGuids\n );\n await this.trackProgress();\n }\n }\n\n /** Tracks incremental progress */\n private async trackProgress(): Promise<void> {\n this._progressCounter++;\n if (0 === this._progressCounter % this.progressInterval) {\n return this.handler.onProgress();\n }\n }\n}\n\n/**\n * Arguments for [[ChangedInstanceIds.initialize]]\n * @public\n */\nexport type ChangedInstanceIdsInitOptions = ExportChangesOptions & {\n iModel: BriefcaseDb;\n};\n\n/** Class for holding change information.\n * @public\n */\nexport class ChangedInstanceOps {\n public insertIds = new Set<Id64String>();\n public updateIds = new Set<Id64String>();\n public deleteIds = new Set<Id64String>();\n\n /** Initializes the object from IModelJsNative.ChangedInstanceOpsProps. */\n public addFromJson(\n val: IModelJsNative.ChangedInstanceOpsProps | undefined\n ): void {\n if (undefined !== val) {\n if (undefined !== val.insert && Array.isArray(val.insert))\n val.insert.forEach((id: Id64String) => this.insertIds.add(id));\n\n if (undefined !== val.update && Array.isArray(val.update))\n val.update.forEach((id: Id64String) => this.updateIds.add(id));\n\n if (undefined !== val.delete && Array.isArray(val.delete))\n val.delete.forEach((id: Id64String) => this.deleteIds.add(id));\n }\n }\n\n /**\n * Checks if empty.\n * @returns true if there no ids in the ChangedInstanceOps object.\n */\n public get isEmpty(): boolean {\n return (\n 0 === this.insertIds.size &&\n 0 === this.updateIds.size &&\n 0 === this.deleteIds.size\n );\n }\n}\n\n/**\n * A change to one EC instance, for recording changes that don't come from a changeset reader.\n * @see [[ChangedInstanceIds.addChangeRecord]]\n * @beta\n */\nexport interface ChangeRecord {\n /** ID of the changed instance. */\n id: Id64String;\n /** EC class ID of the changed instance, used to tell elements, models, aspects, relationships, and CodeSpecs apart. */\n ecClassId: Id64String;\n /** The operation that changed the instance. */\n op: SqliteChangeOp;\n /**\n * For an aspect, the element that owns it. Required for a deleted aspect, because the source iModel no longer has it.\n * When undefined for an inserted or updated aspect, the owner is read from the source iModel.\n */\n aspectOwnerElementId?: Id64String;\n}\n\n/**\n * Class for discovering modified elements between 2 versions of an iModel.\n * @public\n */\nexport class ChangedInstanceIds {\n public codeSpec = new ChangedInstanceOps();\n public model = new ChangedInstanceOps();\n public element = new ChangedInstanceOps();\n public aspect = new ChangedInstanceOps();\n public relationship = new ChangedInstanceOps();\n public font = new ChangedInstanceOps();\n private _classKinds?: SourceClassKinds;\n private readonly _aspectOwnerElementIds = new Set<Id64String>();\n\n /** Element IDs that own the aspects represented by `aspect` changes.\n * @internal\n */\n public get aspectOwnerElementIds(): ReadonlySet<Id64String> {\n return this._aspectOwnerElementIds;\n }\n\n private _db: IModelDb;\n public constructor(db: IModelDb) {\n this._db = db;\n }\n\n /** Checks if there are any changes.\n * @returns true if there are any changes in the ChangedInstanceIds object.\n */\n public get hasChanges(): boolean {\n return (\n !this.codeSpec.isEmpty ||\n !this.model.isEmpty ||\n !this.element.isEmpty ||\n !this.aspect.isEmpty ||\n !this.relationship.isEmpty ||\n !this.font.isEmpty\n );\n }\n\n /**\n * Adds the provided [[ChangeInstance]] to the appropriate set of changes by class type (codeSpec, model, element, aspect, or relationship) maintained by this instance of ChangedInstanceIds.\n * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'\n * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.\n * @param change Changed EC instance with the ID, operation, and EC class ID of the changed entity.\n */\n public async addChange(change: ChangeInstance): Promise<void> {\n return this.recordChange(change, undefined);\n }\n\n /**\n * Adds a change read from somewhere other than a changeset, such as a precomputed cache, like [[addChange]]\n * does for a changeset reader's [ChangeInstance]($backend). Add changes in the order they were made, so that,\n * for example, an insert followed by a delete of the same instance cancels out.\n * @throws [ITwinError]($bentley) with key `AspectOwnerRequired` if a deleted aspect has no `aspectOwnerElementId`.\n * @beta\n */\n public async addChangeRecord(change: ChangeRecord): Promise<void> {\n if (change.op === \"Deleted\" && change.aspectOwnerElementId === undefined) {\n this._classKinds ??= await SourceClassKinds.query(this._db);\n const kind = this._classKinds.kindOf(change.ecClassId);\n // The source no longer has the aspect, so without its owner the target aspect would silently stay.\n if (kind === \"aspect\" || kind === \"externalSourceAspect\")\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.AspectOwnerRequired,\n },\n message: `Deleted ElementAspect change ${change.id} requires the owning element ID.`,\n });\n }\n return this.applyChangeRecord(change, undefined);\n }\n\n private async recordChange(\n change: ChangeInstance,\n unresolvedAspectIds: Set<Id64String> | undefined\n ): Promise<void> {\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 const changeType: SqliteChangeOp | undefined = change.$meta.op;\n if (changeType === undefined)\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.ChangedInstanceMetadataMissing,\n },\n message: `ChangeType was undefined for id: ${change.ECInstanceId}.`,\n });\n return this.applyChangeRecord(\n {\n id: change.ECInstanceId,\n ecClassId,\n op: changeType,\n aspectOwnerElementId: change.Element?.Id,\n },\n unresolvedAspectIds\n );\n }\n\n private async applyChangeRecord(\n change: ChangeRecord,\n unresolvedAspectIds: Set<Id64String> | undefined\n ): Promise<void> {\n // Await only the first time, so later changes are classified without yielding.\n this._classKinds ??= await SourceClassKinds.query(this._db);\n const { id, ecClassId, op } = change;\n switch (this._classKinds.kindOf(ecClassId)) {\n case \"relationship\":\n return this.handleChange(this.relationship, op, id);\n case \"codeSpec\":\n return this.handleChange(this.codeSpec, op, id);\n case \"aspect\":\n case \"externalSourceAspect\": {\n let ownerElementId = change.aspectOwnerElementId;\n if (ownerElementId === undefined) {\n if (unresolvedAspectIds !== undefined) unresolvedAspectIds.add(id);\n else ownerElementId = this.tryGetAspectOwnerElementId(id);\n }\n if (ownerElementId !== undefined)\n this._aspectOwnerElementIds.add(ownerElementId);\n return this.handleChange(this.aspect, op, id);\n }\n case \"model\":\n return this.handleChange(this.model, op, id);\n case \"element\":\n return this.handleChange(this.element, op, id);\n case \"skippedRelationship\":\n case undefined:\n return;\n }\n }\n\n private tryGetAspectOwnerElementId(\n aspectId: Id64String\n ): Id64String | undefined {\n try {\n return this._db.elements.getAspect(aspectId).element.id;\n } catch (error) {\n if (\n error instanceof IModelError &&\n error.errorNumber === IModelStatus.NotFound\n ) {\n return undefined;\n }\n throw error;\n }\n }\n\n /**\n * This method should only be called inside [[IModelTransformer.addCustomChanges]].\n * It adds the provided change to the element changes maintained by this instance of ChangedInstanceIds.\n * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'\n * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.\n * @note Custom element 'Insert' and 'Update' will mark element's parent model hierarchy and their modeled elements as 'Updated' in [[ChangedInstanceIds.model]] and [[ChangedInstanceIds.element]]. Parent models have to be marked as 'Updated' to make sure that added change is not skipped by transformer. Transformer starts processing elements from RepositoryModel and then visits all child models. Modeled elements hierarchy is marked as updated to trigger their inserts in case a new model (or its parent) needs to be inserted.\n * @note Custom element 'Insert' will also mark element aspects and all element relationships as inserted.\n * @note It is the responsibility of the caller to ensure that the provided id is, in fact an element.\n * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.\n * @note In data processing with filter criteria scenarios it is important to consistently filter out models and their modeled elements that were previously removed from target via [[addCustomModelChange]] or [[shouldExportElement]] apis.\n * @beta\n */\n public async addCustomElementChange(\n changeType: SqliteChangeOp,\n ids: Id64Arg\n ): Promise<void> {\n if (Id64.sizeOf(ids) === 0) {\n return;\n }\n\n for (const id of Id64.iterable(ids)) {\n this.handleChange(this.element, changeType, id);\n }\n\n if (changeType === \"Deleted\") {\n return;\n }\n\n const idsSet = Id64.toIdSet(ids, true);\n // Parent models have to be marked as 'Updated' to make sure that added change is not skipped by transformer. Transformer starts processing elements from RepositoryModel and then visits all child models.\n // Transformer handles update as insert if element is not found in target, for this reason modeled elements will be also marked as updated to trigger their inserts in case a new model (or its parent) needs to be inserted. Otherwise error would be thrown about missing modeled element while inserting new model.\n const parentModelIds = await this.markParentModelsAsUpdated(idsSet);\n\n // Aspects and relationships of inserted data needs to be marked as inserted otherwise those would not be exported\n if (changeType === \"Inserted\") {\n // Adding parents as well as we are not sure if those were inserted or updated\n parentModelIds.forEach((parentId) => {\n idsSet.add(parentId);\n });\n\n await this.markElementAspectsAsInserted(idsSet);\n // Marking only ElementRefersToElements.classFullName as only those are exported in exportRelationships()\n await this.markElementRelationshipsAsInserted(\n ElementRefersToElements.classFullName,\n idsSet\n );\n }\n }\n\n /**\n * This method should only be called inside [IModelTransformer.addCustomChanges].\n * Adds the provided change to the model changes maintained by this instance of ChangedInstanceIds.\n * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'\n * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.\n * Will add same change to the model's modeledElement by calling [[ChangedInstanceIds.addCustomElementChange]] which will register more needed changes. This is to ensure the changes from the model and its modeledElement get exported together.\n * @note It is the responsibility of the caller to ensure that the provided id is, in fact a model.\n * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.\n * @note In data processing with filter criteria scenarios it is important to consistently filter out models and their modeled elements that were previously removed from target via [[addCustomModelChange]] or [[shouldExportElement]] apis.\n * @beta\n */\n public async addCustomModelChange(\n changeType: SqliteChangeOp,\n ids: Id64Arg\n ): Promise<void> {\n // Also add the model's modeledElement to the element changes. The modeledElement and model go hand in hand and have the same id.\n await this.addCustomElementChange(changeType, ids);\n for (const id of Id64.iterable(ids)) {\n this.handleChange(this.model, changeType, id);\n }\n }\n\n /**\n * This method should only be called inside [IModelTransformer.addCustomChanges].\n * Adds the provided change to the aspect changes maintained by this instance of ChangedInstanceIds\n * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'\n * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.\n * @note It is the responsibility of the caller to ensure that the provided id is, in fact an aspect.\n * @param elementIds Owning element IDs. Required when `changeType` is\n * `Deleted` or the source aspect row is unavailable.\n * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.\n * @beta\n */\n public addCustomAspectChange(\n changeType: SqliteChangeOp,\n ids: Id64Arg,\n elementIds?: Id64Arg\n ): void {\n if (elementIds !== undefined) {\n for (const elementId of Id64.iterable(elementIds)) {\n this._aspectOwnerElementIds.add(elementId);\n }\n }\n for (const id of Id64.iterable(ids)) {\n if (elementIds === undefined && changeType === \"Deleted\") {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.AspectOwnerRequired,\n },\n message:\n \"Custom deleted ElementAspect changes require the owning element ID.\",\n });\n }\n if (elementIds === undefined && changeType !== \"Deleted\") {\n const ownerElementId = this.tryGetAspectOwnerElementId(id);\n if (ownerElementId === undefined) {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.AspectOwnerRequired,\n },\n message:\n \"Custom ElementAspect changes require the owning element ID when the source aspect is unavailable.\",\n });\n }\n this._aspectOwnerElementIds.add(ownerElementId);\n }\n\n this.handleChange(this.aspect, changeType, id);\n }\n }\n\n private recordCustomAspectChange(\n changeType: SqliteChangeOp,\n aspectId: Id64String,\n ownerElementId: Id64String\n ): void {\n this._aspectOwnerElementIds.add(ownerElementId);\n this.handleChange(this.aspect, changeType, aspectId);\n }\n\n /**\n * There is an optimization in [IModelExporter.exportModelContents] which doesn't try to export elements within a model unless the model itself is marked as `Updated` or 'Inserted' in sourceDbChanges. This method is used in [[addCustomElementChange]] and [[addCustomModelChange]] to add the parent model hierarchy to the 'updatedIds' so that the custom element changes are exported.\n * Transformer will insert 'Updated' model to target if it does not exist there already. To handle such case, modeled elements of parent models are also marked as updated. This is done, because model can not be inserted without it's modeled element.\n */\n private async markParentModelsAsUpdated(elementIds: Id64Set) {\n const params = new QueryBinder().bindIdSet(\"elementIds\", elementIds);\n\n const ecQuery = `\n WITH RECURSIVE hierarchy (parentId) AS (\n SELECT element.Model.Id\n FROM bis.Element element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.ECInstanceId\n UNION\n SELECT ParentModel.id\n FROM bis.Model e\n INNER JOIN hierarchy h ON h.parentId = e.ECInstanceId\n )\n SELECT parentId FROM hierarchy where parentId is not null\n `;\n const parentModelIds = new Set<Id64String>();\n for await (const row of this._db.createQueryReader(ecQuery, params, {\n usePrimaryConn: true,\n })) {\n // Transformer handles update as insert when element does not exist in target.\n // Which means that in scenario where child and parent model are filtered out from target,\n // and child element is inserted trough custom change, its parent model will be marked as updated.\n // Transformer then will:\n // 1. Handle parent update as insert (since it does not exist in target).\n // 2. Will insert child element (otherwise this insert would be ignored due to missing parent).\n this.handleChange(this.model, \"Updated\", row.parentId);\n this.handleChange(this.element, \"Updated\", row.parentId);\n parentModelIds.add(row.parentId);\n }\n return parentModelIds;\n }\n\n private async markElementRelationshipsAsInserted(\n relationshipClassName: string,\n elementIds: Id64Set\n ) {\n const ecQuery = `SELECT relationship.ECInstanceId\n FROM ${relationshipClassName} relationship\n INNER JOIN IdSet(:elementIds) ids\n ON ids.id = relationship.TargetECInstanceId\n UNION\n SELECT relationship.ECInstanceId\n FROM ${relationshipClassName} relationship\n INNER JOIN IdSet(:elementIds) ids\n ON ids.id = relationship.SourceECInstanceId`;\n\n const queryBinder = new QueryBinder().bindIdSet(\"elementIds\", elementIds);\n const queryReader = this._db.createQueryReader(ecQuery, queryBinder, {\n usePrimaryConn: true,\n });\n\n for await (const row of queryReader) {\n this.handleChange(this.relationship, \"Inserted\", row.ECInstanceId);\n }\n }\n\n private async markElementAspectsAsInserted(elementIds: Id64Set) {\n for (const aspectClassName of [\n ElementUniqueAspect.classFullName,\n ElementMultiAspect.classFullName,\n ]) {\n const ecQuery = `SELECT aspect.ECInstanceId, aspect.Element.Id\n FROM ${aspectClassName} aspect\n INNER JOIN IdSet(:elementIds) ids ON ids.id = aspect.Element.Id`;\n const queryBinder = new QueryBinder().bindIdSet(\"elementIds\", elementIds);\n const queryReader = this._db.createQueryReader(ecQuery, queryBinder, {\n usePrimaryConn: true,\n });\n for await (const row of queryReader) {\n const [aspectId, elementId] = row.toArray();\n this.recordCustomAspectChange(\"Inserted\", aspectId, elementId);\n }\n }\n }\n\n private handleChange(\n changedInstanceOps: ChangedInstanceOps,\n changeType: SqliteChangeOp,\n id: Id64String\n ) {\n // if changeType is a delete and we already have the id in the inserts then we can remove the id from the inserts.\n // if changeType is a delete and we already have the id in the updates then we can remove the id from the updates AND add it to the deletes.\n // if changeType is an insert and we already have the id in the deletes then we can remove the id from the deletes AND add it to the inserts.\n if (changeType === \"Inserted\") {\n changedInstanceOps.insertIds.add(id);\n changedInstanceOps.deleteIds.delete(id);\n } else if (changeType === \"Updated\") {\n if (!changedInstanceOps.insertIds.has(id))\n changedInstanceOps.updateIds.add(id);\n } else if (changeType === \"Deleted\") {\n // If we've inserted the entity at some point already and now we're seeing a delete. We can simply remove the entity from our inserted ids without adding it to deletedIds.\n if (changedInstanceOps.insertIds.has(id))\n changedInstanceOps.insertIds.delete(id);\n else {\n changedInstanceOps.updateIds.delete(id);\n changedInstanceOps.deleteIds.add(id);\n }\n }\n }\n\n /**\n * Initializes a new ChangedInstanceIds object with information taken from a range of changesets.\n * @public\n */\n public static async initialize(\n opts: ChangedInstanceIdsInitOptions\n ): Promise<ChangedInstanceIds | undefined> {\n if (\"changedInstanceIds\" in opts) return opts.changedInstanceIds;\n\n const iModelId = opts.iModel.iModelId;\n\n const startChangeset =\n \"startChangeset\" in opts ? opts.startChangeset : undefined;\n const changesetRanges: [number, number][] | undefined =\n startChangeset !== undefined\n ? [\n [\n startChangeset.index ??\n (\n await BriefcaseManager.queryChangeset({\n iModelId,\n changeset: {\n id: startChangeset.id ?? opts.iModel.changeset.id,\n },\n })\n ).index,\n opts.iModel.changeset.index ??\n (\n await BriefcaseManager.queryChangeset({\n iModelId,\n changeset: { id: opts.iModel.changeset.id },\n })\n ).index,\n ],\n ]\n : \"changesetRanges\" in opts\n ? opts.changesetRanges\n : undefined;\n const csFileProps =\n changesetRanges !== undefined\n ? (await ChangesetScanner.download(opts.iModel, changesetRanges)).flat()\n : \"csFileProps\" in opts\n ? opts.csFileProps\n : undefined;\n\n if (csFileProps === undefined) return undefined;\n\n const changedInstanceIds = new ChangedInstanceIds(opts.iModel);\n await ChangesetScanner.scan(opts.iModel, [csFileProps], {\n changedInstanceIds,\n collectDeletionRecords: false,\n });\n return changedInstanceIds;\n }\n\n /** Record an ordered batch, then resolve missing aspect owners against current source state.\n * @internal\n */\n public async addChanges(changes: Iterable<ChangeInstance>): Promise<void> {\n const unresolvedAspectIds = new Set<Id64String>();\n for (const change of changes)\n await this.recordChange(change, unresolvedAspectIds);\n // Only resolve missing owners from current source state. Changeset-provided\n // owners, including historical owners, were retained while recording changes.\n if (unresolvedAspectIds.size > 0) {\n this._db.withQueryReader(\n `WITH AspectIds AS (SELECT id FROM IdSet(:aspectIds))\n SELECT Element.Id FROM BisCore.ElementMultiAspect\n WHERE ECInstanceId IN (SELECT id FROM AspectIds)\n UNION ALL\n SELECT Element.Id FROM BisCore.ElementUniqueAspect\n WHERE ECInstanceId IN (SELECT id FROM AspectIds)`,\n (reader) => {\n while (reader.step())\n this._aspectOwnerElementIds.add(reader.current[0]);\n },\n new QueryBinder().bindIdSet(\"aspectIds\", unresolvedAspectIds)\n );\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"IModelExporter.js","sourceRoot":"","sources":["../src/IModelExporter.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 {\n BriefcaseDb,\n BriefcaseManager,\n ChangeInstance,\n DefinitionModel,\n // eslint-disable-next-line @typescript-eslint/no-redeclare\n Element,\n ElementAspect,\n ElementMultiAspect,\n ElementRefersToElements,\n ElementUniqueAspect,\n GeometricElement,\n IModelDb,\n IModelJsNative,\n Model,\n RecipeDefinitionElement,\n Relationship,\n SqliteChangeOp,\n} from \"@itwin/core-backend\";\nimport {\n assert,\n GuidString,\n Id64,\n Id64Arg,\n Id64Set,\n Id64String,\n IModelStatus,\n ITwinError,\n JsonUtils,\n Logger,\n YieldManager,\n} from \"@itwin/core-bentley\";\nimport {\n Base64EncodedString,\n ChangesetFileProps,\n CodeSpec,\n ECJsNames,\n FontFamilyDescriptor,\n FontId,\n FontProps,\n IModel,\n IModelError,\n QueryBinder,\n RelationshipProps,\n} from \"@itwin/core-common\";\nimport { ECVersion, Schema, SchemaKey } from \"@itwin/ecschema-metadata\";\nimport { TransformerLoggerCategory } from \"./TransformerLoggerCategory.js\";\nimport { strict as nodeAssert } from \"node:assert\";\nimport { ElementAspectExportProcessor } from \"./ElementAspectExportProcessor.js\";\nimport { ElementAspectExportCoordinator } from \"./ElementAspectExportCoordinator.js\";\nimport {\n IModelTransformerError,\n IModelTransformerErrorScope,\n} from \"./IModelTransformerError.js\";\nimport { ChangesetScanner } from \"./ChangesetScanner.js\";\nimport { SourceClassKinds } from \"./SourceClassKinds.js\";\nimport { ChangedElementForest } from \"./ChangedElementForest.js\";\n\nconst loggerCategory = TransformerLoggerCategory.IModelExporter;\n\ninterface AspectElementFact {\n id: Id64String;\n parentId?: Id64String;\n modelId: Id64String;\n classFullName: string;\n categoryId?: Id64String;\n}\n\ninterface AspectModelFact {\n id: Id64String;\n parentModelId?: Id64String;\n isTemplate: boolean;\n}\n\n/**\n * @beta\n * The (optional) result of [[IModelExportHandler.onExportSchema]]\n */\nexport interface ExportSchemaResult {\n /** set this property to notify subclasses where you wrote a schema for later import */\n schemaPath?: string;\n}\n\n/**\n * Arguments for [[IModelExporter.initialize]], usually in case you want to query changedata early\n * such as in the case of the IModelTransformer\n * @beta\n */\nexport type ExporterInitOptions = ExportChangesOptions;\n\n/**\n * Arguments for [[IModelExporter.exportChanges]]\n * @public\n */\nexport type ExportChangesOptions = {\n skipPropagateChangesToRootElements?: boolean;\n} /**\n * an array of ChangesetFileProps which are used to read the changesets and populate the ChangedInstanceIds using [[ChangedInstanceIds.initialize]] in [[IModelExporter.exportChanges]]\n * @note mutually exclusive with @see changesetRanges, @see startChangeset and @see changedInstanceIds, so define one of the four, never more\n */ & (\n | { csFileProps: ChangesetFileProps[] }\n /**\n * Class instance that contains modified elements between 2 versions of an iModel.\n * If this parameter is not provided, then [[ChangedInstanceIds.initialize]] in [[IModelExporter.exportChanges]]\n * will be called to discover changed elements.\n * @note mutually exclusive with @see changesetRanges, @see csFileProps and @see startChangeset, so define one of the four, never more\n */\n | { changedInstanceIds: ChangedInstanceIds }\n /**\n * An ordered array of changeset index ranges, e.g. [[2,2], [4,5]] is [2,4,5]\n * @note mutually exclusive with @see changedInstanceIds, @see csFileProps and @see startChangeset, so define one of the four, never more\n */\n | { changesetRanges: [number, number][] }\n /**\n * Include changes from this changeset up through and including the current changeset.\n * @note To form a range of versions to process, set `startChangeset` for the start (inclusive)\n * of the desired range and open the source iModel as of the end (inclusive) of the desired range.\n * @default the current changeset of the sourceDb, if undefined\n */\n | { startChangeset: { id?: string; index?: number } }\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n | {}\n);\n\n/** The FederationGuids of a relationship's source and target elements, read by [[IModelExporter]] while it reads the relationship.\n * A missing property means that endpoint element has no FederationGuid.\n * @see [[IModelExportHandler.onExportRelationship]]\n * @beta\n */\nexport interface RelationshipEndpointFederationGuids {\n /** The FederationGuid of the relationship's source element. */\n source?: GuidString;\n /** The FederationGuid of the relationship's target element. */\n target?: GuidString;\n}\n\n/** Handles the events generated by IModelExporter.\n * @note Change information is available when `IModelExportHandler` methods are invoked via [IModelExporter.exportChanges]($transformer), but not available when invoked via [IModelExporter.exportAll]($transformer).\n * @note The handler is intended to be owned by (registered with) and called from the IModelExporter exclusively\n * @see [iModel Transformation and Data Exchange]($docs/learning/transformer/index.md), [IModelExporter]($transformer)\n * @beta\n */\nexport abstract class IModelExportHandler {\n /** If `true` is returned, then the CodeSpec will be exported.\n * @note This method can optionally be overridden to exclude an individual CodeSpec from the export. The base implementation always returns `true`.\n */\n public async shouldExportCodeSpec(_codeSpec: CodeSpec): Promise<boolean> {\n return true;\n }\n\n /** Called when a CodeSpec should be exported.\n * @param codeSpec The CodeSpec to export\n * @param isUpdate If defined, then `true` indicates an UPDATE operation while `false` indicates an INSERT operation. If not defined, then INSERT vs. UPDATE is not known.\n * @note This should be overridden to actually do the export.\n */\n public async onExportCodeSpec(\n _codeSpec: CodeSpec,\n _isUpdate: boolean | undefined\n ): Promise<void> {}\n\n /** Called when a font should be exported.\n * @param font The font to export\n * @param isUpdate If defined, then `true` indicates an UPDATE operation while `false` indicates an INSERT operation. If not defined, then INSERT vs. UPDATE is not known.\n * @note This should be overridden to actually do the export.\n */\n public async onExportFont(\n _font: FontProps,\n _isUpdate: boolean | undefined\n ): Promise<void> {}\n\n /** Called when a model should be exported.\n * @param model The model to export\n * @param isUpdate If defined, then `true` indicates an UPDATE operation while `false` indicates an INSERT operation. If not defined, then INSERT vs. UPDATE is not known.\n * @note This should be overridden to actually do the export.\n */\n public async onExportModel(\n _model: Model,\n _isUpdate: boolean | undefined\n ): Promise<void> {}\n\n /** Called when a model should be deleted. */\n public async onDeleteModel(_modelId: Id64String): Promise<void> {}\n\n /** If `true` is returned, then the element will be exported.\n * @note This method can optionally be overridden to exclude an individual Element (and its children and ElementAspects) from the export. The base implementation always returns `true`.\n * @note During [IModelExporter.exportChanges]($transformer), this method is also called once for each unchanged ancestor of a changed element, so that a rejected ancestor excludes its changed descendants.\n */\n public async shouldExportElement(_element: Element): Promise<boolean> {\n return true;\n }\n\n /** Called when element is skipped instead of exported.\n * @note When an element is skipped, exporter will not export any of its child elements. Because of this, [[onSkipElement]] will not be invoked for any children of a \"skipped\" element.\n * @note During [IModelExporter.exportChanges]($transformer), an unchanged ancestor is filtered only when a changed descendant is reached. An element excluded by ID below it may therefore receive [[onSkipElement]] before the ancestor is rejected.\n */\n public async onSkipElement(_elementId: Id64String): Promise<void> {}\n\n /** Called when an element should be exported.\n * @param element The element to export\n * @param isUpdate If defined, then `true` indicates an UPDATE operation while `false` indicates an INSERT operation. If not defined, then INSERT vs. UPDATE is not known.\n * @note This should be overridden to actually do the export.\n */\n public async onExportElement(\n _element: Element,\n _isUpdate: boolean | undefined\n ): Promise<void> {}\n\n /**\n * Do any asynchronous actions before exporting an element\n * @note Do not implement this handler manually, it is internal, it will be removed.\n * This will become a part of onExportElement once that becomes async\n * @internal\n */\n public async preExportElement(_element: Element): Promise<void> {}\n\n /** Called once with the source IDs of all elements deleted by the exported changes. */\n public async onDeleteElements(\n _elementIds: ReadonlySet<Id64String>\n ): Promise<void> {}\n\n /** If `true` is returned, then the ElementAspect will be exported.\n * @note This method can optionally be overridden to exclude an individual ElementAspect from the export. The base implementation always returns `true`.\n */\n public async shouldExportElementAspect(\n _aspect: ElementAspect\n ): Promise<boolean> {\n return true;\n }\n\n /** Called when an ElementUniqueAspect should be exported.\n * @param aspect The ElementUniqueAspect to export\n * @param isUpdate If defined, then `true` indicates an UPDATE operation while `false` indicates an INSERT operation. If not defined, then INSERT vs. UPDATE is not known.\n * @note This should be overridden to actually do the export.\n */\n public async onExportElementUniqueAspect(\n _aspect: ElementUniqueAspect,\n _isUpdate: boolean | undefined\n ): Promise<void> {}\n\n /** Called when ElementMultiAspects should be exported.\n * @note This should be overridden to actually do the export.\n */\n public async onExportElementMultiAspects(\n _aspects: ElementMultiAspect[]\n ): Promise<void> {}\n\n /** If `true` is returned, then the relationship will be exported.\n * @note This method can optionally be overridden to exclude an individual CodeSpec from the export. The base implementation always returns `true`.\n */\n public async shouldExportRelationship(\n _relationship: Relationship\n ): Promise<boolean> {\n return true;\n }\n\n /** Called when a Relationship should be exported.\n * @param relationship The Relationship to export\n * @param isUpdate If defined, then `true` indicates an UPDATE operation while `false` indicates an INSERT operation. If not defined, then INSERT vs. UPDATE is not known.\n * @param endpointFedGuids The FederationGuids of the relationship's source and target elements. [[IModelExporter]] always supplies them. `undefined` means the caller did not supply them.\n * @note This should be overridden to actually do the export.\n */\n public async onExportRelationship(\n _relationship: Relationship,\n _isUpdate: boolean | undefined,\n _endpointFedGuids?: RelationshipEndpointFederationGuids\n ): Promise<void> {}\n\n /** Called when a relationship should be deleted. */\n public async onDeleteRelationship(\n _relInstanceId: Id64String\n ): Promise<void> {}\n\n /** If `true` is returned, then the schema will be exported.\n * @note This method can optionally be overridden to exclude an individual schema from the export. The base implementation always returns `true`.\n */\n public async shouldExportSchema(_schemaKey: SchemaKey): Promise<boolean> {\n return true;\n }\n\n /** Called when a schema should be exported.\n * @param schema The schema to export\n * @note This should be overridden to actually do the export.\n * @note return an [[ExportSchemaResult]] with a `schemaPath` property to notify overrides that call `super`\n * where a schema was written for import.\n */\n public async onExportSchema(\n _schema: Schema\n ): Promise<void | ExportSchemaResult> {}\n\n /** This method is called when IModelExporter has made incremental progress based on the [[IModelExporter.progressInterval]] setting.\n * This method is `async` to make it easier to integrate with asynchronous status and health reporting services.\n * @note A subclass may override this method to report custom progress. The base implementation does nothing.\n */\n public async onProgress(): Promise<void> {}\n}\n\n/** Base class for exporting data from an iModel.\n * @note Most uses cases will not require a custom subclass of `IModelExporter`. Instead, it is more typical to subclass/customize [IModelExportHandler]($transformer).\n * ElementAspects are exported separately from element callbacks in bounded,\n * owner-scoped groups. Aspect callbacks are not guaranteed to be adjacent to\n * callbacks for their owners.\n * @see [iModel Transformation and Data Exchange]($docs/learning/transformer/index.md), [[registerHandler]], [IModelTransformer]($transformer), [IModelImporter]($transformer)\n * @beta\n */\nexport class IModelExporter {\n private static readonly _elementAspectOwnerBatchSize = 1000;\n /** The read-only source iModel. */\n public readonly sourceDb: IModelDb;\n /** A flag that indicates whether element GeometryStreams are loaded or not.\n * @note As an optimization, exporters that don't need geometry can set this flag to `false`. The default is `true`.\n * @note The transformer by default sets this to `false` as an optimization.\n * @note This implies the `wantBRepData` option when loading elements.\n * @see [ElementLoadProps.wantGeometry]($common)\n */\n public wantGeometry: boolean = true;\n /** A flag that indicates whether template models should be exported or not. The default is `true`.\n * @note If only exporting *instances* then template models can be skipped since they are just definitions that are cloned to create new instances.\n * @see [Model.isTemplate]($backend)\n */\n public wantTemplateModels: boolean = true;\n /** A flag that indicates whether *system* schemas should be exported or not. The default is `true` (previously false).\n * This can be set to false for the legacy default behavior, but it may cause errors during schema processing in some cases.\n * @see [[exportSchemas]]\n */\n public wantSystemSchemas: boolean = true;\n /** A flag that determines whether this IModelExporter should visit Elements or not. The default is `true`.\n * @note This flag is available as an optimization when the exporter doesn't need to visit elements, so can skip loading them.\n */\n public visitElements: boolean = true;\n /** A flag that determines whether this IModelExporter should visit Relationships or not. The default is `true`.\n * @note This flag is available as an optimization when the exporter doesn't need to visit relationships, so can skip loading them.\n */\n public visitRelationships: boolean = true;\n /** The number of entities exported before incremental progress should be reported via the [[onProgress]] callback. */\n public progressInterval: number = 1000;\n /** Tracks the current total number of entities exported. */\n private _progressCounter: number = 0;\n /** Optionally cached entity change information */\n private _sourceDbChanges?: ChangedInstanceIds;\n /** State shared by nested calls in one change-processing element traversal. */\n private _changedElementTraversal?: {\n forest?: Promise<ChangedElementForest | undefined>;\n useForest: boolean;\n };\n /** Unchanged elements on the current change-processing path. Each is filtered only when a changed descendant is reached. */\n private readonly _unchangedAncestors: {\n elementId: Id64String;\n accepted?: boolean;\n }[] = [];\n /** Bounds the additional hierarchy retained by the sparse changed-element path. */\n private readonly _changedElementForestElementLimit = 100_000;\n\n /**\n * Retrieve the cached entity change information.\n * @note This will only be initialized after [IModelExporter.exportChanges] is invoked or [IModelExporter.initialize] is called.\n */\n public get sourceDbChanges(): ChangedInstanceIds | undefined {\n return this._sourceDbChanges;\n }\n /** The handler called by this IModelExporter. */\n private _handler: IModelExportHandler | undefined;\n /** The handler called by this IModelExporter. */\n protected get handler(): IModelExportHandler {\n if (undefined === this._handler) {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.ExportHandlerNotRegistered,\n },\n message: \"IModelExportHandler not registered\",\n });\n }\n\n return this._handler;\n }\n\n /** The set of CodeSpecs to exclude from the export. */\n private _excludedCodeSpecNames = new Set<string>();\n /** The set of specific Elements to exclude from the export. */\n private _excludedElementIds = new Set<Id64String>();\n /** The set of Categories where Elements in that Category will be excluded from transformation to the target iModel. */\n private _excludedElementCategoryIds = new Set<Id64String>();\n /** The set of classes of Elements that will be excluded (polymorphically) from transformation to the target iModel. */\n private _excludedElementClasses = new Set<typeof Element>();\n /** The set of classes of Relationships that will be excluded (polymorphically) from transformation to the target iModel. */\n private _excludedRelationshipClasses = new Set<typeof Relationship>();\n\n /** Exports ElementAspects for accepted owner groups. */\n private _elementAspectExportProcessor: ElementAspectExportProcessor;\n /** Coordinates accepted-owner scopes and bounded group processing. */\n private readonly _elementAspectExportCoordinator: ElementAspectExportCoordinator;\n\n /** Coordinates accepted ElementAspect owners and bounded group processing.\n * @internal\n */\n public get elementAspectExportCoordinator(): ElementAspectExportCoordinator {\n return this._elementAspectExportCoordinator;\n }\n /** Whether change traversal skips root-owned entities. */\n private _skipPropagateChangesToRootElements = false;\n private readonly _rootElementIds = new Set<Id64String>([\n IModel.rootSubjectId,\n IModel.repositoryModelId,\n IModel.dictionaryId,\n \"0xe\", // The reality-data-sources modelId, skipped with root propagation.\n ]);\n\n /** Construct a new IModelExporter\n * @param sourceDb The source IModelDb\n * @see registerHandler\n */\n public constructor(sourceDb: IModelDb) {\n this.sourceDb = sourceDb;\n this._elementAspectExportProcessor = new ElementAspectExportProcessor(\n this.sourceDb,\n {\n onExportElementMultiAspects: async (aspects) =>\n this.handler.onExportElementMultiAspects(aspects),\n onExportElementUniqueAspect: async (aspect, isUpdate) =>\n this.handler.onExportElementUniqueAspect(aspect, isUpdate),\n shouldExportElementAspect: async (aspect) =>\n this.handler.shouldExportElementAspect(aspect),\n trackProgress: async () => this.trackProgress(),\n }\n );\n this._elementAspectExportCoordinator = new ElementAspectExportCoordinator(\n IModelExporter._elementAspectOwnerBatchSize,\n () =>\n this._elementAspectExportProcessor.excludedElementAspectClassFullNames,\n async (elementIds) =>\n this._elementAspectExportProcessor.exportAllElementAspects(elementIds),\n () => this._elementAspectExportProcessor.resetCaches()\n );\n }\n\n /**\n * Initialize prerequisites of exporting. This is implicitly done by any `export*` calls that need initialization\n * which is currently just `exportChanges`.\n * Prefer to not call this explicitly (e.g. just call [[IModelExporter.exportChanges]])\n * @note that if you do call this explicitly, you must do so with the same options that\n * you pass to [[IModelExporter.exportChanges]]\n */\n public async initialize(options: ExporterInitOptions): Promise<void> {\n if (!this.sourceDb.isBriefcaseDb() || this._sourceDbChanges) return;\n\n this._sourceDbChanges = await ChangedInstanceIds.initialize({\n iModel: this.sourceDb,\n ...options,\n });\n if (this._sourceDbChanges === undefined) return;\n\n this._elementAspectExportProcessor.setAspectChanges(\n this._sourceDbChanges.aspect\n );\n }\n\n /** Register the handler that will be called by IModelExporter. */\n public registerHandler(handler: IModelExportHandler): void {\n this._handler = handler;\n }\n\n /** Add a rule to exclude a CodeSpec */\n public excludeCodeSpec(codeSpecName: string): void {\n this._excludedCodeSpecNames.add(codeSpecName);\n }\n\n /** Add a rule to exclude a specific Element.\n * @note Configure exclusions before starting an export operation. Changing exclusions while an export is in progress is unsupported.\n */\n public excludeElement(elementId: Id64String): void {\n this._excludedElementIds.add(elementId);\n }\n\n /** Add a rule to exclude all Elements in a specified Category. */\n public excludeElementsInCategory(categoryId: Id64String): void {\n this._excludedElementCategoryIds.add(categoryId);\n }\n\n /** Add a rule to exclude all Elements of a specified class. */\n public excludeElementClass(classFullName: string): void {\n this._excludedElementClasses.add(\n this.sourceDb.getJsClass<typeof Element>(classFullName)\n );\n }\n\n /** Add a rule to exclude all ElementAspects of a specified class. */\n public excludeElementAspectClass(classFullName: string): void {\n this._elementAspectExportProcessor.excludeElementAspectClass(classFullName);\n }\n\n /** Add a rule to exclude all Relationships of a specified class. */\n public excludeRelationshipClass(classFullName: string): void {\n this._excludedRelationshipClasses.add(\n this.sourceDb.getJsClass<typeof Relationship>(classFullName)\n );\n }\n\n /** Export all entity instance types from the source iModel.\n * @note [[exportSchemas]] must be called separately.\n */\n public async exportAll(): Promise<void> {\n await this.initialize({});\n\n await this.exportCodeSpecs();\n await this.exportFonts();\n await this._elementAspectExportCoordinator.run(async () =>\n this.exportModel(IModel.repositoryModelId)\n );\n await this.exportRelationships(ElementRefersToElements.classFullName);\n }\n\n /** Export changes from the source iModel.\n * Inserts, updates, and deletes are determined by inspecting the changeset(s).\n * @throws [[ITwinError]] with scope `@itwin/imodel-transformer` and key `no-changesets` if the source iModel has no changesets and no custom changes. Call [[exportAll]] to export all content.\n * @note To form a range of versions to process, set `startChangesetId` for the start (inclusive) of the desired\n * range and open the source iModel as of the end (inclusive) of the desired range.\n * @note the changedInstanceIds are just for this call to exportChanges, so you must continue to pass it in\n * for consecutive calls\n */\n public async exportChanges(args?: ExportChangesOptions): Promise<void> {\n if (!this.sourceDb.isBriefcaseDb())\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.ExportChangesRequiresBriefcase,\n },\n message: \"Must be a briefcase to export changes\",\n });\n\n let initOpts: ExporterInitOptions = args ?? {};\n const hasExplicitChangeSource =\n \"csFileProps\" in initOpts ||\n \"changedInstanceIds\" in initOpts ||\n \"changesetRanges\" in initOpts ||\n \"startChangeset\" in initOpts;\n const currentChangesetId = this.sourceDb.changeset.id;\n\n if (!hasExplicitChangeSource && currentChangesetId !== \"\") {\n initOpts = {\n ...initOpts,\n startChangeset: { id: currentChangesetId },\n };\n }\n\n await this.initialize(initOpts);\n\n if (currentChangesetId === \"\" && !this.sourceDbChanges?.hasChanges) {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.NoChangesets,\n },\n message:\n \"Cannot export changes because the source iModel has no changesets or custom changes. Call exportAll() to export all content.\",\n });\n }\n\n this._skipPropagateChangesToRootElements =\n initOpts.skipPropagateChangesToRootElements ?? false;\n // _sourceDbChanges are initialized in this.initialize\n nodeAssert(\n this._sourceDbChanges !== undefined,\n \"sourceDbChanges must be initialized.\"\n );\n\n await this.exportCodeSpecs();\n await this.exportFonts();\n nodeAssert(\n this.beginChangedElementTraversalScope(),\n \"exportChanges must own its changed-element traversal scope\"\n );\n try {\n await this._elementAspectExportCoordinator.run(async () => {\n if (initOpts.skipPropagateChangesToRootElements) {\n // The root Subject is in the RepositoryModel. Traverse its children\n // separately, then export other top-level repository elements while\n // excluding the root so no element is visited twice.\n await this.exportChildElements(IModel.rootSubjectId);\n await this.exportModelContents(\n IModel.repositoryModelId,\n Element.classFullName,\n true\n );\n await this.exportSubModels(IModel.repositoryModelId);\n } else {\n await this.exportModel(IModel.repositoryModelId);\n }\n });\n\n const aspectOnlyOwnerElementIds = new Set(\n this._sourceDbChanges.aspectOwnerElementIds\n );\n for (const elementId of this._sourceDbChanges.element.insertIds) {\n aspectOnlyOwnerElementIds.delete(elementId);\n }\n for (const elementId of this._sourceDbChanges.element.updateIds) {\n aspectOnlyOwnerElementIds.delete(elementId);\n }\n await this.exportAspectsForOwners(\n await this.filterOwnerElementIdsForAspectExport(\n aspectOnlyOwnerElementIds\n )\n );\n } finally {\n this.endChangedElementTraversalScope();\n }\n await this.exportRelationships(ElementRefersToElements.classFullName);\n\n // handle deletes\n if (this.visitElements) {\n // must delete models first since they have a constraint on the submodeling element which may also be deleted\n for (const modelId of this._sourceDbChanges.model.deleteIds) {\n await this.handler.onDeleteModel(modelId);\n }\n if (this._sourceDbChanges.element.deleteIds.size > 0) {\n await this.handler.onDeleteElements(\n new Set(this._sourceDbChanges.element.deleteIds)\n );\n }\n }\n\n if (this.visitRelationships) {\n for (const relInstanceId of this._sourceDbChanges.relationship\n .deleteIds) {\n await this.handler.onDeleteRelationship(relInstanceId);\n }\n }\n\n // Enable consecutive exportChanges runs without the need to re-instantiate the exporter.\n // You can counteract the obvious impact of losing this expensive data by always calling\n // exportChanges with the [[ExportChangesOptions.changedInstanceIds]] option set to\n // whatever you want\n if (this._resetChangeDataOnExport) {\n this._sourceDbChanges = undefined;\n this._elementAspectExportProcessor.setAspectChanges(undefined);\n }\n }\n\n private _resetChangeDataOnExport = true;\n\n /** Enumerate schemas from the source iModel in database order.\n * @note Override this method to customize schema discovery for both direct exports and transformer schema processing.\n * @beta\n */\n public async *enumerateSchemas(): AsyncIterable<Schema> {\n const sql = `\n SELECT s.Name, s.VersionMajor, s.VersionWrite, s.VersionMinor\n FROM ECDbMeta.ECSchemaDef s\n ${\n this.wantSystemSchemas\n ? \"\"\n : `\n WHERE ECInstanceId >= (SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore')\n `\n }\n ORDER BY ECInstanceId\n `;\n for await (const row of this.sourceDb.createQueryReader(sql, undefined, {\n usePrimaryConn: true,\n })) {\n const schemaKey = new SchemaKey(\n row[0],\n new ECVersion(row[1], row[2], row[3])\n );\n const schema = await this.sourceDb.schemaContext.getSchema(schemaKey);\n if (!schema) {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.SchemaLoadFailed,\n },\n message: `Failed to load schema: ${schemaKey.name}`,\n });\n }\n yield schema;\n }\n }\n\n /** Export schemas from the source iModel.\n * @note This must be called separately from [[exportAll]] or [[exportChanges]].\n */\n public async exportSchemas(): Promise<void> {\n const schemasToExport: Schema[] = [];\n for await (const schema of this.enumerateSchemas()) {\n if (await this.handler.shouldExportSchema(schema.schemaKey)) {\n schemasToExport.push(schema);\n }\n }\n\n await Promise.all(\n schemasToExport.map(async (schema) => {\n Logger.logTrace(loggerCategory, `exportSchema(${schema.name})`);\n return this.handler.onExportSchema(schema);\n })\n );\n }\n\n /** For logging, indicate the change type if known. */\n private getChangeOpSuffix(isUpdate: boolean | undefined): string {\n return isUpdate ? \" UPDATE\" : undefined === isUpdate ? \"\" : \" INSERT\";\n }\n\n /** Export all CodeSpecs from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportCodeSpecs(): Promise<void> {\n Logger.logTrace(loggerCategory, \"exportCodeSpecs()\");\n const sql = \"SELECT Name FROM BisCore:CodeSpec ORDER BY ECInstanceId\";\n for await (const row of this.sourceDb.createQueryReader(sql, undefined, {\n usePrimaryConn: true,\n })) {\n await this.exportCodeSpecByName(row[0]);\n }\n }\n\n /** Export a single CodeSpec from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportCodeSpecByName(codeSpecName: string): Promise<void> {\n const codeSpec: CodeSpec = this.sourceDb.codeSpecs.getByName(codeSpecName);\n let isUpdate: boolean | undefined;\n if (undefined !== this._sourceDbChanges) {\n // is changeset information available?\n if (this._sourceDbChanges.codeSpec.insertIds.has(codeSpec.id)) {\n isUpdate = false;\n } else if (this._sourceDbChanges.codeSpec.updateIds.has(codeSpec.id)) {\n isUpdate = true;\n } else {\n return; // not in changeset, don't export\n }\n }\n // passed changeset test, now apply standard exclusion rules\n if (this._excludedCodeSpecNames.has(codeSpec.name)) {\n Logger.logInfo(loggerCategory, `Excluding CodeSpec: ${codeSpec.name}`);\n return;\n }\n // CodeSpec has passed standard exclusion rules, now give handler a chance to accept/reject export\n if (await this.handler.shouldExportCodeSpec(codeSpec)) {\n Logger.logTrace(\n loggerCategory,\n `exportCodeSpec(${codeSpecName})${this.getChangeOpSuffix(isUpdate)}`\n );\n await this.handler.onExportCodeSpec(codeSpec, isUpdate);\n return this.trackProgress();\n }\n }\n\n /** Export a single CodeSpec from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportCodeSpecById(codeSpecId: Id64String): Promise<void> {\n const codeSpec: CodeSpec = this.sourceDb.codeSpecs.getById(codeSpecId);\n return this.exportCodeSpecByName(codeSpec.name);\n }\n\n /** Export all fonts from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportFonts(): Promise<void> {\n Logger.logTrace(loggerCategory, \"exportFonts()\");\n for (const font of this.sourceDb.fonts.queryMappedFamilies()) {\n await this.exportFontByFontProps(font);\n }\n }\n\n /** Export a single font from the source iModel.\n * @note multiple fonts can have the same font name, if a font with a specific type is needed use exportFontByFontFamilyDescriptor.\n * If not this will only export the first font with this type in the db.\n */\n public async exportFontByName(fontName: string): Promise<void> {\n Logger.logTrace(loggerCategory, `exportFontByName(${fontName})`);\n const fontId: FontId | undefined = this.sourceDb.fonts.findId({\n name: fontName,\n });\n if (undefined !== fontId) {\n await this.exportFontByNumber(fontId);\n }\n }\n\n /** Export a single font from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportFontByFontProps(fontProps: FontProps): Promise<void> {\n Logger.logTrace(\n loggerCategory,\n `exportFontByFamily(${fontProps.name}, ${fontProps.type})`\n );\n await this.handler.onExportFont(fontProps, true);\n return this.trackProgress();\n }\n\n /** Export a single font from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportFontByFontFamilyDescriptor(\n fontFamily: FontFamilyDescriptor\n ): Promise<void> {\n Logger.logTrace(\n loggerCategory,\n `exportFontByFamilyDescriptor(${fontFamily.name}, ${fontFamily.type})`\n );\n const fontId: FontId | undefined =\n await this.sourceDb.fonts.acquireId(fontFamily);\n if (undefined !== fontId) {\n await this.exportFontByFontProps({ ...fontFamily, id: fontId });\n }\n }\n\n /** Export a single font from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportFontByNumber(fontNumber: number): Promise<void> {\n /** ChangedInstanceIds contains EC-mapped changes, but the font table is not EC-mapped.\n * Always export fonts because their changes are therefore absent from sourceDbChanges.\n * It is very rare and even problematic for the font table to reach a large size, so it is not a bottleneck in transforming changes.\n * See https://github.com/iTwin/imodel-transformer/pull/135 for removed code.\n */\n Logger.logTrace(loggerCategory, `exportFontById(${fontNumber})`);\n const font: FontFamilyDescriptor | undefined =\n this.sourceDb.fonts.findDescriptor(fontNumber);\n if (undefined !== font) {\n await this.exportFontByFontFamilyDescriptor(font);\n }\n }\n\n /** Export the model container, contents, and sub-models from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportModel(modeledElementId: Id64String): Promise<void> {\n return this.runScopedElementExport(async () =>\n this.exportModelImpl(modeledElementId)\n );\n }\n\n private async exportModelImpl(modeledElementId: Id64String): Promise<void> {\n const model: Model = this.sourceDb.models.getModel(modeledElementId);\n if (model.isTemplate && !this.wantTemplateModels) {\n return;\n }\n const modeledElement: Element = this.sourceDb.elements.getElement({\n id: modeledElementId,\n wantGeometry: this.wantGeometry,\n wantBRepData: this.wantGeometry,\n });\n Logger.logTrace(loggerCategory, `exportModel(${modeledElementId})`);\n if (await this.shouldExportElement(modeledElement)) {\n await this.exportModelContainer(model);\n if (this.visitElements) {\n await this.exportModelContents(modeledElementId);\n }\n await this.exportSubModels(modeledElementId);\n }\n }\n\n /** Export the model (the container only) from the source iModel. */\n private async exportModelContainer(model: Model): Promise<void> {\n let isUpdate: boolean | undefined;\n if (undefined !== this._sourceDbChanges) {\n // is changeset information available?\n if (this._sourceDbChanges.model.insertIds.has(model.id)) {\n isUpdate = false;\n } else if (this._sourceDbChanges.model.updateIds.has(model.id)) {\n isUpdate = true;\n } else {\n return; // not in changeset, don't export\n }\n }\n await this._elementAspectExportCoordinator.runHandlerCallback(async () =>\n this.handler.onExportModel(model, isUpdate)\n );\n return this.trackProgress();\n }\n\n private _yieldManager = new YieldManager();\n\n /** Export the model contents.\n * @param modelId The only required parameter\n * @param elementClassFullName Can be optionally specified if the goal is to export a subset of the model contents\n * @param skipRootSubject Decides whether or not to export the root Subject. It is normally left undefined except for internal implementation purposes.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportModelContents(\n modelId: Id64String,\n elementClassFullName: string = Element.classFullName,\n skipRootSubject?: boolean\n ): Promise<void> {\n return this.runScopedElementExport(async () =>\n this.exportModelContentsImpl(\n modelId,\n elementClassFullName,\n skipRootSubject\n )\n );\n }\n\n private async exportModelContentsImpl(\n modelId: Id64String,\n elementClassFullName: string,\n skipRootSubject?: boolean\n ): Promise<void> {\n if (skipRootSubject) {\n // NOTE: IModelTransformer.processAll should skip the root Subject since it is specific to the individual iModel and is not part of the changes that need to be synchronized\n // NOTE: IModelExporter.exportAll should not skip the root Subject since the goal is to export everything\n assert(modelId === IModel.repositoryModelId); // flag is only relevant when processing the RepositoryModel\n }\n if (!this.visitElements) {\n Logger.logTrace(\n loggerCategory,\n `visitElements=false, skipping exportModelContents(${modelId})`\n );\n return;\n }\n if (undefined !== this._sourceDbChanges) {\n // is changeset information available?\n if (\n !this._sourceDbChanges.model.insertIds.has(modelId) &&\n !this._sourceDbChanges.model.updateIds.has(modelId)\n ) {\n return; // this optimization assumes that the Model changes (LastMod) any time an Element in the Model changes\n }\n if (\n this.canUseChangedElementForest() &&\n elementClassFullName === Element.classFullName\n ) {\n const forest = await this.getChangedElementForest();\n if (forest !== undefined) {\n Logger.logTrace(\n loggerCategory,\n `exportModelContents(${modelId}) via changed-element index`\n );\n for (const rootId of forest.getModelRoots(modelId)) {\n if (skipRootSubject && rootId === IModel.rootSubjectId) continue;\n await this.exportElement(rootId);\n await this._yieldManager.allowYield();\n }\n return;\n }\n }\n }\n Logger.logTrace(loggerCategory, `exportModelContents(${modelId})`);\n const rootFilter = skipRootSubject\n ? \"e.Parent.Id IS NULL AND e.Model.Id=:modelId AND e.ECInstanceId!=:rootSubjectId\"\n : \"e.Parent.Id IS NULL AND e.Model.Id=:modelId\";\n const params = new QueryBinder().bindId(\"modelId\", modelId);\n if (skipRootSubject) {\n params.bindId(\"rootSubjectId\", IModel.rootSubjectId);\n }\n if (this.canUseSetBasedTraversal()) {\n return this.exportElementTreesStreamed(\n `SELECT e.ECInstanceId, 0 FROM ${elementClassFullName} e WHERE ${rootFilter}`,\n params\n );\n }\n const sql = `SELECT e.ECInstanceId FROM ${elementClassFullName} e WHERE ${rootFilter} ORDER BY e.ECInstanceId`;\n for await (const row of this.sourceDb.createQueryReader(sql, params, {\n usePrimaryConn: true,\n })) {\n await this.exportElement(row.id);\n await this._yieldManager.allowYield();\n }\n }\n\n /** Whether the public element traversal methods still have their base implementations. */\n private hasDefaultElementTraversal(): boolean {\n // The optimized helpers bypass these public overridable methods. Compare function\n // identity so subclass, bound, wrapped, or instrumented methods retain legacy dispatch.\n return (\n this.exportElement === IModelExporter.prototype.exportElement &&\n this.exportChildElements === IModelExporter.prototype.exportChildElements\n );\n }\n\n /** Whether hierarchy traversal can use the streamed query.\n * Changes mode and overrides of the public traversal methods require legacy dispatch.\n */\n private canUseSetBasedTraversal(): boolean {\n return (\n this._sourceDbChanges === undefined && this.hasDefaultElementTraversal()\n );\n }\n\n /** Stream element trees in the legacy depth-first order with one recursive ECSQL query.\n * Rejected subtrees are skipped in the exporter without loading their descendants.\n * @param anchorSelect a SELECT producing `(ECInstanceId, 0)` rows for the tree roots\n */\n private async exportElementTreesStreamed(\n anchorSelect: string,\n params: QueryBinder\n ): Promise<void> {\n // The anchor seeds roots at depth 0; the recursive term follows parent links.\n // SQLite's documented recursive-CTE queue behavior makes this ORDER BY a\n // depth-first priority queue, with ascending IDs breaking ties. Supported\n // iModel databases use SQLite, so the outer SELECT intentionally consumes\n // the CTE rows in this queue order.\n const sql = `\n WITH RECURSIVE ElementTree (ECInstanceId, Depth) AS (\n ${anchorSelect}\n UNION ALL\n SELECT c.ECInstanceId, t.Depth + 1 FROM ${Element.classFullName} c\n JOIN ElementTree t ON c.Parent.Id = t.ECInstanceId\n ORDER BY 2 DESC, 1 ASC\n )\n SELECT ECInstanceId, Depth FROM ElementTree`;\n let pruneDepth: number | undefined;\n for await (const row of this.sourceDb.createQueryReader(sql, params, {\n usePrimaryConn: true,\n })) {\n const elementId: Id64String = row[0];\n const depth: number = row[1];\n const isPruned = pruneDepth !== undefined && depth > pruneDepth;\n if (!isPruned) {\n pruneDepth = undefined;\n if ((await this.exportElementShallow(elementId)) === \"skip\")\n pruneDepth = depth;\n }\n // Keep the streamed loop responsive, including while consuming a rejected subtree.\n await this._yieldManager.allowYield();\n }\n }\n\n /** Export the sub-models directly below the specified model.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportSubModels(parentModelId: Id64String): Promise<void> {\n return this.runScopedElementExport(async () =>\n this.exportSubModelsImpl(parentModelId)\n );\n }\n\n private async exportSubModelsImpl(parentModelId: Id64String): Promise<void> {\n Logger.logTrace(loggerCategory, `exportSubModels(${parentModelId})`);\n // Export DefinitionModels before other Models, each in ECInstanceId order.\n // Classifying in ECSQL avoids loading every sub-model here and again in exportModel.\n // Partition in JS: sorting on the classification in ECSQL raised peak native memory on many-model iModels.\n const sql = `\n SELECT ECInstanceId, IIF(ECClassId IS (${DefinitionModel.classFullName}), 1, 0) isDefinitionModel\n FROM ${Model.classFullName}\n WHERE ParentModel.Id=:parentModelId\n ORDER BY ECInstanceId`;\n const params = new QueryBinder().bindId(\"parentModelId\", parentModelId);\n const definitionModelIds: Id64String[] = [];\n const otherModelIds: Id64String[] = [];\n for await (const row of this.sourceDb.createQueryReader(sql, params, {\n usePrimaryConn: true,\n })) {\n (row.isDefinitionModel ? definitionModelIds : otherModelIds).push(row.id);\n }\n for (const subModelId of [...definitionModelIds, ...otherModelIds]) {\n await this.exportModel(subModelId);\n }\n }\n\n /** Returns true if the specified element should be exported.\n * This considers the standard IModelExporter exclusion rules plus calls [IModelExportHandler.shouldExportElement]($transformer) for any custom exclusion rules.\n * @note This method is called from within [[exportChanges]] and [[exportAll]], so usually does not need to be called directly.\n */\n public async shouldExportElement(element: Element): Promise<boolean> {\n if (this._excludedElementIds.has(element.id)) {\n Logger.logInfo(loggerCategory, `Excluded element ${element.id} by Id`);\n return false;\n }\n if (\n element instanceof GeometricElement &&\n this._excludedElementCategoryIds.has(element.category)\n ) {\n Logger.logInfo(\n loggerCategory,\n `Excluded element ${element.id} by Category`\n );\n return false;\n }\n if (\n !this.wantTemplateModels &&\n element instanceof RecipeDefinitionElement\n ) {\n Logger.logInfo(\n loggerCategory,\n `Excluded RecipeDefinitionElement ${element.id} because wantTemplate=false`\n );\n return false;\n }\n for (const excludedElementClass of this._excludedElementClasses) {\n if (element instanceof excludedElementClass) {\n Logger.logInfo(\n loggerCategory,\n `Excluded element ${element.id} by class: ${excludedElementClass.classFullName}`\n );\n return false;\n }\n }\n // element has passed standard exclusion rules, now give handler a chance to accept/reject\n if (!(await this.handler.shouldExportElement(element))) {\n return false;\n }\n return true;\n }\n\n /** Export the specified element and its child elements (if applicable).\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n * @note ElementAspects are exported separately in owner-scoped groups, so their callbacks are not guaranteed to follow this element callback.\n */\n public async exportElement(elementId: Id64String): Promise<void> {\n return this.runScopedElementExport(async () =>\n this.exportElementImpl(elementId)\n );\n }\n\n private async exportElementImpl(elementId: Id64String): Promise<void> {\n if (!this.visitElements) {\n Logger.logTrace(\n loggerCategory,\n `visitElements=false, skipping exportElement(${elementId})`\n );\n return;\n }\n\n const childVisit = await this.exportElementShallow(elementId);\n if (childVisit === \"visit\") return this.exportChildElements(elementId);\n if (childVisit === \"passThrough\") {\n // The element's own filter result is decided later, if a changed descendant is reached.\n this._unchangedAncestors.push({ elementId });\n try {\n await this.exportChildElements(elementId);\n } finally {\n this._unchangedAncestors.pop();\n }\n }\n }\n\n /** Returns the filter result for an unchanged ancestor on the current change-processing path, or `undefined` if it has not been filtered.\n * @internal\n */\n public getUnchangedAncestorFilterResult(\n elementId: Id64String\n ): boolean | undefined {\n return this._unchangedAncestors.find(\n (ancestor) => ancestor.elementId === elementId\n )?.accepted;\n }\n\n /** Filters the unchanged ancestors of a changed element, top-down, once each.\n * @returns `false` if an ancestor is rejected.\n */\n private async acceptUnchangedAncestors(): Promise<boolean> {\n for (const ancestor of this._unchangedAncestors) {\n if (ancestor.accepted === undefined) {\n const element = this.sourceDb.elements.getElement({\n id: ancestor.elementId,\n wantGeometry: this.wantGeometry,\n wantBRepData: this.wantGeometry,\n });\n ancestor.accepted = await this.shouldExportElement(element);\n if (!ancestor.accepted)\n await this.handler.onSkipElement(ancestor.elementId);\n }\n if (!ancestor.accepted) return false;\n }\n return true;\n }\n\n /** Runs the export callbacks for a single element without visiting its children.\n * @returns how to continue with the element's children: skip them, visit them, or pass through an unchanged element to reach changed descendants.\n */\n private async exportElementShallow(\n elementId: Id64String\n ): Promise<\"skip\" | \"visit\" | \"passThrough\"> {\n // Descendants of a rejected unchanged ancestor are skipped, as in a full export.\n if (\n this._unchangedAncestors.some((ancestor) => ancestor.accepted === false)\n )\n return \"skip\";\n\n // Return early if the elementId is already excluded so it does not need to be loaded.\n if (this._excludedElementIds.has(elementId)) {\n Logger.logInfo(loggerCategory, `Excluded element ${elementId} by Id`);\n await this.handler.onSkipElement(elementId);\n return \"skip\";\n }\n\n const isUpdate = this._sourceDbChanges?.element.insertIds.has(elementId)\n ? false\n : this._sourceDbChanges?.element.updateIds.has(elementId)\n ? true\n : undefined;\n\n // An unchanged element may still connect a changed descendant to its model root.\n if (this._sourceDbChanges !== undefined && isUpdate === undefined)\n return \"passThrough\";\n\n if (!(await this.acceptUnchangedAncestors())) return \"skip\";\n\n const element = this.sourceDb.elements.getElement({\n id: elementId,\n wantGeometry: this.wantGeometry,\n wantBRepData: this.wantGeometry,\n });\n Logger.logTrace(\n loggerCategory,\n `exportElement(${\n element.id\n }, \"${element.getDisplayLabel()}\")${this.getChangeOpSuffix(isUpdate)}`\n );\n // the order and `await`ing of calls beyond here is depended upon by the IModelTransformer for a current bug workaround\n if (await this.shouldExportElement(element)) {\n await this._elementAspectExportCoordinator.runHandlerCallback(\n async () => {\n await this.handler.preExportElement(element);\n await this.handler.onExportElement(element, isUpdate);\n }\n );\n await this.trackProgress();\n await this._elementAspectExportCoordinator.addAcceptedOwner(elementId);\n return \"visit\";\n }\n await this.handler.onSkipElement(element.id);\n return \"skip\";\n }\n\n /** Export the child elements of the specified element from the source iModel.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n */\n public async exportChildElements(elementId: Id64String): Promise<void> {\n return this.runScopedElementExport(async () =>\n this.exportChildElementsImpl(elementId)\n );\n }\n\n private async exportChildElementsImpl(elementId: Id64String): Promise<void> {\n if (!this.visitElements) {\n Logger.logTrace(\n loggerCategory,\n `visitElements=false, skipping exportChildElements(${elementId})`\n );\n return;\n }\n if (this.canUseSetBasedTraversal()) {\n Logger.logTrace(loggerCategory, `exportChildElements(${elementId})`);\n // Seed the stream with direct children; the helper adds their descendants.\n return this.exportElementTreesStreamed(\n `SELECT e.ECInstanceId, 0 FROM ${Element.classFullName} e WHERE e.Parent.Id=:parentId`,\n new QueryBinder().bindId(\"parentId\", elementId)\n );\n }\n\n let childElementIds: readonly Id64String[] | undefined;\n if (this.canUseChangedElementForest()) {\n const forest = await this.getChangedElementForest();\n if (forest !== undefined) {\n Logger.logTrace(\n loggerCategory,\n `exportChildElements(${elementId}) via changed-element index`\n );\n childElementIds = forest.getChildren(elementId);\n }\n }\n childElementIds ??= this.sourceDb.elements.queryChildren(elementId);\n\n if (childElementIds.length > 0) {\n Logger.logTrace(loggerCategory, `exportChildElements(${elementId})`);\n for (const childElementId of childElementIds) {\n await this.exportElement(childElementId);\n }\n }\n }\n\n /** Whether change processing may use the sparse hierarchy as the child-id source.\n * Custom traversal overrides retain the previous full element dispatch.\n */\n private canUseChangedElementForest(): boolean {\n return (\n this._sourceDbChanges !== undefined &&\n this._changedElementTraversal?.useForest === true &&\n this.hasDefaultElementTraversal()\n );\n }\n\n private getOverriddenElementTraversalMethods(): string[] {\n const methods: string[] = [];\n if (this.exportElement !== IModelExporter.prototype.exportElement)\n methods.push(\"exportElement\");\n if (\n this.exportChildElements !== IModelExporter.prototype.exportChildElements\n )\n methods.push(\"exportChildElements\");\n return methods;\n }\n\n private disableChangedElementForest(reason: string): void {\n if (!this._changedElementTraversal?.useForest) return;\n this._changedElementTraversal.useForest = false;\n Logger.logInfo(\n loggerCategory,\n `Using full element traversal for change processing because ${reason}.`\n );\n }\n\n private async createChangedElementForest(): Promise<\n ChangedElementForest | undefined\n > {\n nodeAssert(\n this._sourceDbChanges !== undefined,\n \"changed-element traversal requires sourceDbChanges\"\n );\n const excludedElementIds = this._excludedElementIds;\n const candidateCountUpperBound =\n this._sourceDbChanges.element.insertIds.size +\n this._sourceDbChanges.element.updateIds.size +\n excludedElementIds.size;\n if (candidateCountUpperBound > this._changedElementForestElementLimit) {\n this.disableChangedElementForest(\n `${candidateCountUpperBound} candidate element references exceed the ${this._changedElementForestElementLimit}-element in-memory index limit`\n );\n return undefined;\n }\n\n const forest = await ChangedElementForest.create(\n this.sourceDb,\n [\n ...this._sourceDbChanges.element.insertIds,\n ...this._sourceDbChanges.element.updateIds,\n ...excludedElementIds,\n ],\n this._changedElementForestElementLimit\n );\n if (forest === undefined) {\n this.disableChangedElementForest(\n `the required parent hierarchy exceeds the ${this._changedElementForestElementLimit}-element in-memory index limit`\n );\n }\n return forest;\n }\n\n private async getChangedElementForest(): Promise<\n ChangedElementForest | undefined\n > {\n const traversal = this._changedElementTraversal;\n nodeAssert(\n traversal !== undefined,\n \"changed-element index requires an active traversal scope\"\n );\n return (traversal.forest ??= this.createChangedElementForest());\n }\n\n /** Exports all aspects owned by the supplied elements. */\n private async exportAspectsForOwners(\n ownerElementIds: ReadonlySet<Id64String>\n ): Promise<void> {\n return this._elementAspectExportCoordinator.exportOwners(ownerElementIds);\n }\n\n private async filterOwnerElementIdsForAspectExport(\n ownerElementIds: ReadonlySet<Id64String>\n ): Promise<ReadonlySet<Id64String>> {\n if (ownerElementIds.size === 0) return new Set<Id64String>();\n\n const elementFacts =\n await this.queryAspectElementHierarchyFacts(ownerElementIds);\n const modelFacts = await this.queryAspectModelHierarchyFacts(\n new Set(\n [...elementFacts.values()].map((elementFact) => elementFact.modelId)\n )\n );\n await this.queryAspectElementFacts(\n new Set(modelFacts.keys()),\n elementFacts\n );\n\n const elementIds = new Set<Id64String>();\n for (const elementId of ownerElementIds) {\n if (\n this._skipPropagateChangesToRootElements &&\n this._rootElementIds.has(elementId)\n ) {\n continue;\n }\n if (\n await this.shouldExportElementHierarchyForAspect(\n elementId,\n elementFacts,\n modelFacts\n )\n ) {\n elementIds.add(elementId);\n }\n }\n return elementIds;\n }\n\n private async shouldExportElementHierarchyForAspect(\n elementId: Id64String,\n elementFacts: ReadonlyMap<Id64String, AspectElementFact>,\n modelFacts: ReadonlyMap<Id64String, AspectModelFact>\n ): Promise<boolean> {\n let elementFact = elementFacts.get(elementId);\n while (elementFact !== undefined) {\n if (\n !(await this.shouldExportElementForAspect(elementFact.id, elementFact))\n )\n return false;\n if (\n !(await this.shouldExportModelForAspect(\n elementFact.modelId,\n elementFacts,\n modelFacts\n ))\n ) {\n return false;\n }\n const parentId = elementFact.parentId;\n if (\n parentId === undefined ||\n (this._skipPropagateChangesToRootElements &&\n parentId === IModel.rootSubjectId)\n ) {\n return true;\n }\n elementFact = elementFacts.get(parentId);\n }\n return false;\n }\n\n private async shouldExportModelForAspect(\n modelId: Id64String,\n elementFacts: ReadonlyMap<Id64String, AspectElementFact>,\n modelFacts: ReadonlyMap<Id64String, AspectModelFact>\n ): Promise<boolean> {\n const modelFact = modelFacts.get(modelId);\n if (modelFact === undefined) {\n this.sourceDb.models.getModel(modelId);\n return false;\n }\n if (modelFact.isTemplate && !this.wantTemplateModels) return false;\n if (\n modelFact.id !== IModel.repositoryModelId &&\n modelFact.id !== IModel.dictionaryId &&\n modelFact.id !== \"0xe\" &&\n !(await this.shouldExportElementForAspect(\n modelFact.id,\n elementFacts.get(modelFact.id)\n ))\n ) {\n return false;\n }\n if (\n modelFact.parentModelId === undefined ||\n modelFact.parentModelId === modelFact.id\n ) {\n return true;\n }\n return this.shouldExportModelForAspect(\n modelFact.parentModelId,\n elementFacts,\n modelFacts\n );\n }\n\n private beginChangedElementTraversalScope(): boolean {\n if (\n this._sourceDbChanges === undefined ||\n this._changedElementTraversal !== undefined\n ) {\n return false;\n }\n\n this._changedElementTraversal = { useForest: true };\n\n const overriddenMethods = this.getOverriddenElementTraversalMethods();\n if (this.visitElements && overriddenMethods.length > 0) {\n this.disableChangedElementForest(\n `${overriddenMethods.join(\" and \")} ${overriddenMethods.length === 1 ? \"is\" : \"are\"} overridden by the exporter subclass`\n );\n }\n return true;\n }\n\n private endChangedElementTraversalScope(): void {\n this._changedElementTraversal = undefined;\n }\n\n private async runScopedElementExport(\n exportElements: () => Promise<void>\n ): Promise<void> {\n const ownsChangedElementTraversal =\n this.beginChangedElementTraversalScope();\n try {\n await this._elementAspectExportCoordinator.run(exportElements);\n } finally {\n if (ownsChangedElementTraversal) this.endChangedElementTraversalScope();\n }\n }\n\n /** Apply the element export filter when deciding whether to process an aspect owner. @internal */\n private async shouldExportElementForAspect(\n elementId: Id64String,\n elementFact?: AspectElementFact\n ): Promise<boolean> {\n if (!this.visitElements) return false;\n\n if (\n this.shouldExportElement ===\n IModelExporter.prototype.shouldExportElement &&\n elementFact !== undefined &&\n !this.shouldExportElementFact(elementFact)\n ) {\n return false;\n }\n\n const element = this.sourceDb.elements.getElement({\n id: elementId,\n wantGeometry: false,\n wantBRepData: false,\n });\n return this.shouldExportElement(element);\n }\n\n private shouldExportElementFact(elementFact: AspectElementFact): boolean {\n if (this._excludedElementIds.has(elementFact.id)) {\n Logger.logInfo(\n loggerCategory,\n `Excluded element ${elementFact.id} by Id`\n );\n return false;\n }\n\n const elementClass = this.sourceDb.getJsClass<typeof Element>(\n elementFact.classFullName\n );\n if (\n (elementFact.classFullName === GeometricElement.classFullName ||\n elementClass.prototype instanceof GeometricElement) &&\n elementFact.categoryId !== undefined &&\n this._excludedElementCategoryIds.has(elementFact.categoryId)\n ) {\n Logger.logInfo(\n loggerCategory,\n `Excluded element ${elementFact.id} by Category`\n );\n return false;\n }\n if (\n !this.wantTemplateModels &&\n (elementFact.classFullName === RecipeDefinitionElement.classFullName ||\n elementClass.prototype instanceof RecipeDefinitionElement)\n ) {\n Logger.logInfo(\n loggerCategory,\n `Excluded RecipeDefinitionElement ${elementFact.id} because wantTemplate=false`\n );\n return false;\n }\n for (const excludedElementClass of this._excludedElementClasses) {\n if (\n elementFact.classFullName === excludedElementClass.classFullName ||\n elementClass.prototype instanceof excludedElementClass\n ) {\n Logger.logInfo(\n loggerCategory,\n `Excluded element ${elementFact.id} by class: ${excludedElementClass.classFullName}`\n );\n return false;\n }\n }\n return true;\n }\n\n private async queryAspectElementHierarchyFacts(\n elementIds: ReadonlySet<Id64String>\n ): Promise<Map<Id64String, AspectElementFact>> {\n const elementFacts = new Map<Id64String, AspectElementFact>();\n const queriedElementIds = new Set<Id64String>();\n let pendingElementIds = new Set(elementIds);\n while (pendingElementIds.size > 0) {\n const currentElementIds = pendingElementIds;\n pendingElementIds = new Set<Id64String>();\n await this.queryAspectElementFacts(currentElementIds, elementFacts);\n for (const elementId of currentElementIds)\n queriedElementIds.add(elementId);\n for (const elementId of currentElementIds) {\n const parentId = elementFacts.get(elementId)?.parentId;\n if (\n parentId !== undefined &&\n !queriedElementIds.has(parentId) &&\n !elementFacts.has(parentId)\n ) {\n pendingElementIds.add(parentId);\n }\n }\n }\n return elementFacts;\n }\n\n private async queryAspectElementFacts(\n elementIds: ReadonlySet<Id64String>,\n elementFacts: Map<Id64String, AspectElementFact>\n ): Promise<void> {\n const unqueriedElementIds = new Set(\n [...elementIds].filter((elementId) => !elementFacts.has(elementId))\n );\n if (unqueriedElementIds.size === 0) return;\n\n for (const elementIdBatch of this.getAspectOwnerIdBatches(\n unqueriedElementIds\n )) {\n const queryParams = new QueryBinder().bindIdSet(\n \"elementIds\",\n elementIdBatch\n );\n for await (const row of this.sourceDb.createQueryReader(\n `SELECT e.ECInstanceId id, e.Parent.Id parentId, e.Model.Id modelId,\n ec_className(e.ECClassId, 's') schemaName,\n ec_className(e.ECClassId, 'c') className\n FROM bis.Element e\n INNER JOIN IdSet(:elementIds) ids ON ids.id = e.ECInstanceId`,\n queryParams,\n { usePrimaryConn: true }\n )) {\n elementFacts.set(row.id, {\n id: row.id,\n parentId: row.parentId ?? undefined,\n modelId: row.modelId,\n classFullName: `${row.schemaName}:${row.className}`,\n });\n }\n if (this._excludedElementCategoryIds.size > 0) {\n const categoryQueryParams = new QueryBinder().bindIdSet(\n \"elementIds\",\n elementIdBatch\n );\n for await (const row of this.sourceDb.createQueryReader(\n `SELECT g.ECInstanceId id, g.Category.Id categoryId\n FROM bis.GeometricElement g\n INNER JOIN IdSet(:elementIds) ids ON ids.id = g.ECInstanceId`,\n categoryQueryParams,\n { usePrimaryConn: true }\n )) {\n const elementFact = elementFacts.get(row.id);\n if (elementFact !== undefined) {\n elementFact.categoryId = row.categoryId;\n }\n }\n }\n }\n }\n\n private async queryAspectModelHierarchyFacts(\n modelIds: ReadonlySet<Id64String>\n ): Promise<Map<Id64String, AspectModelFact>> {\n const modelFacts = new Map<Id64String, AspectModelFact>();\n const queriedModelIds = new Set<Id64String>();\n let pendingModelIds = new Set(modelIds);\n while (pendingModelIds.size > 0) {\n const currentModelIds = pendingModelIds;\n pendingModelIds = new Set<Id64String>();\n for (const modelIdBatch of this.getAspectOwnerIdBatches(\n currentModelIds\n )) {\n const queryParams = new QueryBinder().bindIdSet(\n \"modelIds\",\n modelIdBatch\n );\n for await (const row of this.sourceDb.createQueryReader(\n `SELECT model.ECInstanceId id, model.ParentModel.Id parentModelId, model.IsTemplate isTemplate\n FROM bis.Model model\n INNER JOIN IdSet(:modelIds) ids ON ids.id = model.ECInstanceId`,\n queryParams,\n { usePrimaryConn: true }\n )) {\n modelFacts.set(row.id, {\n id: row.id,\n parentModelId: row.parentModelId ?? undefined,\n isTemplate: row.isTemplate === true || row.isTemplate === 1,\n });\n }\n }\n for (const modelId of currentModelIds) queriedModelIds.add(modelId);\n for (const modelId of currentModelIds) {\n const parentModelId = modelFacts.get(modelId)?.parentModelId;\n if (\n parentModelId !== undefined &&\n !queriedModelIds.has(parentModelId) &&\n !modelFacts.has(parentModelId)\n ) {\n pendingModelIds.add(parentModelId);\n }\n }\n }\n return modelFacts;\n }\n\n private *getAspectOwnerIdBatches(\n ids: ReadonlySet<Id64String>\n ): Iterable<Id64Set> {\n let batch = new Set<Id64String>();\n for (const id of ids) {\n batch.add(id);\n if (batch.size === IModelExporter._elementAspectOwnerBatchSize) {\n yield batch;\n batch = new Set<Id64String>();\n }\n }\n if (batch.size > 0) yield batch;\n }\n\n /** Exports all relationships that subclass from the specified base class.\n * @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.\n * @note This is the bulk traversal path. It hydrates relationships with one streaming query and calls [[exportRelationshipInstance]] directly; it does not call [[exportRelationship]] once per row.\n */\n public async exportRelationships(\n baseRelClassFullName: string\n ): Promise<void> {\n if (!this.visitRelationships) {\n Logger.logTrace(\n loggerCategory,\n \"visitRelationships=false, skipping exportRelationships()\"\n );\n return;\n }\n Logger.logTrace(\n loggerCategory,\n `exportRelationships(${baseRelClassFullName})`\n );\n\n const changedRelationshipIds =\n this._sourceDbChanges === undefined\n ? undefined\n : new Set<Id64String>([\n ...this._sourceDbChanges.relationship.insertIds,\n ...this._sourceDbChanges.relationship.updateIds,\n ]);\n if (changedRelationshipIds?.size === 0) {\n // Deleted relationships are handled by exportChanges after this traversal; they are no\n // longer present in the source iModel and must not cause a full relationship scan here.\n Logger.logTrace(\n loggerCategory,\n \"No inserted or updated relationships, skipping exportRelationships()\"\n );\n return;\n }\n\n const changedRelationshipJoin =\n changedRelationshipIds === undefined\n ? undefined\n : \"INNER JOIN IdSet(:changedRelationshipIds) changed ON changed.id = r.ECInstanceId\";\n const relationshipWhereClause =\n \"s.ECInstanceId IS NOT NULL AND t.ECInstanceId IS NOT NULL\";\n // Bound the async reader's retained raw rows while preserving batched query throughput.\n // Keyset pagination avoids rescanning rows returned by earlier batches.\n const relationshipQueryBatchSize = 1000;\n let lastRelationshipId: Id64String | undefined;\n while (true) {\n let rowsRead = 0;\n const whereClause =\n lastRelationshipId === undefined\n ? relationshipWhereClause\n : `${relationshipWhereClause} AND r.ECInstanceId > :lastRelationshipId`;\n // QueryBinder parameters are immutable after binding a name. Recreate the binder for each\n // keyset page so the changing boundary can be bound without redefining a property.\n const queryParams =\n changedRelationshipIds === undefined && lastRelationshipId === undefined\n ? undefined\n : new QueryBinder();\n if (queryParams !== undefined) {\n if (changedRelationshipIds !== undefined) {\n queryParams.bindIdSet(\n \"changedRelationshipIds\",\n changedRelationshipIds\n );\n }\n if (lastRelationshipId !== undefined) {\n queryParams.bindId(\"lastRelationshipId\", lastRelationshipId);\n }\n }\n const reader = this.sourceDb.createQueryReader(\n this.getRelationshipQuery(\n baseRelClassFullName,\n \"JOIN\",\n whereClause,\n changedRelationshipJoin\n ),\n queryParams,\n {\n usePrimaryConn: true,\n limit: { count: relationshipQueryBatchSize },\n }\n );\n for await (const row of reader) {\n rowsRead++;\n const relInstanceId: Id64String = row.relInstanceId;\n lastRelationshipId = relInstanceId;\n const changesetFilter =\n this.checkRelationshipChangesetFilter(relInstanceId);\n if (changesetFilter.skip) {\n await this._yieldManager.allowYield();\n continue;\n }\n await this.exportHydratedRelationship(\n row.rawInstance,\n row.sourceFedGuid,\n row.targetFedGuid,\n changesetFilter.isUpdate\n );\n await this._yieldManager.allowYield();\n }\n if (rowsRead < relationshipQueryBatchSize) break;\n }\n }\n\n /** Builds the raw relationship query used by the bulk and targeted export paths. */\n private getRelationshipQuery(\n relClassFullName: string,\n endpointJoin: \"JOIN\" | \"LEFT JOIN\",\n whereClause: string,\n relationshipJoin?: string\n ): string {\n return `SELECT r.$ AS rawInstance, r.ECInstanceId AS relInstanceId, s.FederationGuid AS sourceFedGuid, t.FederationGuid AS targetFedGuid FROM ${relClassFullName} r\n ${relationshipJoin ?? \"\"}\n ${endpointJoin} bis.Element s ON s.ECInstanceId = r.SourceECInstanceId\n ${endpointJoin} bis.Element t ON t.ECInstanceId = r.TargetECInstanceId\n WHERE ${whereClause}\n ORDER BY r.ECInstanceId\n OPTIONS USE_JS_PROP_NAMES DO_NOT_TRUNCATE_BLOB`;\n }\n\n /** Applies the changeset filter (when exporting changes) to a relationship instance id.\n * @returns whether to skip the relationship, and whether the export is an update.\n */\n private checkRelationshipChangesetFilter(relInstanceId: Id64String): {\n skip: boolean;\n isUpdate: boolean | undefined;\n } {\n if (undefined === this._sourceDbChanges)\n return { skip: false, isUpdate: undefined };\n if (this._sourceDbChanges.relationship.insertIds.has(relInstanceId))\n return { skip: false, isUpdate: false };\n if (this._sourceDbChanges.relationship.updateIds.has(relInstanceId))\n return { skip: false, isUpdate: true };\n return { skip: true, isUpdate: undefined }; // not in changeset, don't export\n }\n\n /** Converts a raw `$` instance-access row into [RelationshipProps]($common). */\n private getRelationshipProps(rawInstance: unknown): RelationshipProps {\n const parsedRow: unknown =\n typeof rawInstance === \"string\"\n ? JSON.parse(rawInstance, Base64EncodedString.reviver)\n : rawInstance;\n if (!JsonUtils.isObject(parsedRow))\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.InvalidRelationshipData,\n },\n message: \"Expected a Relationship instance query to return an object\",\n });\n\n const row: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(parsedRow)) {\n const ecPropertyName =\n key.length === 0 ? key : key[0].toUpperCase() + key.substring(1);\n row[ECJsNames.toJsName(ecPropertyName)] = value;\n }\n\n const className = row.className;\n if (typeof className !== \"string\")\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.InvalidRelationshipData,\n },\n message: \"Expected a Relationship instance query to return a className\",\n });\n\n row.classFullName = className.replace(\".\", \":\");\n delete row.className;\n delete row.sourceClassName;\n delete row.targetClassName;\n return row as unknown as RelationshipProps;\n }\n\n /** Export one specified relationship from the source iModel.\n * @note This targeted path is separate from [[exportRelationships]], which traverses a class hierarchy. It uses the same raw instance query and passes endpoint FederationGuids to the handler.\n */\n public async exportRelationship(\n relClassFullName: string,\n relInstanceId: Id64String\n ): Promise<void> {\n if (!this.visitRelationships) {\n Logger.logTrace(\n loggerCategory,\n `visitRelationships=false, skipping exportRelationship(${relClassFullName}, ${relInstanceId})`\n );\n return;\n }\n const changesetFilter =\n this.checkRelationshipChangesetFilter(relInstanceId);\n if (changesetFilter.skip) return;\n\n const queryParams = new QueryBinder().bindId(\n \"relInstanceId\",\n relInstanceId\n );\n const reader = this.sourceDb.createQueryReader(\n this.getRelationshipQuery(\n relClassFullName,\n \"LEFT JOIN\",\n \"r.ECInstanceId = :relInstanceId\"\n ),\n queryParams,\n { usePrimaryConn: true }\n );\n if (await reader.step()) {\n const row = reader.current;\n await this.exportHydratedRelationship(\n row.rawInstance,\n row.sourceFedGuid,\n row.targetFedGuid,\n changesetFilter.isUpdate\n );\n return;\n }\n\n // The LEFT JOIN query only returns no row when the relationship doesn't exist, so this throws core's not-found error.\n this.sourceDb.relationships.getInstance(relClassFullName, relInstanceId);\n }\n\n /** Hydrates a relationship query row and runs the common export pipeline. */\n private async exportHydratedRelationship(\n rawInstance: unknown,\n sourceFedGuid: GuidString | null | undefined,\n targetFedGuid: GuidString | null | undefined,\n isUpdate: boolean | undefined\n ): Promise<void> {\n const relationship = this.sourceDb.constructEntity<Relationship>(\n this.getRelationshipProps(rawInstance)\n );\n await this.exportRelationshipInstance(relationship, isUpdate, {\n source: sourceFedGuid ?? undefined,\n target: targetFedGuid ?? undefined,\n });\n }\n\n /** Applies exclusion rules and handler callbacks to an already-hydrated relationship instance.\n * @param endpointFedGuids The FederationGuids of the relationship's source and target elements, passed to [[IModelExportHandler.onExportRelationship]].\n * @note This is the common protected hook used by both [[exportRelationship]] and [[exportRelationships]]. Most consumers should customize [[IModelExportHandler]] instead.\n */\n protected async exportRelationshipInstance(\n relationship: Relationship,\n isUpdate: boolean | undefined,\n endpointFedGuids?: RelationshipEndpointFederationGuids\n ): Promise<void> {\n // passed changeset test, now apply standard exclusion rules\n Logger.logTrace(\n loggerCategory,\n `exportRelationship(${relationship.classFullName}, ${relationship.id})`\n );\n for (const excludedRelationshipClass of this._excludedRelationshipClasses) {\n if (relationship instanceof excludedRelationshipClass) {\n Logger.logInfo(\n loggerCategory,\n `Excluded relationship by class: ${excludedRelationshipClass.classFullName}`\n );\n return;\n }\n }\n // relationship has passed standard exclusion rules, now give handler a chance to accept/reject export\n if (await this.handler.shouldExportRelationship(relationship)) {\n await this.handler.onExportRelationship(\n relationship,\n isUpdate,\n endpointFedGuids\n );\n await this.trackProgress();\n }\n }\n\n /** Tracks incremental progress */\n private async trackProgress(): Promise<void> {\n this._progressCounter++;\n if (0 === this._progressCounter % this.progressInterval) {\n return this.handler.onProgress();\n }\n }\n}\n\n/**\n * Arguments for [[ChangedInstanceIds.initialize]]\n * @public\n */\nexport type ChangedInstanceIdsInitOptions = ExportChangesOptions & {\n iModel: BriefcaseDb;\n};\n\n/** Class for holding change information.\n * @public\n */\nexport class ChangedInstanceOps {\n public insertIds = new Set<Id64String>();\n public updateIds = new Set<Id64String>();\n public deleteIds = new Set<Id64String>();\n\n /** Initializes the object from IModelJsNative.ChangedInstanceOpsProps. */\n public addFromJson(\n val: IModelJsNative.ChangedInstanceOpsProps | undefined\n ): void {\n if (undefined !== val) {\n if (undefined !== val.insert && Array.isArray(val.insert))\n val.insert.forEach((id: Id64String) => this.insertIds.add(id));\n\n if (undefined !== val.update && Array.isArray(val.update))\n val.update.forEach((id: Id64String) => this.updateIds.add(id));\n\n if (undefined !== val.delete && Array.isArray(val.delete))\n val.delete.forEach((id: Id64String) => this.deleteIds.add(id));\n }\n }\n\n /**\n * Checks if empty.\n * @returns true if there no ids in the ChangedInstanceOps object.\n */\n public get isEmpty(): boolean {\n return (\n 0 === this.insertIds.size &&\n 0 === this.updateIds.size &&\n 0 === this.deleteIds.size\n );\n }\n}\n\n/**\n * A change to one EC instance, for recording changes that don't come from a changeset reader.\n * @see [[ChangedInstanceIds.addChangeRecord]]\n * @beta\n */\nexport interface ChangeRecord {\n /** ID of the changed instance. */\n id: Id64String;\n /** EC class ID of the changed instance, used to tell elements, models, aspects, relationships, and CodeSpecs apart. */\n ecClassId: Id64String;\n /** The operation that changed the instance. */\n op: SqliteChangeOp;\n /**\n * For an aspect, the element that owns it. Required for a deleted aspect, because the source iModel no longer has it.\n * When undefined for an inserted or updated aspect, the owner is read from the source iModel.\n */\n aspectOwnerElementId?: Id64String;\n}\n\n/**\n * Class for discovering modified elements between 2 versions of an iModel.\n * @public\n */\nexport class ChangedInstanceIds {\n public codeSpec = new ChangedInstanceOps();\n public model = new ChangedInstanceOps();\n public element = new ChangedInstanceOps();\n public aspect = new ChangedInstanceOps();\n public relationship = new ChangedInstanceOps();\n public font = new ChangedInstanceOps();\n private _classKinds?: SourceClassKinds;\n private readonly _aspectOwnerElementIds = new Set<Id64String>();\n\n /** Element IDs that own the aspects represented by `aspect` changes.\n * @internal\n */\n public get aspectOwnerElementIds(): ReadonlySet<Id64String> {\n return this._aspectOwnerElementIds;\n }\n\n private _db: IModelDb;\n public constructor(db: IModelDb) {\n this._db = db;\n }\n\n /** Checks if there are any changes.\n * @returns true if there are any changes in the ChangedInstanceIds object.\n */\n public get hasChanges(): boolean {\n return (\n !this.codeSpec.isEmpty ||\n !this.model.isEmpty ||\n !this.element.isEmpty ||\n !this.aspect.isEmpty ||\n !this.relationship.isEmpty ||\n !this.font.isEmpty\n );\n }\n\n /**\n * Adds the provided [[ChangeInstance]] to the appropriate set of changes by class type (codeSpec, model, element, aspect, or relationship) maintained by this instance of ChangedInstanceIds.\n * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'\n * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.\n * @param change Changed EC instance with the ID, operation, and EC class ID of the changed entity.\n */\n public async addChange(change: ChangeInstance): Promise<void> {\n return this.recordChange(change, undefined);\n }\n\n /**\n * Adds a change read from somewhere other than a changeset, such as a precomputed cache, like [[addChange]]\n * does for a changeset reader's [ChangeInstance]($backend). Add changes in the order they were made, so that,\n * for example, an insert followed by a delete of the same instance cancels out.\n * @throws [ITwinError]($bentley) with key `AspectOwnerRequired` if a deleted aspect has no `aspectOwnerElementId`.\n * @beta\n */\n public async addChangeRecord(change: ChangeRecord): Promise<void> {\n if (change.op === \"Deleted\" && change.aspectOwnerElementId === undefined) {\n this._classKinds ??= await SourceClassKinds.query(this._db);\n const kind = this._classKinds.kindOf(change.ecClassId);\n // The source no longer has the aspect, so without its owner the target aspect would silently stay.\n if (kind === \"aspect\" || kind === \"externalSourceAspect\")\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.AspectOwnerRequired,\n },\n message: `Deleted ElementAspect change ${change.id} requires the owning element ID.`,\n });\n }\n return this.applyChangeRecord(change, undefined);\n }\n\n private async recordChange(\n change: ChangeInstance,\n unresolvedAspectIds: Set<Id64String> | undefined\n ): Promise<void> {\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 const changeType: SqliteChangeOp | undefined = change.$meta.op;\n if (changeType === undefined)\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.ChangedInstanceMetadataMissing,\n },\n message: `ChangeType was undefined for id: ${change.ECInstanceId}.`,\n });\n return this.applyChangeRecord(\n {\n id: change.ECInstanceId,\n ecClassId,\n op: changeType,\n aspectOwnerElementId: change.Element?.Id,\n },\n unresolvedAspectIds\n );\n }\n\n private async applyChangeRecord(\n change: ChangeRecord,\n unresolvedAspectIds: Set<Id64String> | undefined\n ): Promise<void> {\n // Await only the first time, so later changes are classified without yielding.\n this._classKinds ??= await SourceClassKinds.query(this._db);\n const { id, ecClassId, op } = change;\n switch (this._classKinds.kindOf(ecClassId)) {\n case \"relationship\":\n return this.handleChange(this.relationship, op, id);\n case \"codeSpec\":\n return this.handleChange(this.codeSpec, op, id);\n case \"aspect\":\n case \"externalSourceAspect\": {\n let ownerElementId = change.aspectOwnerElementId;\n if (ownerElementId === undefined) {\n if (unresolvedAspectIds !== undefined) unresolvedAspectIds.add(id);\n else ownerElementId = this.tryGetAspectOwnerElementId(id);\n }\n if (ownerElementId !== undefined)\n this._aspectOwnerElementIds.add(ownerElementId);\n return this.handleChange(this.aspect, op, id);\n }\n case \"model\":\n return this.handleChange(this.model, op, id);\n case \"element\":\n return this.handleChange(this.element, op, id);\n case \"skippedRelationship\":\n case undefined:\n return;\n }\n }\n\n private tryGetAspectOwnerElementId(\n aspectId: Id64String\n ): Id64String | undefined {\n try {\n return this._db.elements.getAspect(aspectId).element.id;\n } catch (error) {\n if (\n error instanceof IModelError &&\n error.errorNumber === IModelStatus.NotFound\n ) {\n return undefined;\n }\n throw error;\n }\n }\n\n /**\n * This method should only be called inside [[IModelTransformer.addCustomChanges]].\n * It adds the provided change to the element changes maintained by this instance of ChangedInstanceIds.\n * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'\n * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.\n * @note Custom element 'Insert' and 'Update' will mark element's parent model hierarchy and their modeled elements as 'Updated' in [[ChangedInstanceIds.model]] and [[ChangedInstanceIds.element]]. Parent models have to be marked as 'Updated' to make sure that added change is not skipped by transformer. Transformer starts processing elements from RepositoryModel and then visits all child models. Modeled elements hierarchy is marked as updated to trigger their inserts in case a new model (or its parent) needs to be inserted.\n * @note Custom element 'Insert' will also mark element aspects and all element relationships as inserted.\n * @note It is the responsibility of the caller to ensure that the provided id is, in fact an element.\n * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.\n * @note In data processing with filter criteria scenarios it is important to consistently filter out models and their modeled elements that were previously removed from target via [[addCustomModelChange]] or [[shouldExportElement]] apis.\n * @beta\n */\n public async addCustomElementChange(\n changeType: SqliteChangeOp,\n ids: Id64Arg\n ): Promise<void> {\n if (Id64.sizeOf(ids) === 0) {\n return;\n }\n\n for (const id of Id64.iterable(ids)) {\n this.handleChange(this.element, changeType, id);\n }\n\n if (changeType === \"Deleted\") {\n return;\n }\n\n const idsSet = Id64.toIdSet(ids, true);\n // Parent models have to be marked as 'Updated' to make sure that added change is not skipped by transformer. Transformer starts processing elements from RepositoryModel and then visits all child models.\n // Transformer handles update as insert if element is not found in target, for this reason modeled elements will be also marked as updated to trigger their inserts in case a new model (or its parent) needs to be inserted. Otherwise error would be thrown about missing modeled element while inserting new model.\n const parentModelIds = await this.markParentModelsAsUpdated(idsSet);\n\n // Aspects and relationships of inserted data needs to be marked as inserted otherwise those would not be exported\n if (changeType === \"Inserted\") {\n // Adding parents as well as we are not sure if those were inserted or updated\n parentModelIds.forEach((parentId) => {\n idsSet.add(parentId);\n });\n\n await this.markElementAspectsAsInserted(idsSet);\n // Marking only ElementRefersToElements.classFullName as only those are exported in exportRelationships()\n await this.markElementRelationshipsAsInserted(\n ElementRefersToElements.classFullName,\n idsSet\n );\n }\n }\n\n /**\n * This method should only be called inside [IModelTransformer.addCustomChanges].\n * Adds the provided change to the model changes maintained by this instance of ChangedInstanceIds.\n * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'\n * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.\n * Will add same change to the model's modeledElement by calling [[ChangedInstanceIds.addCustomElementChange]] which will register more needed changes. This is to ensure the changes from the model and its modeledElement get exported together.\n * @note It is the responsibility of the caller to ensure that the provided id is, in fact a model.\n * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.\n * @note In data processing with filter criteria scenarios it is important to consistently filter out models and their modeled elements that were previously removed from target via [[addCustomModelChange]] or [[shouldExportElement]] apis.\n * @beta\n */\n public async addCustomModelChange(\n changeType: SqliteChangeOp,\n ids: Id64Arg\n ): Promise<void> {\n // Also add the model's modeledElement to the element changes. The modeledElement and model go hand in hand and have the same id.\n await this.addCustomElementChange(changeType, ids);\n for (const id of Id64.iterable(ids)) {\n this.handleChange(this.model, changeType, id);\n }\n }\n\n /**\n * This method should only be called inside [IModelTransformer.addCustomChanges].\n * Adds the provided change to the aspect changes maintained by this instance of ChangedInstanceIds\n * If the same ECInstanceId is seen multiple times, the changedInstanceIds will be modified accordingly, i.e. if an id 'x' was updated but now we see 'x' was deleted, we will remove 'x'\n * from the set of updatedIds and add it to the set of deletedIds for the appropriate class type.\n * @note It is the responsibility of the caller to ensure that the provided id is, in fact an aspect.\n * @param elementIds Owning element IDs. Required when `changeType` is\n * `Deleted` or the source aspect row is unavailable.\n * @note In most cases, this method does not need to be called. Its only for consumers to mimic changes as if they were found in a changeset, which should only be useful in certain cases such as the changing of filter criteria for a preexisting master branch relationship.\n * @beta\n */\n public addCustomAspectChange(\n changeType: SqliteChangeOp,\n ids: Id64Arg,\n elementIds?: Id64Arg\n ): void {\n if (elementIds !== undefined) {\n for (const elementId of Id64.iterable(elementIds)) {\n this._aspectOwnerElementIds.add(elementId);\n }\n }\n for (const id of Id64.iterable(ids)) {\n if (elementIds === undefined && changeType === \"Deleted\") {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.AspectOwnerRequired,\n },\n message:\n \"Custom deleted ElementAspect changes require the owning element ID.\",\n });\n }\n if (elementIds === undefined && changeType !== \"Deleted\") {\n const ownerElementId = this.tryGetAspectOwnerElementId(id);\n if (ownerElementId === undefined) {\n ITwinError.throwError({\n iTwinErrorId: {\n scope: IModelTransformerErrorScope,\n key: IModelTransformerError.AspectOwnerRequired,\n },\n message:\n \"Custom ElementAspect changes require the owning element ID when the source aspect is unavailable.\",\n });\n }\n this._aspectOwnerElementIds.add(ownerElementId);\n }\n\n this.handleChange(this.aspect, changeType, id);\n }\n }\n\n private recordCustomAspectChange(\n changeType: SqliteChangeOp,\n aspectId: Id64String,\n ownerElementId: Id64String\n ): void {\n this._aspectOwnerElementIds.add(ownerElementId);\n this.handleChange(this.aspect, changeType, aspectId);\n }\n\n /**\n * There is an optimization in [IModelExporter.exportModelContents] which doesn't try to export elements within a model unless the model itself is marked as `Updated` or 'Inserted' in sourceDbChanges. This method is used in [[addCustomElementChange]] and [[addCustomModelChange]] to add the parent model hierarchy to the 'updatedIds' so that the custom element changes are exported.\n * Transformer will insert 'Updated' model to target if it does not exist there already. To handle such case, modeled elements of parent models are also marked as updated. This is done, because model can not be inserted without it's modeled element.\n */\n private async markParentModelsAsUpdated(elementIds: Id64Set) {\n const params = new QueryBinder().bindIdSet(\"elementIds\", elementIds);\n\n const ecQuery = `\n WITH RECURSIVE hierarchy (parentId) AS (\n SELECT element.Model.Id\n FROM bis.Element element\n INNER JOIN IdSet(:elementIds) ids ON ids.id = element.ECInstanceId\n UNION\n SELECT ParentModel.id\n FROM bis.Model e\n INNER JOIN hierarchy h ON h.parentId = e.ECInstanceId\n )\n SELECT parentId FROM hierarchy where parentId is not null\n `;\n const parentModelIds = new Set<Id64String>();\n for await (const row of this._db.createQueryReader(ecQuery, params, {\n usePrimaryConn: true,\n })) {\n // Transformer handles update as insert when element does not exist in target.\n // Which means that in scenario where child and parent model are filtered out from target,\n // and child element is inserted trough custom change, its parent model will be marked as updated.\n // Transformer then will:\n // 1. Handle parent update as insert (since it does not exist in target).\n // 2. Will insert child element (otherwise this insert would be ignored due to missing parent).\n this.handleChange(this.model, \"Updated\", row.parentId);\n this.handleChange(this.element, \"Updated\", row.parentId);\n parentModelIds.add(row.parentId);\n }\n return parentModelIds;\n }\n\n private async markElementRelationshipsAsInserted(\n relationshipClassName: string,\n elementIds: Id64Set\n ) {\n const ecQuery = `SELECT relationship.ECInstanceId\n FROM ${relationshipClassName} relationship\n INNER JOIN IdSet(:elementIds) ids\n ON ids.id = relationship.TargetECInstanceId\n UNION\n SELECT relationship.ECInstanceId\n FROM ${relationshipClassName} relationship\n INNER JOIN IdSet(:elementIds) ids\n ON ids.id = relationship.SourceECInstanceId`;\n\n const queryBinder = new QueryBinder().bindIdSet(\"elementIds\", elementIds);\n const queryReader = this._db.createQueryReader(ecQuery, queryBinder, {\n usePrimaryConn: true,\n });\n\n for await (const row of queryReader) {\n this.handleChange(this.relationship, \"Inserted\", row.ECInstanceId);\n }\n }\n\n private async markElementAspectsAsInserted(elementIds: Id64Set) {\n for (const aspectClassName of [\n ElementUniqueAspect.classFullName,\n ElementMultiAspect.classFullName,\n ]) {\n const ecQuery = `SELECT aspect.ECInstanceId, aspect.Element.Id\n FROM ${aspectClassName} aspect\n INNER JOIN IdSet(:elementIds) ids ON ids.id = aspect.Element.Id`;\n const queryBinder = new QueryBinder().bindIdSet(\"elementIds\", elementIds);\n const queryReader = this._db.createQueryReader(ecQuery, queryBinder, {\n usePrimaryConn: true,\n });\n for await (const row of queryReader) {\n const [aspectId, elementId] = row.toArray();\n this.recordCustomAspectChange(\"Inserted\", aspectId, elementId);\n }\n }\n }\n\n private handleChange(\n changedInstanceOps: ChangedInstanceOps,\n changeType: SqliteChangeOp,\n id: Id64String\n ) {\n // if changeType is a delete and we already have the id in the inserts then we can remove the id from the inserts.\n // if changeType is a delete and we already have the id in the updates then we can remove the id from the updates AND add it to the deletes.\n // if changeType is an insert and we already have the id in the deletes then we can remove the id from the deletes AND add it to the inserts.\n if (changeType === \"Inserted\") {\n changedInstanceOps.insertIds.add(id);\n changedInstanceOps.deleteIds.delete(id);\n } else if (changeType === \"Updated\") {\n if (!changedInstanceOps.insertIds.has(id))\n changedInstanceOps.updateIds.add(id);\n } else if (changeType === \"Deleted\") {\n // If we've inserted the entity at some point already and now we're seeing a delete. We can simply remove the entity from our inserted ids without adding it to deletedIds.\n if (changedInstanceOps.insertIds.has(id))\n changedInstanceOps.insertIds.delete(id);\n else {\n changedInstanceOps.updateIds.delete(id);\n changedInstanceOps.deleteIds.add(id);\n }\n }\n }\n\n /**\n * Initializes a new ChangedInstanceIds object with information taken from a range of changesets.\n * @public\n */\n public static async initialize(\n opts: ChangedInstanceIdsInitOptions\n ): Promise<ChangedInstanceIds | undefined> {\n if (\"changedInstanceIds\" in opts) return opts.changedInstanceIds;\n\n const iModelId = opts.iModel.iModelId;\n\n const startChangeset =\n \"startChangeset\" in opts ? opts.startChangeset : undefined;\n const changesetRanges: [number, number][] | undefined =\n startChangeset !== undefined\n ? [\n [\n startChangeset.index ??\n (\n await BriefcaseManager.queryChangeset({\n iModelId,\n changeset: {\n id: startChangeset.id ?? opts.iModel.changeset.id,\n },\n })\n ).index,\n opts.iModel.changeset.index ??\n (\n await BriefcaseManager.queryChangeset({\n iModelId,\n changeset: { id: opts.iModel.changeset.id },\n })\n ).index,\n ],\n ]\n : \"changesetRanges\" in opts\n ? opts.changesetRanges\n : undefined;\n const csFileProps =\n changesetRanges !== undefined\n ? (await ChangesetScanner.download(opts.iModel, changesetRanges)).flat()\n : \"csFileProps\" in opts\n ? opts.csFileProps\n : undefined;\n\n if (csFileProps === undefined) return undefined;\n\n const changedInstanceIds = new ChangedInstanceIds(opts.iModel);\n await ChangesetScanner.scan(opts.iModel, [csFileProps], {\n changedInstanceIds,\n collectDeletionRecords: false,\n });\n return changedInstanceIds;\n }\n\n /** Record an ordered batch, then resolve missing aspect owners against current source state.\n * @internal\n */\n public async addChanges(changes: Iterable<ChangeInstance>): Promise<void> {\n const unresolvedAspectIds = new Set<Id64String>();\n for (const change of changes)\n await this.recordChange(change, unresolvedAspectIds);\n // Only resolve missing owners from current source state. Changeset-provided\n // owners, including historical owners, were retained while recording changes.\n if (unresolvedAspectIds.size > 0) {\n this._db.withQueryReader(\n `WITH AspectIds AS (SELECT id FROM IdSet(:aspectIds))\n SELECT Element.Id FROM BisCore.ElementMultiAspect\n WHERE ECInstanceId IN (SELECT id FROM AspectIds)\n UNION ALL\n SELECT Element.Id FROM BisCore.ElementUniqueAspect\n WHERE ECInstanceId IN (SELECT id FROM AspectIds)`,\n (reader) => {\n while (reader.step())\n this._aspectOwnerElementIds.add(reader.current[0]);\n },\n new QueryBinder().bindIdSet(\"aspectIds\", unresolvedAspectIds)\n );\n }\n }\n}\n"]}
|
package/package.json
CHANGED