@itwin/imodel-transformer 0.0.1-dev.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.
Files changed (43) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +33 -0
  3. package/lib/cjs/ECReferenceTypesCache.d.ts +37 -0
  4. package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -0
  5. package/lib/cjs/ECReferenceTypesCache.js +180 -0
  6. package/lib/cjs/ECReferenceTypesCache.js.map +1 -0
  7. package/lib/cjs/EntityMap.d.ts +26 -0
  8. package/lib/cjs/EntityMap.d.ts.map +1 -0
  9. package/lib/cjs/EntityMap.js +55 -0
  10. package/lib/cjs/EntityMap.js.map +1 -0
  11. package/lib/cjs/EntityUnifier.d.ts +16 -0
  12. package/lib/cjs/EntityUnifier.d.ts.map +1 -0
  13. package/lib/cjs/EntityUnifier.js +72 -0
  14. package/lib/cjs/EntityUnifier.js.map +1 -0
  15. package/lib/cjs/IModelCloneContext.d.ts +32 -0
  16. package/lib/cjs/IModelCloneContext.d.ts.map +1 -0
  17. package/lib/cjs/IModelCloneContext.js +195 -0
  18. package/lib/cjs/IModelCloneContext.js.map +1 -0
  19. package/lib/cjs/IModelExporter.d.ts +353 -0
  20. package/lib/cjs/IModelExporter.d.ts.map +1 -0
  21. package/lib/cjs/IModelExporter.js +804 -0
  22. package/lib/cjs/IModelExporter.js.map +1 -0
  23. package/lib/cjs/IModelImporter.d.ts +230 -0
  24. package/lib/cjs/IModelImporter.d.ts.map +1 -0
  25. package/lib/cjs/IModelImporter.js +591 -0
  26. package/lib/cjs/IModelImporter.js.map +1 -0
  27. package/lib/cjs/IModelTransformer.d.ts +499 -0
  28. package/lib/cjs/IModelTransformer.d.ts.map +1 -0
  29. package/lib/cjs/IModelTransformer.js +1357 -0
  30. package/lib/cjs/IModelTransformer.js.map +1 -0
  31. package/lib/cjs/PendingReferenceMap.d.ts +35 -0
  32. package/lib/cjs/PendingReferenceMap.d.ts.map +1 -0
  33. package/lib/cjs/PendingReferenceMap.js +81 -0
  34. package/lib/cjs/PendingReferenceMap.js.map +1 -0
  35. package/lib/cjs/TransformerLoggerCategory.d.ts +23 -0
  36. package/lib/cjs/TransformerLoggerCategory.d.ts.map +1 -0
  37. package/lib/cjs/TransformerLoggerCategory.js +31 -0
  38. package/lib/cjs/TransformerLoggerCategory.js.map +1 -0
  39. package/lib/cjs/transformer.d.ts +25 -0
  40. package/lib/cjs/transformer.d.ts.map +1 -0
  41. package/lib/cjs/transformer.js +77 -0
  42. package/lib/cjs/transformer.js.map +1 -0
  43. package/package.json +120 -0
package/LICENSE.md ADDED
@@ -0,0 +1,9 @@
1
+ # MIT License
2
+
3
+ Copyright © 2017-2023 Bentley Systems, Incorporated. All rights reserved.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # @itwin/imodel-transformer
2
+
3
+ Copyright © Bentley Systems, Incorporated. All rights reserved. See LICENSE.md for license terms and full copyright notice.
4
+
5
+ ## Description
6
+
7
+ The __@itwin/imodel-transformer__ package contains classes that handle traversing iModels for exporting and importing their parts.
8
+
9
+ ## Documentation
10
+
11
+ See the [iTwin.js](https://www.itwinjs.org) documentation for more information.
12
+
13
+ ## Versioning
14
+
15
+ This package, for the time being, relies on @internal APIs in iTwin.js, and therefore has very strict peerDependencies versions.
16
+ We perform a version check at runtime to ensure this. Every new iTwin.js version must be validated, and fixes are rarely ported
17
+ to old versions currently, you must request this in an issue. Removing Dependencies on internal APIs is ongoing.
18
+ You can find the latest @itwin/imodel-transformer version for your iTwin.js version by copy and pasting this into a bash shell
19
+
20
+ (use git bash on windows).
21
+
22
+ ```sh
23
+ MY_ITWINJS_VERSION="3.6.0" # edit me
24
+ pnpm -s --package=semver -c dlx node <<EOF
25
+ json=""
26
+ require("https").get("https://registry.npmjs.org/@itwin/imodel-transformer", r=>r.setEncoding("utf8").on("data", d=>json+=d).on("end", ()=>{
27
+ semver=require(process.env.PATH.split(":").find(x=>x.includes(".bin"))+"/../semver")
28
+ console.log(Object.entries(JSON.parse(json).versions)
29
+ .filter(([,v])=>semver.satisfies("$MY_ITWINJS_VERSION", v.peerDependencies["@itwin/core-backend"]))
30
+ .map(([k,v])=>k).reverse())
31
+ }))
32
+ EOF
33
+ ```
@@ -0,0 +1,37 @@
1
+ /** @packageDocumentation
2
+ * @module iModels
3
+ */
4
+ import { ConcreteEntityTypes, RelTypeInfo } from "@itwin/core-common";
5
+ import { IModelDb } from "@itwin/core-backend";
6
+ /** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
7
+ * @internal
8
+ */
9
+ export declare class SchemaNotInCacheErr extends Error {
10
+ constructor();
11
+ }
12
+ /**
13
+ * A cache of the entity types referenced by navprops in ecchemas, as well as the source and target entity types of
14
+ * The transformer needs the referenced type to determine how to resolve references.
15
+ *
16
+ * Using multiple of these usually performs redundant computation, for static schemas at least. A possible future optimization
17
+ * would be to seed the computation from a global cache of non-dynamic schemas, but dynamic schemas can collide willy-nilly
18
+ * @internal
19
+ */
20
+ export declare class ECReferenceTypesCache {
21
+ /** nesting based tuple map keyed by qualified property path tuple [schemaName, className, propName] */
22
+ private _propQualifierToRefType;
23
+ private _relClassNameEndToRefTypes;
24
+ private _initedSchemas;
25
+ private static bisRootClassToRefType;
26
+ private getRootBisClass;
27
+ private getAbstractConstraintClass;
28
+ /** initialize from an imodel with metadata */
29
+ initAllSchemasInIModel(imodel: IModelDb): Promise<void>;
30
+ private considerInitSchema;
31
+ private initSchema;
32
+ private relInfoFromRelClass;
33
+ getNavPropRefType(schemaName: string, className: string, propName: string): undefined | ConcreteEntityTypes;
34
+ getRelationshipEndType(schemaName: string, className: string): undefined | RelTypeInfo;
35
+ clear(): void;
36
+ }
37
+ //# sourceMappingURL=ECReferenceTypesCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ECReferenceTypesCache.d.ts","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,mBAAmB,EAAe,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGnF,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;;CAE7C;AAED;;;;;;;GAOG;AACH,qBAAa,qBAAqB;IAChC,uGAAuG;IACvG,OAAO,CAAC,uBAAuB,CAAsE;IACrG,OAAO,CAAC,0BAA0B,CAAsD;IACxF,OAAO,CAAC,cAAc,CAAgC;IAEtD,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAUlC;YAEY,eAAe;YAsBf,0BAA0B;IAOxC,8CAA8C;IACjC,sBAAsB,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;YA2BtD,kBAAkB;YAYlB,UAAU;YAuBV,mBAAmB;IAwB1B,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,mBAAmB;IAU3G,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW;IAStF,KAAK;CAIb"}
@@ -0,0 +1,180 @@
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 iModels
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ECReferenceTypesCache = exports.SchemaNotInCacheErr = void 0;
11
+ const core_bentley_1 = require("@itwin/core-bentley");
12
+ const core_common_1 = require("@itwin/core-common");
13
+ const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
14
+ const assert = require("assert");
15
+ /** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
16
+ * @internal
17
+ */
18
+ class SchemaNotInCacheErr extends Error {
19
+ constructor() { super("Schema was not in cache, initialize that schema"); }
20
+ }
21
+ exports.SchemaNotInCacheErr = SchemaNotInCacheErr;
22
+ /**
23
+ * A cache of the entity types referenced by navprops in ecchemas, as well as the source and target entity types of
24
+ * The transformer needs the referenced type to determine how to resolve references.
25
+ *
26
+ * Using multiple of these usually performs redundant computation, for static schemas at least. A possible future optimization
27
+ * would be to seed the computation from a global cache of non-dynamic schemas, but dynamic schemas can collide willy-nilly
28
+ * @internal
29
+ */
30
+ class ECReferenceTypesCache {
31
+ constructor() {
32
+ /** nesting based tuple map keyed by qualified property path tuple [schemaName, className, propName] */
33
+ this._propQualifierToRefType = new core_bentley_1.TupleKeyedMap();
34
+ this._relClassNameEndToRefTypes = new core_bentley_1.TupleKeyedMap();
35
+ this._initedSchemas = new Map();
36
+ }
37
+ async getRootBisClass(ecclass) {
38
+ let bisRootForConstraint = ecclass;
39
+ await ecclass.traverseBaseClasses((baseClass) => {
40
+ var _a;
41
+ // The depth first traversal will descend all the way to the root class before making any lateral traversal
42
+ // of mixin hierarchies, (or if the constraint is a mixin, it will traverse to the root of the mixin hierarchy)
43
+ // Once we see that we've moved laterally, we can terminate early
44
+ const isFirstTest = bisRootForConstraint === ecclass;
45
+ const traversalSwitchedRootPath = baseClass.name !== ((_a = bisRootForConstraint.baseClass) === null || _a === void 0 ? void 0 : _a.name);
46
+ const stillTraversingRootPath = isFirstTest || !traversalSwitchedRootPath;
47
+ if (!stillTraversingRootPath)
48
+ return true; // stop traversal early
49
+ bisRootForConstraint = baseClass;
50
+ return false;
51
+ });
52
+ // if the root class of the constraint was a mixin, use its AppliesToEntityClass
53
+ if (bisRootForConstraint instanceof ecschema_metadata_1.Mixin) {
54
+ assert(bisRootForConstraint.appliesTo !== undefined, "The referenced AppliesToEntityClass could not be found, how did it pass schema validation?");
55
+ bisRootForConstraint = await this.getRootBisClass(await bisRootForConstraint.appliesTo);
56
+ }
57
+ return bisRootForConstraint;
58
+ }
59
+ async getAbstractConstraintClass(constraint) {
60
+ var _a;
61
+ // constraint classes must share a base so we can get the root from any of them, just use the first
62
+ const ecclass = await (((_a = constraint.constraintClasses) === null || _a === void 0 ? void 0 : _a[0]) || constraint.abstractConstraint);
63
+ assert(ecclass !== undefined, "At least one constraint class or an abstract constraint must have been defined, the constraint is not valid");
64
+ return ecclass;
65
+ }
66
+ /** initialize from an imodel with metadata */
67
+ async initAllSchemasInIModel(imodel) {
68
+ const schemaLoader = new ecschema_metadata_1.SchemaLoader((name) => imodel.getSchemaProps(name));
69
+ await imodel.withPreparedStatement(`
70
+ WITH RECURSIVE refs(SchemaId) AS (
71
+ SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'
72
+ UNION ALL
73
+ SELECT sr.SourceECInstanceId
74
+ FROM ECDbMeta.SchemaHasSchemaReferences sr
75
+ JOIN refs ON sr.TargetECInstanceId = refs.SchemaId
76
+ )
77
+ SELECT s.Name
78
+ FROM refs
79
+ JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId
80
+ -- ensure schema dependency order
81
+ ORDER BY ECInstanceId
82
+ `, async (stmt) => {
83
+ let status;
84
+ while ((status = stmt.step()) === core_bentley_1.DbResult.BE_SQLITE_ROW) {
85
+ const schemaName = stmt.getValue(0).getString();
86
+ const schema = schemaLoader.getSchema(schemaName);
87
+ await this.considerInitSchema(schema);
88
+ }
89
+ if (status !== core_bentley_1.DbResult.BE_SQLITE_DONE)
90
+ throw new core_common_1.IModelError(status, "unexpected query failure");
91
+ });
92
+ }
93
+ async considerInitSchema(schema) {
94
+ if (this._initedSchemas.has(schema.name)) {
95
+ const cachedSchemaKey = this._initedSchemas.get(schema.name);
96
+ assert(cachedSchemaKey !== undefined);
97
+ const incomingSchemaIsEqualOrOlder = schema.schemaKey.compareByVersion(cachedSchemaKey) <= 0;
98
+ if (incomingSchemaIsEqualOrOlder) {
99
+ return;
100
+ }
101
+ }
102
+ return this.initSchema(schema);
103
+ }
104
+ async initSchema(schema) {
105
+ for (const ecclass of schema.getClasses()) {
106
+ for (const prop of await ecclass.getProperties()) {
107
+ if (!prop.isNavigation())
108
+ continue;
109
+ const relClass = await prop.relationshipClass;
110
+ const relInfo = await this.relInfoFromRelClass(relClass);
111
+ if (relInfo === undefined)
112
+ continue;
113
+ const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward ? relInfo.target : relInfo.source;
114
+ this._propQualifierToRefType.set([schema.name.toLowerCase(), ecclass.name.toLowerCase(), prop.name.toLowerCase()], navPropRefType);
115
+ }
116
+ if (ecclass instanceof ecschema_metadata_1.RelationshipClass) {
117
+ const relInfo = await this.relInfoFromRelClass(ecclass);
118
+ if (relInfo)
119
+ this._relClassNameEndToRefTypes.set([schema.name.toLowerCase(), ecclass.name.toLowerCase()], relInfo);
120
+ }
121
+ }
122
+ this._initedSchemas.set(schema.name, schema.schemaKey);
123
+ }
124
+ async relInfoFromRelClass(ecclass) {
125
+ assert(ecclass.source.constraintClasses !== undefined);
126
+ assert(ecclass.target.constraintClasses !== undefined);
127
+ const [[sourceClass, sourceRootBisClass], [targetClass, targetRootBisClass]] = await Promise.all([
128
+ this.getAbstractConstraintClass(ecclass.source)
129
+ .then(async (constraintClass) => [constraintClass, await this.getRootBisClass(constraintClass)]),
130
+ this.getAbstractConstraintClass(ecclass.target)
131
+ .then(async (constraintClass) => [constraintClass, await this.getRootBisClass(constraintClass)]),
132
+ ]);
133
+ if (sourceRootBisClass.name === "CodeSpec" || targetRootBisClass.name === "CodeSpec")
134
+ return undefined;
135
+ const sourceType = ECReferenceTypesCache.bisRootClassToRefType[sourceRootBisClass.name];
136
+ const targetType = ECReferenceTypesCache.bisRootClassToRefType[targetRootBisClass.name];
137
+ const makeAssertMsg = (root, cls) => [
138
+ `An unknown root class '${root.fullName}' was encountered while populating`,
139
+ `the nav prop reference type cache for ${cls.fullName}.`,
140
+ "This is a bug.",
141
+ ].join("\n");
142
+ assert(sourceType !== undefined, makeAssertMsg(sourceRootBisClass, sourceClass));
143
+ assert(targetType !== undefined, makeAssertMsg(targetRootBisClass, targetClass));
144
+ return { source: sourceType, target: targetType };
145
+ }
146
+ getNavPropRefType(schemaName, className, propName) {
147
+ if (!this._initedSchemas.has(schemaName))
148
+ throw new SchemaNotInCacheErr();
149
+ return this._propQualifierToRefType.get([
150
+ schemaName.toLowerCase(),
151
+ className.toLowerCase(),
152
+ propName.toLowerCase(),
153
+ ]);
154
+ }
155
+ getRelationshipEndType(schemaName, className) {
156
+ if (!this._initedSchemas.has(schemaName))
157
+ throw new SchemaNotInCacheErr();
158
+ return this._relClassNameEndToRefTypes.get([
159
+ schemaName.toLowerCase(),
160
+ className.toLowerCase(),
161
+ ]);
162
+ }
163
+ clear() {
164
+ this._initedSchemas.clear();
165
+ this._propQualifierToRefType.clear();
166
+ }
167
+ }
168
+ exports.ECReferenceTypesCache = ECReferenceTypesCache;
169
+ ECReferenceTypesCache.bisRootClassToRefType = {
170
+ /* eslint-disable quote-props, @typescript-eslint/naming-convention */
171
+ "Element": core_common_1.ConcreteEntityTypes.Element,
172
+ "Model": core_common_1.ConcreteEntityTypes.Model,
173
+ "ElementAspect": core_common_1.ConcreteEntityTypes.ElementAspect,
174
+ "ElementRefersToElements": core_common_1.ConcreteEntityTypes.Relationship,
175
+ "ElementDrivesElement": core_common_1.ConcreteEntityTypes.Relationship,
176
+ // code spec is technically a potential root class but it is ignored currently
177
+ // see [ConcreteEntityTypes]($common)
178
+ /* eslint-enable quote-props, @typescript-eslint/naming-convention */
179
+ };
180
+ //# sourceMappingURL=ECReferenceTypesCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ECReferenceTypesCache.js","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iModels\n */\n\nimport { DbResult, TupleKeyedMap } from \"@itwin/core-bentley\";\nimport { ConcreteEntityTypes, IModelError, RelTypeInfo } from \"@itwin/core-common\";\nimport { ECClass, Mixin, RelationshipClass, RelationshipConstraint, Schema, SchemaKey, SchemaLoader, StrengthDirection } from \"@itwin/ecschema-metadata\";\nimport * as assert from \"assert\";\nimport { IModelDb } from \"@itwin/core-backend\";\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 SchemaNotInCacheErr extends Error {\n public constructor() { super(\"Schema was not in cache, initialize that schema\"); }\n}\n\n/**\n * A cache of the entity types referenced by navprops in ecchemas, as well as the source and target entity types of\n * The transformer needs the referenced type to determine how to resolve references.\n *\n * Using multiple of these usually performs redundant computation, for static schemas at least. A possible future optimization\n * would be to seed the computation from a global cache of non-dynamic schemas, but dynamic schemas can collide willy-nilly\n * @internal\n */\nexport class ECReferenceTypesCache {\n /** nesting based tuple map keyed by qualified property path tuple [schemaName, className, propName] */\n private _propQualifierToRefType = new TupleKeyedMap<[string, string, string], ConcreteEntityTypes>();\n private _relClassNameEndToRefTypes = new TupleKeyedMap<[string, string], RelTypeInfo>();\n private _initedSchemas = new Map<string, SchemaKey>();\n\n private static bisRootClassToRefType: Record<string, ConcreteEntityTypes | undefined> = {\n /* eslint-disable quote-props, @typescript-eslint/naming-convention */\n \"Element\": ConcreteEntityTypes.Element,\n \"Model\": ConcreteEntityTypes.Model,\n \"ElementAspect\": ConcreteEntityTypes.ElementAspect,\n \"ElementRefersToElements\": ConcreteEntityTypes.Relationship,\n \"ElementDrivesElement\": ConcreteEntityTypes.Relationship,\n // code spec is technically a potential root class but it is ignored currently\n // see [ConcreteEntityTypes]($common)\n /* eslint-enable quote-props, @typescript-eslint/naming-convention */\n };\n\n private async getRootBisClass(ecclass: ECClass) {\n let bisRootForConstraint: ECClass = ecclass;\n await ecclass.traverseBaseClasses((baseClass) => {\n // The depth first traversal will descend all the way to the root class before making any lateral traversal\n // of mixin hierarchies, (or if the constraint is a mixin, it will traverse to the root of the mixin hierarchy)\n // Once we see that we've moved laterally, we can terminate early\n const isFirstTest = bisRootForConstraint === ecclass;\n const traversalSwitchedRootPath = baseClass.name !== bisRootForConstraint.baseClass?.name;\n const stillTraversingRootPath = isFirstTest || !traversalSwitchedRootPath;\n if (!stillTraversingRootPath)\n return true; // stop traversal early\n bisRootForConstraint = baseClass;\n return false;\n });\n // if the root class of the constraint was a mixin, use its AppliesToEntityClass\n if (bisRootForConstraint instanceof Mixin) {\n assert(bisRootForConstraint.appliesTo !== undefined, \"The referenced AppliesToEntityClass could not be found, how did it pass schema validation?\");\n bisRootForConstraint = await this.getRootBisClass(await bisRootForConstraint.appliesTo);\n }\n return bisRootForConstraint;\n }\n\n private async getAbstractConstraintClass(constraint: RelationshipConstraint): Promise<ECClass> {\n // constraint classes must share a base so we can get the root from any of them, just use the first\n const ecclass = await (constraint.constraintClasses?.[0] || constraint.abstractConstraint);\n assert(ecclass !== undefined, \"At least one constraint class or an abstract constraint must have been defined, the constraint is not valid\");\n return ecclass;\n }\n\n /** initialize from an imodel with metadata */\n public async initAllSchemasInIModel(imodel: IModelDb): Promise<void> {\n const schemaLoader = new SchemaLoader((name: string) => imodel.getSchemaProps(name));\n await imodel.withPreparedStatement(`\n WITH RECURSIVE refs(SchemaId) AS (\n SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'\n UNION ALL\n SELECT sr.SourceECInstanceId\n FROM ECDbMeta.SchemaHasSchemaReferences sr\n JOIN refs ON sr.TargetECInstanceId = refs.SchemaId\n )\n SELECT s.Name\n FROM refs\n JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId\n -- ensure schema dependency order\n ORDER BY ECInstanceId\n `, async (stmt) => {\n let status: DbResult;\n while ((status = stmt.step()) === DbResult.BE_SQLITE_ROW) {\n const schemaName = stmt.getValue(0).getString();\n const schema = schemaLoader.getSchema(schemaName);\n await this.considerInitSchema(schema);\n }\n if (status !== DbResult.BE_SQLITE_DONE)\n throw new IModelError(status, \"unexpected query failure\");\n });\n }\n\n private async considerInitSchema(schema: Schema): Promise<void> {\n if (this._initedSchemas.has(schema.name)) {\n const cachedSchemaKey = this._initedSchemas.get(schema.name);\n assert(cachedSchemaKey !== undefined);\n const incomingSchemaIsEqualOrOlder = schema.schemaKey.compareByVersion(cachedSchemaKey) <= 0;\n if (incomingSchemaIsEqualOrOlder) {\n return;\n }\n }\n return this.initSchema(schema);\n }\n\n private async initSchema(schema: Schema): Promise<void> {\n for (const ecclass of schema.getClasses()) {\n for (const prop of await ecclass.getProperties()) {\n if (!prop.isNavigation())\n continue;\n const relClass = await prop.relationshipClass;\n const relInfo = await this.relInfoFromRelClass(relClass);\n if (relInfo === undefined)\n continue;\n const navPropRefType = prop.direction === StrengthDirection.Forward ? relInfo.target : relInfo.source;\n this._propQualifierToRefType.set([schema.name.toLowerCase(), ecclass.name.toLowerCase(), prop.name.toLowerCase()], navPropRefType);\n }\n\n if (ecclass instanceof RelationshipClass) {\n const relInfo = await this.relInfoFromRelClass(ecclass);\n if (relInfo)\n this._relClassNameEndToRefTypes.set([schema.name.toLowerCase(), ecclass.name.toLowerCase()], relInfo);\n }\n }\n\n this._initedSchemas.set(schema.name, schema.schemaKey);\n }\n\n private async relInfoFromRelClass(ecclass: RelationshipClass): Promise<RelTypeInfo | undefined> {\n assert(ecclass.source.constraintClasses !== undefined);\n assert(ecclass.target.constraintClasses !== undefined);\n const [[sourceClass, sourceRootBisClass], [targetClass, targetRootBisClass]] = await Promise.all([\n this.getAbstractConstraintClass(ecclass.source)\n .then(async (constraintClass) => [constraintClass, await this.getRootBisClass(constraintClass)]),\n this.getAbstractConstraintClass(ecclass.target)\n .then(async (constraintClass) => [constraintClass, await this.getRootBisClass(constraintClass)]),\n ]);\n\n if (sourceRootBisClass.name === \"CodeSpec\" || targetRootBisClass.name === \"CodeSpec\")\n return undefined;\n const sourceType = ECReferenceTypesCache.bisRootClassToRefType[sourceRootBisClass.name];\n const targetType = ECReferenceTypesCache.bisRootClassToRefType[targetRootBisClass.name];\n const makeAssertMsg = (root: ECClass, cls: ECClass) => [\n `An unknown root class '${root.fullName}' was encountered while populating`,\n `the nav prop reference type cache for ${cls.fullName}.`,\n \"This is a bug.\",\n ].join(\"\\n\");\n assert(sourceType !== undefined, makeAssertMsg(sourceRootBisClass, sourceClass));\n assert(targetType !== undefined, makeAssertMsg(targetRootBisClass, targetClass));\n return { source: sourceType, target: targetType };\n }\n\n public getNavPropRefType(schemaName: string, className: string, propName: string): undefined | ConcreteEntityTypes {\n if (!this._initedSchemas.has(schemaName))\n throw new SchemaNotInCacheErr();\n return this._propQualifierToRefType.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n propName.toLowerCase(),\n ]);\n }\n\n public getRelationshipEndType(schemaName: string, className: string): undefined | RelTypeInfo {\n if (!this._initedSchemas.has(schemaName))\n throw new SchemaNotInCacheErr();\n return this._relClassNameEndToRefTypes.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n ]);\n }\n\n public clear() {\n this._initedSchemas.clear();\n this._propQualifierToRefType.clear();\n }\n}\n"]}
@@ -0,0 +1,26 @@
1
+ /** @packageDocumentation
2
+ * @module Utils
3
+ */
4
+ import { EntityReference } from "@itwin/core-common";
5
+ import { ConcreteEntity } from "@itwin/core-backend";
6
+ /** @internal */
7
+ export declare type EntityKey = EntityReference;
8
+ /** @internal */
9
+ export declare class EntityMap<V> {
10
+ private _map;
11
+ static makeKey(entity: ConcreteEntity): EntityKey;
12
+ clear(): void;
13
+ has(entity: ConcreteEntity): boolean;
14
+ set(entity: ConcreteEntity, val: V): EntityMap<V>;
15
+ setByKey(k: EntityKey, val: V): EntityMap<V>;
16
+ get(entity: ConcreteEntity): V | undefined;
17
+ getByKey(k: EntityKey): V | undefined;
18
+ delete(entity: ConcreteEntity): boolean;
19
+ deleteByKey(k: EntityKey): boolean;
20
+ keys(): IterableIterator<`m${string}` | `e${string}` | `a${string}` | `r${string}`>;
21
+ values(): IterableIterator<V>;
22
+ entries(): IterableIterator<[`m${string}` | `e${string}` | `a${string}` | `r${string}`, V]>;
23
+ [Symbol.iterator](): IterableIterator<[`m${string}` | `e${string}` | `a${string}` | `r${string}`, V]>;
24
+ get size(): number;
25
+ }
26
+ //# sourceMappingURL=EntityMap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityMap.d.ts","sourceRoot":"","sources":["../../src/EntityMap.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAoB,MAAM,qBAAqB,CAAC;AAEvE,gBAAgB;AAChB,oBAAY,SAAS,GAAG,eAAe,CAAC;AAExC,gBAAgB;AAChB,qBAAa,SAAS,CAAC,CAAC;IACtB,OAAO,CAAC,IAAI,CAA2B;WAEzB,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS;IAIjD,KAAK,IAAI,IAAI;IAIb,GAAG,CAAC,MAAM,EAAE,cAAc;IAK1B,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAIjD,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAK5C,GAAG,CAAC,MAAM,EAAE,cAAc,GAAG,CAAC,GAAG,SAAS;IAI1C,QAAQ,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,GAAG,SAAS;IAIrC,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO;IAIvC,WAAW,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO;IAIlC,IAAI;IAIJ,MAAM;IAIN,OAAO;IAIP,CAAC,MAAM,CAAC,QAAQ,CAAC;IAIxB,IAAW,IAAI,WAEd;CACF"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EntityMap = void 0;
4
+ const core_backend_1 = require("@itwin/core-backend");
5
+ /** @internal */
6
+ class EntityMap {
7
+ constructor() {
8
+ this._map = new Map();
9
+ }
10
+ static makeKey(entity) {
11
+ return core_backend_1.EntityReferences.from(entity);
12
+ }
13
+ clear() {
14
+ return this._map.clear();
15
+ }
16
+ has(entity) {
17
+ return this._map.has(EntityMap.makeKey(entity));
18
+ }
19
+ set(entity, val) {
20
+ return this.setByKey(EntityMap.makeKey(entity), val);
21
+ }
22
+ setByKey(k, val) {
23
+ this._map.set(k, val);
24
+ return this;
25
+ }
26
+ get(entity) {
27
+ return this.getByKey(EntityMap.makeKey(entity));
28
+ }
29
+ getByKey(k) {
30
+ return this._map.get(k);
31
+ }
32
+ delete(entity) {
33
+ return this.deleteByKey(EntityMap.makeKey(entity));
34
+ }
35
+ deleteByKey(k) {
36
+ return this._map.delete(k);
37
+ }
38
+ keys() {
39
+ return this._map.keys();
40
+ }
41
+ values() {
42
+ return this._map.values();
43
+ }
44
+ entries() {
45
+ return this._map.entries();
46
+ }
47
+ [Symbol.iterator]() {
48
+ return this._map[Symbol.iterator]();
49
+ }
50
+ get size() {
51
+ return this._map.size;
52
+ }
53
+ }
54
+ exports.EntityMap = EntityMap;
55
+ //# sourceMappingURL=EntityMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityMap.js","sourceRoot":"","sources":["../../src/EntityMap.ts"],"names":[],"mappings":";;;AAQA,sDAAuE;AAKvE,gBAAgB;AAChB,MAAa,SAAS;IAAtB;QACU,SAAI,GAAG,IAAI,GAAG,EAAgB,CAAC;IA2DzC,CAAC;IAzDQ,MAAM,CAAC,OAAO,CAAC,MAAsB;QAC1C,OAAO,+BAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAEM,KAAK;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAEM,GAAG,CAAC,MAAsB;QAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAC7C,CAAC;IACJ,CAAC;IAEM,GAAG,CAAC,MAAsB,EAAE,GAAM;QACvC,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAEM,QAAQ,CAAC,CAAY,EAAE,GAAM;QAClC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,GAAG,CAAC,MAAsB;QAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC;IAEM,QAAQ,CAAC,CAAY;QAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAEM,MAAM,CAAC,MAAsB;QAClC,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC;IAEM,WAAW,CAAC,CAAY;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC;IAEM,IAAI;QACT,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;IAEM,OAAO;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAEM,CAAC,MAAM,CAAC,QAAQ,CAAC;QACtB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IACtC,CAAC;IAED,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;CACF;AA5DD,8BA4DC","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 */\nimport { EntityReference } from \"@itwin/core-common\";\nimport { ConcreteEntity, EntityReferences } from \"@itwin/core-backend\";\n\n/** @internal */\nexport type EntityKey = EntityReference;\n\n/** @internal */\nexport class EntityMap<V> {\n private _map = new Map<EntityKey, V>();\n\n public static makeKey(entity: ConcreteEntity): EntityKey {\n return EntityReferences.from(entity);\n }\n\n public clear(): void {\n return this._map.clear();\n }\n\n public has(entity: ConcreteEntity) {\n return this._map.has(EntityMap.makeKey(entity)\n );\n }\n\n public set(entity: ConcreteEntity, val: V): EntityMap<V> {\n return this.setByKey(EntityMap.makeKey(entity), val);\n }\n\n public setByKey(k: EntityKey, val: V): EntityMap<V> {\n this._map.set(k, val);\n return this;\n }\n\n public get(entity: ConcreteEntity): V | undefined {\n return this.getByKey(EntityMap.makeKey(entity));\n }\n\n public getByKey(k: EntityKey): V | undefined {\n return this._map.get(k);\n }\n\n public delete(entity: ConcreteEntity): boolean {\n return this.deleteByKey(EntityMap.makeKey(entity));\n }\n\n public deleteByKey(k: EntityKey): boolean {\n return this._map.delete(k);\n }\n\n public keys() {\n return this._map.keys();\n }\n\n public values() {\n return this._map.values();\n }\n\n public entries() {\n return this._map.entries();\n }\n\n public [Symbol.iterator]() {\n return this._map[Symbol.iterator]();\n }\n\n public get size() {\n return this._map.size;\n }\n}\n\n"]}
@@ -0,0 +1,16 @@
1
+ import { EntityReference } from "@itwin/core-common";
2
+ import { ConcreteEntity, ConcreteEntityProps, IModelDb } from "@itwin/core-backend";
3
+ /** @internal */
4
+ export declare namespace EntityUnifier {
5
+ export function getReadableType(entity: ConcreteEntity): "element" | "element aspect" | "relationship" | "unknown entity type";
6
+ type EntityUpdater = (entityProps: ConcreteEntityProps) => void;
7
+ /** needs to return a widened type otherwise typescript complains when result is used with a narrow type */
8
+ export function updaterFor(db: IModelDb, entity: ConcreteEntity): EntityUpdater;
9
+ export function exists(db: IModelDb, arg: {
10
+ entity: ConcreteEntity;
11
+ } | {
12
+ entityReference: EntityReference;
13
+ }): boolean;
14
+ export {};
15
+ }
16
+ //# sourceMappingURL=EntityUnifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityUnifier.d.ts","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":"AAUA,OAAO,EAAkC,eAAe,EAAe,MAAM,oBAAoB,CAAC;AAClG,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAA4C,QAAQ,EAAgB,MAAM,qBAAqB,CAAC;AAE5I,gBAAgB;AAChB,yBAAiB,aAAa,CAAC;IAC7B,MAAM,UAAU,eAAe,CAAC,MAAM,EAAE,cAAc,yEASrD;IAED,KAAK,aAAa,GAAG,CAAC,WAAW,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAEhE,2GAA2G;IAC3G,MAAM,UAAU,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,iBAS9D;IAED,MAAM,UAAU,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE;QAAE,MAAM,EAAE,cAAc,CAAA;KAAE,GAAG;QAAE,eAAe,EAAE,eAAe,CAAA;KAAE,WA0B1G;;CACF"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EntityUnifier = void 0;
4
+ /*---------------------------------------------------------------------------------------------
5
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
6
+ * See LICENSE.md in the project root for license terms and full copyright notice.
7
+ *--------------------------------------------------------------------------------------------*/
8
+ /** @packageDocumentation
9
+ * @module Utils
10
+ * utilities that unify operations, especially CRUD operations, on entities
11
+ * for entity-generic operations in the transformer
12
+ */
13
+ const assert = require("assert");
14
+ const core_common_1 = require("@itwin/core-common");
15
+ const core_backend_1 = require("@itwin/core-backend");
16
+ /** @internal */
17
+ var EntityUnifier;
18
+ (function (EntityUnifier) {
19
+ function getReadableType(entity) {
20
+ if (entity instanceof core_backend_1.Element)
21
+ return "element";
22
+ else if (entity instanceof core_backend_1.ElementAspect)
23
+ return "element aspect";
24
+ else if (entity instanceof core_backend_1.Relationship)
25
+ return "relationship";
26
+ else
27
+ return "unknown entity type";
28
+ }
29
+ EntityUnifier.getReadableType = getReadableType;
30
+ /** needs to return a widened type otherwise typescript complains when result is used with a narrow type */
31
+ function updaterFor(db, entity) {
32
+ if (entity instanceof core_backend_1.Element)
33
+ return db.elements.updateElement.bind(db.elements);
34
+ else if (entity instanceof core_backend_1.Relationship)
35
+ return db.relationships.updateInstance.bind(db.relationships);
36
+ else if (entity instanceof core_backend_1.ElementAspect)
37
+ return db.elements.updateAspect.bind(db.elements);
38
+ else
39
+ assert(false, `unreachable; entity was '${entity.constructor.name}' not an Element, Relationship, or ElementAspect`);
40
+ }
41
+ EntityUnifier.updaterFor = updaterFor;
42
+ function exists(db, arg) {
43
+ if ("entityReference" in arg) {
44
+ const [type, id] = core_backend_1.EntityReferences.split(arg.entityReference);
45
+ const bisCoreRootClassName = core_common_1.ConcreteEntityTypes.toBisCoreRootClassFullName(type);
46
+ return db.withPreparedStatement(`SELECT 1 FROM ${bisCoreRootClassName} WHERE ECInstanceId=?`, (stmt) => {
47
+ stmt.bindId(1, id);
48
+ const matchesResult = stmt.step();
49
+ if (matchesResult === core_common_1.DbResult.BE_SQLITE_ROW)
50
+ return true;
51
+ if (matchesResult === core_common_1.DbResult.BE_SQLITE_DONE)
52
+ return false;
53
+ else
54
+ throw new core_common_1.IModelError(matchesResult, "query failed");
55
+ });
56
+ }
57
+ else {
58
+ return db.withPreparedStatement(`SELECT 1 FROM [${arg.entity.schemaName}].[${arg.entity.className}] WHERE ECInstanceId=?`, (stmt) => {
59
+ stmt.bindId(1, arg.entity.id);
60
+ const matchesResult = stmt.step();
61
+ if (matchesResult === core_common_1.DbResult.BE_SQLITE_ROW)
62
+ return true;
63
+ if (matchesResult === core_common_1.DbResult.BE_SQLITE_DONE)
64
+ return false;
65
+ else
66
+ throw new core_common_1.IModelError(matchesResult, "query failed");
67
+ });
68
+ }
69
+ }
70
+ EntityUnifier.exists = exists;
71
+ })(EntityUnifier = exports.EntityUnifier || (exports.EntityUnifier = {}));
72
+ //# sourceMappingURL=EntityUnifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityUnifier.js","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":";;;AAAA;;;+FAG+F;AAC/F;;;;GAIG;AACH,iCAAiC;AACjC,oDAAkG;AAClG,sDAA4I;AAE5I,gBAAgB;AAChB,IAAiB,aAAa,CAqD7B;AArDD,WAAiB,aAAa;IAC5B,SAAgB,eAAe,CAAC,MAAsB;QACpD,IAAI,MAAM,YAAY,sBAAO;YAC3B,OAAO,SAAS,CAAC;aACd,IAAI,MAAM,YAAY,4BAAa;YACtC,OAAO,gBAAgB,CAAC;aACrB,IAAI,MAAM,YAAY,2BAAY;YACrC,OAAO,cAAc,CAAC;;YAEtB,OAAO,qBAAqB,CAAC;IACjC,CAAC;IATe,6BAAe,kBAS9B,CAAA;IAID,2GAA2G;IAC3G,SAAgB,UAAU,CAAC,EAAY,EAAE,MAAsB;QAC7D,IAAI,MAAM,YAAY,sBAAO;YAC3B,OAAO,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAkB,CAAC;aACjE,IAAI,MAAM,YAAY,2BAAY;YACrC,OAAO,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,CAAkB,CAAC;aAC5E,IAAI,MAAM,YAAY,4BAAa;YACtC,OAAO,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAkB,CAAC;;YAEnE,MAAM,CAAC,KAAK,EAAE,4BAA4B,MAAM,CAAC,WAAW,CAAC,IAAI,kDAAkD,CAAC,CAAC;IACzH,CAAC;IATe,wBAAU,aASzB,CAAA;IAED,SAAgB,MAAM,CAAC,EAAY,EAAE,GAAsE;QACzG,IAAI,iBAAiB,IAAI,GAAG,EAAE;YAC5B,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,+BAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC/D,MAAM,oBAAoB,GAAG,iCAAmB,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC;YAClF,OAAO,EAAE,CAAC,qBAAqB,CAAC,iBAAiB,oBAAoB,uBAAuB,EAAE,CAAC,IAAI,EAAE,EAAE;gBACrG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACnB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClC,IAAI,aAAa,KAAK,sBAAQ,CAAC,aAAa;oBAC1C,OAAO,IAAI,CAAC;gBACd,IAAI,aAAa,KAAK,sBAAQ,CAAC,cAAc;oBAC3C,OAAO,KAAK,CAAC;;oBAEb,MAAM,IAAI,yBAAW,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;SACJ;aAAM;YACL,OAAO,EAAE,CAAC,qBAAqB,CAAC,kBAAkB,GAAG,CAAC,MAAM,CAAC,UAAU,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,wBAAwB,EAAE,CAAC,IAAI,EAAE,EAAE;gBAClI,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClC,IAAI,aAAa,KAAK,sBAAQ,CAAC,aAAa;oBAC1C,OAAO,IAAI,CAAC;gBACd,IAAI,aAAa,KAAK,sBAAQ,CAAC,cAAc;oBAC3C,OAAO,KAAK,CAAC;;oBAEb,MAAM,IAAI,yBAAW,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;SACJ;IACH,CAAC;IA1Be,oBAAM,SA0BrB,CAAA;AACH,CAAC,EArDgB,aAAa,GAAb,qBAAa,KAAb,qBAAa,QAqD7B","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 */\nimport * as assert from \"assert\";\nimport { ConcreteEntityTypes, DbResult, EntityReference, IModelError } from \"@itwin/core-common\";\nimport { ConcreteEntity, ConcreteEntityProps, Element, ElementAspect, EntityReferences, IModelDb, Relationship } from \"@itwin/core-backend\";\n\n/** @internal */\nexport namespace EntityUnifier {\n export function getReadableType(entity: ConcreteEntity) {\n if (entity instanceof Element)\n return \"element\";\n else if (entity instanceof ElementAspect)\n return \"element aspect\";\n else if (entity instanceof Relationship)\n return \"relationship\";\n else\n return \"unknown entity type\";\n }\n\n type EntityUpdater = (entityProps: ConcreteEntityProps) => void;\n\n /** needs to return a widened type otherwise typescript complains when result is used with a narrow type */\n export function updaterFor(db: IModelDb, entity: ConcreteEntity) {\n if (entity instanceof Element)\n return db.elements.updateElement.bind(db.elements) as EntityUpdater;\n else if (entity instanceof Relationship)\n return db.relationships.updateInstance.bind(db.relationships) as EntityUpdater;\n else if (entity instanceof ElementAspect)\n return db.elements.updateAspect.bind(db.elements) as EntityUpdater;\n else\n assert(false, `unreachable; entity was '${entity.constructor.name}' not an Element, Relationship, or ElementAspect`);\n }\n\n export function exists(db: IModelDb, arg: { entity: ConcreteEntity } | { entityReference: EntityReference }) {\n if (\"entityReference\" in arg) {\n const [type, id] = EntityReferences.split(arg.entityReference);\n const bisCoreRootClassName = ConcreteEntityTypes.toBisCoreRootClassFullName(type);\n return db.withPreparedStatement(`SELECT 1 FROM ${bisCoreRootClassName} WHERE ECInstanceId=?`, (stmt) => {\n stmt.bindId(1, id);\n const matchesResult = stmt.step();\n if (matchesResult === DbResult.BE_SQLITE_ROW)\n return true;\n if (matchesResult === DbResult.BE_SQLITE_DONE)\n return false;\n else\n throw new IModelError(matchesResult, \"query failed\");\n });\n } else {\n return db.withPreparedStatement(`SELECT 1 FROM [${arg.entity.schemaName}].[${arg.entity.className}] WHERE ECInstanceId=?`, (stmt) => {\n stmt.bindId(1, arg.entity.id);\n const matchesResult = stmt.step();\n if (matchesResult === DbResult.BE_SQLITE_ROW)\n return true;\n if (matchesResult === DbResult.BE_SQLITE_DONE)\n return false;\n else\n throw new IModelError(matchesResult, \"query failed\");\n });\n }\n }\n}\n"]}
@@ -0,0 +1,32 @@
1
+ import { Id64String } from "@itwin/core-bentley";
2
+ import { ElementAspectProps, EntityReference } from "@itwin/core-common";
3
+ import { ElementAspect, IModelElementCloneContext, SQLiteDb } from "@itwin/core-backend";
4
+ /** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
5
+ * @beta
6
+ */
7
+ export declare class IModelCloneContext extends IModelElementCloneContext {
8
+ private _refTypesCache;
9
+ /** perform necessary initialization to use a clone context, namely caching the reference types in the source's schemas */
10
+ initialize(): Promise<void>;
11
+ private _aspectRemapTable;
12
+ /** Add a rule that remaps the specified source ElementAspect to the specified target ElementAspect. */
13
+ remapElementAspect(aspectSourceId: Id64String, aspectTargetId: Id64String): void;
14
+ /** Remove a rule that remaps the specified source ElementAspect */
15
+ removeElementAspect(aspectSourceId: Id64String): void;
16
+ /** Look up a target AspectId from the source AspectId.
17
+ * @returns the target AspectId or [Id64.invalid]($bentley) if a mapping not found.
18
+ */
19
+ findTargetAspectId(sourceAspectId: Id64String): Id64String;
20
+ /** Look up a target [EntityReference]($bentley) from a source [EntityReference]($bentley)
21
+ * @returns the target CodeSpecId or a [EntityReference]($bentley) containing [Id64.invalid]($bentley) if a mapping is not found.
22
+ */
23
+ findTargetEntityId(sourceEntityId: EntityReference): EntityReference;
24
+ /** Clone the specified source Element into ElementProps for the target iModel.
25
+ * @internal
26
+ */
27
+ cloneElementAspect(sourceElementAspect: ElementAspect): ElementAspectProps;
28
+ private static aspectRemapTableName;
29
+ saveStateToDb(db: SQLiteDb): void;
30
+ loadStateFromDb(db: SQLiteDb): void;
31
+ }
32
+ //# sourceMappingURL=IModelCloneContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IModelCloneContext.d.ts","sourceRoot":"","sources":["../../src/IModelCloneContext.ts"],"names":[],"mappings":"AAQA,OAAO,EAAkB,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EACgB,kBAAkB,EAAE,eAAe,EAEzD,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,aAAa,EAAoB,yBAAyB,EAAE,QAAQ,EACrE,MAAM,qBAAqB,CAAC;AAI7B;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,yBAAyB;IAE/D,OAAO,CAAC,cAAc,CAA+B;IAErD,0HAA0H;IACpG,UAAU;IAIhC,OAAO,CAAC,iBAAiB,CAAqC;IAE9D,uGAAuG;IAChG,kBAAkB,CAAC,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,GAAG,IAAI;IAIvF,mEAAmE;IAC5D,mBAAmB,CAAC,cAAc,EAAE,UAAU,GAAG,IAAI;IAI5D;;OAEG;IACI,kBAAkB,CAAC,cAAc,EAAE,UAAU,GAAG,UAAU;IAIjE;;OAEG;IACI,kBAAkB,CAAC,cAAc,EAAE,eAAe,GAAG,eAAe;IA+F3E;;OAEG;IACI,kBAAkB,CAAC,mBAAmB,EAAE,aAAa,GAAG,kBAAkB;IAyBjF,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAoB;IAEvC,aAAa,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI;IAoBjC,eAAe,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI;CAapD"}