@itwin/imodel-transformer 2.0.0-dev.71 → 2.0.0-dev.73
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/README.md +11 -0
- package/lib/Algo.d.ts.map +1 -0
- package/lib/{cjs/Algo.js → Algo.js} +1 -4
- package/lib/Algo.js.map +1 -0
- package/lib/BigMap.d.ts.map +1 -0
- package/lib/{cjs/BigMap.js → BigMap.js} +1 -5
- package/lib/BigMap.js.map +1 -0
- package/lib/BranchProvenanceInitializer.d.ts.map +1 -0
- package/lib/{cjs/BranchProvenanceInitializer.js → BranchProvenanceInitializer.js} +34 -37
- package/lib/BranchProvenanceInitializer.js.map +1 -0
- package/lib/ChangedElementForest.d.ts.map +1 -0
- package/lib/{cjs/ChangedElementForest.js → ChangedElementForest.js} +12 -14
- package/lib/ChangedElementForest.js.map +1 -0
- package/lib/{cjs/ChangesetScanner.d.ts → ChangesetScanner.d.ts} +2 -2
- package/lib/ChangesetScanner.d.ts.map +1 -0
- package/lib/{cjs/ChangesetScanner.js → ChangesetScanner.js} +19 -24
- package/lib/ChangesetScanner.js.map +1 -0
- package/lib/ECReferenceTypesCache.d.ts.map +1 -0
- package/lib/{cjs/ECReferenceTypesCache.js → ECReferenceTypesCache.js} +32 -37
- package/lib/ECReferenceTypesCache.js.map +1 -0
- package/lib/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +1 -0
- package/lib/{cjs/ECSqlReaderAsyncIterableIteratorAdapter.js → ECSqlReaderAsyncIterableIteratorAdapter.js} +2 -7
- package/lib/ECSqlReaderAsyncIterableIteratorAdapter.js.map +1 -0
- package/lib/ElementAspectCleanup.d.ts.map +1 -0
- package/lib/{cjs/ElementAspectCleanup.js → ElementAspectCleanup.js} +9 -13
- package/lib/ElementAspectCleanup.js.map +1 -0
- package/lib/ElementAspectExportCoordinator.d.ts.map +1 -0
- package/lib/{cjs/ElementAspectExportCoordinator.js → ElementAspectExportCoordinator.js} +1 -5
- package/lib/ElementAspectExportCoordinator.js.map +1 -0
- package/lib/ElementAspectExportProcessor.d.ts.map +1 -0
- package/lib/{cjs/ElementAspectExportProcessor.js → ElementAspectExportProcessor.js} +10 -14
- package/lib/ElementAspectExportProcessor.js.map +1 -0
- package/lib/ElementBulkDelete.d.ts.map +1 -0
- package/lib/{cjs/ElementBulkDelete.js → ElementBulkDelete.js} +9 -12
- package/lib/{cjs/ElementBulkDelete.js.map → ElementBulkDelete.js.map} +1 -1
- package/lib/EntityExistenceCache.d.ts.map +1 -0
- package/lib/{cjs/EntityExistenceCache.js → EntityExistenceCache.js} +4 -8
- package/lib/EntityExistenceCache.js.map +1 -0
- package/lib/EntityUnifier.d.ts.map +1 -0
- package/lib/{cjs/EntityUnifier.js → EntityUnifier.js} +21 -22
- package/lib/EntityUnifier.js.map +1 -0
- package/lib/{cjs/IModelCloneContext.d.ts → IModelCloneContext.d.ts} +2 -2
- package/lib/IModelCloneContext.d.ts.map +1 -0
- package/lib/{cjs/IModelCloneContext.js → IModelCloneContext.js} +52 -56
- package/lib/IModelCloneContext.js.map +1 -0
- package/lib/{cjs/IModelExporter.d.ts → IModelExporter.d.ts} +1 -1
- package/lib/IModelExporter.d.ts.map +1 -0
- package/lib/{cjs/IModelExporter.js → IModelExporter.js} +156 -161
- package/lib/IModelExporter.js.map +1 -0
- package/lib/{cjs/IModelImporter.d.ts → IModelImporter.d.ts} +3 -3
- package/lib/IModelImporter.d.ts.map +1 -0
- package/lib/{cjs/IModelImporter.js → IModelImporter.js} +104 -109
- package/lib/IModelImporter.js.map +1 -0
- package/lib/IModelTransformContext.d.ts.map +1 -0
- package/lib/IModelTransformContext.js +2 -0
- package/lib/IModelTransformContext.js.map +1 -0
- package/lib/{cjs/IModelTransformer.d.ts → IModelTransformer.d.ts} +6 -6
- package/lib/IModelTransformer.d.ts.map +1 -0
- package/lib/{cjs/IModelTransformer.js → IModelTransformer.js} +240 -276
- package/lib/IModelTransformer.js.map +1 -0
- package/lib/IModelTransformerError.d.ts.map +1 -0
- package/lib/{cjs/IModelTransformerError.js → IModelTransformerError.js} +3 -6
- package/lib/IModelTransformerError.js.map +1 -0
- package/lib/{cjs/ProvenanceManager.d.ts → ProvenanceManager.d.ts} +3 -3
- package/lib/ProvenanceManager.d.ts.map +1 -0
- package/lib/{cjs/ProvenanceManager.js → ProvenanceManager.js} +69 -73
- package/lib/ProvenanceManager.js.map +1 -0
- package/lib/SourceClassKinds.d.ts.map +1 -0
- package/lib/{cjs/SourceClassKinds.js → SourceClassKinds.js} +1 -5
- package/lib/SourceClassKinds.js.map +1 -0
- package/lib/SyncTypeResolver.d.ts.map +1 -0
- package/lib/{cjs/SyncTypeResolver.js → SyncTypeResolver.js} +15 -19
- package/lib/SyncTypeResolver.js.map +1 -0
- package/lib/TransformerLoggerCategory.d.ts.map +1 -0
- package/lib/{cjs/TransformerLoggerCategory.js → TransformerLoggerCategory.js} +2 -5
- package/lib/TransformerLoggerCategory.js.map +1 -0
- package/lib/TransformerPackageMetadata.d.ts.map +1 -0
- package/lib/TransformerPackageMetadata.js +8 -0
- package/lib/TransformerPackageMetadata.js.map +1 -0
- package/lib/{cjs/imodel-transformer.d.ts → imodel-transformer.d.ts} +9 -9
- package/lib/imodel-transformer.d.ts.map +1 -0
- package/lib/imodel-transformer.js +88 -0
- package/lib/imodel-transformer.js.map +1 -0
- package/lib/{cjs/schema-processing → schema-processing}/DynamicSchemaUnionStrategy.d.ts +1 -1
- package/lib/schema-processing/DynamicSchemaUnionStrategy.d.ts.map +1 -0
- package/lib/{cjs/schema-processing → schema-processing}/DynamicSchemaUnionStrategy.js +16 -20
- package/lib/schema-processing/DynamicSchemaUnionStrategy.js.map +1 -0
- package/lib/{cjs/schema-processing → schema-processing}/SchemaProcessingCoordinator.d.ts +2 -2
- package/lib/schema-processing/SchemaProcessingCoordinator.d.ts.map +1 -0
- package/lib/{cjs/schema-processing → schema-processing}/SchemaProcessingCoordinator.js +15 -52
- package/lib/schema-processing/SchemaProcessingCoordinator.js.map +1 -0
- package/lib/schema-processing/SchemaProcessingStrategy.d.ts.map +1 -0
- package/lib/{cjs/schema-processing → schema-processing}/SchemaProcessingStrategy.js +1 -5
- package/lib/schema-processing/SchemaProcessingStrategy.js.map +1 -0
- package/lib/schema-processing.d.ts +7 -0
- package/lib/schema-processing.d.ts.map +1 -0
- package/lib/schema-processing.js +11 -0
- package/lib/schema-processing.js.map +1 -0
- package/package.json +14 -14
- package/lib/cjs/Algo.d.ts.map +0 -1
- package/lib/cjs/Algo.js.map +0 -1
- package/lib/cjs/BigMap.d.ts.map +0 -1
- package/lib/cjs/BigMap.js.map +0 -1
- package/lib/cjs/BranchProvenanceInitializer.d.ts.map +0 -1
- package/lib/cjs/BranchProvenanceInitializer.js.map +0 -1
- package/lib/cjs/ChangedElementForest.d.ts.map +0 -1
- package/lib/cjs/ChangedElementForest.js.map +0 -1
- package/lib/cjs/ChangesetScanner.d.ts.map +0 -1
- package/lib/cjs/ChangesetScanner.js.map +0 -1
- package/lib/cjs/ECReferenceTypesCache.d.ts.map +0 -1
- package/lib/cjs/ECReferenceTypesCache.js.map +0 -1
- package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +0 -1
- package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js.map +0 -1
- package/lib/cjs/ElementAspectCleanup.d.ts.map +0 -1
- package/lib/cjs/ElementAspectCleanup.js.map +0 -1
- package/lib/cjs/ElementAspectExportCoordinator.d.ts.map +0 -1
- package/lib/cjs/ElementAspectExportCoordinator.js.map +0 -1
- package/lib/cjs/ElementAspectExportProcessor.d.ts.map +0 -1
- package/lib/cjs/ElementAspectExportProcessor.js.map +0 -1
- package/lib/cjs/ElementBulkDelete.d.ts.map +0 -1
- package/lib/cjs/EntityExistenceCache.d.ts.map +0 -1
- package/lib/cjs/EntityExistenceCache.js.map +0 -1
- package/lib/cjs/EntityUnifier.d.ts.map +0 -1
- package/lib/cjs/EntityUnifier.js.map +0 -1
- package/lib/cjs/IModelCloneContext.d.ts.map +0 -1
- package/lib/cjs/IModelCloneContext.js.map +0 -1
- package/lib/cjs/IModelExporter.d.ts.map +0 -1
- package/lib/cjs/IModelExporter.js.map +0 -1
- package/lib/cjs/IModelImporter.d.ts.map +0 -1
- package/lib/cjs/IModelImporter.js.map +0 -1
- package/lib/cjs/IModelTransformContext.d.ts.map +0 -1
- package/lib/cjs/IModelTransformContext.js +0 -3
- package/lib/cjs/IModelTransformContext.js.map +0 -1
- package/lib/cjs/IModelTransformer.d.ts.map +0 -1
- package/lib/cjs/IModelTransformer.js.map +0 -1
- package/lib/cjs/IModelTransformerError.d.ts.map +0 -1
- package/lib/cjs/IModelTransformerError.js.map +0 -1
- package/lib/cjs/ProvenanceManager.d.ts.map +0 -1
- package/lib/cjs/ProvenanceManager.js.map +0 -1
- package/lib/cjs/SourceClassKinds.d.ts.map +0 -1
- package/lib/cjs/SourceClassKinds.js.map +0 -1
- package/lib/cjs/SyncTypeResolver.d.ts.map +0 -1
- package/lib/cjs/SyncTypeResolver.js.map +0 -1
- package/lib/cjs/TransformerLoggerCategory.d.ts.map +0 -1
- package/lib/cjs/TransformerLoggerCategory.js.map +0 -1
- package/lib/cjs/TransformerPackageMetadata.d.ts.map +0 -1
- package/lib/cjs/TransformerPackageMetadata.js +0 -47
- package/lib/cjs/TransformerPackageMetadata.js.map +0 -1
- package/lib/cjs/imodel-transformer.d.ts.map +0 -1
- package/lib/cjs/imodel-transformer.js +0 -125
- package/lib/cjs/imodel-transformer.js.map +0 -1
- package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts.map +0 -1
- package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js.map +0 -1
- package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts.map +0 -1
- package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js.map +0 -1
- package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts.map +0 -1
- package/lib/cjs/schema-processing/SchemaProcessingStrategy.js.map +0 -1
- package/lib/cjs/schema-processing.d.ts +0 -7
- package/lib/cjs/schema-processing.d.ts.map +0 -1
- package/lib/cjs/schema-processing.js +0 -27
- package/lib/cjs/schema-processing.js.map +0 -1
- /package/lib/{cjs/Algo.d.ts → Algo.d.ts} +0 -0
- /package/lib/{cjs/BigMap.d.ts → BigMap.d.ts} +0 -0
- /package/lib/{cjs/BranchProvenanceInitializer.d.ts → BranchProvenanceInitializer.d.ts} +0 -0
- /package/lib/{cjs/ChangedElementForest.d.ts → ChangedElementForest.d.ts} +0 -0
- /package/lib/{cjs/ECReferenceTypesCache.d.ts → ECReferenceTypesCache.d.ts} +0 -0
- /package/lib/{cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts → ECSqlReaderAsyncIterableIteratorAdapter.d.ts} +0 -0
- /package/lib/{cjs/ElementAspectCleanup.d.ts → ElementAspectCleanup.d.ts} +0 -0
- /package/lib/{cjs/ElementAspectExportCoordinator.d.ts → ElementAspectExportCoordinator.d.ts} +0 -0
- /package/lib/{cjs/ElementAspectExportProcessor.d.ts → ElementAspectExportProcessor.d.ts} +0 -0
- /package/lib/{cjs/ElementBulkDelete.d.ts → ElementBulkDelete.d.ts} +0 -0
- /package/lib/{cjs/EntityExistenceCache.d.ts → EntityExistenceCache.d.ts} +0 -0
- /package/lib/{cjs/EntityUnifier.d.ts → EntityUnifier.d.ts} +0 -0
- /package/lib/{cjs/IModelTransformContext.d.ts → IModelTransformContext.d.ts} +0 -0
- /package/lib/{cjs/IModelTransformerError.d.ts → IModelTransformerError.d.ts} +0 -0
- /package/lib/{cjs/SourceClassKinds.d.ts → SourceClassKinds.d.ts} +0 -0
- /package/lib/{cjs/SyncTypeResolver.d.ts → SyncTypeResolver.d.ts} +0 -0
- /package/lib/{cjs/TransformerLoggerCategory.d.ts → TransformerLoggerCategory.d.ts} +0 -0
- /package/lib/{cjs/TransformerPackageMetadata.d.ts → TransformerPackageMetadata.d.ts} +0 -0
- /package/lib/{cjs/schema-processing → schema-processing}/SchemaProcessingStrategy.d.ts +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/*---------------------------------------------------------------------------------------------
|
|
3
2
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -6,28 +5,28 @@
|
|
|
6
5
|
/** @packageDocumentation
|
|
7
6
|
* @module iModels
|
|
8
7
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const loggerCategory =
|
|
8
|
+
import { BriefcaseManager, DefinitionModel,
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
10
|
+
Element, ElementMultiAspect, ElementRefersToElements, ElementUniqueAspect, GeometricElement, Model, RecipeDefinitionElement, } from "@itwin/core-backend";
|
|
11
|
+
import { assert, Id64, IModelStatus, ITwinError, JsonUtils, Logger, YieldManager, } from "@itwin/core-bentley";
|
|
12
|
+
import { Base64EncodedString, ECJsNames, IModel, IModelError, QueryBinder, } from "@itwin/core-common";
|
|
13
|
+
import { ECVersion, SchemaKey } from "@itwin/ecschema-metadata";
|
|
14
|
+
import { TransformerLoggerCategory } from "./TransformerLoggerCategory.js";
|
|
15
|
+
import { strict as nodeAssert } from "node:assert";
|
|
16
|
+
import { ElementAspectExportProcessor } from "./ElementAspectExportProcessor.js";
|
|
17
|
+
import { ElementAspectExportCoordinator } from "./ElementAspectExportCoordinator.js";
|
|
18
|
+
import { IModelTransformerError, IModelTransformerErrorScope, } from "./IModelTransformerError.js";
|
|
19
|
+
import { ChangesetScanner } from "./ChangesetScanner.js";
|
|
20
|
+
import { SourceClassKinds } from "./SourceClassKinds.js";
|
|
21
|
+
import { ChangedElementForest } from "./ChangedElementForest.js";
|
|
22
|
+
const loggerCategory = TransformerLoggerCategory.IModelExporter;
|
|
24
23
|
/** Handles the events generated by IModelExporter.
|
|
25
24
|
* @note Change information is available when `IModelExportHandler` methods are invoked via [IModelExporter.exportChanges]($transformer), but not available when invoked via [IModelExporter.exportAll]($transformer).
|
|
26
25
|
* @note The handler is intended to be owned by (registered with) and called from the IModelExporter exclusively
|
|
27
26
|
* @see [iModel Transformation and Data Exchange]($docs/learning/transformer/index.md), [IModelExporter]($transformer)
|
|
28
27
|
* @beta
|
|
29
28
|
*/
|
|
30
|
-
class IModelExportHandler {
|
|
29
|
+
export class IModelExportHandler {
|
|
31
30
|
/** If `true` is returned, then the CodeSpec will be exported.
|
|
32
31
|
* @note This method can optionally be overridden to exclude an individual CodeSpec from the export. The base implementation always returns `true`.
|
|
33
32
|
*/
|
|
@@ -131,7 +130,6 @@ class IModelExportHandler {
|
|
|
131
130
|
*/
|
|
132
131
|
async onProgress() { }
|
|
133
132
|
}
|
|
134
|
-
exports.IModelExportHandler = IModelExportHandler;
|
|
135
133
|
/** Base class for exporting data from an iModel.
|
|
136
134
|
* @note Most uses cases will not require a custom subclass of `IModelExporter`. Instead, it is more typical to subclass/customize [IModelExportHandler]($transformer).
|
|
137
135
|
* ElementAspects are exported separately from element callbacks in bounded,
|
|
@@ -140,7 +138,7 @@ exports.IModelExportHandler = IModelExportHandler;
|
|
|
140
138
|
* @see [iModel Transformation and Data Exchange]($docs/learning/transformer/index.md), [[registerHandler]], [IModelTransformer]($transformer), [IModelImporter]($transformer)
|
|
141
139
|
* @beta
|
|
142
140
|
*/
|
|
143
|
-
class IModelExporter {
|
|
141
|
+
export class IModelExporter {
|
|
144
142
|
static _elementAspectOwnerBatchSize = 1000;
|
|
145
143
|
/** The read-only source iModel. */
|
|
146
144
|
sourceDb;
|
|
@@ -193,10 +191,10 @@ class IModelExporter {
|
|
|
193
191
|
/** The handler called by this IModelExporter. */
|
|
194
192
|
get handler() {
|
|
195
193
|
if (undefined === this._handler) {
|
|
196
|
-
|
|
194
|
+
ITwinError.throwError({
|
|
197
195
|
iTwinErrorId: {
|
|
198
|
-
scope:
|
|
199
|
-
key:
|
|
196
|
+
scope: IModelTransformerErrorScope,
|
|
197
|
+
key: IModelTransformerError.ExportHandlerNotRegistered,
|
|
200
198
|
},
|
|
201
199
|
message: "IModelExportHandler not registered",
|
|
202
200
|
});
|
|
@@ -226,9 +224,9 @@ class IModelExporter {
|
|
|
226
224
|
/** Whether change traversal skips root-owned entities. */
|
|
227
225
|
_skipPropagateChangesToRootElements = false;
|
|
228
226
|
_rootElementIds = new Set([
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
227
|
+
IModel.rootSubjectId,
|
|
228
|
+
IModel.repositoryModelId,
|
|
229
|
+
IModel.dictionaryId,
|
|
232
230
|
"0xe", // The reality-data-sources modelId, skipped with root propagation.
|
|
233
231
|
]);
|
|
234
232
|
/** Construct a new IModelExporter
|
|
@@ -237,13 +235,13 @@ class IModelExporter {
|
|
|
237
235
|
*/
|
|
238
236
|
constructor(sourceDb) {
|
|
239
237
|
this.sourceDb = sourceDb;
|
|
240
|
-
this._elementAspectExportProcessor = new
|
|
238
|
+
this._elementAspectExportProcessor = new ElementAspectExportProcessor(this.sourceDb, {
|
|
241
239
|
onExportElementMultiAspects: async (aspects) => this.handler.onExportElementMultiAspects(aspects),
|
|
242
240
|
onExportElementUniqueAspect: async (aspect, isUpdate) => this.handler.onExportElementUniqueAspect(aspect, isUpdate),
|
|
243
241
|
shouldExportElementAspect: async (aspect) => this.handler.shouldExportElementAspect(aspect),
|
|
244
242
|
trackProgress: async () => this.trackProgress(),
|
|
245
243
|
});
|
|
246
|
-
this._elementAspectExportCoordinator = new
|
|
244
|
+
this._elementAspectExportCoordinator = new ElementAspectExportCoordinator(IModelExporter._elementAspectOwnerBatchSize, () => this._elementAspectExportProcessor.excludedElementAspectClassFullNames, async (elementIds) => this._elementAspectExportProcessor.exportAllElementAspects(elementIds), () => this._elementAspectExportProcessor.resetCaches());
|
|
247
245
|
}
|
|
248
246
|
/**
|
|
249
247
|
* Initialize prerequisites of exporting. This is implicitly done by any `export*` calls that need initialization
|
|
@@ -300,8 +298,8 @@ class IModelExporter {
|
|
|
300
298
|
await this.initialize({});
|
|
301
299
|
await this.exportCodeSpecs();
|
|
302
300
|
await this.exportFonts();
|
|
303
|
-
await this._elementAspectExportCoordinator.run(async () => this.exportModel(
|
|
304
|
-
await this.exportRelationships(
|
|
301
|
+
await this._elementAspectExportCoordinator.run(async () => this.exportModel(IModel.repositoryModelId));
|
|
302
|
+
await this.exportRelationships(ElementRefersToElements.classFullName);
|
|
305
303
|
}
|
|
306
304
|
/** Export changes from the source iModel.
|
|
307
305
|
* Inserts, updates, and deletes are determined by inspecting the changeset(s).
|
|
@@ -313,10 +311,10 @@ class IModelExporter {
|
|
|
313
311
|
*/
|
|
314
312
|
async exportChanges(args) {
|
|
315
313
|
if (!this.sourceDb.isBriefcaseDb())
|
|
316
|
-
|
|
314
|
+
ITwinError.throwError({
|
|
317
315
|
iTwinErrorId: {
|
|
318
|
-
scope:
|
|
319
|
-
key:
|
|
316
|
+
scope: IModelTransformerErrorScope,
|
|
317
|
+
key: IModelTransformerError.ExportChangesRequiresBriefcase,
|
|
320
318
|
},
|
|
321
319
|
message: "Must be a briefcase to export changes",
|
|
322
320
|
});
|
|
@@ -334,10 +332,10 @@ class IModelExporter {
|
|
|
334
332
|
}
|
|
335
333
|
await this.initialize(initOpts);
|
|
336
334
|
if (currentChangesetId === "" && !this.sourceDbChanges?.hasChanges) {
|
|
337
|
-
|
|
335
|
+
ITwinError.throwError({
|
|
338
336
|
iTwinErrorId: {
|
|
339
|
-
scope:
|
|
340
|
-
key:
|
|
337
|
+
scope: IModelTransformerErrorScope,
|
|
338
|
+
key: IModelTransformerError.NoChangesets,
|
|
341
339
|
},
|
|
342
340
|
message: "Cannot export changes because the source iModel has no changesets or custom changes. Call exportAll() to export all content.",
|
|
343
341
|
});
|
|
@@ -345,22 +343,22 @@ class IModelExporter {
|
|
|
345
343
|
this._skipPropagateChangesToRootElements =
|
|
346
344
|
initOpts.skipPropagateChangesToRootElements ?? false;
|
|
347
345
|
// _sourceDbChanges are initialized in this.initialize
|
|
348
|
-
(
|
|
346
|
+
nodeAssert(this._sourceDbChanges !== undefined, "sourceDbChanges must be initialized.");
|
|
349
347
|
await this.exportCodeSpecs();
|
|
350
348
|
await this.exportFonts();
|
|
351
|
-
(
|
|
349
|
+
nodeAssert(this.beginChangedElementTraversalScope(), "exportChanges must own its changed-element traversal scope");
|
|
352
350
|
try {
|
|
353
351
|
await this._elementAspectExportCoordinator.run(async () => {
|
|
354
352
|
if (initOpts.skipPropagateChangesToRootElements) {
|
|
355
353
|
// The root Subject is in the RepositoryModel. Traverse its children
|
|
356
354
|
// separately, then export other top-level repository elements while
|
|
357
355
|
// excluding the root so no element is visited twice.
|
|
358
|
-
await this.exportChildElements(
|
|
359
|
-
await this.exportModelContents(
|
|
360
|
-
await this.exportSubModels(
|
|
356
|
+
await this.exportChildElements(IModel.rootSubjectId);
|
|
357
|
+
await this.exportModelContents(IModel.repositoryModelId, Element.classFullName, true);
|
|
358
|
+
await this.exportSubModels(IModel.repositoryModelId);
|
|
361
359
|
}
|
|
362
360
|
else {
|
|
363
|
-
await this.exportModel(
|
|
361
|
+
await this.exportModel(IModel.repositoryModelId);
|
|
364
362
|
}
|
|
365
363
|
});
|
|
366
364
|
const aspectOnlyOwnerElementIds = new Set(this._sourceDbChanges.aspectOwnerElementIds);
|
|
@@ -375,7 +373,7 @@ class IModelExporter {
|
|
|
375
373
|
finally {
|
|
376
374
|
this.endChangedElementTraversalScope();
|
|
377
375
|
}
|
|
378
|
-
await this.exportRelationships(
|
|
376
|
+
await this.exportRelationships(ElementRefersToElements.classFullName);
|
|
379
377
|
// handle deletes
|
|
380
378
|
if (this.visitElements) {
|
|
381
379
|
// must delete models first since they have a constraint on the submodeling element which may also be deleted
|
|
@@ -420,13 +418,13 @@ class IModelExporter {
|
|
|
420
418
|
for await (const row of this.sourceDb.createQueryReader(sql, undefined, {
|
|
421
419
|
usePrimaryConn: true,
|
|
422
420
|
})) {
|
|
423
|
-
const schemaKey = new
|
|
421
|
+
const schemaKey = new SchemaKey(row[0], new ECVersion(row[1], row[2], row[3]));
|
|
424
422
|
const schema = await this.sourceDb.schemaContext.getSchema(schemaKey);
|
|
425
423
|
if (!schema) {
|
|
426
|
-
|
|
424
|
+
ITwinError.throwError({
|
|
427
425
|
iTwinErrorId: {
|
|
428
|
-
scope:
|
|
429
|
-
key:
|
|
426
|
+
scope: IModelTransformerErrorScope,
|
|
427
|
+
key: IModelTransformerError.SchemaLoadFailed,
|
|
430
428
|
},
|
|
431
429
|
message: `Failed to load schema: ${schemaKey.name}`,
|
|
432
430
|
});
|
|
@@ -445,7 +443,7 @@ class IModelExporter {
|
|
|
445
443
|
}
|
|
446
444
|
}
|
|
447
445
|
await Promise.all(schemasToExport.map(async (schema) => {
|
|
448
|
-
|
|
446
|
+
Logger.logTrace(loggerCategory, `exportSchema(${schema.name})`);
|
|
449
447
|
return this.handler.onExportSchema(schema);
|
|
450
448
|
}));
|
|
451
449
|
}
|
|
@@ -457,7 +455,7 @@ class IModelExporter {
|
|
|
457
455
|
* @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.
|
|
458
456
|
*/
|
|
459
457
|
async exportCodeSpecs() {
|
|
460
|
-
|
|
458
|
+
Logger.logTrace(loggerCategory, "exportCodeSpecs()");
|
|
461
459
|
const sql = "SELECT Name FROM BisCore:CodeSpec ORDER BY ECInstanceId";
|
|
462
460
|
for await (const row of this.sourceDb.createQueryReader(sql, undefined, {
|
|
463
461
|
usePrimaryConn: true,
|
|
@@ -485,12 +483,12 @@ class IModelExporter {
|
|
|
485
483
|
}
|
|
486
484
|
// passed changeset test, now apply standard exclusion rules
|
|
487
485
|
if (this._excludedCodeSpecNames.has(codeSpec.name)) {
|
|
488
|
-
|
|
486
|
+
Logger.logInfo(loggerCategory, `Excluding CodeSpec: ${codeSpec.name}`);
|
|
489
487
|
return;
|
|
490
488
|
}
|
|
491
489
|
// CodeSpec has passed standard exclusion rules, now give handler a chance to accept/reject export
|
|
492
490
|
if (await this.handler.shouldExportCodeSpec(codeSpec)) {
|
|
493
|
-
|
|
491
|
+
Logger.logTrace(loggerCategory, `exportCodeSpec(${codeSpecName})${this.getChangeOpSuffix(isUpdate)}`);
|
|
494
492
|
await this.handler.onExportCodeSpec(codeSpec, isUpdate);
|
|
495
493
|
return this.trackProgress();
|
|
496
494
|
}
|
|
@@ -506,7 +504,7 @@ class IModelExporter {
|
|
|
506
504
|
* @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.
|
|
507
505
|
*/
|
|
508
506
|
async exportFonts() {
|
|
509
|
-
|
|
507
|
+
Logger.logTrace(loggerCategory, "exportFonts()");
|
|
510
508
|
for (const font of this.sourceDb.fonts.queryMappedFamilies()) {
|
|
511
509
|
await this.exportFontByFontProps(font);
|
|
512
510
|
}
|
|
@@ -516,7 +514,7 @@ class IModelExporter {
|
|
|
516
514
|
* If not this will only export the first font with this type in the db.
|
|
517
515
|
*/
|
|
518
516
|
async exportFontByName(fontName) {
|
|
519
|
-
|
|
517
|
+
Logger.logTrace(loggerCategory, `exportFontByName(${fontName})`);
|
|
520
518
|
const fontId = this.sourceDb.fonts.findId({
|
|
521
519
|
name: fontName,
|
|
522
520
|
});
|
|
@@ -528,7 +526,7 @@ class IModelExporter {
|
|
|
528
526
|
* @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.
|
|
529
527
|
*/
|
|
530
528
|
async exportFontByFontProps(fontProps) {
|
|
531
|
-
|
|
529
|
+
Logger.logTrace(loggerCategory, `exportFontByFamily(${fontProps.name}, ${fontProps.type})`);
|
|
532
530
|
await this.handler.onExportFont(fontProps, true);
|
|
533
531
|
return this.trackProgress();
|
|
534
532
|
}
|
|
@@ -536,7 +534,7 @@ class IModelExporter {
|
|
|
536
534
|
* @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.
|
|
537
535
|
*/
|
|
538
536
|
async exportFontByFontFamilyDescriptor(fontFamily) {
|
|
539
|
-
|
|
537
|
+
Logger.logTrace(loggerCategory, `exportFontByFamilyDescriptor(${fontFamily.name}, ${fontFamily.type})`);
|
|
540
538
|
const fontId = await this.sourceDb.fonts.acquireId(fontFamily);
|
|
541
539
|
if (undefined !== fontId) {
|
|
542
540
|
await this.exportFontByFontProps({ ...fontFamily, id: fontId });
|
|
@@ -551,7 +549,7 @@ class IModelExporter {
|
|
|
551
549
|
* 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.
|
|
552
550
|
* See https://github.com/iTwin/imodel-transformer/pull/135 for removed code.
|
|
553
551
|
*/
|
|
554
|
-
|
|
552
|
+
Logger.logTrace(loggerCategory, `exportFontById(${fontNumber})`);
|
|
555
553
|
const font = this.sourceDb.fonts.findDescriptor(fontNumber);
|
|
556
554
|
if (undefined !== font) {
|
|
557
555
|
await this.exportFontByFontFamilyDescriptor(font);
|
|
@@ -573,7 +571,7 @@ class IModelExporter {
|
|
|
573
571
|
wantGeometry: this.wantGeometry,
|
|
574
572
|
wantBRepData: this.wantGeometry,
|
|
575
573
|
});
|
|
576
|
-
|
|
574
|
+
Logger.logTrace(loggerCategory, `exportModel(${modeledElementId})`);
|
|
577
575
|
if (await this.shouldExportElement(modeledElement)) {
|
|
578
576
|
await this.exportModelContainer(model);
|
|
579
577
|
if (this.visitElements) {
|
|
@@ -600,24 +598,24 @@ class IModelExporter {
|
|
|
600
598
|
await this.handler.onExportModel(model, isUpdate);
|
|
601
599
|
return this.trackProgress();
|
|
602
600
|
}
|
|
603
|
-
_yieldManager = new
|
|
601
|
+
_yieldManager = new YieldManager();
|
|
604
602
|
/** Export the model contents.
|
|
605
603
|
* @param modelId The only required parameter
|
|
606
604
|
* @param elementClassFullName Can be optionally specified if the goal is to export a subset of the model contents
|
|
607
605
|
* @param skipRootSubject Decides whether or not to export the root Subject. It is normally left undefined except for internal implementation purposes.
|
|
608
606
|
* @note This method is called from [[exportChanges]] and [[exportAll]], so it only needs to be called directly when exporting a subset of an iModel.
|
|
609
607
|
*/
|
|
610
|
-
async exportModelContents(modelId, elementClassFullName =
|
|
608
|
+
async exportModelContents(modelId, elementClassFullName = Element.classFullName, skipRootSubject) {
|
|
611
609
|
return this.runScopedElementExport(async () => this.exportModelContentsImpl(modelId, elementClassFullName, skipRootSubject));
|
|
612
610
|
}
|
|
613
611
|
async exportModelContentsImpl(modelId, elementClassFullName, skipRootSubject) {
|
|
614
612
|
if (skipRootSubject) {
|
|
615
613
|
// 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
|
|
616
614
|
// NOTE: IModelExporter.exportAll should not skip the root Subject since the goal is to export everything
|
|
617
|
-
|
|
615
|
+
assert(modelId === IModel.repositoryModelId); // flag is only relevant when processing the RepositoryModel
|
|
618
616
|
}
|
|
619
617
|
if (!this.visitElements) {
|
|
620
|
-
|
|
618
|
+
Logger.logTrace(loggerCategory, `visitElements=false, skipping exportModelContents(${modelId})`);
|
|
621
619
|
return;
|
|
622
620
|
}
|
|
623
621
|
if (undefined !== this._sourceDbChanges) {
|
|
@@ -627,12 +625,12 @@ class IModelExporter {
|
|
|
627
625
|
return; // this optimization assumes that the Model changes (LastMod) any time an Element in the Model changes
|
|
628
626
|
}
|
|
629
627
|
if (this.canUseChangedElementForest() &&
|
|
630
|
-
elementClassFullName ===
|
|
628
|
+
elementClassFullName === Element.classFullName) {
|
|
631
629
|
const forest = await this.getChangedElementForest();
|
|
632
630
|
if (forest !== undefined) {
|
|
633
|
-
|
|
631
|
+
Logger.logTrace(loggerCategory, `exportModelContents(${modelId}) via changed-element index`);
|
|
634
632
|
for (const rootId of forest.getModelRoots(modelId)) {
|
|
635
|
-
if (skipRootSubject && rootId ===
|
|
633
|
+
if (skipRootSubject && rootId === IModel.rootSubjectId)
|
|
636
634
|
continue;
|
|
637
635
|
await this.exportElement(rootId);
|
|
638
636
|
await this._yieldManager.allowYield();
|
|
@@ -641,13 +639,13 @@ class IModelExporter {
|
|
|
641
639
|
}
|
|
642
640
|
}
|
|
643
641
|
}
|
|
644
|
-
|
|
642
|
+
Logger.logTrace(loggerCategory, `exportModelContents(${modelId})`);
|
|
645
643
|
const rootFilter = skipRootSubject
|
|
646
644
|
? "e.Parent.Id IS NULL AND e.Model.Id=:modelId AND e.ECInstanceId!=:rootSubjectId"
|
|
647
645
|
: "e.Parent.Id IS NULL AND e.Model.Id=:modelId";
|
|
648
|
-
const params = new
|
|
646
|
+
const params = new QueryBinder().bindId("modelId", modelId);
|
|
649
647
|
if (skipRootSubject) {
|
|
650
|
-
params.bindId("rootSubjectId",
|
|
648
|
+
params.bindId("rootSubjectId", IModel.rootSubjectId);
|
|
651
649
|
}
|
|
652
650
|
if (this.canUseSetBasedTraversal()) {
|
|
653
651
|
return this.exportElementTreesStreamed(`SELECT e.ECInstanceId, 0 FROM ${elementClassFullName} e WHERE ${rootFilter}`, params);
|
|
@@ -687,7 +685,7 @@ class IModelExporter {
|
|
|
687
685
|
WITH RECURSIVE ElementTree (ECInstanceId, Depth) AS (
|
|
688
686
|
${anchorSelect}
|
|
689
687
|
UNION ALL
|
|
690
|
-
SELECT c.ECInstanceId, t.Depth + 1 FROM ${
|
|
688
|
+
SELECT c.ECInstanceId, t.Depth + 1 FROM ${Element.classFullName} c
|
|
691
689
|
JOIN ElementTree t ON c.Parent.Id = t.ECInstanceId
|
|
692
690
|
ORDER BY 2 DESC, 1 ASC
|
|
693
691
|
)
|
|
@@ -715,17 +713,17 @@ class IModelExporter {
|
|
|
715
713
|
return this.runScopedElementExport(async () => this.exportSubModelsImpl(parentModelId));
|
|
716
714
|
}
|
|
717
715
|
async exportSubModelsImpl(parentModelId) {
|
|
718
|
-
|
|
716
|
+
Logger.logTrace(loggerCategory, `exportSubModels(${parentModelId})`);
|
|
719
717
|
const definitionModelIds = [];
|
|
720
718
|
const otherModelIds = [];
|
|
721
|
-
const sql = `SELECT ECInstanceId FROM ${
|
|
722
|
-
const params = new
|
|
719
|
+
const sql = `SELECT ECInstanceId FROM ${Model.classFullName} WHERE ParentModel.Id=:parentModelId ORDER BY ECInstanceId`;
|
|
720
|
+
const params = new QueryBinder().bindId("parentModelId", parentModelId);
|
|
723
721
|
for await (const row of this.sourceDb.createQueryReader(sql, params, {
|
|
724
722
|
usePrimaryConn: true,
|
|
725
723
|
})) {
|
|
726
724
|
const modelId = row.id;
|
|
727
725
|
const model = this.sourceDb.models.getModel(modelId);
|
|
728
|
-
if (model instanceof
|
|
726
|
+
if (model instanceof DefinitionModel) {
|
|
729
727
|
definitionModelIds.push(modelId);
|
|
730
728
|
}
|
|
731
729
|
else {
|
|
@@ -746,22 +744,22 @@ class IModelExporter {
|
|
|
746
744
|
*/
|
|
747
745
|
async shouldExportElement(element) {
|
|
748
746
|
if (this._excludedElementIds.has(element.id)) {
|
|
749
|
-
|
|
747
|
+
Logger.logInfo(loggerCategory, `Excluded element ${element.id} by Id`);
|
|
750
748
|
return false;
|
|
751
749
|
}
|
|
752
|
-
if (element instanceof
|
|
750
|
+
if (element instanceof GeometricElement &&
|
|
753
751
|
this._excludedElementCategoryIds.has(element.category)) {
|
|
754
|
-
|
|
752
|
+
Logger.logInfo(loggerCategory, `Excluded element ${element.id} by Category`);
|
|
755
753
|
return false;
|
|
756
754
|
}
|
|
757
755
|
if (!this.wantTemplateModels &&
|
|
758
|
-
element instanceof
|
|
759
|
-
|
|
756
|
+
element instanceof RecipeDefinitionElement) {
|
|
757
|
+
Logger.logInfo(loggerCategory, `Excluded RecipeDefinitionElement ${element.id} because wantTemplate=false`);
|
|
760
758
|
return false;
|
|
761
759
|
}
|
|
762
760
|
for (const excludedElementClass of this._excludedElementClasses) {
|
|
763
761
|
if (element instanceof excludedElementClass) {
|
|
764
|
-
|
|
762
|
+
Logger.logInfo(loggerCategory, `Excluded element ${element.id} by class: ${excludedElementClass.classFullName}`);
|
|
765
763
|
return false;
|
|
766
764
|
}
|
|
767
765
|
}
|
|
@@ -780,7 +778,7 @@ class IModelExporter {
|
|
|
780
778
|
}
|
|
781
779
|
async exportElementImpl(elementId) {
|
|
782
780
|
if (!this.visitElements) {
|
|
783
|
-
|
|
781
|
+
Logger.logTrace(loggerCategory, `visitElements=false, skipping exportElement(${elementId})`);
|
|
784
782
|
return;
|
|
785
783
|
}
|
|
786
784
|
const childVisit = await this.exportElementShallow(elementId);
|
|
@@ -832,7 +830,7 @@ class IModelExporter {
|
|
|
832
830
|
return "skip";
|
|
833
831
|
// Return early if the elementId is already excluded so it does not need to be loaded.
|
|
834
832
|
if (this._excludedElementIds.has(elementId)) {
|
|
835
|
-
|
|
833
|
+
Logger.logInfo(loggerCategory, `Excluded element ${elementId} by Id`);
|
|
836
834
|
await this.handler.onSkipElement(elementId);
|
|
837
835
|
return "skip";
|
|
838
836
|
}
|
|
@@ -851,7 +849,7 @@ class IModelExporter {
|
|
|
851
849
|
wantGeometry: this.wantGeometry,
|
|
852
850
|
wantBRepData: this.wantGeometry,
|
|
853
851
|
});
|
|
854
|
-
|
|
852
|
+
Logger.logTrace(loggerCategory, `exportElement(${element.id}, "${element.getDisplayLabel()}")${this.getChangeOpSuffix(isUpdate)}`);
|
|
855
853
|
// the order and `await`ing of calls beyond here is depended upon by the IModelTransformer for a current bug workaround
|
|
856
854
|
if (await this.shouldExportElement(element)) {
|
|
857
855
|
await this.handler.preExportElement(element);
|
|
@@ -871,25 +869,25 @@ class IModelExporter {
|
|
|
871
869
|
}
|
|
872
870
|
async exportChildElementsImpl(elementId) {
|
|
873
871
|
if (!this.visitElements) {
|
|
874
|
-
|
|
872
|
+
Logger.logTrace(loggerCategory, `visitElements=false, skipping exportChildElements(${elementId})`);
|
|
875
873
|
return;
|
|
876
874
|
}
|
|
877
875
|
if (this.canUseSetBasedTraversal()) {
|
|
878
|
-
|
|
876
|
+
Logger.logTrace(loggerCategory, `exportChildElements(${elementId})`);
|
|
879
877
|
// Seed the stream with direct children; the helper adds their descendants.
|
|
880
|
-
return this.exportElementTreesStreamed(`SELECT e.ECInstanceId, 0 FROM ${
|
|
878
|
+
return this.exportElementTreesStreamed(`SELECT e.ECInstanceId, 0 FROM ${Element.classFullName} e WHERE e.Parent.Id=:parentId`, new QueryBinder().bindId("parentId", elementId));
|
|
881
879
|
}
|
|
882
880
|
let childElementIds;
|
|
883
881
|
if (this.canUseChangedElementForest()) {
|
|
884
882
|
const forest = await this.getChangedElementForest();
|
|
885
883
|
if (forest !== undefined) {
|
|
886
|
-
|
|
884
|
+
Logger.logTrace(loggerCategory, `exportChildElements(${elementId}) via changed-element index`);
|
|
887
885
|
childElementIds = forest.getChildren(elementId);
|
|
888
886
|
}
|
|
889
887
|
}
|
|
890
888
|
childElementIds ??= this.sourceDb.elements.queryChildren(elementId);
|
|
891
889
|
if (childElementIds.length > 0) {
|
|
892
|
-
|
|
890
|
+
Logger.logTrace(loggerCategory, `exportChildElements(${elementId})`);
|
|
893
891
|
for (const childElementId of childElementIds) {
|
|
894
892
|
await this.exportElement(childElementId);
|
|
895
893
|
}
|
|
@@ -915,10 +913,10 @@ class IModelExporter {
|
|
|
915
913
|
if (!this._changedElementTraversal?.useForest)
|
|
916
914
|
return;
|
|
917
915
|
this._changedElementTraversal.useForest = false;
|
|
918
|
-
|
|
916
|
+
Logger.logInfo(loggerCategory, `Using full element traversal for change processing because ${reason}.`);
|
|
919
917
|
}
|
|
920
918
|
async createChangedElementForest() {
|
|
921
|
-
(
|
|
919
|
+
nodeAssert(this._sourceDbChanges !== undefined, "changed-element traversal requires sourceDbChanges");
|
|
922
920
|
const excludedElementIds = this._excludedElementIds;
|
|
923
921
|
const candidateCountUpperBound = this._sourceDbChanges.element.insertIds.size +
|
|
924
922
|
this._sourceDbChanges.element.updateIds.size +
|
|
@@ -927,7 +925,7 @@ class IModelExporter {
|
|
|
927
925
|
this.disableChangedElementForest(`${candidateCountUpperBound} candidate element references exceed the ${this._changedElementForestElementLimit}-element in-memory index limit`);
|
|
928
926
|
return undefined;
|
|
929
927
|
}
|
|
930
|
-
const forest = await
|
|
928
|
+
const forest = await ChangedElementForest.create(this.sourceDb, [
|
|
931
929
|
...this._sourceDbChanges.element.insertIds,
|
|
932
930
|
...this._sourceDbChanges.element.updateIds,
|
|
933
931
|
...excludedElementIds,
|
|
@@ -939,7 +937,7 @@ class IModelExporter {
|
|
|
939
937
|
}
|
|
940
938
|
async getChangedElementForest() {
|
|
941
939
|
const traversal = this._changedElementTraversal;
|
|
942
|
-
(
|
|
940
|
+
nodeAssert(traversal !== undefined, "changed-element index requires an active traversal scope");
|
|
943
941
|
return (traversal.forest ??= this.createChangedElementForest());
|
|
944
942
|
}
|
|
945
943
|
/** Exports all aspects owned by the supplied elements. */
|
|
@@ -975,7 +973,7 @@ class IModelExporter {
|
|
|
975
973
|
const parentId = elementFact.parentId;
|
|
976
974
|
if (parentId === undefined ||
|
|
977
975
|
(this._skipPropagateChangesToRootElements &&
|
|
978
|
-
parentId ===
|
|
976
|
+
parentId === IModel.rootSubjectId)) {
|
|
979
977
|
return true;
|
|
980
978
|
}
|
|
981
979
|
elementFact = elementFacts.get(parentId);
|
|
@@ -990,8 +988,8 @@ class IModelExporter {
|
|
|
990
988
|
}
|
|
991
989
|
if (modelFact.isTemplate && !this.wantTemplateModels)
|
|
992
990
|
return false;
|
|
993
|
-
if (modelFact.id !==
|
|
994
|
-
modelFact.id !==
|
|
991
|
+
if (modelFact.id !== IModel.repositoryModelId &&
|
|
992
|
+
modelFact.id !== IModel.dictionaryId &&
|
|
995
993
|
modelFact.id !== "0xe" &&
|
|
996
994
|
!(await this.shouldExportElementForAspect(modelFact.id, elementFacts.get(modelFact.id)))) {
|
|
997
995
|
return false;
|
|
@@ -1046,27 +1044,27 @@ class IModelExporter {
|
|
|
1046
1044
|
}
|
|
1047
1045
|
shouldExportElementFact(elementFact) {
|
|
1048
1046
|
if (this._excludedElementIds.has(elementFact.id)) {
|
|
1049
|
-
|
|
1047
|
+
Logger.logInfo(loggerCategory, `Excluded element ${elementFact.id} by Id`);
|
|
1050
1048
|
return false;
|
|
1051
1049
|
}
|
|
1052
1050
|
const elementClass = this.sourceDb.getJsClass(elementFact.classFullName);
|
|
1053
|
-
if ((elementFact.classFullName ===
|
|
1054
|
-
elementClass.prototype instanceof
|
|
1051
|
+
if ((elementFact.classFullName === GeometricElement.classFullName ||
|
|
1052
|
+
elementClass.prototype instanceof GeometricElement) &&
|
|
1055
1053
|
elementFact.categoryId !== undefined &&
|
|
1056
1054
|
this._excludedElementCategoryIds.has(elementFact.categoryId)) {
|
|
1057
|
-
|
|
1055
|
+
Logger.logInfo(loggerCategory, `Excluded element ${elementFact.id} by Category`);
|
|
1058
1056
|
return false;
|
|
1059
1057
|
}
|
|
1060
1058
|
if (!this.wantTemplateModels &&
|
|
1061
|
-
(elementFact.classFullName ===
|
|
1062
|
-
elementClass.prototype instanceof
|
|
1063
|
-
|
|
1059
|
+
(elementFact.classFullName === RecipeDefinitionElement.classFullName ||
|
|
1060
|
+
elementClass.prototype instanceof RecipeDefinitionElement)) {
|
|
1061
|
+
Logger.logInfo(loggerCategory, `Excluded RecipeDefinitionElement ${elementFact.id} because wantTemplate=false`);
|
|
1064
1062
|
return false;
|
|
1065
1063
|
}
|
|
1066
1064
|
for (const excludedElementClass of this._excludedElementClasses) {
|
|
1067
1065
|
if (elementFact.classFullName === excludedElementClass.classFullName ||
|
|
1068
1066
|
elementClass.prototype instanceof excludedElementClass) {
|
|
1069
|
-
|
|
1067
|
+
Logger.logInfo(loggerCategory, `Excluded element ${elementFact.id} by class: ${excludedElementClass.classFullName}`);
|
|
1070
1068
|
return false;
|
|
1071
1069
|
}
|
|
1072
1070
|
}
|
|
@@ -1098,7 +1096,7 @@ class IModelExporter {
|
|
|
1098
1096
|
if (unqueriedElementIds.size === 0)
|
|
1099
1097
|
return;
|
|
1100
1098
|
for (const elementIdBatch of this.getAspectOwnerIdBatches(unqueriedElementIds)) {
|
|
1101
|
-
const queryParams = new
|
|
1099
|
+
const queryParams = new QueryBinder().bindIdSet("elementIds", elementIdBatch);
|
|
1102
1100
|
for await (const row of this.sourceDb.createQueryReader(`SELECT e.ECInstanceId id, e.Parent.Id parentId, e.Model.Id modelId,
|
|
1103
1101
|
ec_className(e.ECClassId, 's') schemaName,
|
|
1104
1102
|
ec_className(e.ECClassId, 'c') className
|
|
@@ -1112,7 +1110,7 @@ class IModelExporter {
|
|
|
1112
1110
|
});
|
|
1113
1111
|
}
|
|
1114
1112
|
if (this._excludedElementCategoryIds.size > 0) {
|
|
1115
|
-
const categoryQueryParams = new
|
|
1113
|
+
const categoryQueryParams = new QueryBinder().bindIdSet("elementIds", elementIdBatch);
|
|
1116
1114
|
for await (const row of this.sourceDb.createQueryReader(`SELECT g.ECInstanceId id, g.Category.Id categoryId
|
|
1117
1115
|
FROM bis.GeometricElement g
|
|
1118
1116
|
INNER JOIN IdSet(:elementIds) ids ON ids.id = g.ECInstanceId`, categoryQueryParams, { usePrimaryConn: true })) {
|
|
@@ -1132,7 +1130,7 @@ class IModelExporter {
|
|
|
1132
1130
|
const currentModelIds = pendingModelIds;
|
|
1133
1131
|
pendingModelIds = new Set();
|
|
1134
1132
|
for (const modelIdBatch of this.getAspectOwnerIdBatches(currentModelIds)) {
|
|
1135
|
-
const queryParams = new
|
|
1133
|
+
const queryParams = new QueryBinder().bindIdSet("modelIds", modelIdBatch);
|
|
1136
1134
|
for await (const row of this.sourceDb.createQueryReader(`SELECT model.ECInstanceId id, model.ParentModel.Id parentModelId, model.IsTemplate isTemplate
|
|
1137
1135
|
FROM bis.Model model
|
|
1138
1136
|
INNER JOIN IdSet(:modelIds) ids ON ids.id = model.ECInstanceId`, queryParams, { usePrimaryConn: true })) {
|
|
@@ -1174,10 +1172,10 @@ class IModelExporter {
|
|
|
1174
1172
|
*/
|
|
1175
1173
|
async exportRelationships(baseRelClassFullName) {
|
|
1176
1174
|
if (!this.visitRelationships) {
|
|
1177
|
-
|
|
1175
|
+
Logger.logTrace(loggerCategory, "visitRelationships=false, skipping exportRelationships()");
|
|
1178
1176
|
return;
|
|
1179
1177
|
}
|
|
1180
|
-
|
|
1178
|
+
Logger.logTrace(loggerCategory, `exportRelationships(${baseRelClassFullName})`);
|
|
1181
1179
|
const changedRelationshipIds = this._sourceDbChanges === undefined
|
|
1182
1180
|
? undefined
|
|
1183
1181
|
: new Set([
|
|
@@ -1187,7 +1185,7 @@ class IModelExporter {
|
|
|
1187
1185
|
if (changedRelationshipIds?.size === 0) {
|
|
1188
1186
|
// Deleted relationships are handled by exportChanges after this traversal; they are no
|
|
1189
1187
|
// longer present in the source iModel and must not cause a full relationship scan here.
|
|
1190
|
-
|
|
1188
|
+
Logger.logTrace(loggerCategory, "No inserted or updated relationships, skipping exportRelationships()");
|
|
1191
1189
|
return;
|
|
1192
1190
|
}
|
|
1193
1191
|
const changedRelationshipJoin = changedRelationshipIds === undefined
|
|
@@ -1207,7 +1205,7 @@ class IModelExporter {
|
|
|
1207
1205
|
// keyset page so the changing boundary can be bound without redefining a property.
|
|
1208
1206
|
const queryParams = changedRelationshipIds === undefined && lastRelationshipId === undefined
|
|
1209
1207
|
? undefined
|
|
1210
|
-
: new
|
|
1208
|
+
: new QueryBinder();
|
|
1211
1209
|
if (queryParams !== undefined) {
|
|
1212
1210
|
if (changedRelationshipIds !== undefined) {
|
|
1213
1211
|
queryParams.bindIdSet("changedRelationshipIds", changedRelationshipIds);
|
|
@@ -1261,27 +1259,27 @@ class IModelExporter {
|
|
|
1261
1259
|
/** Converts a raw `$` instance-access row into [RelationshipProps]($common). */
|
|
1262
1260
|
getRelationshipProps(rawInstance) {
|
|
1263
1261
|
const parsedRow = typeof rawInstance === "string"
|
|
1264
|
-
? JSON.parse(rawInstance,
|
|
1262
|
+
? JSON.parse(rawInstance, Base64EncodedString.reviver)
|
|
1265
1263
|
: rawInstance;
|
|
1266
|
-
if (!
|
|
1267
|
-
|
|
1264
|
+
if (!JsonUtils.isObject(parsedRow))
|
|
1265
|
+
ITwinError.throwError({
|
|
1268
1266
|
iTwinErrorId: {
|
|
1269
|
-
scope:
|
|
1270
|
-
key:
|
|
1267
|
+
scope: IModelTransformerErrorScope,
|
|
1268
|
+
key: IModelTransformerError.InvalidRelationshipData,
|
|
1271
1269
|
},
|
|
1272
1270
|
message: "Expected a Relationship instance query to return an object",
|
|
1273
1271
|
});
|
|
1274
1272
|
const row = {};
|
|
1275
1273
|
for (const [key, value] of Object.entries(parsedRow)) {
|
|
1276
1274
|
const ecPropertyName = key.length === 0 ? key : key[0].toUpperCase() + key.substring(1);
|
|
1277
|
-
row[
|
|
1275
|
+
row[ECJsNames.toJsName(ecPropertyName)] = value;
|
|
1278
1276
|
}
|
|
1279
1277
|
const className = row.className;
|
|
1280
1278
|
if (typeof className !== "string")
|
|
1281
|
-
|
|
1279
|
+
ITwinError.throwError({
|
|
1282
1280
|
iTwinErrorId: {
|
|
1283
|
-
scope:
|
|
1284
|
-
key:
|
|
1281
|
+
scope: IModelTransformerErrorScope,
|
|
1282
|
+
key: IModelTransformerError.InvalidRelationshipData,
|
|
1285
1283
|
},
|
|
1286
1284
|
message: "Expected a Relationship instance query to return a className",
|
|
1287
1285
|
});
|
|
@@ -1296,13 +1294,13 @@ class IModelExporter {
|
|
|
1296
1294
|
*/
|
|
1297
1295
|
async exportRelationship(relClassFullName, relInstanceId) {
|
|
1298
1296
|
if (!this.visitRelationships) {
|
|
1299
|
-
|
|
1297
|
+
Logger.logTrace(loggerCategory, `visitRelationships=false, skipping exportRelationship(${relClassFullName}, ${relInstanceId})`);
|
|
1300
1298
|
return;
|
|
1301
1299
|
}
|
|
1302
1300
|
const changesetFilter = this.checkRelationshipChangesetFilter(relInstanceId);
|
|
1303
1301
|
if (changesetFilter.skip)
|
|
1304
1302
|
return;
|
|
1305
|
-
const queryParams = new
|
|
1303
|
+
const queryParams = new QueryBinder().bindId("relInstanceId", relInstanceId);
|
|
1306
1304
|
const reader = this.sourceDb.createQueryReader(this.getRelationshipQuery(relClassFullName, "LEFT JOIN", "r.ECInstanceId = :relInstanceId"), queryParams, { usePrimaryConn: true });
|
|
1307
1305
|
if (await reader.step()) {
|
|
1308
1306
|
const row = reader.current;
|
|
@@ -1326,10 +1324,10 @@ class IModelExporter {
|
|
|
1326
1324
|
*/
|
|
1327
1325
|
async exportRelationshipInstance(relationship, isUpdate, endpointFedGuids) {
|
|
1328
1326
|
// passed changeset test, now apply standard exclusion rules
|
|
1329
|
-
|
|
1327
|
+
Logger.logTrace(loggerCategory, `exportRelationship(${relationship.classFullName}, ${relationship.id})`);
|
|
1330
1328
|
for (const excludedRelationshipClass of this._excludedRelationshipClasses) {
|
|
1331
1329
|
if (relationship instanceof excludedRelationshipClass) {
|
|
1332
|
-
|
|
1330
|
+
Logger.logInfo(loggerCategory, `Excluded relationship by class: ${excludedRelationshipClass.classFullName}`);
|
|
1333
1331
|
return;
|
|
1334
1332
|
}
|
|
1335
1333
|
}
|
|
@@ -1347,11 +1345,10 @@ class IModelExporter {
|
|
|
1347
1345
|
}
|
|
1348
1346
|
}
|
|
1349
1347
|
}
|
|
1350
|
-
exports.IModelExporter = IModelExporter;
|
|
1351
1348
|
/** Class for holding change information.
|
|
1352
1349
|
* @public
|
|
1353
1350
|
*/
|
|
1354
|
-
class ChangedInstanceOps {
|
|
1351
|
+
export class ChangedInstanceOps {
|
|
1355
1352
|
insertIds = new Set();
|
|
1356
1353
|
updateIds = new Set();
|
|
1357
1354
|
deleteIds = new Set();
|
|
@@ -1376,12 +1373,11 @@ class ChangedInstanceOps {
|
|
|
1376
1373
|
0 === this.deleteIds.size);
|
|
1377
1374
|
}
|
|
1378
1375
|
}
|
|
1379
|
-
exports.ChangedInstanceOps = ChangedInstanceOps;
|
|
1380
1376
|
/**
|
|
1381
1377
|
* Class for discovering modified elements between 2 versions of an iModel.
|
|
1382
1378
|
* @public
|
|
1383
1379
|
*/
|
|
1384
|
-
class ChangedInstanceIds {
|
|
1380
|
+
export class ChangedInstanceIds {
|
|
1385
1381
|
codeSpec = new ChangedInstanceOps();
|
|
1386
1382
|
model = new ChangedInstanceOps();
|
|
1387
1383
|
element = new ChangedInstanceOps();
|
|
@@ -1429,14 +1425,14 @@ class ChangedInstanceIds {
|
|
|
1429
1425
|
*/
|
|
1430
1426
|
async addChangeRecord(change) {
|
|
1431
1427
|
if (change.op === "Deleted" && change.aspectOwnerElementId === undefined) {
|
|
1432
|
-
this._classKinds ??= await
|
|
1428
|
+
this._classKinds ??= await SourceClassKinds.query(this._db);
|
|
1433
1429
|
const kind = this._classKinds.kindOf(change.ecClassId);
|
|
1434
1430
|
// The source no longer has the aspect, so without its owner the target aspect would silently stay.
|
|
1435
1431
|
if (kind === "aspect" || kind === "externalSourceAspect")
|
|
1436
|
-
|
|
1432
|
+
ITwinError.throwError({
|
|
1437
1433
|
iTwinErrorId: {
|
|
1438
|
-
scope:
|
|
1439
|
-
key:
|
|
1434
|
+
scope: IModelTransformerErrorScope,
|
|
1435
|
+
key: IModelTransformerError.AspectOwnerRequired,
|
|
1440
1436
|
},
|
|
1441
1437
|
message: `Deleted ElementAspect change ${change.id} requires the owning element ID.`,
|
|
1442
1438
|
});
|
|
@@ -1446,19 +1442,19 @@ class ChangedInstanceIds {
|
|
|
1446
1442
|
async recordChange(change, unresolvedAspectIds) {
|
|
1447
1443
|
const ecClassId = change.ECClassId;
|
|
1448
1444
|
if (ecClassId === undefined)
|
|
1449
|
-
|
|
1445
|
+
ITwinError.throwError({
|
|
1450
1446
|
iTwinErrorId: {
|
|
1451
|
-
scope:
|
|
1452
|
-
key:
|
|
1447
|
+
scope: IModelTransformerErrorScope,
|
|
1448
|
+
key: IModelTransformerError.ChangedInstanceMetadataMissing,
|
|
1453
1449
|
},
|
|
1454
1450
|
message: `ECClassId was not found for id: ${change.ECInstanceId}! Table is : ${change.$meta.tables}`,
|
|
1455
1451
|
});
|
|
1456
1452
|
const changeType = change.$meta.op;
|
|
1457
1453
|
if (changeType === undefined)
|
|
1458
|
-
|
|
1454
|
+
ITwinError.throwError({
|
|
1459
1455
|
iTwinErrorId: {
|
|
1460
|
-
scope:
|
|
1461
|
-
key:
|
|
1456
|
+
scope: IModelTransformerErrorScope,
|
|
1457
|
+
key: IModelTransformerError.ChangedInstanceMetadataMissing,
|
|
1462
1458
|
},
|
|
1463
1459
|
message: `ChangeType was undefined for id: ${change.ECInstanceId}.`,
|
|
1464
1460
|
});
|
|
@@ -1471,7 +1467,7 @@ class ChangedInstanceIds {
|
|
|
1471
1467
|
}
|
|
1472
1468
|
async applyChangeRecord(change, unresolvedAspectIds) {
|
|
1473
1469
|
// Await only the first time, so later changes are classified without yielding.
|
|
1474
|
-
this._classKinds ??= await
|
|
1470
|
+
this._classKinds ??= await SourceClassKinds.query(this._db);
|
|
1475
1471
|
const { id, ecClassId, op } = change;
|
|
1476
1472
|
switch (this._classKinds.kindOf(ecClassId)) {
|
|
1477
1473
|
case "relationship":
|
|
@@ -1505,8 +1501,8 @@ class ChangedInstanceIds {
|
|
|
1505
1501
|
return this._db.elements.getAspect(aspectId).element.id;
|
|
1506
1502
|
}
|
|
1507
1503
|
catch (error) {
|
|
1508
|
-
if (error instanceof
|
|
1509
|
-
error.errorNumber ===
|
|
1504
|
+
if (error instanceof IModelError &&
|
|
1505
|
+
error.errorNumber === IModelStatus.NotFound) {
|
|
1510
1506
|
return undefined;
|
|
1511
1507
|
}
|
|
1512
1508
|
throw error;
|
|
@@ -1525,16 +1521,16 @@ class ChangedInstanceIds {
|
|
|
1525
1521
|
* @beta
|
|
1526
1522
|
*/
|
|
1527
1523
|
async addCustomElementChange(changeType, ids) {
|
|
1528
|
-
if (
|
|
1524
|
+
if (Id64.sizeOf(ids) === 0) {
|
|
1529
1525
|
return;
|
|
1530
1526
|
}
|
|
1531
|
-
for (const id of
|
|
1527
|
+
for (const id of Id64.iterable(ids)) {
|
|
1532
1528
|
this.handleChange(this.element, changeType, id);
|
|
1533
1529
|
}
|
|
1534
1530
|
if (changeType === "Deleted") {
|
|
1535
1531
|
return;
|
|
1536
1532
|
}
|
|
1537
|
-
const idsSet =
|
|
1533
|
+
const idsSet = Id64.toIdSet(ids, true);
|
|
1538
1534
|
// 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.
|
|
1539
1535
|
// 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.
|
|
1540
1536
|
const parentModelIds = await this.markParentModelsAsUpdated(idsSet);
|
|
@@ -1546,7 +1542,7 @@ class ChangedInstanceIds {
|
|
|
1546
1542
|
});
|
|
1547
1543
|
await this.markElementAspectsAsInserted(idsSet);
|
|
1548
1544
|
// Marking only ElementRefersToElements.classFullName as only those are exported in exportRelationships()
|
|
1549
|
-
await this.markElementRelationshipsAsInserted(
|
|
1545
|
+
await this.markElementRelationshipsAsInserted(ElementRefersToElements.classFullName, idsSet);
|
|
1550
1546
|
}
|
|
1551
1547
|
}
|
|
1552
1548
|
/**
|
|
@@ -1563,7 +1559,7 @@ class ChangedInstanceIds {
|
|
|
1563
1559
|
async addCustomModelChange(changeType, ids) {
|
|
1564
1560
|
// Also add the model's modeledElement to the element changes. The modeledElement and model go hand in hand and have the same id.
|
|
1565
1561
|
await this.addCustomElementChange(changeType, ids);
|
|
1566
|
-
for (const id of
|
|
1562
|
+
for (const id of Id64.iterable(ids)) {
|
|
1567
1563
|
this.handleChange(this.model, changeType, id);
|
|
1568
1564
|
}
|
|
1569
1565
|
}
|
|
@@ -1580,16 +1576,16 @@ class ChangedInstanceIds {
|
|
|
1580
1576
|
*/
|
|
1581
1577
|
addCustomAspectChange(changeType, ids, elementIds) {
|
|
1582
1578
|
if (elementIds !== undefined) {
|
|
1583
|
-
for (const elementId of
|
|
1579
|
+
for (const elementId of Id64.iterable(elementIds)) {
|
|
1584
1580
|
this._aspectOwnerElementIds.add(elementId);
|
|
1585
1581
|
}
|
|
1586
1582
|
}
|
|
1587
|
-
for (const id of
|
|
1583
|
+
for (const id of Id64.iterable(ids)) {
|
|
1588
1584
|
if (elementIds === undefined && changeType === "Deleted") {
|
|
1589
|
-
|
|
1585
|
+
ITwinError.throwError({
|
|
1590
1586
|
iTwinErrorId: {
|
|
1591
|
-
scope:
|
|
1592
|
-
key:
|
|
1587
|
+
scope: IModelTransformerErrorScope,
|
|
1588
|
+
key: IModelTransformerError.AspectOwnerRequired,
|
|
1593
1589
|
},
|
|
1594
1590
|
message: "Custom deleted ElementAspect changes require the owning element ID.",
|
|
1595
1591
|
});
|
|
@@ -1597,10 +1593,10 @@ class ChangedInstanceIds {
|
|
|
1597
1593
|
if (elementIds === undefined && changeType !== "Deleted") {
|
|
1598
1594
|
const ownerElementId = this.tryGetAspectOwnerElementId(id);
|
|
1599
1595
|
if (ownerElementId === undefined) {
|
|
1600
|
-
|
|
1596
|
+
ITwinError.throwError({
|
|
1601
1597
|
iTwinErrorId: {
|
|
1602
|
-
scope:
|
|
1603
|
-
key:
|
|
1598
|
+
scope: IModelTransformerErrorScope,
|
|
1599
|
+
key: IModelTransformerError.AspectOwnerRequired,
|
|
1604
1600
|
},
|
|
1605
1601
|
message: "Custom ElementAspect changes require the owning element ID when the source aspect is unavailable.",
|
|
1606
1602
|
});
|
|
@@ -1619,7 +1615,7 @@ class ChangedInstanceIds {
|
|
|
1619
1615
|
* 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.
|
|
1620
1616
|
*/
|
|
1621
1617
|
async markParentModelsAsUpdated(elementIds) {
|
|
1622
|
-
const params = new
|
|
1618
|
+
const params = new QueryBinder().bindIdSet("elementIds", elementIds);
|
|
1623
1619
|
const ecQuery = `
|
|
1624
1620
|
WITH RECURSIVE hierarchy (parentId) AS (
|
|
1625
1621
|
SELECT element.Model.Id
|
|
@@ -1658,7 +1654,7 @@ class ChangedInstanceIds {
|
|
|
1658
1654
|
FROM ${relationshipClassName} relationship
|
|
1659
1655
|
INNER JOIN IdSet(:elementIds) ids
|
|
1660
1656
|
ON ids.id = relationship.SourceECInstanceId`;
|
|
1661
|
-
const queryBinder = new
|
|
1657
|
+
const queryBinder = new QueryBinder().bindIdSet("elementIds", elementIds);
|
|
1662
1658
|
const queryReader = this._db.createQueryReader(ecQuery, queryBinder, {
|
|
1663
1659
|
usePrimaryConn: true,
|
|
1664
1660
|
});
|
|
@@ -1668,13 +1664,13 @@ class ChangedInstanceIds {
|
|
|
1668
1664
|
}
|
|
1669
1665
|
async markElementAspectsAsInserted(elementIds) {
|
|
1670
1666
|
for (const aspectClassName of [
|
|
1671
|
-
|
|
1672
|
-
|
|
1667
|
+
ElementUniqueAspect.classFullName,
|
|
1668
|
+
ElementMultiAspect.classFullName,
|
|
1673
1669
|
]) {
|
|
1674
1670
|
const ecQuery = `SELECT aspect.ECInstanceId, aspect.Element.Id
|
|
1675
1671
|
FROM ${aspectClassName} aspect
|
|
1676
1672
|
INNER JOIN IdSet(:elementIds) ids ON ids.id = aspect.Element.Id`;
|
|
1677
|
-
const queryBinder = new
|
|
1673
|
+
const queryBinder = new QueryBinder().bindIdSet("elementIds", elementIds);
|
|
1678
1674
|
const queryReader = this._db.createQueryReader(ecQuery, queryBinder, {
|
|
1679
1675
|
usePrimaryConn: true,
|
|
1680
1676
|
});
|
|
@@ -1719,14 +1715,14 @@ class ChangedInstanceIds {
|
|
|
1719
1715
|
? [
|
|
1720
1716
|
[
|
|
1721
1717
|
startChangeset.index ??
|
|
1722
|
-
(await
|
|
1718
|
+
(await BriefcaseManager.queryChangeset({
|
|
1723
1719
|
iModelId,
|
|
1724
1720
|
changeset: {
|
|
1725
1721
|
id: startChangeset.id ?? opts.iModel.changeset.id,
|
|
1726
1722
|
},
|
|
1727
1723
|
})).index,
|
|
1728
1724
|
opts.iModel.changeset.index ??
|
|
1729
|
-
(await
|
|
1725
|
+
(await BriefcaseManager.queryChangeset({
|
|
1730
1726
|
iModelId,
|
|
1731
1727
|
changeset: { id: opts.iModel.changeset.id },
|
|
1732
1728
|
})).index,
|
|
@@ -1736,14 +1732,14 @@ class ChangedInstanceIds {
|
|
|
1736
1732
|
? opts.changesetRanges
|
|
1737
1733
|
: undefined;
|
|
1738
1734
|
const csFileProps = changesetRanges !== undefined
|
|
1739
|
-
? (await
|
|
1735
|
+
? (await ChangesetScanner.download(opts.iModel, changesetRanges)).flat()
|
|
1740
1736
|
: "csFileProps" in opts
|
|
1741
1737
|
? opts.csFileProps
|
|
1742
1738
|
: undefined;
|
|
1743
1739
|
if (csFileProps === undefined)
|
|
1744
1740
|
return undefined;
|
|
1745
1741
|
const changedInstanceIds = new ChangedInstanceIds(opts.iModel);
|
|
1746
|
-
await
|
|
1742
|
+
await ChangesetScanner.scan(opts.iModel, [csFileProps], {
|
|
1747
1743
|
changedInstanceIds,
|
|
1748
1744
|
collectDeletionRecords: false,
|
|
1749
1745
|
});
|
|
@@ -1767,9 +1763,8 @@ class ChangedInstanceIds {
|
|
|
1767
1763
|
WHERE ECInstanceId IN (SELECT id FROM AspectIds)`, (reader) => {
|
|
1768
1764
|
while (reader.step())
|
|
1769
1765
|
this._aspectOwnerElementIds.add(reader.current[0]);
|
|
1770
|
-
}, new
|
|
1766
|
+
}, new QueryBinder().bindIdSet("aspectIds", unresolvedAspectIds));
|
|
1771
1767
|
}
|
|
1772
1768
|
}
|
|
1773
1769
|
}
|
|
1774
|
-
exports.ChangedInstanceIds = ChangedInstanceIds;
|
|
1775
1770
|
//# sourceMappingURL=IModelExporter.js.map
|