@itwin/imodel-transformer 2.0.0-dev.9 → 2.0.0-experimental.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -27
- package/lib/cjs/Algo.d.ts +0 -4
- package/lib/cjs/Algo.d.ts.map +1 -1
- package/lib/cjs/Algo.js +0 -11
- package/lib/cjs/Algo.js.map +1 -1
- package/lib/cjs/BigMap.d.ts.map +1 -1
- package/lib/cjs/BigMap.js.map +1 -1
- package/lib/cjs/BranchProvenanceInitializer.d.ts.map +1 -1
- package/lib/cjs/BranchProvenanceInitializer.js +26 -26
- package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
- package/lib/cjs/ChangedElementForest.d.ts +14 -0
- package/lib/cjs/ChangedElementForest.d.ts.map +1 -0
- package/lib/cjs/ChangedElementForest.js +86 -0
- package/lib/cjs/ChangedElementForest.js.map +1 -0
- package/lib/cjs/ChangesetScanner.d.ts +61 -0
- package/lib/cjs/ChangesetScanner.d.ts.map +1 -0
- package/lib/cjs/ChangesetScanner.js +104 -0
- package/lib/cjs/ChangesetScanner.js.map +1 -0
- package/lib/cjs/ECReferenceTypesCache.d.ts +0 -4
- package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -1
- package/lib/cjs/ECReferenceTypesCache.js +54 -102
- package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
- package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +1 -1
- package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js.map +1 -1
- package/lib/cjs/ElementAspectCleanup.d.ts +56 -0
- package/lib/cjs/ElementAspectCleanup.d.ts.map +1 -0
- package/lib/cjs/ElementAspectCleanup.js +175 -0
- package/lib/cjs/ElementAspectCleanup.js.map +1 -0
- package/lib/cjs/ElementAspectExportCoordinator.d.ts +47 -0
- package/lib/cjs/ElementAspectExportCoordinator.d.ts.map +1 -0
- package/lib/cjs/ElementAspectExportCoordinator.js +160 -0
- package/lib/cjs/ElementAspectExportCoordinator.js.map +1 -0
- package/lib/cjs/ElementAspectExportProcessor.d.ts +44 -0
- package/lib/cjs/ElementAspectExportProcessor.d.ts.map +1 -0
- package/lib/cjs/ElementAspectExportProcessor.js +152 -0
- package/lib/cjs/ElementAspectExportProcessor.js.map +1 -0
- package/lib/cjs/ElementBulkDelete.d.ts +30 -0
- package/lib/cjs/ElementBulkDelete.d.ts.map +1 -0
- package/lib/cjs/ElementBulkDelete.js +358 -0
- package/lib/cjs/ElementBulkDelete.js.map +1 -0
- package/lib/cjs/EntityExistenceCache.d.ts +43 -0
- package/lib/cjs/EntityExistenceCache.d.ts.map +1 -0
- package/lib/cjs/EntityExistenceCache.js +91 -0
- package/lib/cjs/EntityExistenceCache.js.map +1 -0
- package/lib/cjs/EntityUnifier.d.ts +7 -7
- package/lib/cjs/EntityUnifier.d.ts.map +1 -1
- package/lib/cjs/EntityUnifier.js +55 -32
- package/lib/cjs/EntityUnifier.js.map +1 -1
- package/lib/cjs/IModelCloneContext.d.ts +8 -2
- package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
- package/lib/cjs/IModelCloneContext.js +42 -12
- package/lib/cjs/IModelCloneContext.js.map +1 -1
- package/lib/cjs/IModelExporter.d.ts +143 -30
- package/lib/cjs/IModelExporter.d.ts.map +1 -1
- package/lib/cjs/IModelExporter.js +871 -172
- package/lib/cjs/IModelExporter.js.map +1 -1
- package/lib/cjs/IModelImporter.d.ts +87 -31
- package/lib/cjs/IModelImporter.d.ts.map +1 -1
- package/lib/cjs/IModelImporter.js +361 -139
- package/lib/cjs/IModelImporter.js.map +1 -1
- package/lib/cjs/IModelTransformContext.d.ts +54 -0
- package/lib/cjs/IModelTransformContext.d.ts.map +1 -0
- package/lib/cjs/IModelTransformContext.js +3 -0
- package/lib/cjs/IModelTransformContext.js.map +1 -0
- package/lib/cjs/IModelTransformer.d.ts +132 -174
- package/lib/cjs/IModelTransformer.d.ts.map +1 -1
- package/lib/cjs/IModelTransformer.js +679 -1025
- package/lib/cjs/IModelTransformer.js.map +1 -1
- package/lib/cjs/IModelTransformerError.d.ts +84 -0
- package/lib/cjs/IModelTransformerError.d.ts.map +1 -0
- package/lib/cjs/IModelTransformerError.js +93 -0
- package/lib/cjs/IModelTransformerError.js.map +1 -0
- package/lib/cjs/ProvenanceManager.d.ts +194 -0
- package/lib/cjs/ProvenanceManager.d.ts.map +1 -0
- package/lib/cjs/ProvenanceManager.js +771 -0
- package/lib/cjs/ProvenanceManager.js.map +1 -0
- package/lib/cjs/SyncTypeResolver.d.ts +32 -0
- package/lib/cjs/SyncTypeResolver.d.ts.map +1 -0
- package/lib/cjs/SyncTypeResolver.js +92 -0
- package/lib/cjs/SyncTypeResolver.js.map +1 -0
- package/lib/cjs/TransformerLoggerCategory.d.ts +1 -1
- package/lib/cjs/TransformerLoggerCategory.js +1 -1
- package/lib/cjs/TransformerLoggerCategory.js.map +1 -1
- package/lib/cjs/TransformerPackageMetadata.d.ts +8 -0
- package/lib/cjs/TransformerPackageMetadata.d.ts.map +1 -0
- package/lib/cjs/TransformerPackageMetadata.js +47 -0
- package/lib/cjs/TransformerPackageMetadata.js.map +1 -0
- package/lib/cjs/imodel-transformer.d.ts +27 -0
- package/lib/cjs/imodel-transformer.d.ts.map +1 -1
- package/lib/cjs/imodel-transformer.js +61 -34
- package/lib/cjs/imodel-transformer.js.map +1 -1
- package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts +29 -0
- package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.d.ts.map +1 -0
- package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js +212 -0
- package/lib/cjs/schema-processing/DynamicSchemaUnionStrategy.js.map +1 -0
- package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts +25 -0
- package/lib/cjs/schema-processing/SchemaProcessingCoordinator.d.ts.map +1 -0
- package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js +196 -0
- package/lib/cjs/schema-processing/SchemaProcessingCoordinator.js.map +1 -0
- package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts +59 -0
- package/lib/cjs/schema-processing/SchemaProcessingStrategy.d.ts.map +1 -0
- package/lib/cjs/schema-processing/SchemaProcessingStrategy.js +28 -0
- package/lib/cjs/schema-processing/SchemaProcessingStrategy.js.map +1 -0
- package/lib/cjs/schema-processing.d.ts +7 -0
- package/lib/cjs/schema-processing.d.ts.map +1 -0
- package/lib/cjs/schema-processing.js +27 -0
- package/lib/cjs/schema-processing.js.map +1 -0
- package/package.json +70 -57
- package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts +0 -16
- package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +0 -1
- package/lib/cjs/DetachedExportElementAspectsStrategy.js +0 -106
- package/lib/cjs/DetachedExportElementAspectsStrategy.js.map +0 -1
- package/lib/cjs/ElementCascadingDeleter.d.ts +0 -22
- package/lib/cjs/ElementCascadingDeleter.d.ts.map +0 -1
- package/lib/cjs/ElementCascadingDeleter.js +0 -57
- package/lib/cjs/ElementCascadingDeleter.js.map +0 -1
- package/lib/cjs/EntityMap.d.ts +0 -26
- package/lib/cjs/EntityMap.d.ts.map +0 -1
- package/lib/cjs/EntityMap.js +0 -54
- package/lib/cjs/EntityMap.js.map +0 -1
- package/lib/cjs/ExportElementAspectsStrategy.d.ts +0 -35
- package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +0 -1
- package/lib/cjs/ExportElementAspectsStrategy.js +0 -52
- package/lib/cjs/ExportElementAspectsStrategy.js.map +0 -1
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts +0 -12
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts.map +0 -1
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +0 -47
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.js.map +0 -1
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
* for entity-generic operations in the transformer
|
|
5
5
|
*/
|
|
6
6
|
import { EntityReference } from "@itwin/core-common";
|
|
7
|
-
import { ConcreteEntity,
|
|
7
|
+
import { ConcreteEntity, IModelDb } from "@itwin/core-backend";
|
|
8
8
|
/** @internal */
|
|
9
9
|
export declare namespace EntityUnifier {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/** needs to return a widened type otherwise typescript complains when result is used with a narrow type */
|
|
13
|
-
export function updaterFor(db: IModelDb, entity: ConcreteEntity): EntityUpdater;
|
|
14
|
-
export function exists(db: IModelDb, arg: {
|
|
10
|
+
function getReadableType(entity: ConcreteEntity): "element" | "element aspect" | "relationship" | "unknown entity type";
|
|
11
|
+
function exists(db: IModelDb, arg: {
|
|
15
12
|
entity: ConcreteEntity;
|
|
16
13
|
} | {
|
|
17
14
|
entityReference: EntityReference;
|
|
18
15
|
}): Promise<boolean>;
|
|
19
|
-
|
|
16
|
+
/** Batched existence check: returns the subset of `entityReferences` that exist in `db`,
|
|
17
|
+
* using one query per concrete entity type instead of one query per reference.
|
|
18
|
+
*/
|
|
19
|
+
function existsAll(db: IModelDb, entityReferences: Iterable<EntityReference>): Promise<Set<EntityReference>>;
|
|
20
20
|
}
|
|
21
21
|
//# sourceMappingURL=EntityUnifier.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityUnifier.d.ts","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":"AAIA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"EntityUnifier.d.ts","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,EAEL,eAAe,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EAMd,QAAQ,EAGT,MAAM,qBAAqB,CAAC;AAU7B,gBAAgB;AAChB,yBAAiB,aAAa,CAAC;IAC7B,SAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,yEAKrD;IAED,SAAsB,MAAM,CAC1B,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE;QAAE,MAAM,EAAE,cAAc,CAAA;KAAE,GAAG;QAAE,eAAe,EAAE,eAAe,CAAA;KAAE,oBAqBvE;IAED;;OAEG;IACH,SAAsB,SAAS,CAC7B,EAAE,EAAE,QAAQ,EACZ,gBAAgB,EAAE,QAAQ,CAAC,eAAe,CAAC,GAC1C,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CA8B/B;CACF"}
|
package/lib/cjs/EntityUnifier.js
CHANGED
|
@@ -10,10 +10,15 @@
|
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.EntityUnifier = void 0;
|
|
13
|
-
const assert = require("assert");
|
|
14
13
|
const core_common_1 = require("@itwin/core-common");
|
|
15
14
|
const core_backend_1 = require("@itwin/core-backend");
|
|
16
15
|
const core_bentley_1 = require("@itwin/core-bentley");
|
|
16
|
+
const bisCoreRootClasses = {
|
|
17
|
+
[core_common_1.ConcreteEntityTypes.Model]: core_backend_1.Model,
|
|
18
|
+
[core_common_1.ConcreteEntityTypes.Element]: core_backend_1.Element,
|
|
19
|
+
[core_common_1.ConcreteEntityTypes.ElementAspect]: core_backend_1.ElementAspect,
|
|
20
|
+
[core_common_1.ConcreteEntityTypes.Relationship]: core_backend_1.Relationship,
|
|
21
|
+
};
|
|
17
22
|
/** @internal */
|
|
18
23
|
var EntityUnifier;
|
|
19
24
|
(function (EntityUnifier) {
|
|
@@ -28,41 +33,59 @@ var EntityUnifier;
|
|
|
28
33
|
return "unknown entity type";
|
|
29
34
|
}
|
|
30
35
|
EntityUnifier.getReadableType = getReadableType;
|
|
31
|
-
/** needs to return a widened type otherwise typescript complains when result is used with a narrow type */
|
|
32
|
-
function updaterFor(db, entity) {
|
|
33
|
-
if (entity instanceof core_backend_1.Element)
|
|
34
|
-
return db.elements.updateElement.bind(db.elements);
|
|
35
|
-
else if (entity instanceof core_backend_1.Relationship)
|
|
36
|
-
return db.relationships.updateInstance.bind(db.relationships);
|
|
37
|
-
else if (entity instanceof core_backend_1.ElementAspect)
|
|
38
|
-
return db.elements.updateAspect.bind(db.elements);
|
|
39
|
-
else
|
|
40
|
-
assert(false, `unreachable; entity was '${entity.constructor.name}' not an Element, Relationship, or ElementAspect`);
|
|
41
|
-
}
|
|
42
|
-
EntityUnifier.updaterFor = updaterFor;
|
|
43
36
|
async function exists(db, arg) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
37
|
+
let classFullName;
|
|
38
|
+
let id;
|
|
39
|
+
if ("entityReference" in arg) {
|
|
40
|
+
const [type, entityId] = core_backend_1.EntityReferences.split(arg.entityReference);
|
|
41
|
+
classFullName = bisCoreRootClasses[type].classFullName;
|
|
42
|
+
id = entityId;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
classFullName = `[${arg.entity.schemaName}].[${arg.entity.className}]`;
|
|
46
|
+
id = arg.entity.id;
|
|
47
|
+
}
|
|
48
|
+
if (core_bentley_1.Id64.isInvalid(id))
|
|
52
49
|
return false;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const matchesResult = stmt.step();
|
|
58
|
-
if (matchesResult === core_bentley_1.DbResult.BE_SQLITE_ROW)
|
|
59
|
-
return true;
|
|
60
|
-
if (matchesResult === core_bentley_1.DbResult.BE_SQLITE_DONE)
|
|
61
|
-
return false;
|
|
62
|
-
else
|
|
63
|
-
throw new core_common_1.IModelError(matchesResult, "query failed");
|
|
50
|
+
const query = `SELECT 1 FROM ${classFullName} WHERE ECInstanceId=:id`;
|
|
51
|
+
const params = new core_common_1.QueryBinder().bindId("id", id);
|
|
52
|
+
const reader = db.createQueryReader(query, params, {
|
|
53
|
+
usePrimaryConn: true,
|
|
64
54
|
});
|
|
55
|
+
return reader.step();
|
|
65
56
|
}
|
|
66
57
|
EntityUnifier.exists = exists;
|
|
58
|
+
/** Batched existence check: returns the subset of `entityReferences` that exist in `db`,
|
|
59
|
+
* using one query per concrete entity type instead of one query per reference.
|
|
60
|
+
*/
|
|
61
|
+
async function existsAll(db, entityReferences) {
|
|
62
|
+
const idsByType = new Map();
|
|
63
|
+
for (const entityReference of entityReferences) {
|
|
64
|
+
const [type, id] = core_backend_1.EntityReferences.split(entityReference);
|
|
65
|
+
if (core_bentley_1.Id64.isInvalid(id))
|
|
66
|
+
continue;
|
|
67
|
+
let ids = idsByType.get(type);
|
|
68
|
+
if (ids === undefined) {
|
|
69
|
+
ids = new Set();
|
|
70
|
+
idsByType.set(type, ids);
|
|
71
|
+
}
|
|
72
|
+
ids.add(id);
|
|
73
|
+
}
|
|
74
|
+
const found = new Set();
|
|
75
|
+
for (const [type, ids] of idsByType) {
|
|
76
|
+
const classFullName = bisCoreRootClasses[type].classFullName;
|
|
77
|
+
// Join IdSet so SQLite looks up each id by primary key; InVirtualSet scans the whole table.
|
|
78
|
+
const query = `SELECT e.ECInstanceId FROM ${classFullName} e INNER JOIN IdSet(:ids) s ON s.id = e.ECInstanceId`;
|
|
79
|
+
const params = new core_common_1.QueryBinder().bindIdSet("ids", core_bentley_1.OrderedId64Iterable.sortArray([...ids]));
|
|
80
|
+
const reader = db.createQueryReader(query, params, {
|
|
81
|
+
usePrimaryConn: true,
|
|
82
|
+
});
|
|
83
|
+
while (await reader.step()) {
|
|
84
|
+
found.add(core_backend_1.EntityReferences.fromEntityType(reader.current[0], type));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return found;
|
|
88
|
+
}
|
|
89
|
+
EntityUnifier.existsAll = existsAll;
|
|
67
90
|
})(EntityUnifier || (exports.EntityUnifier = EntityUnifier = {}));
|
|
68
91
|
//# sourceMappingURL=EntityUnifier.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityUnifier.js","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;AAChG;;;;GAIG;;;AAEH,
|
|
1
|
+
{"version":3,"file":"EntityUnifier.js","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Utils\n * utilities that unify operations, especially CRUD operations, on entities\n * for entity-generic operations in the transformer\n */\n\nimport {\n ConcreteEntityTypes,\n EntityReference,\n QueryBinder,\n} from \"@itwin/core-common\";\nimport {\n ConcreteEntity,\n // eslint-disable-next-line @typescript-eslint/no-redeclare\n Element,\n ElementAspect,\n Entity,\n EntityReferences,\n IModelDb,\n Model,\n Relationship,\n} from \"@itwin/core-backend\";\nimport { Id64, Id64String, OrderedId64Iterable } from \"@itwin/core-bentley\";\n\nconst bisCoreRootClasses: Record<ConcreteEntityTypes, typeof Entity> = {\n [ConcreteEntityTypes.Model]: Model,\n [ConcreteEntityTypes.Element]: Element,\n [ConcreteEntityTypes.ElementAspect]: ElementAspect,\n [ConcreteEntityTypes.Relationship]: Relationship,\n};\n\n/** @internal */\nexport namespace EntityUnifier {\n export function getReadableType(entity: ConcreteEntity) {\n if (entity instanceof Element) return \"element\";\n else if (entity instanceof ElementAspect) return \"element aspect\";\n else if (entity instanceof Relationship) return \"relationship\";\n else return \"unknown entity type\";\n }\n\n export async function exists(\n db: IModelDb,\n arg: { entity: ConcreteEntity } | { entityReference: EntityReference }\n ) {\n let classFullName: string;\n let id: Id64String;\n if (\"entityReference\" in arg) {\n const [type, entityId] = EntityReferences.split(arg.entityReference);\n classFullName = bisCoreRootClasses[type].classFullName;\n id = entityId;\n } else {\n classFullName = `[${arg.entity.schemaName}].[${arg.entity.className}]`;\n id = arg.entity.id;\n }\n\n if (Id64.isInvalid(id)) return false;\n\n const query = `SELECT 1 FROM ${classFullName} WHERE ECInstanceId=:id`;\n const params = new QueryBinder().bindId(\"id\", id);\n const reader = db.createQueryReader(query, params, {\n usePrimaryConn: true,\n });\n return reader.step();\n }\n\n /** Batched existence check: returns the subset of `entityReferences` that exist in `db`,\n * using one query per concrete entity type instead of one query per reference.\n */\n export async function existsAll(\n db: IModelDb,\n entityReferences: Iterable<EntityReference>\n ): Promise<Set<EntityReference>> {\n const idsByType = new Map<ConcreteEntityTypes, Set<Id64String>>();\n for (const entityReference of entityReferences) {\n const [type, id] = EntityReferences.split(entityReference);\n if (Id64.isInvalid(id)) continue;\n let ids = idsByType.get(type);\n if (ids === undefined) {\n ids = new Set();\n idsByType.set(type, ids);\n }\n ids.add(id);\n }\n\n const found = new Set<EntityReference>();\n for (const [type, ids] of idsByType) {\n const classFullName = bisCoreRootClasses[type].classFullName;\n // Join IdSet so SQLite looks up each id by primary key; InVirtualSet scans the whole table.\n const query = `SELECT e.ECInstanceId FROM ${classFullName} e INNER JOIN IdSet(:ids) s ON s.id = e.ECInstanceId`;\n const params = new QueryBinder().bindIdSet(\n \"ids\",\n OrderedId64Iterable.sortArray([...ids])\n );\n const reader = db.createQueryReader(query, params, {\n usePrimaryConn: true,\n });\n while (await reader.step()) {\n found.add(EntityReferences.fromEntityType(reader.current[0], type));\n }\n }\n return found;\n }\n}\n"]}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { Id64String } from "@itwin/core-bentley";
|
|
2
2
|
import { ElementAspectProps, ElementProps, EntityReference } from "@itwin/core-common";
|
|
3
3
|
import { Element, ElementAspect, IModelElementCloneContext, IModelJsNative } from "@itwin/core-backend";
|
|
4
|
+
import { EntityExistenceCache } from "./EntityExistenceCache";
|
|
5
|
+
import type { IModelTransformContext } from "./IModelTransformContext";
|
|
4
6
|
/** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
|
|
5
|
-
* @
|
|
7
|
+
* @internal
|
|
6
8
|
*/
|
|
7
|
-
export declare class IModelCloneContext extends IModelElementCloneContext {
|
|
9
|
+
export declare class IModelCloneContext extends IModelElementCloneContext implements IModelTransformContext {
|
|
8
10
|
private _refTypesCache;
|
|
9
11
|
private _aspectRemapTable;
|
|
12
|
+
/** A positive-only cache of entity existence checks, scoped to the current transformation run.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
readonly existenceCache: EntityExistenceCache;
|
|
10
16
|
/** perform necessary initialization to use a clone context, namely caching the reference types in the source's schemas */
|
|
11
17
|
initialize(): Promise<void>;
|
|
12
18
|
/** Clone the specified source Element into ElementProps for the target iModel.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IModelCloneContext.d.ts","sourceRoot":"","sources":["../../src/IModelCloneContext.ts"],"names":[],"mappings":"AAQA,OAAO,EAAQ,UAAU,EAAU,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAKL,kBAAkB,EAClB,YAAY,EACZ,eAAe,EAKhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,OAAO,EACP,aAAa,EAEb,yBAAyB,EACzB,cAAc,EACf,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"IModelCloneContext.d.ts","sourceRoot":"","sources":["../../src/IModelCloneContext.ts"],"names":[],"mappings":"AAQA,OAAO,EAAQ,UAAU,EAAU,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAKL,kBAAkB,EAClB,YAAY,EACZ,eAAe,EAKhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,OAAO,EACP,aAAa,EAEb,yBAAyB,EACzB,cAAc,EACf,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAIvE;;GAEG;AACH,qBAAa,kBACX,SAAQ,yBACR,YAAW,sBAAsB;IAEjC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,iBAAiB,CAA4B;IAErD;;OAEG;IACH,SAAgB,cAAc,uBAA8B;IAE5D,0HAA0H;IACpG,UAAU,kBAE/B;IAED;;OAEG;IACmB,YAAY,CAChC,aAAa,EAAE,OAAO,EACtB,YAAY,CAAC,EAAE,cAAc,CAAC,mBAAmB,GAChD,OAAO,CAAC,YAAY,CAAC,CAgFvB;IAED,uGAAuG;IAChG,kBAAkB,CACvB,cAAc,EAAE,UAAU,EAC1B,cAAc,EAAE,UAAU,GACzB,IAAI,CAEN;IAED,mEAAmE;IAC5D,mBAAmB,CAAC,cAAc,EAAE,UAAU,GAAG,IAAI,CAE3D;IAED;;OAEG;IACI,kBAAkB,CAAC,cAAc,EAAE,UAAU,GAAG,UAAU,CAEhE;IAED;;OAEG;IACU,kBAAkB,CAC7B,cAAc,EAAE,eAAe,GAC9B,OAAO,CAAC,eAAe,CAAC,CA+H1B;IAED;;OAEG;IACU,kBAAkB,CAC7B,mBAAmB,EAAE,aAAa,GACjC,OAAO,CAAC,kBAAkB,CAAC,CAqD7B;CACF"}
|
|
@@ -8,20 +8,26 @@ exports.IModelCloneContext = void 0;
|
|
|
8
8
|
/** @packageDocumentation
|
|
9
9
|
* @module iModels
|
|
10
10
|
*/
|
|
11
|
-
const
|
|
11
|
+
const node_assert_1 = require("node:assert");
|
|
12
12
|
const core_bentley_1 = require("@itwin/core-bentley");
|
|
13
13
|
const core_common_1 = require("@itwin/core-common");
|
|
14
14
|
const core_backend_1 = require("@itwin/core-backend");
|
|
15
|
+
const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
|
|
15
16
|
const ECReferenceTypesCache_1 = require("./ECReferenceTypesCache");
|
|
16
|
-
const
|
|
17
|
+
const EntityExistenceCache_1 = require("./EntityExistenceCache");
|
|
17
18
|
const TransformerLoggerCategory_1 = require("./TransformerLoggerCategory");
|
|
19
|
+
const BigMap_1 = require("./BigMap");
|
|
18
20
|
const loggerCategory = TransformerLoggerCategory_1.TransformerLoggerCategory.IModelCloneContext;
|
|
19
21
|
/** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
|
|
20
|
-
* @
|
|
22
|
+
* @internal
|
|
21
23
|
*/
|
|
22
24
|
class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
|
|
23
25
|
_refTypesCache = new ECReferenceTypesCache_1.ECReferenceTypesCache();
|
|
24
|
-
_aspectRemapTable = new
|
|
26
|
+
_aspectRemapTable = new BigMap_1.BigMap();
|
|
27
|
+
/** A positive-only cache of entity existence checks, scoped to the current transformation run.
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
existenceCache = new EntityExistenceCache_1.EntityExistenceCache();
|
|
25
31
|
/** perform necessary initialization to use a clone context, namely caching the reference types in the source's schemas */
|
|
26
32
|
async initialize() {
|
|
27
33
|
await this._refTypesCache.initAllSchemasInIModel(this.sourceDb);
|
|
@@ -31,14 +37,37 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
|
|
|
31
37
|
*/
|
|
32
38
|
async cloneElement(sourceElement, cloneOptions) {
|
|
33
39
|
const targetElementProps = this["_nativeContext"].cloneElement(sourceElement.id, cloneOptions);
|
|
40
|
+
// Native same-iModel cloning clears codes for inserts, but identity mappings are updates.
|
|
41
|
+
if (!this.isBetweenIModels &&
|
|
42
|
+
this.findTargetElementId(sourceElement.id) === sourceElement.id) {
|
|
43
|
+
targetElementProps.code.value = sourceElement.code.value;
|
|
44
|
+
if (!core_bentley_1.Id64.isValidId64(targetElementProps.code.spec)) {
|
|
45
|
+
const mappedCodeSpecId = this.findTargetCodeSpecId(sourceElement.code.spec);
|
|
46
|
+
targetElementProps.code.spec = core_bentley_1.Id64.isValidId64(mappedCodeSpecId)
|
|
47
|
+
? mappedCodeSpecId
|
|
48
|
+
: sourceElement.code.spec;
|
|
49
|
+
}
|
|
50
|
+
if (!core_bentley_1.Id64.isValidId64(targetElementProps.code.scope)) {
|
|
51
|
+
const mappedCodeScopeId = this.findTargetElementId(sourceElement.code.scope);
|
|
52
|
+
targetElementProps.code.scope = core_bentley_1.Id64.isValidId64(mappedCodeScopeId)
|
|
53
|
+
? mappedCodeScopeId
|
|
54
|
+
: sourceElement.code.scope;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
34
57
|
// Ensure that all NavigationProperties in targetElementProps have a defined value so "clearing" changes will be part of the JSON used for update
|
|
35
|
-
sourceElement.
|
|
58
|
+
const sourceElementClass = sourceElement.iModel.schemaContext.getSchemaItemSync(sourceElement.schemaItemKey, ecschema_metadata_1.EntityClass);
|
|
59
|
+
(0, node_assert_1.strict)(sourceElementClass !== undefined, `Cannot get metadata for ${sourceElement.classFullName}.`);
|
|
60
|
+
for (const property of sourceElementClass.getPropertiesSync()) {
|
|
61
|
+
// Exclude custom properties because C++ has already handled them.
|
|
62
|
+
if (property.customAttributes?.has("BisCore.CustomHandledProperty"))
|
|
63
|
+
continue;
|
|
64
|
+
const name = property.name;
|
|
36
65
|
if (property.isNavigation() &&
|
|
37
66
|
undefined === sourceElement[core_common_1.ECJsNames.toJsName(name)]) {
|
|
38
67
|
targetElementProps[core_common_1.ECJsNames.toJsName(name)] =
|
|
39
68
|
core_common_1.RelatedElement.none;
|
|
40
69
|
}
|
|
41
|
-
}
|
|
70
|
+
}
|
|
42
71
|
if (this.isBetweenIModels) {
|
|
43
72
|
// The native C++ cloneElement strips off federationGuid, want to put it back if transformation is between iModels
|
|
44
73
|
targetElementProps.federationGuid = sourceElement.federationGuid;
|
|
@@ -98,9 +127,7 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
|
|
|
98
127
|
}
|
|
99
128
|
// Check if the model exists, `findTargetElementId` may have worked because the element exists when the model doesn't.
|
|
100
129
|
// That can occur in the transformer since a submodeled element is imported before its submodel.
|
|
101
|
-
if (await
|
|
102
|
-
entityReference: targetId,
|
|
103
|
-
}))
|
|
130
|
+
if (await this.existenceCache.exists(this.targetDb, targetId))
|
|
104
131
|
return targetId;
|
|
105
132
|
break;
|
|
106
133
|
}
|
|
@@ -196,13 +223,16 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
|
|
|
196
223
|
const targetElementAspectProps = sourceElementAspect.toJSON();
|
|
197
224
|
targetElementAspectProps.id = undefined;
|
|
198
225
|
const targetEntityIds = [];
|
|
199
|
-
sourceElementAspect.
|
|
226
|
+
const sourceElementAspectClass = sourceElementAspect.iModel.schemaContext.getSchemaItemSync(sourceElementAspect.schemaItemKey, ecschema_metadata_1.EntityClass);
|
|
227
|
+
(0, node_assert_1.strict)(sourceElementAspectClass !== undefined, `Cannot get metadata for ${sourceElementAspect.classFullName}.`);
|
|
228
|
+
for (const property of sourceElementAspectClass.getPropertiesSync()) {
|
|
229
|
+
const ecName = property.name;
|
|
200
230
|
const name = core_common_1.ECJsNames.toJsName(ecName);
|
|
201
231
|
if (property.isNavigation()) {
|
|
202
232
|
const sourceNavProp = sourceElementAspect.asAny[name];
|
|
203
233
|
if (sourceNavProp?.id) {
|
|
204
234
|
const navPropRefType = this._refTypesCache.getNavPropRefType(sourceElementAspect.schemaName, sourceElementAspect.className, name);
|
|
205
|
-
|
|
235
|
+
(0, node_assert_1.strict)(navPropRefType !== undefined, `nav prop ref type for '${name}' was not in the cache, this is a bug.`);
|
|
206
236
|
targetEntityIds.push(this.findTargetEntityId(core_backend_1.EntityReferences.fromEntityType(sourceNavProp.id, navPropRefType)).then((targetEntityReference) => {
|
|
207
237
|
const targetEntityId = core_backend_1.EntityReferences.toId64(targetEntityReference);
|
|
208
238
|
// spread the property in case toJSON did not deep-clone
|
|
@@ -216,7 +246,7 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
|
|
|
216
246
|
else if (property.isPrimitive() && "Id" === property.extendedTypeName) {
|
|
217
247
|
targetElementAspectProps[name] = this.findTargetElementId(sourceElementAspect.asAny[name]);
|
|
218
248
|
}
|
|
219
|
-
}
|
|
249
|
+
}
|
|
220
250
|
await Promise.all(targetEntityIds);
|
|
221
251
|
return targetElementAspectProps;
|
|
222
252
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IModelCloneContext.js","sourceRoot":"","sources":["../../src/IModelCloneContext.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iModels\n */\nimport * as assert from \"assert\";\nimport { Id64, Id64String, Logger } from \"@itwin/core-bentley\";\nimport {\n Code,\n CodeScopeSpec,\n ConcreteEntityTypes,\n ECJsNames,\n ElementAspectProps,\n ElementProps,\n EntityReference,\n IModel,\n QueryBinder,\n RelatedElement,\n RelatedElementProps,\n} from \"@itwin/core-common\";\nimport {\n // eslint-disable-next-line @typescript-eslint/no-redeclare\n Element,\n ElementAspect,\n EntityReferences,\n IModelElementCloneContext,\n IModelJsNative,\n} from \"@itwin/core-backend\";\nimport { ECReferenceTypesCache } from \"./ECReferenceTypesCache\";\nimport { EntityUnifier } from \"./EntityUnifier\";\nimport { TransformerLoggerCategory } from \"./TransformerLoggerCategory\";\nimport { Property } from \"@itwin/ecschema-metadata\";\n\nconst loggerCategory: string = TransformerLoggerCategory.IModelCloneContext;\n\n/** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.\n * @beta\n */\nexport class IModelCloneContext extends IModelElementCloneContext {\n private _refTypesCache = new ECReferenceTypesCache();\n private _aspectRemapTable = new Map<Id64String, Id64String>();\n\n /** perform necessary initialization to use a clone context, namely caching the reference types in the source's schemas */\n public override async initialize() {\n await this._refTypesCache.initAllSchemasInIModel(this.sourceDb);\n }\n\n /** Clone the specified source Element into ElementProps for the target iModel.\n * @internal\n */\n public override async cloneElement(\n sourceElement: Element,\n cloneOptions?: IModelJsNative.CloneElementOptions\n ): Promise<ElementProps> {\n const targetElementProps: ElementProps = this[\n \"_nativeContext\"\n ].cloneElement(sourceElement.id, cloneOptions);\n // Ensure that all NavigationProperties in targetElementProps have a defined value so \"clearing\" changes will be part of the JSON used for update\n sourceElement.forEach((name: string, property: Property) => {\n if (\n property.isNavigation() &&\n undefined === (sourceElement as any)[ECJsNames.toJsName(name)]\n ) {\n (targetElementProps as any)[ECJsNames.toJsName(name)] =\n RelatedElement.none;\n }\n }, false); // exclude custom because C++ has already handled them\n if (this.isBetweenIModels) {\n // The native C++ cloneElement strips off federationGuid, want to put it back if transformation is between iModels\n targetElementProps.federationGuid = sourceElement.federationGuid;\n const targetElementCodeScopeType = this.targetDb.codeSpecs.getById(\n targetElementProps.code.spec\n ).scopeType;\n if (\n CodeScopeSpec.Type.Repository === targetElementCodeScopeType &&\n targetElementProps.code.scope !== IModel.rootSubjectId\n ) {\n Logger.logWarning(\n loggerCategory,\n `Incorrect CodeScope '${targetElementCodeScopeType}' is set for target element ${targetElementProps.id}`\n );\n }\n }\n // unlike other references, code cannot be null. If it is null, use an empty code instead\n // this will be updated back later as the transformer resolves references\n if (\n targetElementProps.code.scope === Id64.invalid ||\n targetElementProps.code.spec === Id64.invalid\n ) {\n targetElementProps.code = Code.createEmpty();\n }\n const jsClass = this.sourceDb.getJsClass<typeof Element>(\n sourceElement.classFullName\n );\n await jsClass[\"onCloned\"](this, sourceElement.toJSON(), targetElementProps);\n return targetElementProps;\n }\n\n /** Add a rule that remaps the specified source ElementAspect to the specified target ElementAspect. */\n public remapElementAspect(\n aspectSourceId: Id64String,\n aspectTargetId: Id64String\n ): void {\n this._aspectRemapTable.set(aspectSourceId, aspectTargetId);\n }\n\n /** Remove a rule that remaps the specified source ElementAspect */\n public removeElementAspect(aspectSourceId: Id64String): void {\n this._aspectRemapTable.delete(aspectSourceId);\n }\n\n /** Look up a target AspectId from the source AspectId.\n * @returns the target AspectId or [Id64.invalid]($bentley) if a mapping not found.\n */\n public findTargetAspectId(sourceAspectId: Id64String): Id64String {\n return this._aspectRemapTable.get(sourceAspectId) ?? Id64.invalid;\n }\n\n /** Look up a target [EntityReference]($bentley) from a source [EntityReference]($bentley)\n * @returns the target CodeSpecId or a [EntityReference]($bentley) containing [Id64.invalid]($bentley) if a mapping is not found.\n */\n public async findTargetEntityId(\n sourceEntityId: EntityReference\n ): Promise<EntityReference> {\n const [type, rawId] = EntityReferences.split(sourceEntityId);\n if (Id64.isValid(rawId)) {\n switch (type) {\n case ConcreteEntityTypes.Model: {\n let targetId;\n /**\n * The repository model is a singleton container which exists in all iModels which has a modelId of 0x1.\n * It is possible to remap the root subject (id 0x1) to some other non root subject, but this is not possible for the repository model.\n * The RepositoryModel only contains bis:Subject elements and bis:InformationpartitionElement instances (https://www.itwinjs.org/bis/domains/biscore.ecschema/#repositorymodel)\n * The system handler for both bis:InformationPartitionElement and bis:Subject will only permit instances to be inserted into the RepositoryModel.\n * https://www.itwinjs.org/bis/domains/biscore.ecschema/#informationpartitionelement\n * https://www.itwinjs.org/bis/domains/biscore.ecschema/#subject\n * Since there is a chance that the root subject is remapped to some other subject which has the same id as the repositoryModel, we need to ignore the remapping for the repository model.\n */\n if (rawId === IModel.repositoryModelId) {\n targetId = `m${IModel.repositoryModelId}` as const;\n } else {\n targetId = `m${this.findTargetElementId(rawId)}` as const;\n }\n // Check if the model exists, `findTargetElementId` may have worked because the element exists when the model doesn't.\n // That can occur in the transformer since a submodeled element is imported before its submodel.\n if (\n await EntityUnifier.exists(this.targetDb, {\n entityReference: targetId,\n })\n )\n return targetId;\n break;\n }\n case ConcreteEntityTypes.Element:\n return `e${this.findTargetElementId(rawId)}`;\n case ConcreteEntityTypes.ElementAspect:\n return `a${this.findTargetAspectId(rawId)}`;\n case ConcreteEntityTypes.Relationship: {\n const makeGetConcreteEntityTypeSql = (property: string) => `\n CASE\n WHEN [${property}] IS (BisCore.ElementUniqueAspect) OR [${property}] IS (BisCore.ElementMultiAspect)\n THEN 'a'\n WHEN [${property}] IS (BisCore.Element)\n THEN 'e'\n WHEN [${property}] IS (BisCore.Model)\n THEN 'm'\n WHEN [${property}] IS (BisCore.CodeSpec)\n THEN 'c'\n WHEN [${property}] IS (BisCore.ElementRefersToElements) -- TODO: ElementDrivesElement still not handled by the transformer\n THEN 'r'\n ELSE 'error'\n END\n `;\n const sql = `\n SELECT\n SourceECInstanceId,\n TargetECInstanceId,\n (${makeGetConcreteEntityTypeSql(\n \"SourceECClassId\"\n )}) AS SourceType,\n (${makeGetConcreteEntityTypeSql(\"TargetECClassId\")}) AS TargetType\n FROM BisCore:ElementRefersToElements\n WHERE ECInstanceId=?\n `;\n const params = new QueryBinder().bindId(1, rawId);\n const reader = this.sourceDb.createQueryReader(sql, params, {\n usePrimaryConn: true,\n });\n const relInSource = await (async () => {\n if (await reader.step()) {\n const sourceId = reader.current[0];\n const targetId = reader.current[1];\n const sourceType = reader.current[2] as\n | ConcreteEntityTypes\n | \"error\";\n const targetType = reader.current[3] as\n | ConcreteEntityTypes\n | \"error\";\n if (sourceType === \"error\" || targetType === \"error\")\n throw Error(\"relationship end had unknown root class\");\n return {\n sourceId: `${sourceType}${sourceId}`,\n targetId: `${targetType}${targetId}`,\n } as const;\n }\n return undefined;\n })();\n if (relInSource === undefined) break;\n // just in case prevent recursion\n if (\n relInSource.sourceId === sourceEntityId ||\n relInSource.targetId === sourceEntityId\n )\n throw Error(\n \"link table relationship end was resolved to itself. This should be impossible\"\n );\n const relInTarget = {\n sourceId: await this.findTargetEntityId(relInSource.sourceId),\n targetId: await this.findTargetEntityId(relInSource.targetId),\n };\n // return a null\n if (\n !EntityReferences.isValid(relInTarget.sourceId) ||\n !EntityReferences.isValid(relInTarget.targetId)\n )\n break;\n const relInTargetSql = `\n SELECT ECInstanceId\n FROM BisCore:ElementRefersToElements\n WHERE SourceECInstanceId=?\n AND TargetECInstanceId=?\n `;\n const relInTargetParams = new QueryBinder();\n relInTargetParams.bindId(\n 1,\n EntityReferences.toId64(relInTarget.sourceId)\n );\n relInTargetParams.bindId(\n 2,\n EntityReferences.toId64(relInTarget.targetId)\n );\n const relInTargetResult = await this.targetDb\n .createQueryReader(relInTargetSql, relInTargetParams, {\n usePrimaryConn: true,\n })\n .next();\n const relInTargetId = relInTargetResult.done\n ? Id64.invalid\n : relInTargetResult.value.id;\n return `r${relInTargetId}`;\n }\n }\n }\n return `${type}${Id64.invalid}`;\n }\n\n /** Clone the specified source Element into ElementProps for the target iModel.\n * @internal\n */\n public async cloneElementAspect(\n sourceElementAspect: ElementAspect\n ): Promise<ElementAspectProps> {\n const targetElementAspectProps: ElementAspectProps =\n sourceElementAspect.toJSON();\n targetElementAspectProps.id = undefined;\n const targetEntityIds: Promise<void>[] = [];\n sourceElementAspect.forEach((ecName, property) => {\n const name = ECJsNames.toJsName(ecName);\n if (property.isNavigation()) {\n const sourceNavProp: RelatedElementProps | undefined =\n sourceElementAspect.asAny[name];\n if (sourceNavProp?.id) {\n const navPropRefType = this._refTypesCache.getNavPropRefType(\n sourceElementAspect.schemaName,\n sourceElementAspect.className,\n name\n );\n assert(\n navPropRefType !== undefined,\n `nav prop ref type for '${name}' was not in the cache, this is a bug.`\n );\n targetEntityIds.push(\n this.findTargetEntityId(\n EntityReferences.fromEntityType(sourceNavProp.id, navPropRefType)\n ).then((targetEntityReference) => {\n const targetEntityId = EntityReferences.toId64(\n targetEntityReference\n );\n // spread the property in case toJSON did not deep-clone\n (targetElementAspectProps as any)[name] = {\n ...(targetElementAspectProps as any)[name],\n id: targetEntityId,\n };\n })\n );\n }\n } else if (property.isPrimitive() && \"Id\" === property.extendedTypeName) {\n (targetElementAspectProps as any)[name] = this.findTargetElementId(\n sourceElementAspect.asAny[name]\n );\n }\n });\n await Promise.all(targetEntityIds);\n return targetElementAspectProps;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"IModelCloneContext.js","sourceRoot":"","sources":["../../src/IModelCloneContext.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iModels\n */\nimport { strict as assert } from \"node:assert\";\nimport { Id64, Id64String, Logger } from \"@itwin/core-bentley\";\nimport {\n Code,\n CodeScopeSpec,\n ConcreteEntityTypes,\n ECJsNames,\n ElementAspectProps,\n ElementProps,\n EntityReference,\n IModel,\n QueryBinder,\n RelatedElement,\n RelatedElementProps,\n} from \"@itwin/core-common\";\nimport {\n // eslint-disable-next-line @typescript-eslint/no-redeclare\n Element,\n ElementAspect,\n EntityReferences,\n IModelElementCloneContext,\n IModelJsNative,\n} from \"@itwin/core-backend\";\nimport { EntityClass } from \"@itwin/ecschema-metadata\";\nimport { ECReferenceTypesCache } from \"./ECReferenceTypesCache\";\nimport { EntityExistenceCache } from \"./EntityExistenceCache\";\nimport { TransformerLoggerCategory } from \"./TransformerLoggerCategory\";\nimport { BigMap } from \"./BigMap\";\nimport type { IModelTransformContext } from \"./IModelTransformContext\";\n\nconst loggerCategory: string = TransformerLoggerCategory.IModelCloneContext;\n\n/** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.\n * @internal\n */\nexport class IModelCloneContext\n extends IModelElementCloneContext\n implements IModelTransformContext\n{\n private _refTypesCache = new ECReferenceTypesCache();\n private _aspectRemapTable = new BigMap<Id64String>();\n\n /** A positive-only cache of entity existence checks, scoped to the current transformation run.\n * @internal\n */\n public readonly existenceCache = new EntityExistenceCache();\n\n /** perform necessary initialization to use a clone context, namely caching the reference types in the source's schemas */\n public override async initialize() {\n await this._refTypesCache.initAllSchemasInIModel(this.sourceDb);\n }\n\n /** Clone the specified source Element into ElementProps for the target iModel.\n * @internal\n */\n public override async cloneElement(\n sourceElement: Element,\n cloneOptions?: IModelJsNative.CloneElementOptions\n ): Promise<ElementProps> {\n const targetElementProps: ElementProps = this[\n \"_nativeContext\"\n ].cloneElement(sourceElement.id, cloneOptions);\n // Native same-iModel cloning clears codes for inserts, but identity mappings are updates.\n if (\n !this.isBetweenIModels &&\n this.findTargetElementId(sourceElement.id) === sourceElement.id\n ) {\n targetElementProps.code.value = sourceElement.code.value;\n if (!Id64.isValidId64(targetElementProps.code.spec)) {\n const mappedCodeSpecId = this.findTargetCodeSpecId(\n sourceElement.code.spec\n );\n targetElementProps.code.spec = Id64.isValidId64(mappedCodeSpecId)\n ? mappedCodeSpecId\n : sourceElement.code.spec;\n }\n if (!Id64.isValidId64(targetElementProps.code.scope)) {\n const mappedCodeScopeId = this.findTargetElementId(\n sourceElement.code.scope\n );\n targetElementProps.code.scope = Id64.isValidId64(mappedCodeScopeId)\n ? mappedCodeScopeId\n : sourceElement.code.scope;\n }\n }\n // Ensure that all NavigationProperties in targetElementProps have a defined value so \"clearing\" changes will be part of the JSON used for update\n const sourceElementClass =\n sourceElement.iModel.schemaContext.getSchemaItemSync(\n sourceElement.schemaItemKey,\n EntityClass\n );\n assert(\n sourceElementClass !== undefined,\n `Cannot get metadata for ${sourceElement.classFullName}.`\n );\n for (const property of sourceElementClass.getPropertiesSync()) {\n // Exclude custom properties because C++ has already handled them.\n if (property.customAttributes?.has(\"BisCore.CustomHandledProperty\"))\n continue;\n\n const name = property.name;\n if (\n property.isNavigation() &&\n undefined === (sourceElement as any)[ECJsNames.toJsName(name)]\n ) {\n (targetElementProps as any)[ECJsNames.toJsName(name)] =\n RelatedElement.none;\n }\n }\n if (this.isBetweenIModels) {\n // The native C++ cloneElement strips off federationGuid, want to put it back if transformation is between iModels\n targetElementProps.federationGuid = sourceElement.federationGuid;\n const targetElementCodeScopeType = this.targetDb.codeSpecs.getById(\n targetElementProps.code.spec\n ).scopeType;\n if (\n CodeScopeSpec.Type.Repository === targetElementCodeScopeType &&\n targetElementProps.code.scope !== IModel.rootSubjectId\n ) {\n Logger.logWarning(\n loggerCategory,\n `Incorrect CodeScope '${targetElementCodeScopeType}' is set for target element ${targetElementProps.id}`\n );\n }\n }\n // unlike other references, code cannot be null. If it is null, use an empty code instead\n // this will be updated back later as the transformer resolves references\n if (\n targetElementProps.code.scope === Id64.invalid ||\n targetElementProps.code.spec === Id64.invalid\n ) {\n targetElementProps.code = Code.createEmpty();\n }\n const jsClass = this.sourceDb.getJsClass<typeof Element>(\n sourceElement.classFullName\n );\n await jsClass[\"onCloned\"](this, sourceElement.toJSON(), targetElementProps);\n return targetElementProps;\n }\n\n /** Add a rule that remaps the specified source ElementAspect to the specified target ElementAspect. */\n public remapElementAspect(\n aspectSourceId: Id64String,\n aspectTargetId: Id64String\n ): void {\n this._aspectRemapTable.set(aspectSourceId, aspectTargetId);\n }\n\n /** Remove a rule that remaps the specified source ElementAspect */\n public removeElementAspect(aspectSourceId: Id64String): void {\n this._aspectRemapTable.delete(aspectSourceId);\n }\n\n /** Look up a target AspectId from the source AspectId.\n * @returns the target AspectId or [Id64.invalid]($bentley) if a mapping not found.\n */\n public findTargetAspectId(sourceAspectId: Id64String): Id64String {\n return this._aspectRemapTable.get(sourceAspectId) ?? Id64.invalid;\n }\n\n /** Look up a target [EntityReference]($bentley) from a source [EntityReference]($bentley)\n * @returns the target CodeSpecId or a [EntityReference]($bentley) containing [Id64.invalid]($bentley) if a mapping is not found.\n */\n public async findTargetEntityId(\n sourceEntityId: EntityReference\n ): Promise<EntityReference> {\n const [type, rawId] = EntityReferences.split(sourceEntityId);\n if (Id64.isValid(rawId)) {\n switch (type) {\n case ConcreteEntityTypes.Model: {\n let targetId;\n /**\n * The repository model is a singleton container which exists in all iModels which has a modelId of 0x1.\n * It is possible to remap the root subject (id 0x1) to some other non root subject, but this is not possible for the repository model.\n * The RepositoryModel only contains bis:Subject elements and bis:InformationpartitionElement instances (https://www.itwinjs.org/bis/domains/biscore.ecschema/#repositorymodel)\n * The system handler for both bis:InformationPartitionElement and bis:Subject will only permit instances to be inserted into the RepositoryModel.\n * https://www.itwinjs.org/bis/domains/biscore.ecschema/#informationpartitionelement\n * https://www.itwinjs.org/bis/domains/biscore.ecschema/#subject\n * Since there is a chance that the root subject is remapped to some other subject which has the same id as the repositoryModel, we need to ignore the remapping for the repository model.\n */\n if (rawId === IModel.repositoryModelId) {\n targetId = `m${IModel.repositoryModelId}` as const;\n } else {\n targetId = `m${this.findTargetElementId(rawId)}` as const;\n }\n // Check if the model exists, `findTargetElementId` may have worked because the element exists when the model doesn't.\n // That can occur in the transformer since a submodeled element is imported before its submodel.\n if (await this.existenceCache.exists(this.targetDb, targetId))\n return targetId;\n break;\n }\n case ConcreteEntityTypes.Element:\n return `e${this.findTargetElementId(rawId)}`;\n case ConcreteEntityTypes.ElementAspect:\n return `a${this.findTargetAspectId(rawId)}`;\n case ConcreteEntityTypes.Relationship: {\n const makeGetConcreteEntityTypeSql = (property: string) => `\n CASE\n WHEN [${property}] IS (BisCore.ElementUniqueAspect) OR [${property}] IS (BisCore.ElementMultiAspect)\n THEN 'a'\n WHEN [${property}] IS (BisCore.Element)\n THEN 'e'\n WHEN [${property}] IS (BisCore.Model)\n THEN 'm'\n WHEN [${property}] IS (BisCore.CodeSpec)\n THEN 'c'\n WHEN [${property}] IS (BisCore.ElementRefersToElements) -- TODO: ElementDrivesElement still not handled by the transformer\n THEN 'r'\n ELSE 'error'\n END\n `;\n const sql = `\n SELECT\n SourceECInstanceId,\n TargetECInstanceId,\n (${makeGetConcreteEntityTypeSql(\n \"SourceECClassId\"\n )}) AS SourceType,\n (${makeGetConcreteEntityTypeSql(\"TargetECClassId\")}) AS TargetType\n FROM BisCore:ElementRefersToElements\n WHERE ECInstanceId=?\n `;\n const params = new QueryBinder().bindId(1, rawId);\n const reader = this.sourceDb.createQueryReader(sql, params, {\n usePrimaryConn: true,\n });\n const relInSource = await (async () => {\n if (await reader.step()) {\n const sourceId = reader.current[0];\n const targetId = reader.current[1];\n const sourceType = reader.current[2] as\n | ConcreteEntityTypes\n | \"error\";\n const targetType = reader.current[3] as\n | ConcreteEntityTypes\n | \"error\";\n if (sourceType === \"error\" || targetType === \"error\")\n throw Error(\"relationship end had unknown root class\");\n return {\n sourceId: `${sourceType}${sourceId}`,\n targetId: `${targetType}${targetId}`,\n } as const;\n }\n return undefined;\n })();\n if (relInSource === undefined) break;\n // just in case prevent recursion\n if (\n relInSource.sourceId === sourceEntityId ||\n relInSource.targetId === sourceEntityId\n )\n throw Error(\n \"link table relationship end was resolved to itself. This should be impossible\"\n );\n const relInTarget = {\n sourceId: await this.findTargetEntityId(relInSource.sourceId),\n targetId: await this.findTargetEntityId(relInSource.targetId),\n };\n // return a null\n if (\n !EntityReferences.isValid(relInTarget.sourceId) ||\n !EntityReferences.isValid(relInTarget.targetId)\n )\n break;\n const relInTargetSql = `\n SELECT ECInstanceId\n FROM BisCore:ElementRefersToElements\n WHERE SourceECInstanceId=?\n AND TargetECInstanceId=?\n `;\n const relInTargetParams = new QueryBinder();\n relInTargetParams.bindId(\n 1,\n EntityReferences.toId64(relInTarget.sourceId)\n );\n relInTargetParams.bindId(\n 2,\n EntityReferences.toId64(relInTarget.targetId)\n );\n const relInTargetResult = await this.targetDb\n .createQueryReader(relInTargetSql, relInTargetParams, {\n usePrimaryConn: true,\n })\n .next();\n const relInTargetId = relInTargetResult.done\n ? Id64.invalid\n : relInTargetResult.value.id;\n return `r${relInTargetId}`;\n }\n }\n }\n return `${type}${Id64.invalid}`;\n }\n\n /** Clone the specified source Element into ElementProps for the target iModel.\n * @internal\n */\n public async cloneElementAspect(\n sourceElementAspect: ElementAspect\n ): Promise<ElementAspectProps> {\n const targetElementAspectProps: ElementAspectProps =\n sourceElementAspect.toJSON();\n targetElementAspectProps.id = undefined;\n const targetEntityIds: Promise<void>[] = [];\n const sourceElementAspectClass =\n sourceElementAspect.iModel.schemaContext.getSchemaItemSync(\n sourceElementAspect.schemaItemKey,\n EntityClass\n );\n assert(\n sourceElementAspectClass !== undefined,\n `Cannot get metadata for ${sourceElementAspect.classFullName}.`\n );\n for (const property of sourceElementAspectClass.getPropertiesSync()) {\n const ecName = property.name;\n const name = ECJsNames.toJsName(ecName);\n if (property.isNavigation()) {\n const sourceNavProp: RelatedElementProps | undefined =\n sourceElementAspect.asAny[name];\n if (sourceNavProp?.id) {\n const navPropRefType = this._refTypesCache.getNavPropRefType(\n sourceElementAspect.schemaName,\n sourceElementAspect.className,\n name\n );\n assert(\n navPropRefType !== undefined,\n `nav prop ref type for '${name}' was not in the cache, this is a bug.`\n );\n targetEntityIds.push(\n this.findTargetEntityId(\n EntityReferences.fromEntityType(sourceNavProp.id, navPropRefType)\n ).then((targetEntityReference) => {\n const targetEntityId = EntityReferences.toId64(\n targetEntityReference\n );\n // spread the property in case toJSON did not deep-clone\n (targetElementAspectProps as any)[name] = {\n ...(targetElementAspectProps as any)[name],\n id: targetEntityId,\n };\n })\n );\n }\n } else if (property.isPrimitive() && \"Id\" === property.extendedTypeName) {\n (targetElementAspectProps as any)[name] = this.findTargetElementId(\n sourceElementAspect.asAny[name]\n );\n }\n }\n await Promise.all(targetEntityIds);\n return targetElementAspectProps;\n }\n}\n"]}
|