@itwin/imodel-transformer 2.0.0-dev.72 → 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,39 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.TemplateModelCloner = exports.IModelTransformer = void 0;
|
|
37
1
|
/*---------------------------------------------------------------------------------------------
|
|
38
2
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
39
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -41,26 +5,28 @@ exports.TemplateModelCloner = exports.IModelTransformer = void 0;
|
|
|
41
5
|
/** @packageDocumentation
|
|
42
6
|
* @module iModels
|
|
43
7
|
*/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import * as Semver from "semver";
|
|
10
|
+
import { strict as nodeAssert } from "node:assert";
|
|
11
|
+
import { assert, Guid, Id64, IModelStatus, ITwinError, Logger, } from "@itwin/core-bentley";
|
|
12
|
+
import * as ECSchemaMetaData from "@itwin/ecschema-metadata";
|
|
13
|
+
import { Angle, AxisIndex, Matrix3d, Point3d, Transform, Vector3d, } from "@itwin/core-geometry";
|
|
14
|
+
import { BriefcaseManager, ChangeSummaryManager, ChannelRootAspect, DefinitionElement, DefinitionModel, DefinitionPartition, EditTxn,
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
16
|
+
Element, ElementRefersToElements, EntityReferences, ExternalSourceAspect, GeometricElement, GeometricElement3d, IModelDb, IModelHost, InformationPartitionElement, KnownLocations, RecipeDefinitionElement, Schema, Subject, } from "@itwin/core-backend";
|
|
17
|
+
import { Code, ConcreteEntityTypes, ECJsNames, IModel, IModelError, Placement2d, Placement3d, QueryBinder, } from "@itwin/core-common";
|
|
18
|
+
import { ChangedInstanceIds, IModelExporter, IModelExportHandler, } from "./IModelExporter.js";
|
|
19
|
+
import { IModelImporter } from "./IModelImporter.js";
|
|
20
|
+
import { TransformerLoggerCategory } from "./TransformerLoggerCategory.js";
|
|
21
|
+
import { IModelCloneContext } from "./IModelCloneContext.js";
|
|
22
|
+
import { rangesFromRangeAndSkipped } from "./Algo.js";
|
|
23
|
+
import { SyncTypeResolver } from "./SyncTypeResolver.js";
|
|
24
|
+
import { ProvenanceManager } from "./ProvenanceManager.js";
|
|
25
|
+
import { NewerVersionSchemaImportStrategy, } from "./schema-processing/SchemaProcessingStrategy.js";
|
|
26
|
+
import { SchemaProcessingCoordinator } from "./schema-processing/SchemaProcessingCoordinator.js";
|
|
27
|
+
import { ChangesetScanner, } from "./ChangesetScanner.js";
|
|
28
|
+
import { IModelTransformerError, IModelTransformerErrorScope, } from "./IModelTransformerError.js";
|
|
29
|
+
const loggerCategory = TransformerLoggerCategory.IModelTransformer;
|
|
64
30
|
/** Key of a relationship's source and target element ids. */
|
|
65
31
|
function relationshipEndpointsKey(sourceId, targetId) {
|
|
66
32
|
return `${sourceId}|${targetId}`;
|
|
@@ -74,7 +40,7 @@ function relationshipEndpointsKey(sourceId, targetId) {
|
|
|
74
40
|
function mapId64(idContainer, func) {
|
|
75
41
|
const isId64String = (arg) => {
|
|
76
42
|
const isString = typeof arg === "string";
|
|
77
|
-
|
|
43
|
+
assert(() => !isString || Id64.isValidId64(arg));
|
|
78
44
|
return isString;
|
|
79
45
|
};
|
|
80
46
|
const isRelatedElem = (arg) => arg && typeof arg === "object" && "id" in arg;
|
|
@@ -90,10 +56,10 @@ function mapId64(idContainer, func) {
|
|
|
90
56
|
results.push(func(idContainer.id));
|
|
91
57
|
}
|
|
92
58
|
else {
|
|
93
|
-
|
|
59
|
+
ITwinError.throwError({
|
|
94
60
|
iTwinErrorId: {
|
|
95
|
-
scope:
|
|
96
|
-
key:
|
|
61
|
+
scope: IModelTransformerErrorScope,
|
|
62
|
+
key: IModelTransformerError.InvalidEntityReference,
|
|
97
63
|
},
|
|
98
64
|
message: [
|
|
99
65
|
`Id64 container '${JSON.stringify(idContainer)}' is unsupported.`,
|
|
@@ -107,7 +73,7 @@ function mapId64(idContainer, func) {
|
|
|
107
73
|
* @see [iModel Transformation and Data Exchange]($docs/learning/transformer/index.md), [IModelExporter]($transformer), [IModelImporter]($transformer)
|
|
108
74
|
* @beta
|
|
109
75
|
*/
|
|
110
|
-
class IModelTransformer extends
|
|
76
|
+
export class IModelTransformer extends IModelExportHandler {
|
|
111
77
|
/** The IModelExporter that will export from the source iModel. */
|
|
112
78
|
exporter;
|
|
113
79
|
_schemaProcessingCoordinator;
|
|
@@ -176,11 +142,11 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
176
142
|
_isProvenanceInitTransform;
|
|
177
143
|
/** The element classes that are considered to define provenance in the iModel */
|
|
178
144
|
static get provenanceElementClasses() {
|
|
179
|
-
return
|
|
145
|
+
return ProvenanceManager.provenanceElementClasses;
|
|
180
146
|
}
|
|
181
147
|
/** The element aspect classes that are considered to define provenance in the iModel */
|
|
182
148
|
static get provenanceElementAspectClasses() {
|
|
183
|
-
return
|
|
149
|
+
return ProvenanceManager.provenanceElementAspectClasses;
|
|
184
150
|
}
|
|
185
151
|
/** Construct a new IModelTransformer
|
|
186
152
|
* @param args The required arguments including source and target.
|
|
@@ -194,23 +160,23 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
194
160
|
...options,
|
|
195
161
|
// non-falsy defaults
|
|
196
162
|
cloneUsingBinaryGeometry: options?.cloneUsingBinaryGeometry ?? true,
|
|
197
|
-
targetScopeElementId: options?.targetScopeElementId ??
|
|
163
|
+
targetScopeElementId: options?.targetScopeElementId ?? IModel.rootSubjectId,
|
|
198
164
|
danglingReferencesBehavior: options?.danglingReferencesBehavior ?? "reject",
|
|
199
165
|
branchRelationshipDataBehavior: options?.branchRelationshipDataBehavior ?? "reject",
|
|
200
166
|
skipPropagateChangesToRootElements: options?.skipPropagateChangesToRootElements ?? true,
|
|
201
167
|
tryAlignGeolocation: options?.tryAlignGeolocation ?? false,
|
|
202
168
|
};
|
|
203
169
|
// check if authorization client is defined
|
|
204
|
-
if (
|
|
205
|
-
|
|
170
|
+
if (IModelHost.authorizationClient === undefined) {
|
|
171
|
+
Logger.logWarning(loggerCategory, "Authorization client is not set in IModelHost. If the transformer needs an accessToken, then it will fail.");
|
|
206
172
|
}
|
|
207
173
|
this._isProvenanceInitTransform = this._options
|
|
208
174
|
.wasSourceIModelCopiedToTarget
|
|
209
175
|
? true
|
|
210
176
|
: undefined;
|
|
211
177
|
// initialize exporter and sourceDb
|
|
212
|
-
if (source instanceof
|
|
213
|
-
this.exporter = new
|
|
178
|
+
if (source instanceof IModelDb) {
|
|
179
|
+
this.exporter = new IModelExporter(source);
|
|
214
180
|
}
|
|
215
181
|
else {
|
|
216
182
|
this.exporter = source;
|
|
@@ -223,11 +189,11 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
223
189
|
IModelTransformer.provenanceElementClasses.forEach((cls) => this.exporter.excludeElementClass(cls.classFullName));
|
|
224
190
|
IModelTransformer.provenanceElementAspectClasses.forEach((cls) => this.exporter.excludeElementAspectClass(cls.classFullName));
|
|
225
191
|
}
|
|
226
|
-
this.exporter.excludeElementAspectClass(
|
|
192
|
+
this.exporter.excludeElementAspectClass(ChannelRootAspect.classFullName); // Channel boundaries within the source iModel are not relevant to the target iModel
|
|
227
193
|
this.exporter.excludeElementAspectClass("BisCore:TextAnnotationData"); // This ElementAspect is auto-created by the BisCore:TextAnnotation2d/3d element handlers
|
|
228
194
|
// initialize importer and targetDb
|
|
229
|
-
if (target instanceof
|
|
230
|
-
this.importer = new
|
|
195
|
+
if (target instanceof EditTxn) {
|
|
196
|
+
this.importer = new IModelImporter(target, {
|
|
231
197
|
preserveElementIdsForFiltering: this._options.preserveElementIdsForFiltering,
|
|
232
198
|
skipPropagateChangesToRootElements: this._options.skipPropagateChangesToRootElements,
|
|
233
199
|
});
|
|
@@ -239,7 +205,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
239
205
|
this.targetDb = this.importer.targetDb;
|
|
240
206
|
this._targetEditTxn = this.importer.editTxn;
|
|
241
207
|
this._sourceEditTxn = options?.sourceEditTxn;
|
|
242
|
-
this._schemaProcessingCoordinator = new
|
|
208
|
+
this._schemaProcessingCoordinator = new SchemaProcessingCoordinator({
|
|
243
209
|
exporter: this.exporter,
|
|
244
210
|
targetDb: this.targetDb,
|
|
245
211
|
getSchemaExportDirectory: () => this._schemaExportDir,
|
|
@@ -248,24 +214,24 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
248
214
|
});
|
|
249
215
|
this.exporter.elementAspectExportCoordinator.setPreparation(async (excludedClasses, elementIds) => this.prepareElementAspects(excludedClasses, elementIds));
|
|
250
216
|
// create the IModelCloneContext, it must be initialized later
|
|
251
|
-
this._cloneContext = new
|
|
217
|
+
this._cloneContext = new IModelCloneContext(this.sourceDb, this.targetDb);
|
|
252
218
|
this.importer.registerEntityExistenceCache(this._cloneContext.existenceCache);
|
|
253
219
|
this.setCodeValueBehavior("exact");
|
|
254
|
-
this._syncTypeResolver = new
|
|
255
|
-
this._provenanceManager = new
|
|
220
|
+
this._syncTypeResolver = new SyncTypeResolver(this.sourceDb, this.targetDb, this._options.targetScopeElementId, !!this._isProvenanceInitTransform, !!this._options.argsForProcessChanges);
|
|
221
|
+
this._provenanceManager = new ProvenanceManager(this._options.targetScopeElementId, this._options, this._cloneContext, this._syncTypeResolver, this._targetEditTxn, this._sourceEditTxn);
|
|
256
222
|
if (this._options.tryAlignGeolocation) {
|
|
257
223
|
if (this.sourceDb.geographicCoordinateSystem ||
|
|
258
224
|
this.targetDb.geographicCoordinateSystem) {
|
|
259
|
-
|
|
225
|
+
Logger.logTrace(loggerCategory, "Aligning Additional transforms between imodels due to imodels containing GeographicCoordinateSystem data");
|
|
260
226
|
this._linearSpatialTransform =
|
|
261
227
|
this.calculateTransformFromHelmertTransforms();
|
|
262
228
|
}
|
|
263
229
|
else if (this.sourceDb.ecefLocation && this.targetDb.ecefLocation) {
|
|
264
|
-
|
|
230
|
+
Logger.logTrace(loggerCategory, "Aligning ECEF Location's between imodels due to imodels not containing GeographicCoordinateSystem data");
|
|
265
231
|
this._linearSpatialTransform = this.calculateEcefTransform();
|
|
266
232
|
}
|
|
267
233
|
else
|
|
268
|
-
|
|
234
|
+
Logger.logTrace(loggerCategory, "No Geolcation data to align, both GCS and ECEF are undefined");
|
|
269
235
|
}
|
|
270
236
|
}
|
|
271
237
|
/** validates that the importer set on the transformer has the same values for its shared options as the transformer.
|
|
@@ -274,20 +240,20 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
274
240
|
validateSharedOptionsMatch() {
|
|
275
241
|
if (Boolean(this._options.preserveElementIdsForFiltering) !==
|
|
276
242
|
this.importer.options.preserveElementIdsForFiltering) {
|
|
277
|
-
|
|
243
|
+
ITwinError.throwError({
|
|
278
244
|
iTwinErrorId: {
|
|
279
|
-
scope:
|
|
280
|
-
key:
|
|
245
|
+
scope: IModelTransformerErrorScope,
|
|
246
|
+
key: IModelTransformerError.ImporterOptionMismatch,
|
|
281
247
|
},
|
|
282
248
|
message: "A custom importer was passed as a target but its 'preserveElementIdsForFiltering' option is out of sync with the transformer's option.",
|
|
283
249
|
});
|
|
284
250
|
}
|
|
285
251
|
if (Boolean(this._options.skipPropagateChangesToRootElements) !==
|
|
286
252
|
this.importer.options.skipPropagateChangesToRootElements) {
|
|
287
|
-
|
|
253
|
+
ITwinError.throwError({
|
|
288
254
|
iTwinErrorId: {
|
|
289
|
-
scope:
|
|
290
|
-
key:
|
|
255
|
+
scope: IModelTransformerErrorScope,
|
|
256
|
+
key: IModelTransformerError.ImporterOptionMismatch,
|
|
291
257
|
},
|
|
292
258
|
message: "A custom importer was passed as a target but its 'skipPropagateChangesToRootElements' option is out of sync with the transformer's option.",
|
|
293
259
|
});
|
|
@@ -295,25 +261,25 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
295
261
|
}
|
|
296
262
|
/** Dispose any native resources associated with this IModelTransformer. */
|
|
297
263
|
dispose() {
|
|
298
|
-
|
|
264
|
+
Logger.logTrace(loggerCategory, "dispose()");
|
|
299
265
|
this.importer.unregisterEntityExistenceCache(this._cloneContext.existenceCache);
|
|
300
266
|
this._cloneContext.existenceCache.clear();
|
|
301
267
|
this._cloneContext[Symbol.dispose]();
|
|
302
268
|
}
|
|
303
269
|
/** Log current settings that affect IModelTransformer's behavior. */
|
|
304
270
|
logSettings() {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
271
|
+
Logger.logInfo(TransformerLoggerCategory.IModelExporter, `this.exporter.visitElements=${this.exporter.visitElements}`);
|
|
272
|
+
Logger.logInfo(TransformerLoggerCategory.IModelExporter, `this.exporter.visitRelationships=${this.exporter.visitRelationships}`);
|
|
273
|
+
Logger.logInfo(TransformerLoggerCategory.IModelExporter, `this.exporter.wantGeometry=${this.exporter.wantGeometry}`);
|
|
274
|
+
Logger.logInfo(TransformerLoggerCategory.IModelExporter, `this.exporter.wantSystemSchemas=${this.exporter.wantSystemSchemas}`);
|
|
275
|
+
Logger.logInfo(TransformerLoggerCategory.IModelExporter, `this.exporter.wantTemplateModels=${this.exporter.wantTemplateModels}`);
|
|
276
|
+
Logger.logInfo(loggerCategory, `this.targetScopeElementId=${this.targetScopeElementId}`);
|
|
277
|
+
Logger.logInfo(loggerCategory, `this._noProvenance=${this._options.noProvenance}`);
|
|
278
|
+
Logger.logInfo(loggerCategory, `this._includeSourceProvenance=${this._options.includeSourceProvenance}`);
|
|
279
|
+
Logger.logInfo(loggerCategory, `this._cloneUsingBinaryGeometry=${this._options.cloneUsingBinaryGeometry}`);
|
|
280
|
+
Logger.logInfo(loggerCategory, `this._wasSourceIModelCopiedToTarget=${this._options.wasSourceIModelCopiedToTarget}`);
|
|
281
|
+
Logger.logInfo(TransformerLoggerCategory.IModelImporter, `this.importer.autoExtendProjectExtents=${JSON.stringify(this.importer.options.autoExtendProjectExtents)}`);
|
|
282
|
+
Logger.logInfo(TransformerLoggerCategory.IModelImporter, `this.importer.simplifyElementGeometry=${this.importer.options.simplifyElementGeometry}`);
|
|
317
283
|
}
|
|
318
284
|
/**
|
|
319
285
|
* Previously the transformer would insert provenance always pointing to the "target" relationship.
|
|
@@ -394,34 +360,34 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
394
360
|
* @note This can be called more than once for an element in arbitrary order, so it should not have side-effects.
|
|
395
361
|
*/
|
|
396
362
|
async onTransformElement(sourceElement) {
|
|
397
|
-
|
|
363
|
+
Logger.logTrace(loggerCategory, `onTransformElement(${sourceElement.id}) "${sourceElement.getDisplayLabel()}"`);
|
|
398
364
|
const targetElementProps = await this._cloneContext.cloneElement(sourceElement, {
|
|
399
365
|
binaryGeometry: this._options.cloneUsingBinaryGeometry,
|
|
400
366
|
});
|
|
401
367
|
// Special case: source element is the root subject
|
|
402
|
-
if (sourceElement.id ===
|
|
368
|
+
if (sourceElement.id === IModel.rootSubjectId) {
|
|
403
369
|
const targetElementId = this.context.findTargetElementId(sourceElement.id);
|
|
404
370
|
// When remapping rootSubject from source to non root subject in target, the code.scope gets remapped incorrectly.
|
|
405
371
|
// This is because the rootSubject has no parent and its code.scope is unique in that it is the id of itself.
|
|
406
372
|
// For all other subjects which do have parents the code.scope and its parent should be in agreement.
|
|
407
|
-
if (targetElementId !==
|
|
408
|
-
targetElementId !==
|
|
373
|
+
if (targetElementId !== Id64.invalid &&
|
|
374
|
+
targetElementId !== IModel.rootSubjectId) {
|
|
409
375
|
const targetElement = this.targetDb.elements.getElement(targetElementId);
|
|
410
376
|
targetElementProps.parent =
|
|
411
377
|
targetElement.parent ?? targetElementProps.parent;
|
|
412
378
|
targetElementProps.code.scope = targetElement.code.scope;
|
|
413
379
|
}
|
|
414
380
|
}
|
|
415
|
-
if (sourceElement instanceof
|
|
381
|
+
if (sourceElement instanceof Subject) {
|
|
416
382
|
if (targetElementProps.jsonProperties?.Subject?.Job) {
|
|
417
383
|
// don't propagate source channels into target (legacy bridge case)
|
|
418
384
|
targetElementProps.jsonProperties.Subject.Job = undefined;
|
|
419
385
|
}
|
|
420
386
|
}
|
|
421
387
|
if (this._linearSpatialTransform !== undefined &&
|
|
422
|
-
sourceElement instanceof
|
|
388
|
+
sourceElement instanceof GeometricElement3d) {
|
|
423
389
|
// can check the sourceElement since this IModelTransformer does not remap classes
|
|
424
|
-
const placement =
|
|
390
|
+
const placement = Placement3d.fromJSON(targetElementProps.placement);
|
|
425
391
|
if (placement.isValid) {
|
|
426
392
|
placement.multiplyTransform(this._linearSpatialTransform);
|
|
427
393
|
targetElementProps.placement = placement;
|
|
@@ -440,25 +406,25 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
440
406
|
const srcEcefLoc = this.sourceDb.ecefLocation;
|
|
441
407
|
const targetEcefLoc = this.targetDb.ecefLocation;
|
|
442
408
|
if (srcEcefLoc === undefined || targetEcefLoc === undefined) {
|
|
443
|
-
|
|
409
|
+
ITwinError.throwError({
|
|
444
410
|
iTwinErrorId: {
|
|
445
|
-
scope:
|
|
446
|
-
key:
|
|
411
|
+
scope: IModelTransformerErrorScope,
|
|
412
|
+
key: IModelTransformerError.GeolocationUnavailable,
|
|
447
413
|
},
|
|
448
414
|
message: "Both source and target ECEF locations must be defined to calculate the transform.",
|
|
449
415
|
});
|
|
450
416
|
}
|
|
451
417
|
if (srcEcefLoc.getTransform().isAlmostEqual(targetEcefLoc.getTransform())) {
|
|
452
|
-
|
|
418
|
+
Logger.logTrace(loggerCategory, "ECEF data is already aligned. No spatial transforms needed.");
|
|
453
419
|
return undefined;
|
|
454
420
|
}
|
|
455
421
|
const srcSpatialToECEF = srcEcefLoc.getTransform(); // converts relative to ECEF in relation to source
|
|
456
422
|
const targetECEFToSpatial = targetEcefLoc.getTransform().inverse(); // converts ECEF to relative in relation to target
|
|
457
423
|
if (!targetECEFToSpatial) {
|
|
458
|
-
|
|
424
|
+
ITwinError.throwError({
|
|
459
425
|
iTwinErrorId: {
|
|
460
|
-
scope:
|
|
461
|
-
key:
|
|
426
|
+
scope: IModelTransformerErrorScope,
|
|
427
|
+
key: IModelTransformerError.GeolocationUnavailable,
|
|
462
428
|
},
|
|
463
429
|
message: "Failed to invert target ECEF transform.",
|
|
464
430
|
});
|
|
@@ -468,48 +434,48 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
468
434
|
}
|
|
469
435
|
static convertHelmertToTransform(helmert) {
|
|
470
436
|
if (!helmert) {
|
|
471
|
-
return
|
|
437
|
+
return Transform.createIdentity();
|
|
472
438
|
}
|
|
473
|
-
const rotationXY =
|
|
439
|
+
const rotationXY = Matrix3d.createRotationAroundAxisIndex(AxisIndex.Z, Angle.createDegrees(helmert?.rotDeg));
|
|
474
440
|
rotationXY.scaleColumnsInPlace(helmert.scale, helmert.scale, 1.0);
|
|
475
|
-
const translation =
|
|
476
|
-
const helmertTransform =
|
|
441
|
+
const translation = Vector3d.create(helmert.translationX, helmert.translationY, helmert.translationZ);
|
|
442
|
+
const helmertTransform = Transform.createRefs(translation, rotationXY);
|
|
477
443
|
return helmertTransform;
|
|
478
444
|
}
|
|
479
445
|
calculateTransformFromHelmertTransforms() {
|
|
480
446
|
if (this.sourceDb.geographicCoordinateSystem?.horizontalCRS === undefined ||
|
|
481
447
|
this.sourceDb.geographicCoordinateSystem?.verticalCRS === undefined) {
|
|
482
|
-
|
|
448
|
+
ITwinError.throwError({
|
|
483
449
|
iTwinErrorId: {
|
|
484
|
-
scope:
|
|
485
|
-
key:
|
|
450
|
+
scope: IModelTransformerErrorScope,
|
|
451
|
+
key: IModelTransformerError.GeographicCoordinateSystemUnavailable,
|
|
486
452
|
},
|
|
487
453
|
message: "Source iModel does not have a geographic coordinate system defined.",
|
|
488
454
|
});
|
|
489
455
|
}
|
|
490
456
|
if (this.targetDb.geographicCoordinateSystem?.horizontalCRS === undefined ||
|
|
491
457
|
this.targetDb.geographicCoordinateSystem.verticalCRS === undefined) {
|
|
492
|
-
|
|
458
|
+
ITwinError.throwError({
|
|
493
459
|
iTwinErrorId: {
|
|
494
|
-
scope:
|
|
495
|
-
key:
|
|
460
|
+
scope: IModelTransformerErrorScope,
|
|
461
|
+
key: IModelTransformerError.GeographicCoordinateSystemUnavailable,
|
|
496
462
|
},
|
|
497
463
|
message: "Target iModel does not have a geographic coordinate system defined.",
|
|
498
464
|
});
|
|
499
465
|
}
|
|
500
466
|
if (!this.sourceDb.geographicCoordinateSystem.horizontalCRS.equals(this.targetDb.geographicCoordinateSystem.horizontalCRS) ||
|
|
501
467
|
!this.sourceDb.geographicCoordinateSystem.verticalCRS.equals(this.targetDb.geographicCoordinateSystem.verticalCRS)) {
|
|
502
|
-
|
|
468
|
+
ITwinError.throwError({
|
|
503
469
|
iTwinErrorId: {
|
|
504
|
-
scope:
|
|
505
|
-
key:
|
|
470
|
+
scope: IModelTransformerErrorScope,
|
|
471
|
+
key: IModelTransformerError.GeographicCoordinateSystemMismatch,
|
|
506
472
|
},
|
|
507
473
|
message: "Source and target geographic coordinate systems must match to calculate the spatial transform.",
|
|
508
474
|
});
|
|
509
475
|
}
|
|
510
476
|
if (this.sourceDb.geographicCoordinateSystem.additionalTransform ===
|
|
511
477
|
this.targetDb.geographicCoordinateSystem.additionalTransform) {
|
|
512
|
-
|
|
478
|
+
Logger.logTrace(loggerCategory, "Geolocation data is already aligned. No spatial transforms needed.");
|
|
513
479
|
return undefined;
|
|
514
480
|
}
|
|
515
481
|
const srcScale = this.sourceDb.geographicCoordinateSystem.additionalTransform
|
|
@@ -517,10 +483,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
517
483
|
const targetScale = this.targetDb.geographicCoordinateSystem.additionalTransform
|
|
518
484
|
?.helmert2DWithZOffset?.scale ?? 1;
|
|
519
485
|
if (srcScale !== targetScale) {
|
|
520
|
-
|
|
486
|
+
ITwinError.throwError({
|
|
521
487
|
iTwinErrorId: {
|
|
522
|
-
scope:
|
|
523
|
-
key:
|
|
488
|
+
scope: IModelTransformerErrorScope,
|
|
489
|
+
key: IModelTransformerError.GeographicCoordinateSystemMismatch,
|
|
524
490
|
},
|
|
525
491
|
message: "Spatial transform is non rigid. Source and target Helmert transforms must have the same scale to calculate a rigid spatial transform.",
|
|
526
492
|
});
|
|
@@ -530,10 +496,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
530
496
|
const targetTransformInv = IModelTransformer.convertHelmertToTransform(this.targetDb.geographicCoordinateSystem.additionalTransform
|
|
531
497
|
?.helmert2DWithZOffset).inverse(); // negates target helmert transform that is applied at render time
|
|
532
498
|
if (!targetTransformInv) {
|
|
533
|
-
|
|
499
|
+
ITwinError.throwError({
|
|
534
500
|
iTwinErrorId: {
|
|
535
|
-
scope:
|
|
536
|
-
key:
|
|
501
|
+
scope: IModelTransformerErrorScope,
|
|
502
|
+
key: IModelTransformerError.GeolocationUnavailable,
|
|
537
503
|
},
|
|
538
504
|
message: "Failed to invert target Helmert transform.",
|
|
539
505
|
});
|
|
@@ -570,7 +536,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
570
536
|
wantBRepData: this.exporter.wantGeometry,
|
|
571
537
|
});
|
|
572
538
|
const targetId = this.context.findTargetElementId(sourceElementId);
|
|
573
|
-
if (
|
|
539
|
+
if (Id64.isInvalid(targetId)) {
|
|
574
540
|
throw new Error(`source-target element mapping not found for element "${sourceElementId}" when completing partially committed elements. This is a bug.`);
|
|
575
541
|
}
|
|
576
542
|
const targetProps = await this.onTransformElement(sourceElement);
|
|
@@ -581,7 +547,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
581
547
|
for (const sourceAspectId of this._partiallyCommittedAspectIds) {
|
|
582
548
|
const sourceAspect = this.sourceDb.elements.getAspect(sourceAspectId);
|
|
583
549
|
const targetAspectId = this.context.findTargetAspectId(sourceAspectId);
|
|
584
|
-
if (
|
|
550
|
+
if (Id64.isInvalid(targetAspectId)) {
|
|
585
551
|
throw new Error(`source-target aspect mapping not found for aspect "${sourceAspectId}" when completing partially committed aspects. This is a bug.`);
|
|
586
552
|
}
|
|
587
553
|
const targetAspectProps = await this.onTransformElementAspect(sourceAspect);
|
|
@@ -597,20 +563,20 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
597
563
|
markSourceEntityExists(entity) {
|
|
598
564
|
if (this._options.danglingReferencesBehavior !== "reject")
|
|
599
565
|
return;
|
|
600
|
-
this._cloneContext.existenceCache.markExists(this.sourceDb,
|
|
566
|
+
this._cloneContext.existenceCache.markExists(this.sourceDb, EntityReferences.from(entity));
|
|
601
567
|
}
|
|
602
568
|
async doAllReferencesExistInTarget(entity) {
|
|
603
569
|
let allReferencesExist = true;
|
|
604
570
|
const checkedReferences = [];
|
|
605
571
|
for (const referenceId of entity.getReferenceIds()) {
|
|
606
|
-
const referencedEntityId =
|
|
607
|
-
if (referencedEntityId ===
|
|
608
|
-
referencedEntityId ===
|
|
572
|
+
const referencedEntityId = EntityReferences.toId64(referenceId);
|
|
573
|
+
if (referencedEntityId === IModel.repositoryModelId ||
|
|
574
|
+
referencedEntityId === IModel.dictionaryId ||
|
|
609
575
|
referencedEntityId === "0xe") {
|
|
610
576
|
continue;
|
|
611
577
|
}
|
|
612
578
|
if (allReferencesExist &&
|
|
613
|
-
!
|
|
579
|
+
!EntityReferences.isValid(await this.context.findTargetEntityId(referenceId))) {
|
|
614
580
|
// if we care about references existing then we cannot return early and must check all other references.
|
|
615
581
|
if (this._options.danglingReferencesBehavior === "ignore") {
|
|
616
582
|
return false;
|
|
@@ -633,10 +599,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
633
599
|
const found = await this._cloneContext.existenceCache.existsAll(this.sourceDb, referenceIds);
|
|
634
600
|
for (const referenceId of referenceIds) {
|
|
635
601
|
if (!found.has(referenceId)) {
|
|
636
|
-
|
|
602
|
+
ITwinError.throwError({
|
|
637
603
|
iTwinErrorId: {
|
|
638
|
-
scope:
|
|
639
|
-
key:
|
|
604
|
+
scope: IModelTransformerErrorScope,
|
|
605
|
+
key: IModelTransformerError.DanglingReference,
|
|
640
606
|
},
|
|
641
607
|
message: [
|
|
642
608
|
`Found a reference to an element "${referenceId}" that doesn't exist while looking for references of "${entity.id}".`,
|
|
@@ -655,11 +621,11 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
655
621
|
*/
|
|
656
622
|
async processElement(sourceElementId) {
|
|
657
623
|
await this.initialize();
|
|
658
|
-
if (sourceElementId ===
|
|
659
|
-
|
|
624
|
+
if (sourceElementId === IModel.rootSubjectId) {
|
|
625
|
+
ITwinError.throwError({
|
|
660
626
|
iTwinErrorId: {
|
|
661
|
-
scope:
|
|
662
|
-
key:
|
|
627
|
+
scope: IModelTransformerErrorScope,
|
|
628
|
+
key: IModelTransformerError.RootSubjectNotProcessable,
|
|
663
629
|
},
|
|
664
630
|
message: "The root Subject should not be directly imported",
|
|
665
631
|
});
|
|
@@ -690,7 +656,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
690
656
|
*/
|
|
691
657
|
async preExportElement(sourceElement) {
|
|
692
658
|
if (!this.hasElementChanged(sourceElement)) {
|
|
693
|
-
|
|
659
|
+
Logger.logTrace(loggerCategory, `Skipping unchanged element (${sourceElement.id}, ${sourceElement.getDisplayLabel()}).`);
|
|
694
660
|
return;
|
|
695
661
|
}
|
|
696
662
|
const elemClass = sourceElement.constructor;
|
|
@@ -700,18 +666,18 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
700
666
|
const referenceType = elemClass.requiredReferenceKeyTypeMap[referenceKey];
|
|
701
667
|
// For now we just consider all required references to be elements (as they are in biscore), and do not support
|
|
702
668
|
// entities that refuse to be inserted without a different kind of entity (e.g. aspect or relationship) first being inserted
|
|
703
|
-
|
|
704
|
-
referenceType ===
|
|
669
|
+
assert(referenceType === ConcreteEntityTypes.Element ||
|
|
670
|
+
referenceType === ConcreteEntityTypes.Model);
|
|
705
671
|
return mapId64(idContainer, (id) => {
|
|
706
|
-
if (id ===
|
|
672
|
+
if (id === Id64.invalid || id === IModel.rootSubjectId)
|
|
707
673
|
return undefined; // not allowed to directly export the root subject
|
|
708
674
|
if (!this.context.isBetweenIModels) {
|
|
709
675
|
// Within the same iModel, can use existing DefinitionElements without remapping
|
|
710
676
|
// This is relied upon by the TemplateModelCloner
|
|
711
677
|
// TODO: extract this out to only be in the TemplateModelCloner
|
|
712
|
-
const asDefinitionElem = this.sourceDb.elements.tryGetElement(id,
|
|
678
|
+
const asDefinitionElem = this.sourceDb.elements.tryGetElement(id, DefinitionElement);
|
|
713
679
|
if (asDefinitionElem &&
|
|
714
|
-
!(asDefinitionElem instanceof
|
|
680
|
+
!(asDefinitionElem instanceof RecipeDefinitionElement)) {
|
|
715
681
|
this.context.remapElement(id, id);
|
|
716
682
|
}
|
|
717
683
|
}
|
|
@@ -720,7 +686,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
720
686
|
if (sourceReferenceId === undefined)
|
|
721
687
|
return false;
|
|
722
688
|
const referenceInTargetId = this.context.findTargetElementId(sourceReferenceId);
|
|
723
|
-
const isInTarget =
|
|
689
|
+
const isInTarget = Id64.isValid(referenceInTargetId);
|
|
724
690
|
return !isInTarget;
|
|
725
691
|
});
|
|
726
692
|
})
|
|
@@ -761,7 +727,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
761
727
|
if (accepted)
|
|
762
728
|
await this.findExistingTargetElement(reference, await this.onTransformElement(reference));
|
|
763
729
|
}
|
|
764
|
-
if (
|
|
730
|
+
if (Id64.isValid(this.context.findTargetElementId(referenceId)))
|
|
765
731
|
return;
|
|
766
732
|
let message;
|
|
767
733
|
if (referenceChanged)
|
|
@@ -770,10 +736,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
770
736
|
message = `Element ${elementId} requires unchanged element ${referenceId}, which is not in the target iModel. Change processing does not insert unchanged elements; to insert element ${referenceId}, add it in addCustomChanges.`;
|
|
771
737
|
else
|
|
772
738
|
message = `Element ${elementId} requires element ${referenceId}, which the export filter rejects. Accept element ${referenceId}, or reject element ${elementId} and every element that requires it.`;
|
|
773
|
-
|
|
739
|
+
ITwinError.throwError({
|
|
774
740
|
iTwinErrorId: {
|
|
775
|
-
scope:
|
|
776
|
-
key:
|
|
741
|
+
scope: IModelTransformerErrorScope,
|
|
742
|
+
key: IModelTransformerError.DependencyMappingMissing,
|
|
777
743
|
},
|
|
778
744
|
message,
|
|
779
745
|
});
|
|
@@ -786,27 +752,27 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
786
752
|
if (this.context.isBetweenIModels &&
|
|
787
753
|
sourceElement.federationGuid !== undefined) {
|
|
788
754
|
const targetElementId = this.targetDb.elements.getIdFromFederationGuid(sourceElement.federationGuid);
|
|
789
|
-
if (targetElementId !== undefined &&
|
|
755
|
+
if (targetElementId !== undefined && Id64.isValid(targetElementId)) {
|
|
790
756
|
this.context.remapElement(sourceElement.id, targetElementId); // record that the targetElement was found
|
|
791
757
|
return targetElementId;
|
|
792
758
|
}
|
|
793
759
|
}
|
|
794
760
|
// check by Code as long as the CodeScope is valid (invalid means a missing reference so not worth checking)
|
|
795
|
-
if (!
|
|
796
|
-
return
|
|
761
|
+
if (!Id64.isValidId64(targetElementProps.code.scope))
|
|
762
|
+
return Id64.invalid;
|
|
797
763
|
// respond the same way to undefined code value as the @see Code class, but don't use that class because it trims
|
|
798
764
|
// whitespace from the value, and there are iModels out there with untrimmed whitespace that we ought not to trim
|
|
799
765
|
targetElementProps.code.value = targetElementProps.code.value ?? "";
|
|
800
766
|
// empty code values are stored as NULL and are never unique, so they cannot identify an existing target element
|
|
801
|
-
if (
|
|
802
|
-
return
|
|
767
|
+
if (Code.isEmpty(targetElementProps.code))
|
|
768
|
+
return Id64.invalid;
|
|
803
769
|
const maybeTargetElementId = this.queryElementIdByCode(this.targetDb, targetElementProps.code);
|
|
804
770
|
if (maybeTargetElementId === undefined)
|
|
805
|
-
return
|
|
771
|
+
return Id64.invalid;
|
|
806
772
|
const maybeTargetElem = this.targetDb.elements.getElement(maybeTargetElementId);
|
|
807
773
|
if (maybeTargetElem.classFullName !== targetElementProps.classFullName) {
|
|
808
|
-
targetElementProps.code =
|
|
809
|
-
return
|
|
774
|
+
targetElementProps.code = Code.createEmpty(); // clear out invalid code
|
|
775
|
+
return Id64.invalid;
|
|
810
776
|
}
|
|
811
777
|
// ensure code remapping doesn't change the target class
|
|
812
778
|
this.context.remapElement(sourceElement.id, maybeTargetElementId); // record that the targetElement was found by Code
|
|
@@ -815,12 +781,12 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
815
781
|
}
|
|
816
782
|
async getElemTransformState(elementId) {
|
|
817
783
|
const dbHasModel = async (db, id) => {
|
|
818
|
-
const maybeModelId =
|
|
784
|
+
const maybeModelId = EntityReferences.fromEntityType(id, ConcreteEntityTypes.Model);
|
|
819
785
|
return this._cloneContext.existenceCache.exists(db, maybeModelId);
|
|
820
786
|
};
|
|
821
787
|
const isSubModeled = await dbHasModel(this.sourceDb, elementId);
|
|
822
788
|
const idOfElemInTarget = this.context.findTargetElementId(elementId);
|
|
823
|
-
const isElemInTarget =
|
|
789
|
+
const isElemInTarget = Id64.invalid !== idOfElemInTarget;
|
|
824
790
|
const needsModelImport = isSubModeled &&
|
|
825
791
|
(!isElemInTarget || !(await dbHasModel(this.targetDb, idOfElemInTarget)));
|
|
826
792
|
return { needsElemImport: !isElemInTarget, needsModelImport };
|
|
@@ -833,25 +799,25 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
833
799
|
// and the cached ECSQL API (withPreparedStatement) is deprecated. Results match the ECSQL query because CodeValue
|
|
834
800
|
// is COLLATE NOCASE, ix_bis_Element_Code is unique, and the primary connection sees uncommitted target inserts.
|
|
835
801
|
queryElementIdByCode(iModel, code) {
|
|
836
|
-
if (
|
|
837
|
-
|
|
802
|
+
if (Id64.isInvalid(code.spec))
|
|
803
|
+
ITwinError.throwError({
|
|
838
804
|
iTwinErrorId: {
|
|
839
|
-
scope:
|
|
840
|
-
key:
|
|
805
|
+
scope: IModelTransformerErrorScope,
|
|
806
|
+
key: IModelTransformerError.InvalidCode,
|
|
841
807
|
},
|
|
842
808
|
message: "Invalid CodeSpec",
|
|
843
809
|
});
|
|
844
810
|
if (code.value === undefined)
|
|
845
|
-
|
|
811
|
+
ITwinError.throwError({
|
|
846
812
|
iTwinErrorId: {
|
|
847
|
-
scope:
|
|
848
|
-
key:
|
|
813
|
+
scope: IModelTransformerErrorScope,
|
|
814
|
+
key: IModelTransformerError.InvalidCode,
|
|
849
815
|
},
|
|
850
816
|
message: "Invalid Code",
|
|
851
817
|
});
|
|
852
818
|
return iModel.withPreparedSqliteStatement("SELECT Id FROM bis_Element WHERE CodeSpecId=? AND CodeScopeId=? AND CodeValue=?", (stmt) => {
|
|
853
819
|
stmt.bindId(1, code.spec);
|
|
854
|
-
stmt.bindId(2,
|
|
820
|
+
stmt.bindId(2, Id64.fromString(code.scope));
|
|
855
821
|
stmt.bindString(3, code.value);
|
|
856
822
|
return stmt.nextRow() ? stmt.getValueId(0) : undefined;
|
|
857
823
|
});
|
|
@@ -861,7 +827,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
861
827
|
*/
|
|
862
828
|
async onExportElement(sourceElement) {
|
|
863
829
|
this.markSourceEntityExists(sourceElement);
|
|
864
|
-
let targetElementId =
|
|
830
|
+
let targetElementId = Id64.invalid;
|
|
865
831
|
let targetElementProps;
|
|
866
832
|
if (this._options.wasSourceIModelCopiedToTarget) {
|
|
867
833
|
targetElementId = sourceElement.id;
|
|
@@ -873,27 +839,27 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
873
839
|
targetElementProps = await this.onTransformElement(sourceElement);
|
|
874
840
|
}
|
|
875
841
|
// if an existing remapping was not yet found, check by FederationGuid and then by Code
|
|
876
|
-
if (!
|
|
842
|
+
if (!Id64.isValid(targetElementId))
|
|
877
843
|
targetElementId = await this.findExistingTargetElement(sourceElement, targetElementProps);
|
|
878
844
|
if (!this.hasElementChanged(sourceElement)) {
|
|
879
|
-
|
|
845
|
+
Logger.logTrace(loggerCategory, `Skipping unchanged element (${sourceElement.id}, ${sourceElement.getDisplayLabel()}).`);
|
|
880
846
|
return;
|
|
881
847
|
}
|
|
882
848
|
if (!(await this.doAllReferencesExistInTarget(sourceElement))) {
|
|
883
849
|
this._partiallyCommittedElementIds.add(sourceElement.id);
|
|
884
850
|
}
|
|
885
851
|
// targetElementId will be valid (indicating update) or undefined (indicating insert)
|
|
886
|
-
targetElementProps.id =
|
|
852
|
+
targetElementProps.id = Id64.isValid(targetElementId)
|
|
887
853
|
? targetElementId
|
|
888
854
|
: undefined;
|
|
889
855
|
if (this._options.preserveElementIdsForFiltering) {
|
|
890
|
-
const isValid =
|
|
856
|
+
const isValid = Id64.isValid(targetElementId);
|
|
891
857
|
if (isValid && targetElementId !== sourceElement.id) {
|
|
892
858
|
// Element found with different id
|
|
893
|
-
|
|
859
|
+
ITwinError.throwError({
|
|
894
860
|
iTwinErrorId: {
|
|
895
|
-
scope:
|
|
896
|
-
key:
|
|
861
|
+
scope: IModelTransformerErrorScope,
|
|
862
|
+
key: IModelTransformerError.ElementIdNotPreservable,
|
|
897
863
|
},
|
|
898
864
|
message: `Element id(${sourceElement.id}) cannot be preserved. Found a different mapping(${targetElementId}) from source element`,
|
|
899
865
|
});
|
|
@@ -907,10 +873,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
907
873
|
// if we don't find mapping for source element in target(invalid) but another element with source id exists in target
|
|
908
874
|
if (sourceInTargetElemProps) {
|
|
909
875
|
// Element id is already taken by another element
|
|
910
|
-
|
|
876
|
+
ITwinError.throwError({
|
|
911
877
|
iTwinErrorId: {
|
|
912
|
-
scope:
|
|
913
|
-
key:
|
|
878
|
+
scope: IModelTransformerErrorScope,
|
|
879
|
+
key: IModelTransformerError.ElementIdNotPreservable,
|
|
914
880
|
},
|
|
915
881
|
message: `Element id(${sourceElement.id}) cannot be preserved. An unrelated element in the target already uses id: ${sourceElement.id}`,
|
|
916
882
|
});
|
|
@@ -929,7 +895,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
929
895
|
}
|
|
930
896
|
this.context.remapElement(sourceElement.id, targetElementProps.id);
|
|
931
897
|
if (this.sourceDb === this.targetDb) {
|
|
932
|
-
this._cloneContext.existenceCache.markExists(this.targetDb,
|
|
898
|
+
this._cloneContext.existenceCache.markExists(this.targetDb, EntityReferences.fromEntityType(targetElementProps.id, ConcreteEntityTypes.Element));
|
|
933
899
|
}
|
|
934
900
|
// the transformer does not currently 'split' or 'join' any elements, therefore, it does not
|
|
935
901
|
// insert external source aspects because federation guids are sufficient for this.
|
|
@@ -947,7 +913,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
947
913
|
: sourceElement.federationGuid;
|
|
948
914
|
if (!provenance) {
|
|
949
915
|
const aspectProps = await this.initElementProvenance(sourceElement.id, targetElementProps.id);
|
|
950
|
-
const foundEsaProps = await
|
|
916
|
+
const foundEsaProps = await ProvenanceManager.queryScopeExternalSourceAspect(provenanceDb, aspectProps);
|
|
951
917
|
if (foundEsaProps === undefined)
|
|
952
918
|
aspectProps.id = provenanceEditTxn.insertAspect(aspectProps);
|
|
953
919
|
else {
|
|
@@ -963,7 +929,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
963
929
|
const targetElementIds = new Set();
|
|
964
930
|
for (const sourceElementId of sourceElementIds) {
|
|
965
931
|
const targetElementId = this.context.findTargetElementId(sourceElementId);
|
|
966
|
-
if (
|
|
932
|
+
if (Id64.isValidId64(targetElementId) &&
|
|
967
933
|
!this._targetElementIdsRemappedByCode.has(targetElementId)) {
|
|
968
934
|
targetElementIds.add(targetElementId);
|
|
969
935
|
}
|
|
@@ -976,11 +942,11 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
976
942
|
async onExportModel(sourceModel) {
|
|
977
943
|
this.markSourceEntityExists(sourceModel);
|
|
978
944
|
if (this._options.skipPropagateChangesToRootElements &&
|
|
979
|
-
|
|
945
|
+
IModel.repositoryModelId === sourceModel.id)
|
|
980
946
|
return; // The RepositoryModel should not be directly imported
|
|
981
947
|
const targetModeledElementId = this.context.findTargetElementId(sourceModel.id);
|
|
982
948
|
// there can only be one repositoryModel per database, so ignore the repo model on remapped subjects
|
|
983
|
-
const isRemappedRootSubject = sourceModel.id ===
|
|
949
|
+
const isRemappedRootSubject = sourceModel.id === IModel.repositoryModelId &&
|
|
984
950
|
targetModeledElementId !== sourceModel.id;
|
|
985
951
|
if (isRemappedRootSubject)
|
|
986
952
|
return;
|
|
@@ -989,7 +955,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
989
955
|
if (targetModelProps.id === undefined) {
|
|
990
956
|
throw new Error("targetModelProps.id should be assigned by now");
|
|
991
957
|
}
|
|
992
|
-
this._cloneContext.existenceCache.markExists(this.targetDb,
|
|
958
|
+
this._cloneContext.existenceCache.markExists(this.targetDb, EntityReferences.fromEntityType(targetModelProps.id, ConcreteEntityTypes.Model));
|
|
993
959
|
this._targetModelsImportedInCurrentTransform.add(targetModelProps.id);
|
|
994
960
|
}
|
|
995
961
|
/** Override of [IModelExportHandler.onDeleteModel]($transformer) that is called when [IModelExporter]($transformer) detects that a [Model]($backend) has been deleted from the source iModel. */
|
|
@@ -998,13 +964,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
998
964
|
// - If only the model is deleted, [[initFromExternalSourceAspects]] will have already remapped the underlying element since it still exists.
|
|
999
965
|
// - If both were deleted, [[remapDeletedSourceEntities]] will find and remap the deleted element making this operation valid
|
|
1000
966
|
const targetModelId = this.context.findTargetElementId(sourceModelId);
|
|
1001
|
-
if (!
|
|
967
|
+
if (!Id64.isValidId64(targetModelId))
|
|
1002
968
|
return;
|
|
1003
969
|
// This handles cases where model with a partition element was remapped to
|
|
1004
970
|
// new element by code value after recreation.
|
|
1005
971
|
if (this._targetElementIdsRemappedByCode.has(targetModelId) &&
|
|
1006
972
|
this._targetModelsImportedInCurrentTransform.has(targetModelId)) {
|
|
1007
|
-
|
|
973
|
+
Logger.logTrace(loggerCategory, `Skipping delete operation for model (source id: ${sourceModelId}) because the target model (id: ${targetModelId}) was remapped by Code and re-imported during this transformation pass.`);
|
|
1008
974
|
return;
|
|
1009
975
|
}
|
|
1010
976
|
const sql = `
|
|
@@ -1017,7 +983,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1017
983
|
WHERE ECInstanceId=:targetModelId
|
|
1018
984
|
`;
|
|
1019
985
|
if (this.exporter.sourceDbChanges?.element.deleteIds.has(sourceModelId)) {
|
|
1020
|
-
const params = new
|
|
986
|
+
const params = new QueryBinder().bindId("targetModelId", targetModelId);
|
|
1021
987
|
const reader = this.targetDb.createQueryReader(sql, params, {
|
|
1022
988
|
usePrimaryConn: true,
|
|
1023
989
|
});
|
|
@@ -1033,9 +999,9 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1033
999
|
await this.importer.deleteModel(targetModelId);
|
|
1034
1000
|
}
|
|
1035
1001
|
catch (error) {
|
|
1036
|
-
const isDeletionProhibitedErr = error instanceof
|
|
1037
|
-
(error.errorNumber ===
|
|
1038
|
-
error.errorNumber ===
|
|
1002
|
+
const isDeletionProhibitedErr = error instanceof IModelError &&
|
|
1003
|
+
(error.errorNumber === IModelStatus.DeletionProhibited ||
|
|
1004
|
+
error.errorNumber === IModelStatus.ForeignKeyConstraint);
|
|
1039
1005
|
if (!isDeletionProhibitedErr)
|
|
1040
1006
|
throw error;
|
|
1041
1007
|
// Models are processed before elements, but a definition model cannot be deleted while it contains elements.
|
|
@@ -1067,7 +1033,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1067
1033
|
* @note This method is called from [[process]], so it only needs to be called directly when processing a subset of an iModel.
|
|
1068
1034
|
* @note After composing subset processing calls, call [[IModelImporter.finalize]] before saving target changes.
|
|
1069
1035
|
*/
|
|
1070
|
-
async processModelContents(sourceModelId, targetModelId, elementClassFullName =
|
|
1036
|
+
async processModelContents(sourceModelId, targetModelId, elementClassFullName = Element.classFullName) {
|
|
1071
1037
|
await this.initialize();
|
|
1072
1038
|
this.targetDb.models.getModel(targetModelId); // throws if Model does not exist
|
|
1073
1039
|
this.context.remapElement(sourceModelId, targetModelId); // set remapping in case importModelContents is called directly
|
|
@@ -1077,22 +1043,22 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1077
1043
|
async processSubjectSubModels(sourceSubjectId) {
|
|
1078
1044
|
await this.initialize();
|
|
1079
1045
|
// import DefinitionModels first
|
|
1080
|
-
const childDefinitionPartitionSql = `SELECT ECInstanceId FROM ${
|
|
1081
|
-
const params = new
|
|
1046
|
+
const childDefinitionPartitionSql = `SELECT ECInstanceId FROM ${DefinitionPartition.classFullName} WHERE Parent.Id=:subjectId`;
|
|
1047
|
+
const params = new QueryBinder().bindId("subjectId", sourceSubjectId);
|
|
1082
1048
|
for await (const row of this.sourceDb.createQueryReader(childDefinitionPartitionSql, params, { usePrimaryConn: true })) {
|
|
1083
1049
|
await this.processModel(row.id);
|
|
1084
1050
|
}
|
|
1085
1051
|
// import other partitions next
|
|
1086
|
-
const childPartitionSql = `SELECT ECInstanceId FROM ${
|
|
1052
|
+
const childPartitionSql = `SELECT ECInstanceId FROM ${InformationPartitionElement.classFullName} WHERE Parent.Id=:subjectId`;
|
|
1087
1053
|
for await (const row of this.sourceDb.createQueryReader(childPartitionSql, params, { usePrimaryConn: true })) {
|
|
1088
1054
|
const modelId = row.id;
|
|
1089
1055
|
const model = this.sourceDb.models.getModel(modelId);
|
|
1090
|
-
if (!(model instanceof
|
|
1056
|
+
if (!(model instanceof DefinitionModel)) {
|
|
1091
1057
|
await this.processModel(modelId);
|
|
1092
1058
|
}
|
|
1093
1059
|
}
|
|
1094
1060
|
// recurse into child Subjects
|
|
1095
|
-
const childSubjectSql = `SELECT ECInstanceId FROM ${
|
|
1061
|
+
const childSubjectSql = `SELECT ECInstanceId FROM ${Subject.classFullName} WHERE Parent.Id=:subjectId`;
|
|
1096
1062
|
for await (const row of this.sourceDb.createQueryReader(childSubjectSql, params, { usePrimaryConn: true })) {
|
|
1097
1063
|
await this.processSubjectSubModels(row.id);
|
|
1098
1064
|
}
|
|
@@ -1112,10 +1078,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1112
1078
|
};
|
|
1113
1079
|
targetModelProps.id = targetModeledElementId;
|
|
1114
1080
|
if (targetModelProps.parentModel === undefined) {
|
|
1115
|
-
|
|
1081
|
+
ITwinError.throwError({
|
|
1116
1082
|
iTwinErrorId: {
|
|
1117
|
-
scope:
|
|
1118
|
-
key:
|
|
1083
|
+
scope: IModelTransformerErrorScope,
|
|
1084
|
+
key: IModelTransformerError.ParentModelRequired,
|
|
1119
1085
|
},
|
|
1120
1086
|
message: "targetElementProps must have a defined parentModel",
|
|
1121
1087
|
});
|
|
@@ -1132,8 +1098,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1132
1098
|
});
|
|
1133
1099
|
// TODO: ignore if we remove change cache usage
|
|
1134
1100
|
if (!this._options.noDetachChangeCache) {
|
|
1135
|
-
if (
|
|
1136
|
-
|
|
1101
|
+
if (ChangeSummaryManager.isChangeCacheAttached(this.sourceDb))
|
|
1102
|
+
ChangeSummaryManager.detachChangeCache(this.sourceDb);
|
|
1137
1103
|
}
|
|
1138
1104
|
this.setCodeValueBehavior("trim-unicode-whitespace");
|
|
1139
1105
|
}
|
|
@@ -1165,7 +1131,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1165
1131
|
const targetRelationshipProps = this.onTransformRelationship(sourceRelationship);
|
|
1166
1132
|
const targetRelationshipInstanceId = await this.importer.importRelationship(targetRelationshipProps);
|
|
1167
1133
|
if (this._pendingRelationshipDeleteTargets.size > 0 &&
|
|
1168
|
-
|
|
1134
|
+
Id64.isValid(targetRelationshipInstanceId) &&
|
|
1169
1135
|
(this._pendingRelationshipDeleteTargets.has(targetRelationshipInstanceId) ||
|
|
1170
1136
|
this._pendingRelationshipDeleteTargets.has(relationshipEndpointsKey(targetRelationshipProps.sourceId, targetRelationshipProps.targetId)))) {
|
|
1171
1137
|
this._reimportedTargetRelationshipIds.add(targetRelationshipInstanceId);
|
|
@@ -1173,7 +1139,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1173
1139
|
const provenanceDb = await this.getProvenanceDb();
|
|
1174
1140
|
const provenanceEditTxn = await this._provenanceManager.getProvenanceEditTxn();
|
|
1175
1141
|
if (!this._options.noProvenance &&
|
|
1176
|
-
|
|
1142
|
+
Id64.isValid(targetRelationshipInstanceId)) {
|
|
1177
1143
|
const needsEsaProvenance = this._options.forceExternalSourceAspectProvenance ||
|
|
1178
1144
|
!this.relationshipEndpointsHaveFedGuids(sourceRelationship, endpointFedGuids);
|
|
1179
1145
|
if (needsEsaProvenance) {
|
|
@@ -1181,7 +1147,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1181
1147
|
sourceRelSourceElementId: sourceRelationship.sourceId,
|
|
1182
1148
|
targetRelSourceElementId: targetRelationshipProps.sourceId,
|
|
1183
1149
|
});
|
|
1184
|
-
const foundEsaProps = await
|
|
1150
|
+
const foundEsaProps = await ProvenanceManager.queryScopeExternalSourceAspect(provenanceDb, aspectProps);
|
|
1185
1151
|
// onExportRelationship doesn't need to call updateAspect if esaProps were found, because relationship provenance doesn't have the same concept of a version as element provenance (which uses last mod time on the elements).
|
|
1186
1152
|
if (undefined === foundEsaProps) {
|
|
1187
1153
|
aspectProps.id = provenanceEditTxn.insertAspect(aspectProps);
|
|
@@ -1201,11 +1167,11 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1201
1167
|
* This override propagates the delete to the target iModel via [IModelImporter.deleteRelationship]($transformer).
|
|
1202
1168
|
*/
|
|
1203
1169
|
async onDeleteRelationship(sourceRelInstanceId) {
|
|
1204
|
-
(
|
|
1170
|
+
nodeAssert(this._deletedSourceRelationshipData, "should be defined at initialization by now");
|
|
1205
1171
|
const deletedRelData = this._deletedSourceRelationshipData.get(sourceRelInstanceId);
|
|
1206
1172
|
if (!deletedRelData) {
|
|
1207
1173
|
// this can occur if both the source and target deleted it
|
|
1208
|
-
|
|
1174
|
+
Logger.logWarning(loggerCategory, "tried to delete a relationship that wasn't in change data");
|
|
1209
1175
|
return;
|
|
1210
1176
|
}
|
|
1211
1177
|
const id = deletedRelData.relId ??
|
|
@@ -1215,7 +1181,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1215
1181
|
})?.id;
|
|
1216
1182
|
if (id && this._reimportedTargetRelationshipIds.has(id)) {
|
|
1217
1183
|
// The source relationship was recreated with the same endpoints and already imported into this target relationship.
|
|
1218
|
-
|
|
1184
|
+
Logger.logTrace(loggerCategory, `Skipping delete of target relationship ${id} because source relationship ${sourceRelInstanceId} was recreated`);
|
|
1219
1185
|
}
|
|
1220
1186
|
else if (id) {
|
|
1221
1187
|
await this.importer.deleteRelationship({
|
|
@@ -1229,7 +1195,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1229
1195
|
}
|
|
1230
1196
|
catch (error) {
|
|
1231
1197
|
// This aspect may no longer exist if it was deleted at some other point during the transformation. This is fine.
|
|
1232
|
-
if (error.errorNumber ===
|
|
1198
|
+
if (error.errorNumber === IModelStatus.NotFound)
|
|
1233
1199
|
return;
|
|
1234
1200
|
throw error;
|
|
1235
1201
|
}
|
|
@@ -1246,12 +1212,12 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1246
1212
|
targetRelationshipProps.targetId = this.context.findTargetElementId(sourceRelationship.targetId);
|
|
1247
1213
|
// TODO: move to cloneRelationship in IModelCloneContext
|
|
1248
1214
|
const relationshipClass = sourceRelationship.iModel.schemaContext.getSchemaItemSync(sourceRelationship.schemaItemKey, ECSchemaMetaData.RelationshipClass);
|
|
1249
|
-
|
|
1215
|
+
assert(relationshipClass !== undefined, `Cannot get metadata for ${sourceRelationship.classFullName}.`);
|
|
1250
1216
|
for (const property of relationshipClass.getPropertiesSync()) {
|
|
1251
1217
|
const propertyName = property.name;
|
|
1252
1218
|
if (property.isPrimitive() && "Id" === property.extendedTypeName) {
|
|
1253
|
-
targetRelationshipProps[
|
|
1254
|
-
this.context.findTargetElementId(sourceRelationship.asAny[
|
|
1219
|
+
targetRelationshipProps[ECJsNames.toJsName(propertyName)] =
|
|
1220
|
+
this.context.findTargetElementId(sourceRelationship.asAny[ECJsNames.toJsName(propertyName)]);
|
|
1255
1221
|
}
|
|
1256
1222
|
}
|
|
1257
1223
|
return targetRelationshipProps;
|
|
@@ -1259,7 +1225,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1259
1225
|
async shouldExportElementAspect(aspect) {
|
|
1260
1226
|
// An aspect cannot be exported when its owner has no source-to-target
|
|
1261
1227
|
// mapping.
|
|
1262
|
-
return this.context.findTargetElementId(aspect.element.id) !==
|
|
1228
|
+
return this.context.findTargetElementId(aspect.element.id) !== Id64.invalid;
|
|
1263
1229
|
}
|
|
1264
1230
|
async prepareElementAspects(excludedElementAspectClassFullNames, elementIds) {
|
|
1265
1231
|
if (!this.exporter.visitElements)
|
|
@@ -1269,7 +1235,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1269
1235
|
const targetElementIds = new Set();
|
|
1270
1236
|
for (const sourceElementId of elementIds) {
|
|
1271
1237
|
const targetElementId = this.context.findTargetElementId(sourceElementId);
|
|
1272
|
-
if (
|
|
1238
|
+
if (Id64.isValid(targetElementId)) {
|
|
1273
1239
|
targetElementIds.add(targetElementId);
|
|
1274
1240
|
}
|
|
1275
1241
|
}
|
|
@@ -1299,7 +1265,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1299
1265
|
}
|
|
1300
1266
|
}
|
|
1301
1267
|
const targetIds = await this.importer.importElementMultiAspects(await Promise.all(targetAspectPropsArray), (a) => {
|
|
1302
|
-
const isExternalSourceAspectFromTransformer = a instanceof
|
|
1268
|
+
const isExternalSourceAspectFromTransformer = a instanceof ExternalSourceAspect &&
|
|
1303
1269
|
a.scope?.id === this.targetScopeElementId;
|
|
1304
1270
|
return (!this._options.includeSourceProvenance ||
|
|
1305
1271
|
!isExternalSourceAspectFromTransformer);
|
|
@@ -1318,7 +1284,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1318
1284
|
return targetElementAspectProps;
|
|
1319
1285
|
}
|
|
1320
1286
|
/** The directory where schemas will be exported, a random temporary directory */
|
|
1321
|
-
_schemaExportDir = path.join(
|
|
1287
|
+
_schemaExportDir = path.join(KnownLocations.tmpdir, Guid.createValue());
|
|
1322
1288
|
/** Override of [IModelExportHandler.shouldExportSchema]($transformer) that is called to determine if a schema should be exported
|
|
1323
1289
|
* @note the default behavior doesn't import schemas older than those already in the target
|
|
1324
1290
|
*/
|
|
@@ -1326,7 +1292,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1326
1292
|
const versionInTarget = this.targetDb.querySchemaVersion(schemaKey.name);
|
|
1327
1293
|
if (versionInTarget === undefined)
|
|
1328
1294
|
return true;
|
|
1329
|
-
return Semver.gt(`${schemaKey.version.read}.${schemaKey.version.write}.${schemaKey.version.minor}`,
|
|
1295
|
+
return Semver.gt(`${schemaKey.version.read}.${schemaKey.version.write}.${schemaKey.version.minor}`, Schema.toSemverString(versionInTarget));
|
|
1330
1296
|
}
|
|
1331
1297
|
/** Serialize a source schema to the temporary directory used by [[processSchemas]].
|
|
1332
1298
|
* @returns A path to the serialized schema file.
|
|
@@ -1342,7 +1308,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1342
1308
|
* It is more efficient to process *data* changes after the schema changes have been saved.
|
|
1343
1309
|
*/
|
|
1344
1310
|
async processSchemas(options) {
|
|
1345
|
-
return this._schemaProcessingCoordinator.process(options?.strategy ?? new
|
|
1311
|
+
return this._schemaProcessingCoordinator.process(options?.strategy ?? new NewerVersionSchemaImportStrategy());
|
|
1346
1312
|
}
|
|
1347
1313
|
/** Cause all fonts to be exported from the source iModel and imported into the target iModel.
|
|
1348
1314
|
* @note This method is called from [[process]], so it only needs to be called directly when processing a subset of an iModel.
|
|
@@ -1385,8 +1351,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1385
1351
|
*/
|
|
1386
1352
|
async processSubject(sourceSubjectId, targetSubjectId) {
|
|
1387
1353
|
await this.initialize();
|
|
1388
|
-
this.sourceDb.elements.getElement(sourceSubjectId,
|
|
1389
|
-
this.targetDb.elements.getElement(targetSubjectId,
|
|
1354
|
+
this.sourceDb.elements.getElement(sourceSubjectId, Subject); // throws if sourceSubjectId is not a Subject
|
|
1355
|
+
this.targetDb.elements.getElement(targetSubjectId, Subject); // throws if targetSubjectId is not a Subject
|
|
1390
1356
|
this.context.remapElement(sourceSubjectId, targetSubjectId);
|
|
1391
1357
|
await this.processScopedElementExport(async () => {
|
|
1392
1358
|
await this.processChildElements(sourceSubjectId);
|
|
@@ -1429,7 +1395,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1429
1395
|
: undefined);
|
|
1430
1396
|
if (changedInstanceIds !== undefined) {
|
|
1431
1397
|
// The caller supplied changed IDs, so only deletion metadata is read.
|
|
1432
|
-
this._deletionBatches = await
|
|
1398
|
+
this._deletionBatches = await ChangesetScanner.scan(this.sourceDb, await ChangesetScanner.download(this.sourceDb, ranges), {});
|
|
1433
1399
|
}
|
|
1434
1400
|
else {
|
|
1435
1401
|
const scanResult = await this.collectChanges(ranges);
|
|
@@ -1466,8 +1432,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1466
1432
|
* the changesets to find deletion records.
|
|
1467
1433
|
* @beta
|
|
1468
1434
|
*/
|
|
1469
|
-
async collectChanges(ranges, changedInstanceIds = new
|
|
1470
|
-
const deletionBatches = await
|
|
1435
|
+
async collectChanges(ranges, changedInstanceIds = new ChangedInstanceIds(this.sourceDb)) {
|
|
1436
|
+
const deletionBatches = await ChangesetScanner.scan(this.sourceDb, await ChangesetScanner.download(this.sourceDb, ranges), { changedInstanceIds });
|
|
1471
1437
|
return { changedInstanceIds, deletionBatches };
|
|
1472
1438
|
}
|
|
1473
1439
|
/**
|
|
@@ -1497,12 +1463,12 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1497
1463
|
const alreadyImportedModelInserts = new Set();
|
|
1498
1464
|
this.exporter.sourceDbChanges?.element.insertIds.forEach((insertedSourceElementId) => {
|
|
1499
1465
|
const targetElementId = this.context.findTargetElementId(insertedSourceElementId);
|
|
1500
|
-
if (
|
|
1466
|
+
if (Id64.isValid(targetElementId))
|
|
1501
1467
|
alreadyImportedElementInserts.add(targetElementId);
|
|
1502
1468
|
});
|
|
1503
1469
|
this.exporter.sourceDbChanges?.model.insertIds.forEach((insertedSourceModelId) => {
|
|
1504
1470
|
const targetModelId = this.context.findTargetElementId(insertedSourceModelId);
|
|
1505
|
-
if (
|
|
1471
|
+
if (Id64.isValid(targetModelId))
|
|
1506
1472
|
alreadyImportedModelInserts.add(targetModelId);
|
|
1507
1473
|
});
|
|
1508
1474
|
this._deletedSourceRelationshipData = new Map();
|
|
@@ -1514,7 +1480,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1514
1480
|
const deletedScopeEsaByElementId = new Map();
|
|
1515
1481
|
for (const aspect of batch.externalSourceAspects) {
|
|
1516
1482
|
if (aspect.scopeId === this.targetScopeElementId &&
|
|
1517
|
-
aspect.kind ===
|
|
1483
|
+
aspect.kind === ExternalSourceAspect.Kind.Element)
|
|
1518
1484
|
deletedScopeEsaByElementId.set(aspect.elementId, aspect);
|
|
1519
1485
|
}
|
|
1520
1486
|
const deletedFederationGuidByElementId = new Map();
|
|
@@ -1554,9 +1520,9 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1554
1520
|
if (this.sourceDb === (await this.getProvenanceDb())) {
|
|
1555
1521
|
let identifierValue;
|
|
1556
1522
|
// TODO: clarify what happens if there are multiple (e.g. elements were merged)
|
|
1557
|
-
for await (const row of this.sourceDb.createQueryReader("SELECT esa.Identifier FROM bis.ExternalSourceAspect esa WHERE Scope.Id=:scopeId AND Kind=:kind AND Element.Id=:relatedElementId LIMIT 1",
|
|
1523
|
+
for await (const row of this.sourceDb.createQueryReader("SELECT esa.Identifier FROM bis.ExternalSourceAspect esa WHERE Scope.Id=:scopeId AND Kind=:kind AND Element.Id=:relatedElementId LIMIT 1", QueryBinder.from([
|
|
1558
1524
|
this.targetScopeElementId,
|
|
1559
|
-
|
|
1525
|
+
ExternalSourceAspect.Kind.Element,
|
|
1560
1526
|
sourceId,
|
|
1561
1527
|
]), { usePrimaryConn: true })) {
|
|
1562
1528
|
identifierValue = row.Identifier;
|
|
@@ -1629,7 +1595,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1629
1595
|
if (targetId === undefined &&
|
|
1630
1596
|
this.sourceDb === (await this._provenanceManager.getProvenanceSourceDb())) {
|
|
1631
1597
|
const contextTargetId = this.context.findTargetElementId(sourceId);
|
|
1632
|
-
if (
|
|
1598
|
+
if (Id64.isValidId64(contextTargetId))
|
|
1633
1599
|
targetId = contextTargetId;
|
|
1634
1600
|
}
|
|
1635
1601
|
// Entities inserted and deleted since the last synchronization were never synced and can be safely ignored.
|
|
@@ -1666,7 +1632,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1666
1632
|
const endChangesetId = this.sourceDb.changeset.id;
|
|
1667
1633
|
const [startChangesetIndex, endChangesetIndex] = await Promise.all([startChangesetIndexOrId, endChangesetId].map(async (indexOrId) => typeof indexOrId === "number"
|
|
1668
1634
|
? indexOrId
|
|
1669
|
-
:
|
|
1635
|
+
: BriefcaseManager.queryChangeset({
|
|
1670
1636
|
iModelId: this.sourceDb.iModelId,
|
|
1671
1637
|
changeset: { id: indexOrId },
|
|
1672
1638
|
}).then((changeset) => changeset.index)));
|
|
@@ -1675,10 +1641,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1675
1641
|
?.ignoreMissingChangesetsInSynchronizations &&
|
|
1676
1642
|
startChangesetIndex !== syncVersion.index + 1 &&
|
|
1677
1643
|
syncVersion.index !== -1) {
|
|
1678
|
-
|
|
1644
|
+
ITwinError.throwError({
|
|
1679
1645
|
iTwinErrorId: {
|
|
1680
|
-
scope:
|
|
1681
|
-
key:
|
|
1646
|
+
scope: IModelTransformerErrorScope,
|
|
1647
|
+
key: IModelTransformerError.SynchronizationRangeInvalid,
|
|
1682
1648
|
},
|
|
1683
1649
|
message: `synchronization is ${missingChangesets ? "missing changesets" : ""},` +
|
|
1684
1650
|
" startChangesetId should be" +
|
|
@@ -1690,9 +1656,9 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1690
1656
|
});
|
|
1691
1657
|
}
|
|
1692
1658
|
const changesetsToSkip = await this._provenanceManager.getChangesetsToSkip();
|
|
1693
|
-
|
|
1694
|
-
this._changesetRanges =
|
|
1695
|
-
|
|
1659
|
+
Logger.logTrace(loggerCategory, `changesets to skip: ${changesetsToSkip}`);
|
|
1660
|
+
this._changesetRanges = rangesFromRangeAndSkipped(startChangesetIndex, endChangesetIndex, changesetsToSkip);
|
|
1661
|
+
Logger.logTrace(loggerCategory, `ranges: ${this._changesetRanges}`);
|
|
1696
1662
|
/** Skipping indices found in the pendingSync and pendingReverseSync arrays can leave no ranges to process. */
|
|
1697
1663
|
this._sourceChangeDataState =
|
|
1698
1664
|
this._changesetRanges.length === 0 ? "no-changes" : "has-changes";
|
|
@@ -1700,19 +1666,19 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1700
1666
|
/** Asserts that the EditTxn is active before any write operations. */
|
|
1701
1667
|
assertEditTxnActive() {
|
|
1702
1668
|
if (!this._targetEditTxn.isActive) {
|
|
1703
|
-
|
|
1669
|
+
ITwinError.throwError({
|
|
1704
1670
|
iTwinErrorId: {
|
|
1705
|
-
scope:
|
|
1706
|
-
key:
|
|
1671
|
+
scope: IModelTransformerErrorScope,
|
|
1672
|
+
key: IModelTransformerError.EditTxnNotActive,
|
|
1707
1673
|
},
|
|
1708
1674
|
message: "The target EditTxn must be started before calling process(). Call targetEditTxn.start() before invoking the transformer.",
|
|
1709
1675
|
});
|
|
1710
1676
|
}
|
|
1711
1677
|
if (this._sourceEditTxn && !this._sourceEditTxn.isActive) {
|
|
1712
|
-
|
|
1678
|
+
ITwinError.throwError({
|
|
1713
1679
|
iTwinErrorId: {
|
|
1714
|
-
scope:
|
|
1715
|
-
key:
|
|
1680
|
+
scope: IModelTransformerErrorScope,
|
|
1681
|
+
key: IModelTransformerError.EditTxnNotActive,
|
|
1716
1682
|
},
|
|
1717
1683
|
message: "The source EditTxn was provided but is not active. Call sourceEditTxn.start() before invoking the transformer.",
|
|
1718
1684
|
});
|
|
@@ -1761,20 +1727,20 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1761
1727
|
await this.exporter.elementAspectExportCoordinator.run(async () => {
|
|
1762
1728
|
if (this._options.skipPropagateChangesToRootElements) {
|
|
1763
1729
|
// The RepositoryModel and root Subject of the target iModel should not be transformed.
|
|
1764
|
-
await this.exporter.exportChildElements(
|
|
1765
|
-
await this.exporter.exportModelContents(
|
|
1766
|
-
await this.exporter.exportSubModels(
|
|
1730
|
+
await this.exporter.exportChildElements(IModel.rootSubjectId); // start below the root Subject
|
|
1731
|
+
await this.exporter.exportModelContents(IModel.repositoryModelId, Element.classFullName, true); // after the Subject hierarchy, process the other elements of the RepositoryModel
|
|
1732
|
+
await this.exporter.exportSubModels(IModel.repositoryModelId); // start below the RepositoryModel
|
|
1767
1733
|
}
|
|
1768
1734
|
else {
|
|
1769
|
-
await this.exporter.exportModel(
|
|
1735
|
+
await this.exporter.exportModel(IModel.repositoryModelId);
|
|
1770
1736
|
}
|
|
1771
1737
|
await this.completePartiallyCommittedElements();
|
|
1772
1738
|
});
|
|
1773
1739
|
await this.completePartiallyCommittedAspects();
|
|
1774
|
-
await this.exporter.exportRelationships(
|
|
1740
|
+
await this.exporter.exportRelationships(ElementRefersToElements.classFullName);
|
|
1775
1741
|
if (this._options.forceExternalSourceAspectProvenance &&
|
|
1776
1742
|
(await this.shouldDetectDeletes())) {
|
|
1777
|
-
|
|
1743
|
+
Logger.logWarning(loggerCategory, "This workflows was deprecated in v1 and is no longer supported");
|
|
1778
1744
|
}
|
|
1779
1745
|
if (this._options.optimizeGeometry)
|
|
1780
1746
|
this.importer.optimizeGeometry(this._options.optimizeGeometry);
|
|
@@ -1844,11 +1810,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1844
1810
|
}
|
|
1845
1811
|
}
|
|
1846
1812
|
}
|
|
1847
|
-
exports.IModelTransformer = IModelTransformer;
|
|
1848
1813
|
/** IModelTransformer that clones the contents of a template model.
|
|
1849
1814
|
* @beta
|
|
1850
1815
|
*/
|
|
1851
|
-
class TemplateModelCloner extends IModelTransformer {
|
|
1816
|
+
export class TemplateModelCloner extends IModelTransformer {
|
|
1852
1817
|
/** The Placement to apply to the template. */
|
|
1853
1818
|
_transform3d;
|
|
1854
1819
|
/** Accumulates the mapping of sourceElementIds to targetElementIds from the elements in the template model that were cloned. */
|
|
@@ -1858,7 +1823,7 @@ class TemplateModelCloner extends IModelTransformer {
|
|
|
1858
1823
|
* @note The expectation is that the template definitions are within the same iModel where instances will be placed.
|
|
1859
1824
|
*/
|
|
1860
1825
|
constructor(editTxn) {
|
|
1861
|
-
const target = new
|
|
1826
|
+
const target = new IModelImporter(editTxn, {
|
|
1862
1827
|
autoExtendProjectExtents: false, // autoExtendProjectExtents is intended for transformation service use cases, not template --> instance cloning
|
|
1863
1828
|
});
|
|
1864
1829
|
super({ source: editTxn.iModel, target }, { noProvenance: true }); // WIP: need to decide the proper way to handle provenance
|
|
@@ -1873,7 +1838,7 @@ class TemplateModelCloner extends IModelTransformer {
|
|
|
1873
1838
|
async placeTemplate3d(sourceTemplateModelId, targetModelId, placement) {
|
|
1874
1839
|
await this.initialize();
|
|
1875
1840
|
this.context.remapElement(sourceTemplateModelId, targetModelId);
|
|
1876
|
-
this._transform3d =
|
|
1841
|
+
this._transform3d = Transform.createOriginAndMatrix(placement.origin, placement.angles.toMatrix3d());
|
|
1877
1842
|
this._sourceIdToTargetIdMap = new Map();
|
|
1878
1843
|
await this.exporter.exportModelContents(sourceTemplateModelId);
|
|
1879
1844
|
// Note: the source --> target mapping was needed during the template model cloning phase (remapping parent/child, for example), but needs to be reset afterwards
|
|
@@ -1894,7 +1859,7 @@ class TemplateModelCloner extends IModelTransformer {
|
|
|
1894
1859
|
async placeTemplate2d(sourceTemplateModelId, targetModelId, placement) {
|
|
1895
1860
|
await this.initialize();
|
|
1896
1861
|
this.context.remapElement(sourceTemplateModelId, targetModelId);
|
|
1897
|
-
this._transform3d =
|
|
1862
|
+
this._transform3d = Transform.createOriginAndMatrix(Point3d.createFrom(placement.origin), placement.rotation);
|
|
1898
1863
|
this._sourceIdToTargetIdMap = new Map();
|
|
1899
1864
|
await this.exporter.exportModelContents(sourceTemplateModelId);
|
|
1900
1865
|
// Note: the source --> target mapping was needed during the template model cloning phase (remapping parent/child, for example), but needs to be reset afterwards
|
|
@@ -1910,27 +1875,27 @@ class TemplateModelCloner extends IModelTransformer {
|
|
|
1910
1875
|
const referenceIds = sourceElement.getReferenceIds();
|
|
1911
1876
|
for (const referenceId of referenceIds) {
|
|
1912
1877
|
// TODO: consider going through all definition elements at once and remapping them to themselves
|
|
1913
|
-
if (!
|
|
1878
|
+
if (!EntityReferences.isValid(await this.context.findTargetEntityId(referenceId))) {
|
|
1914
1879
|
if (this.context.isBetweenIModels) {
|
|
1915
|
-
|
|
1880
|
+
ITwinError.throwError({
|
|
1916
1881
|
iTwinErrorId: {
|
|
1917
|
-
scope:
|
|
1918
|
-
key:
|
|
1882
|
+
scope: IModelTransformerErrorScope,
|
|
1883
|
+
key: IModelTransformerError.DependencyMappingMissing,
|
|
1919
1884
|
},
|
|
1920
1885
|
message: `Remapping for source dependency ${referenceId} not found for target iModel`,
|
|
1921
1886
|
});
|
|
1922
1887
|
}
|
|
1923
1888
|
else {
|
|
1924
|
-
const definitionElement = this.sourceDb.elements.tryGetElement(referenceId,
|
|
1889
|
+
const definitionElement = this.sourceDb.elements.tryGetElement(referenceId, DefinitionElement);
|
|
1925
1890
|
if (definitionElement &&
|
|
1926
|
-
!(definitionElement instanceof
|
|
1891
|
+
!(definitionElement instanceof RecipeDefinitionElement)) {
|
|
1927
1892
|
this.context.remapElement(referenceId, referenceId); // when in the same iModel, can use existing DefinitionElements without remapping
|
|
1928
1893
|
}
|
|
1929
1894
|
else {
|
|
1930
|
-
|
|
1895
|
+
ITwinError.throwError({
|
|
1931
1896
|
iTwinErrorId: {
|
|
1932
|
-
scope:
|
|
1933
|
-
key:
|
|
1897
|
+
scope: IModelTransformerErrorScope,
|
|
1898
|
+
key: IModelTransformerError.DependencyMappingMissing,
|
|
1934
1899
|
},
|
|
1935
1900
|
message: `Remapping for dependency ${referenceId} not found`,
|
|
1936
1901
|
});
|
|
@@ -1939,21 +1904,20 @@ class TemplateModelCloner extends IModelTransformer {
|
|
|
1939
1904
|
}
|
|
1940
1905
|
}
|
|
1941
1906
|
const targetElementProps = await super.onTransformElement(sourceElement);
|
|
1942
|
-
targetElementProps.federationGuid =
|
|
1943
|
-
targetElementProps.code =
|
|
1944
|
-
if (sourceElement instanceof
|
|
1945
|
-
const is3d = sourceElement instanceof
|
|
1946
|
-
const placementClass = is3d ?
|
|
1907
|
+
targetElementProps.federationGuid = Guid.createValue(); // clone from template should create a new federationGuid
|
|
1908
|
+
targetElementProps.code = Code.createEmpty(); // clone from template should not maintain codes
|
|
1909
|
+
if (sourceElement instanceof GeometricElement) {
|
|
1910
|
+
const is3d = sourceElement instanceof GeometricElement3d;
|
|
1911
|
+
const placementClass = is3d ? Placement3d : Placement2d;
|
|
1947
1912
|
const placement = placementClass.fromJSON(targetElementProps.placement);
|
|
1948
1913
|
if (placement.isValid) {
|
|
1949
|
-
(
|
|
1914
|
+
nodeAssert(this._transform3d);
|
|
1950
1915
|
placement.multiplyTransform(this._transform3d);
|
|
1951
1916
|
targetElementProps.placement = placement;
|
|
1952
1917
|
}
|
|
1953
1918
|
}
|
|
1954
|
-
this._sourceIdToTargetIdMap?.set(sourceElement.id,
|
|
1919
|
+
this._sourceIdToTargetIdMap?.set(sourceElement.id, Id64.invalid); // keep track of (source) elementIds from the template model, but the target hasn't been inserted yet
|
|
1955
1920
|
return targetElementProps;
|
|
1956
1921
|
}
|
|
1957
1922
|
}
|
|
1958
|
-
exports.TemplateModelCloner = TemplateModelCloner;
|
|
1959
1923
|
//# sourceMappingURL=IModelTransformer.js.map
|