@itwin/imodel-transformer 2.0.0-dev.49 → 2.0.0-dev.50

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.
@@ -0,0 +1,43 @@
1
+ /** @packageDocumentation
2
+ * @module Utils
3
+ */
4
+ import { EntityReference } from "@itwin/core-common";
5
+ import { IModelDb } from "@itwin/core-backend";
6
+ /** A positive-only read-through cache of entity existence checks, scoped to a single transformation run.
7
+ *
8
+ * Entities are created continuously as a transformation progresses, so a negative
9
+ * ("does not exist") result may become stale at any moment — therefore only positive
10
+ * results are ever cached. Positive results can only be invalidated by deletes, which the
11
+ * transformer routes through [[invalidate]] and [[clearDb]].
12
+ *
13
+ * The cache is keyed by [IModelDb]($core-backend) instance, so same-iModel transformations
14
+ * (where sourceDb === targetDb) share a single set and source/target roles cannot be confused.
15
+ *
16
+ * [IModelImporter]($transformer) delete operations invalidate registered caches. Deletes performed
17
+ * directly through an `EditTxn` while a transformation is active are out-of-band and must not be
18
+ * mixed with transformer operations. A successful high-level `process()` clears the cache when the
19
+ * transformation finalizes; low-level or failed transformations clear it when the transformer is
20
+ * disposed.
21
+ * @internal
22
+ */
23
+ export declare class EntityExistenceCache {
24
+ private _existsByDb;
25
+ private getDbSet;
26
+ /** Check whether an entity exists in `db`, consulting the cache first.
27
+ * A `true` result is cached; a `false` result is never cached and will be re-queried.
28
+ */
29
+ exists(db: IModelDb, entityReference: EntityReference): Promise<boolean>;
30
+ /** Read through the cache to check which of the supplied entities exist in `db`, populating it on a miss. */
31
+ existsAll(db: IModelDb, entityReferences: Iterable<EntityReference>): Promise<ReadonlySet<EntityReference>>;
32
+ /** Record that an entity is known to exist in `db` (e.g. it was just imported). */
33
+ markExists(db: IModelDb, entityReference: EntityReference): void;
34
+ /** Remove a single entity from the cache for `db`, forcing a re-query on next check. */
35
+ invalidate(db: IModelDb, entityReference: EntityReference): void;
36
+ /** Drop all cached results for `db`. Used when a delete may cascade to entities the
37
+ * caller cannot enumerate (e.g. element tree deletes that remove descendants and submodels).
38
+ */
39
+ clearDb(db: IModelDb): void;
40
+ /** Drop all cached results. */
41
+ clear(): void;
42
+ }
43
+ //# sourceMappingURL=EntityExistenceCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityExistenceCache.d.ts","sourceRoot":"","sources":["../../src/EntityExistenceCache.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,WAAW,CAA6C;IAEhE,OAAO,CAAC,QAAQ;IAShB;;OAEG;IACU,MAAM,CACjB,EAAE,EAAE,QAAQ,EACZ,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,OAAO,CAAC,CAMlB;IAED,6GAA6G;IAChG,SAAS,CACpB,EAAE,EAAE,QAAQ,EACZ,gBAAgB,EAAE,QAAQ,CAAC,eAAe,CAAC,GAC1C,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAkBvC;IAED,mFAAmF;IAC5E,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CAEtE;IAED,wFAAwF;IACjF,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CAEtE;IAED;;OAEG;IACI,OAAO,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAEjC;IAED,+BAA+B;IACxB,KAAK,IAAI,IAAI,CAEnB;CACF"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ /** @packageDocumentation
7
+ * @module Utils
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.EntityExistenceCache = void 0;
11
+ const EntityUnifier_1 = require("./EntityUnifier");
12
+ /** A positive-only read-through cache of entity existence checks, scoped to a single transformation run.
13
+ *
14
+ * Entities are created continuously as a transformation progresses, so a negative
15
+ * ("does not exist") result may become stale at any moment — therefore only positive
16
+ * results are ever cached. Positive results can only be invalidated by deletes, which the
17
+ * transformer routes through [[invalidate]] and [[clearDb]].
18
+ *
19
+ * The cache is keyed by [IModelDb]($core-backend) instance, so same-iModel transformations
20
+ * (where sourceDb === targetDb) share a single set and source/target roles cannot be confused.
21
+ *
22
+ * [IModelImporter]($transformer) delete operations invalidate registered caches. Deletes performed
23
+ * directly through an `EditTxn` while a transformation is active are out-of-band and must not be
24
+ * mixed with transformer operations. A successful high-level `process()` clears the cache when the
25
+ * transformation finalizes; low-level or failed transformations clear it when the transformer is
26
+ * disposed.
27
+ * @internal
28
+ */
29
+ class EntityExistenceCache {
30
+ _existsByDb = new Map();
31
+ getDbSet(db) {
32
+ let set = this._existsByDb.get(db);
33
+ if (set === undefined) {
34
+ set = new Set();
35
+ this._existsByDb.set(db, set);
36
+ }
37
+ return set;
38
+ }
39
+ /** Check whether an entity exists in `db`, consulting the cache first.
40
+ * A `true` result is cached; a `false` result is never cached and will be re-queried.
41
+ */
42
+ async exists(db, entityReference) {
43
+ const set = this.getDbSet(db);
44
+ if (set.has(entityReference))
45
+ return true;
46
+ const found = await EntityUnifier_1.EntityUnifier.exists(db, { entityReference });
47
+ if (found)
48
+ set.add(entityReference);
49
+ return found;
50
+ }
51
+ /** Read through the cache to check which of the supplied entities exist in `db`, populating it on a miss. */
52
+ async existsAll(db, entityReferences) {
53
+ const dbSet = this.getDbSet(db);
54
+ const found = new Set();
55
+ const unverified = [];
56
+ for (const entityReference of entityReferences) {
57
+ if (dbSet.has(entityReference))
58
+ found.add(entityReference);
59
+ else
60
+ unverified.push(entityReference);
61
+ }
62
+ if (unverified.length === 0)
63
+ return found;
64
+ const queried = await EntityUnifier_1.EntityUnifier.existsAll(db, unverified);
65
+ for (const entityReference of queried) {
66
+ dbSet.add(entityReference);
67
+ found.add(entityReference);
68
+ }
69
+ return found;
70
+ }
71
+ /** Record that an entity is known to exist in `db` (e.g. it was just imported). */
72
+ markExists(db, entityReference) {
73
+ this.getDbSet(db).add(entityReference);
74
+ }
75
+ /** Remove a single entity from the cache for `db`, forcing a re-query on next check. */
76
+ invalidate(db, entityReference) {
77
+ this._existsByDb.get(db)?.delete(entityReference);
78
+ }
79
+ /** Drop all cached results for `db`. Used when a delete may cascade to entities the
80
+ * caller cannot enumerate (e.g. element tree deletes that remove descendants and submodels).
81
+ */
82
+ clearDb(db) {
83
+ this._existsByDb.delete(db);
84
+ }
85
+ /** Drop all cached results. */
86
+ clear() {
87
+ this._existsByDb.clear();
88
+ }
89
+ }
90
+ exports.EntityExistenceCache = EntityExistenceCache;
91
+ //# sourceMappingURL=EntityExistenceCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityExistenceCache.js","sourceRoot":"","sources":["../../src/EntityExistenceCache.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;AAChG;;GAEG;;;AAIH,mDAAgD;AAEhD;;;;;;;;;;;;;;;;GAgBG;AACH;IACU,WAAW,GAAG,IAAI,GAAG,EAAkC,CAAC;IAExD,QAAQ,CAAC,EAAY;QAC3B,IAAI,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,MAAM,CACjB,EAAY,EACZ,eAAgC;QAEhC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC9B,IAAI,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,MAAM,KAAK,GAAG,MAAM,6BAAa,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;QAClE,IAAI,KAAK;YAAE,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,6GAA6G;IACtG,KAAK,CAAC,SAAS,CACpB,EAAY,EACZ,gBAA2C;QAE3C,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;QACzC,MAAM,UAAU,GAAsB,EAAE,CAAC;QAEzC,KAAK,MAAM,eAAe,IAAI,gBAAgB,EAAE,CAAC;YAC/C,IAAI,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;;gBACtD,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAE1C,MAAM,OAAO,GAAG,MAAM,6BAAa,CAAC,SAAS,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAC9D,KAAK,MAAM,eAAe,IAAI,OAAO,EAAE,CAAC;YACtC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC3B,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mFAAmF;IAC5E,UAAU,CAAC,EAAY,EAAE,eAAgC;QAC9D,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACzC,CAAC;IAED,wFAAwF;IACjF,UAAU,CAAC,EAAY,EAAE,eAAgC;QAC9D,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACI,OAAO,CAAC,EAAY;QACzB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,+BAA+B;IACxB,KAAK;QACV,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;CACF","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Utils\n */\n\nimport { EntityReference } from \"@itwin/core-common\";\nimport { IModelDb } from \"@itwin/core-backend\";\nimport { EntityUnifier } from \"./EntityUnifier\";\n\n/** A positive-only read-through cache of entity existence checks, scoped to a single transformation run.\n *\n * Entities are created continuously as a transformation progresses, so a negative\n * (\"does not exist\") result may become stale at any moment — therefore only positive\n * results are ever cached. Positive results can only be invalidated by deletes, which the\n * transformer routes through [[invalidate]] and [[clearDb]].\n *\n * The cache is keyed by [IModelDb]($core-backend) instance, so same-iModel transformations\n * (where sourceDb === targetDb) share a single set and source/target roles cannot be confused.\n *\n * [IModelImporter]($transformer) delete operations invalidate registered caches. Deletes performed\n * directly through an `EditTxn` while a transformation is active are out-of-band and must not be\n * mixed with transformer operations. A successful high-level `process()` clears the cache when the\n * transformation finalizes; low-level or failed transformations clear it when the transformer is\n * disposed.\n * @internal\n */\nexport class EntityExistenceCache {\n private _existsByDb = new Map<IModelDb, Set<EntityReference>>();\n\n private getDbSet(db: IModelDb): Set<EntityReference> {\n let set = this._existsByDb.get(db);\n if (set === undefined) {\n set = new Set();\n this._existsByDb.set(db, set);\n }\n return set;\n }\n\n /** Check whether an entity exists in `db`, consulting the cache first.\n * A `true` result is cached; a `false` result is never cached and will be re-queried.\n */\n public async exists(\n db: IModelDb,\n entityReference: EntityReference\n ): Promise<boolean> {\n const set = this.getDbSet(db);\n if (set.has(entityReference)) return true;\n const found = await EntityUnifier.exists(db, { entityReference });\n if (found) set.add(entityReference);\n return found;\n }\n\n /** Read through the cache to check which of the supplied entities exist in `db`, populating it on a miss. */\n public async existsAll(\n db: IModelDb,\n entityReferences: Iterable<EntityReference>\n ): Promise<ReadonlySet<EntityReference>> {\n const dbSet = this.getDbSet(db);\n const found = new Set<EntityReference>();\n const unverified: EntityReference[] = [];\n\n for (const entityReference of entityReferences) {\n if (dbSet.has(entityReference)) found.add(entityReference);\n else unverified.push(entityReference);\n }\n\n if (unverified.length === 0) return found;\n\n const queried = await EntityUnifier.existsAll(db, unverified);\n for (const entityReference of queried) {\n dbSet.add(entityReference);\n found.add(entityReference);\n }\n return found;\n }\n\n /** Record that an entity is known to exist in `db` (e.g. it was just imported). */\n public markExists(db: IModelDb, entityReference: EntityReference): void {\n this.getDbSet(db).add(entityReference);\n }\n\n /** Remove a single entity from the cache for `db`, forcing a re-query on next check. */\n public invalidate(db: IModelDb, entityReference: EntityReference): void {\n this._existsByDb.get(db)?.delete(entityReference);\n }\n\n /** Drop all cached results for `db`. Used when a delete may cascade to entities the\n * caller cannot enumerate (e.g. element tree deletes that remove descendants and submodels).\n */\n public clearDb(db: IModelDb): void {\n this._existsByDb.delete(db);\n }\n\n /** Drop all cached results. */\n public clear(): void {\n this._existsByDb.clear();\n }\n}\n"]}
@@ -13,5 +13,9 @@ export declare namespace EntityUnifier {
13
13
  } | {
14
14
  entityReference: EntityReference;
15
15
  }): Promise<boolean>;
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>>;
16
20
  }
17
21
  //# sourceMappingURL=EntityUnifier.d.ts.map
@@ -1 +1 @@
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;CACF"}
1
+ {"version":3,"file":"EntityUnifier.d.ts","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,EAEL,eAAe,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,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,CA6B/B;CACF"}
@@ -55,5 +55,36 @@ var EntityUnifier;
55
55
  return reader.step();
56
56
  }
57
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
+ const query = `SELECT ECInstanceId FROM ${classFullName} WHERE InVirtualSet(:ids, ECInstanceId)`;
78
+ const params = new core_common_1.QueryBinder().bindIdSet("ids", core_bentley_1.OrderedId64Iterable.sortArray([...ids]));
79
+ const reader = db.createQueryReader(query, params, {
80
+ usePrimaryConn: true,
81
+ });
82
+ while (await reader.step()) {
83
+ found.add(core_backend_1.EntityReferences.fromEntityType(reader.current[0], type));
84
+ }
85
+ }
86
+ return found;
87
+ }
88
+ EntityUnifier.existsAll = existsAll;
58
89
  })(EntityUnifier || (exports.EntityUnifier = EntityUnifier = {}));
59
90
  //# sourceMappingURL=EntityUnifier.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EntityUnifier.js","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;AAChG;;;;GAIG;;;AAEH,oDAI4B;AAC5B,sDAU6B;AAC7B,sDAAuD;AAEvD,MAAM,kBAAkB,GAA+C;IACrE,CAAC,iCAAmB,CAAC,KAAK,CAAC,EAAE,oBAAK;IAClC,CAAC,iCAAmB,CAAC,OAAO,CAAC,EAAE,sBAAO;IACtC,CAAC,iCAAmB,CAAC,aAAa,CAAC,EAAE,4BAAa;IAClD,CAAC,iCAAmB,CAAC,YAAY,CAAC,EAAE,2BAAY;CACjD,CAAC;AAEF,gBAAgB;AAChB,IAAiB,aAAa,CAgC7B;AAhCD,WAAiB,aAAa;IAC5B,SAAgB,eAAe,CAAC,MAAsB;QACpD,IAAI,MAAM,YAAY,sBAAO;YAAE,OAAO,SAAS,CAAC;aAC3C,IAAI,MAAM,YAAY,4BAAa;YAAE,OAAO,gBAAgB,CAAC;aAC7D,IAAI,MAAM,YAAY,2BAAY;YAAE,OAAO,cAAc,CAAC;;YAC1D,OAAO,qBAAqB,CAAC;IACpC,CAAC;IALe,cAAA,eAAe,kBAK9B,CAAA;IAEM,KAAK,UAAU,MAAM,CAC1B,EAAY,EACZ,GAAsE;QAEtE,IAAI,aAAqB,CAAC;QAC1B,IAAI,EAAc,CAAC;QACnB,IAAI,iBAAiB,IAAI,GAAG,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,+BAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACrE,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;YACvD,EAAE,GAAG,QAAQ,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC;YACvE,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACrB,CAAC;QAED,IAAI,mBAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QAErC,MAAM,KAAK,GAAG,iBAAiB,aAAa,yBAAyB,CAAC;QACtE,MAAM,MAAM,GAAG,IAAI,yBAAW,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;YACjD,cAAc,EAAE,IAAI;SACrB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAvBqB,cAAA,MAAM,SAuB3B,CAAA;AACH,CAAC,EAhCgB,aAAa,aAAb,aAAa,GAAb,aAAa,QAgC7B","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 } 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"]}
1
+ {"version":3,"file":"EntityUnifier.js","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;AAChG;;;;GAIG;;;AAEH,oDAI4B;AAC5B,sDAU6B;AAC7B,sDAA4E;AAE5E,MAAM,kBAAkB,GAA+C;IACrE,CAAC,iCAAmB,CAAC,KAAK,CAAC,EAAE,oBAAK;IAClC,CAAC,iCAAmB,CAAC,OAAO,CAAC,EAAE,sBAAO;IACtC,CAAC,iCAAmB,CAAC,aAAa,CAAC,EAAE,4BAAa;IAClD,CAAC,iCAAmB,CAAC,YAAY,CAAC,EAAE,2BAAY;CACjD,CAAC;AAEF,gBAAgB;AAChB,IAAiB,aAAa,CAqE7B;AArED,WAAiB,aAAa;IAC5B,SAAgB,eAAe,CAAC,MAAsB;QACpD,IAAI,MAAM,YAAY,sBAAO;YAAE,OAAO,SAAS,CAAC;aAC3C,IAAI,MAAM,YAAY,4BAAa;YAAE,OAAO,gBAAgB,CAAC;aAC7D,IAAI,MAAM,YAAY,2BAAY;YAAE,OAAO,cAAc,CAAC;;YAC1D,OAAO,qBAAqB,CAAC;IACpC,CAAC;IALe,cAAA,eAAe,kBAK9B,CAAA;IAEM,KAAK,UAAU,MAAM,CAC1B,EAAY,EACZ,GAAsE;QAEtE,IAAI,aAAqB,CAAC;QAC1B,IAAI,EAAc,CAAC;QACnB,IAAI,iBAAiB,IAAI,GAAG,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,+BAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACrE,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;YACvD,EAAE,GAAG,QAAQ,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC;YACvE,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACrB,CAAC;QAED,IAAI,mBAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QAErC,MAAM,KAAK,GAAG,iBAAiB,aAAa,yBAAyB,CAAC;QACtE,MAAM,MAAM,GAAG,IAAI,yBAAW,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;YACjD,cAAc,EAAE,IAAI;SACrB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAvBqB,cAAA,MAAM,SAuB3B,CAAA;IAED;;OAEG;IACI,KAAK,UAAU,SAAS,CAC7B,EAAY,EACZ,gBAA2C;QAE3C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwC,CAAC;QAClE,KAAK,MAAM,eAAe,IAAI,gBAAgB,EAAE,CAAC;YAC/C,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,+BAAgB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YAC3D,IAAI,mBAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAAE,SAAS;YACjC,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;gBAChB,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAC3B,CAAC;YACD,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;QACzC,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC;YACpC,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;YAC7D,MAAM,KAAK,GAAG,4BAA4B,aAAa,yCAAyC,CAAC;YACjG,MAAM,MAAM,GAAG,IAAI,yBAAW,EAAE,CAAC,SAAS,CACxC,KAAK,EACL,kCAAmB,CAAC,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CACxC,CAAC;YACF,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;gBACjD,cAAc,EAAE,IAAI;aACrB,CAAC,CAAC;YACH,OAAO,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC3B,KAAK,CAAC,GAAG,CAAC,+BAAgB,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAhCqB,cAAA,SAAS,YAgC9B,CAAA;AACH,CAAC,EArEgB,aAAa,aAAb,aAAa,GAAb,aAAa,QAqE7B","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 const query = `SELECT ECInstanceId FROM ${classFullName} WHERE InVirtualSet(:ids, 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,6 +1,7 @@
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";
4
5
  import type { IModelTransformContext } from "./IModelTransformContext";
5
6
  /** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
6
7
  * @internal
@@ -8,6 +9,10 @@ import type { IModelTransformContext } from "./IModelTransformContext";
8
9
  export declare class IModelCloneContext extends IModelElementCloneContext implements IModelTransformContext {
9
10
  private _refTypesCache;
10
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;
11
16
  /** perform necessary initialization to use a clone context, namely caching the reference types in the source's schemas */
12
17
  initialize(): Promise<void>;
13
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;AAM7B,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,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,CAmI1B;IAED;;OAEG;IACU,kBAAkB,CAC7B,mBAAmB,EAAE,aAAa,GACjC,OAAO,CAAC,kBAAkB,CAAC,CAqD7B;CACF"}
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"}
@@ -14,7 +14,7 @@ const core_common_1 = require("@itwin/core-common");
14
14
  const core_backend_1 = require("@itwin/core-backend");
15
15
  const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
16
16
  const ECReferenceTypesCache_1 = require("./ECReferenceTypesCache");
17
- const EntityUnifier_1 = require("./EntityUnifier");
17
+ const EntityExistenceCache_1 = require("./EntityExistenceCache");
18
18
  const TransformerLoggerCategory_1 = require("./TransformerLoggerCategory");
19
19
  const BigMap_1 = require("./BigMap");
20
20
  const loggerCategory = TransformerLoggerCategory_1.TransformerLoggerCategory.IModelCloneContext;
@@ -24,6 +24,10 @@ const loggerCategory = TransformerLoggerCategory_1.TransformerLoggerCategory.IMo
24
24
  class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
25
25
  _refTypesCache = new ECReferenceTypesCache_1.ECReferenceTypesCache();
26
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();
27
31
  /** perform necessary initialization to use a clone context, namely caching the reference types in the source's schemas */
28
32
  async initialize() {
29
33
  await this._refTypesCache.initAllSchemasInIModel(this.sourceDb);
@@ -123,9 +127,7 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
123
127
  }
124
128
  // Check if the model exists, `findTargetElementId` may have worked because the element exists when the model doesn't.
125
129
  // That can occur in the transformer since a submodeled element is imported before its submodel.
126
- if (await EntityUnifier_1.EntityUnifier.exists(this.targetDb, {
127
- entityReference: targetId,
128
- }))
130
+ if (await this.existenceCache.exists(this.targetDb, targetId))
129
131
  return targetId;
130
132
  break;
131
133
  }
@@ -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 { 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 { EntityUnifier } from \"./EntityUnifier\";\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 /** 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 (\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 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"]}
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"]}
@@ -6,6 +6,7 @@ import { ElementAspectProps, ElementProps, EntityProps, ModelProps } from "@itwi
6
6
  import { EditTxn, ElementAspect, ElementMultiAspect, Entity, IModelDb, RelationshipProps } from "@itwin/core-backend";
7
7
  import type { RelationshipPropsForDelete } from "./IModelTransformer";
8
8
  import { ElementAspectCleanup } from "./ElementAspectCleanup";
9
+ import { EntityExistenceCache } from "./EntityExistenceCache";
9
10
  /** Options provided to [[IModelImporter.optimizeGeometry]] specifying post-processing optimizations to be applied to the iModel's geometry.
10
11
  * @beta
11
12
  */
@@ -75,6 +76,7 @@ export declare class IModelImporter {
75
76
  * To resolve code values to their intended values call [[IModelImporter.resolveDuplicateCodeValues]].
76
77
  */
77
78
  private _duplicateCodeValueMap;
79
+ private readonly _entityExistenceCaches;
78
80
  /**
79
81
  * A set of elementIds that the transformer adds to while exporting elements to indicate that the element already exists in the target.
80
82
  * Defaults to an empty set.
@@ -106,6 +108,14 @@ export declare class IModelImporter {
106
108
  * @param options The options that specify how the import should be done.
107
109
  */
108
110
  constructor(editTxn: EditTxn, options?: IModelImportOptions);
111
+ /** Register a transformation-scoped existence cache for delete invalidation.
112
+ * @internal
113
+ */
114
+ registerEntityExistenceCache(cache: EntityExistenceCache): void;
115
+ /** Stop invalidating a transformation-scoped existence cache.
116
+ * @internal
117
+ */
118
+ unregisterEntityExistenceCache(cache: EntityExistenceCache): void;
109
119
  /**
110
120
  * Checks [[IModelImportOptions.skipPropagateChangesToRootElements]], [[IModelImporter.rootElementIds]], and [[IModelImporter.doNotUpdateElementIds]] and returns true for 'do not update', false for do 'update'.
111
121
  */
@@ -222,7 +232,8 @@ export declare class IModelImporter {
222
232
  * Needs to be called to perform necessary cleanup operations.
223
233
  * By not calling `finalize` there is a risk that data imported into targetDb will not be as expected.
224
234
  *
225
- * @note No need to call this If using [[IModelTransformer]] as it automatically invokes this method.
235
+ * @note [[IModelTransformer.process]] invokes this method automatically. Call it explicitly after
236
+ * composing the transformer's lower-level subset processing methods.
226
237
  */
227
238
  finalize(): void;
228
239
  }
@@ -1 +1 @@
1
- {"version":3,"file":"IModelImporter.d.ts","sourceRoot":"","sources":["../../src/IModelImporter.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,OAAO,EAGL,UAAU,EAIX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,kBAAkB,EAClB,YAAY,EACZ,WAAW,EAGX,UAAU,EAGX,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,OAAO,EACP,aAAa,EACb,kBAAkB,EAClB,MAAM,EACN,QAAQ,EAER,iBAAiB,EAGlB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAGtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAa9D;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,wBAAwB,CAAC,EAAE,OAAO,GAAG;QAAE,eAAe,EAAE,OAAO,CAAA;KAAE,CAAC;IAClE,iDAAiD;IACjD,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACzC;;OAEG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;;;OAIG;IACH,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,oCAAoC;IACpC,SAAgB,QAAQ,EAAE,QAAQ,CAAC;IAEnC;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAErC;;OAEG;IACH,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAuB;IAE7D;;OAEG;IACH,IAAW,oBAAoB,IAAI,oBAAoB,CAEtD;IAED;;OAEG;IACH,SAAgB,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IAEvD,OAAO,CAAC,MAAM,CAAC,uCAAuC,CAAqB;IAE3E;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB,CAA0B;IACxD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,kCAAkC,CAA2B;IAErE;;;OAGG;IACH,SAAgB,qBAAqB,cAA2B;IAEhE,mOAAmO;IACnO,OAAO,CAAC,QAAQ,CAAC,eAAe,CAI7B;IAEH,mHAAmH;IAC5G,gBAAgB,EAAE,MAAM,CAAQ;IACvC,yDAAyD;IACzD,OAAO,CAAC,gBAAgB,CAAa;IACrC,MAAM;IACN,OAAO,CAAC,wBAAwB,CAE7B;IAEH;;;OAGG;IACH,YAAmB,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,EAiBjE;IAED;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACI,oCAAoC,CAAC,SAAS,EAAE,UAAU,QAKhE;IAED,iGAAiG;IACpF,WAAW,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkC9D;IAED;;OAEG;IACH,UAAgB,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAuBzE;IAED;;OAEG;IACH,UAAgB,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAOnE;IAED,qCAAqC;IACrC,OAAO,CAAC,oBAAoB;IAK5B;;;OAGG;YACW,gBAAgB;IAoB9B,mGAAmG;IACtF,aAAa,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAiD1E;IAED;;;OAGG;IACH,UAAgB,eAAe,CAC7B,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,UAAU,CAAC,CAsCrB;IAED;;OAEG;IACH,UAAgB,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BzE;IAED;;;OAGG;IACH,UAAgB,eAAe,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAOpE;IAED,2DAA2D;IAC9C,aAAa,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAS/D;IAED;;OAEG;IACH,UAAgB,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhE;IAED,yDAAyD;IAC5C,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3D;IAED,wCAAwC;IACxC,OAAO,CAAC,sBAAsB;IAS9B,4DAA4D;IAC/C,yBAAyB,CACpC,WAAW,EAAE,kBAAkB,GAC9B,OAAO,CAAC,UAAU,CAAC,CAYrB;IAED;;;;;OAKG;IACU,yBAAyB,CACpC,gBAAgB,EAAE,kBAAkB,EAAE;IACtC,2GAA2G;IAC3G,UAAU,GAAE,CAAC,CAAC,EAAE,kBAAkB,KAAK,OAAoB,GAC1D,OAAO,CAAC,UAAU,EAAE,CAAC,CAoEvB;IAED;;OAEG;IACH,UAAgB,qBAAqB,CACnC,WAAW,EAAE,kBAAkB,GAC9B,OAAO,CAAC,UAAU,CAAC,CAsBrB;IAED;;OAEG;IACH,UAAgB,qBAAqB,CACnC,WAAW,EAAE,kBAAkB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAOf;IAED;;OAEG;IACH,UAAgB,qBAAqB,CACnC,mBAAmB,EAAE,aAAa,GACjC,OAAO,CAAC,IAAI,CAAC,CAOf;IAED,8CAA8C;IAC9C,OAAO,CAAC,4BAA4B;IAMpC;;OAEG;IACU,kBAAkB,CAC7B,iBAAiB,EAAE,iBAAiB,GACnC,OAAO,CAAC,UAAU,CAAC,CAyCrB;IAED;;;OAGG;IACH,UAAgB,oBAAoB,CAClC,iBAAiB,EAAE,iBAAiB,GACnC,OAAO,CAAC,UAAU,CAAC,CAuBrB;IAED;;OAEG;IACH,UAAgB,oBAAoB,CAClC,iBAAiB,EAAE,iBAAiB,GACnC,OAAO,CAAC,IAAI,CAAC,CAgBf;IAED,gEAAgE;IAChE,UAAgB,oBAAoB,CAClC,iBAAiB,EAAE,0BAA0B,GAC5C,OAAO,CAAC,IAAI,CAAC,CAWf;IAED,gEAAgE;IACnD,kBAAkB,CAC7B,iBAAiB,EAAE,0BAA0B,GAC5C,OAAO,CAAC,IAAI,CAAC,CAEf;IAED,4CAA4C;IAC5C,OAAO,CAAC,2BAA2B;IAInC,kCAAkC;YACpB,aAAa;IAO3B;;OAEG;IACH,UAAgB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAG;IAE9C;;;OAGG;IACI,qBAAqB,IAAI,IAAI,CA0EnC;IAED;;;OAGG;IACI,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAQ9D;IAED,OAAO,CAAC,0BAA0B;IASlC;;;;;OAKG;IACI,QAAQ,IAAI,IAAI,CAEtB;CACF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC1B,OAAO,CAkCT"}
1
+ {"version":3,"file":"IModelImporter.d.ts","sourceRoot":"","sources":["../../src/IModelImporter.ts"],"names":[],"mappings":"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"}
@@ -58,6 +58,7 @@ class IModelImporter {
58
58
  * To resolve code values to their intended values call [[IModelImporter.resolveDuplicateCodeValues]].
59
59
  */
60
60
  _duplicateCodeValueMap;
61
+ _entityExistenceCaches = new Set();
61
62
  /**
62
63
  * A set of elementIds that the transformer adds to while exporting elements to indicate that the element already exists in the target.
63
64
  * Defaults to an empty set.
@@ -106,6 +107,18 @@ class IModelImporter {
106
107
  this._duplicateCodeValueMap = new Map();
107
108
  this._elementAspectCleanup = new ElementAspectCleanup_1.ElementAspectCleanup(this.targetDb, this._editTxn, async (aspect) => this.onDeleteElementAspect(aspect));
108
109
  }
110
+ /** Register a transformation-scoped existence cache for delete invalidation.
111
+ * @internal
112
+ */
113
+ registerEntityExistenceCache(cache) {
114
+ this._entityExistenceCaches.add(cache);
115
+ }
116
+ /** Stop invalidating a transformation-scoped existence cache.
117
+ * @internal
118
+ */
119
+ unregisterEntityExistenceCache(cache) {
120
+ this._entityExistenceCaches.delete(cache);
121
+ }
109
122
  /**
110
123
  * Checks [[IModelImportOptions.skipPropagateChangesToRootElements]], [[IModelImporter.rootElementIds]], and [[IModelImporter.doNotUpdateElementIds]] and returns true for 'do not update', false for do 'update'.
111
124
  */
@@ -337,6 +350,9 @@ class IModelImporter {
337
350
  return;
338
351
  }
339
352
  await this.onDeleteElement(elementId);
353
+ // Element deletion cascades can remove descendants and their submodels.
354
+ for (const cache of this._entityExistenceCaches)
355
+ cache.clearDb(this.targetDb);
340
356
  }
341
357
  /** Delete the specified Model from the target iModel.
342
358
  * @note A subclass may override this method to customize delete behavior but should call `super.onDeleteModel`.
@@ -349,6 +365,9 @@ class IModelImporter {
349
365
  /** Delete the specified Model from the target iModel. */
350
366
  async deleteModel(modelId) {
351
367
  await this.onDeleteModel(modelId);
368
+ const modelReference = core_backend_1.EntityReferences.fromEntityType(modelId, core_common_1.ConcreteEntityTypes.Model);
369
+ for (const cache of this._entityExistenceCaches)
370
+ cache.invalidate(this.targetDb, modelReference);
352
371
  }
353
372
  /** Format an Element for the Logger. */
354
373
  formatElementForLogger(elementProps) {
@@ -648,7 +667,8 @@ class IModelImporter {
648
667
  * Needs to be called to perform necessary cleanup operations.
649
668
  * By not calling `finalize` there is a risk that data imported into targetDb will not be as expected.
650
669
  *
651
- * @note No need to call this If using [[IModelTransformer]] as it automatically invokes this method.
670
+ * @note [[IModelTransformer.process]] invokes this method automatically. Call it explicitly after
671
+ * composing the transformer's lower-level subset processing methods.
652
672
  */
653
673
  finalize() {
654
674
  this.resolveDuplicateCodeValues();