@itwin/imodel-transformer 2.0.0-dev.2 → 2.0.0-dev.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -1
- package/lib/cjs/BranchProvenanceInitializer.js +4 -4
- package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
- package/lib/cjs/ECReferenceTypesCache.d.ts +3 -0
- package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -1
- package/lib/cjs/ECReferenceTypesCache.js +102 -38
- package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
- package/lib/cjs/ElementCascadingDeleter.js +1 -1
- package/lib/cjs/ElementCascadingDeleter.js.map +1 -1
- package/lib/cjs/EntityUnifier.d.ts.map +1 -1
- package/lib/cjs/EntityUnifier.js +3 -2
- package/lib/cjs/EntityUnifier.js.map +1 -1
- package/lib/cjs/IModelCloneContext.js +2 -2
- package/lib/cjs/IModelCloneContext.js.map +1 -1
- package/lib/cjs/IModelExporter.d.ts.map +1 -1
- package/lib/cjs/IModelExporter.js +10 -12
- package/lib/cjs/IModelExporter.js.map +1 -1
- package/lib/cjs/IModelImporter.d.ts.map +1 -1
- package/lib/cjs/IModelImporter.js +10 -6
- package/lib/cjs/IModelImporter.js.map +1 -1
- package/lib/cjs/IModelTransformer.d.ts +28 -1
- package/lib/cjs/IModelTransformer.d.ts.map +1 -1
- package/lib/cjs/IModelTransformer.js +152 -40
- package/lib/cjs/IModelTransformer.js.map +1 -1
- package/lib/cjs/TransformerLoggerCategory.d.ts +6 -5
- package/lib/cjs/TransformerLoggerCategory.d.ts.map +1 -1
- package/lib/cjs/TransformerLoggerCategory.js +6 -5
- package/lib/cjs/TransformerLoggerCategory.js.map +1 -1
- package/lib/cjs/imodel-transformer.js +2 -2
- package/lib/cjs/imodel-transformer.js.map +1 -1
- package/package.json +32 -32
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
# Change Log - @itwin/imodel-transformer
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Mon, 30 Jun 2025 18:36:23 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 1.2.0
|
|
8
|
+
|
|
9
|
+
Mon, 30 Jun 2025 18:36:23 GMT
|
|
10
|
+
|
|
11
|
+
### Minor changes
|
|
12
|
+
|
|
13
|
+
- allow option to transform spatial elements of linearly located imodels ([commit](https://github.com/iTwin/imodel-transformer/commit/7971863b75b604e9d5b090d69938d17ef40a2d44))
|
|
14
|
+
|
|
7
15
|
## 1.1.3
|
|
8
16
|
|
|
9
17
|
Tue, 29 Apr 2025 14:01:13 GMT
|
|
@@ -18,7 +18,7 @@ async function initializeBranchProvenance(args) {
|
|
|
18
18
|
if (args.createFedGuidsForMaster) {
|
|
19
19
|
// FIXME<LOW>: Consider enforcing that the master and branch dbs passed as part of ProvenanceInitArgs to this function
|
|
20
20
|
// are identical. https://github.com/iTwin/imodel-transformer/issues/138
|
|
21
|
-
/* eslint-disable
|
|
21
|
+
/* eslint-disable @typescript-eslint/no-deprecated */
|
|
22
22
|
args.master.withSqliteStatement(`
|
|
23
23
|
UPDATE bis_Element
|
|
24
24
|
SET FederationGuid=randomblob(16)
|
|
@@ -51,7 +51,7 @@ async function initializeBranchProvenance(args) {
|
|
|
51
51
|
// eslint-disable-next-line @itwin/no-internal
|
|
52
52
|
assert(res === core_bentley_1.DbResult.BE_SQLITE_ERROR, args.branch.getLastError());
|
|
53
53
|
});
|
|
54
|
-
/* eslint-enable
|
|
54
|
+
/* eslint-enable @typescript-eslint/no-deprecated */
|
|
55
55
|
args.branch.performCheckpoint();
|
|
56
56
|
const reopenBranch = makeDbReopener(args.branch);
|
|
57
57
|
// close dbs because element cache could be invalid
|
|
@@ -76,10 +76,10 @@ async function initializeBranchProvenance(args) {
|
|
|
76
76
|
model: core_backend_1.IModelDb.rootSubjectId,
|
|
77
77
|
code: core_common_1.Code.createEmpty(),
|
|
78
78
|
repository: new core_backend_1.ExternalSourceIsInRepository(masterRepoLinkId),
|
|
79
|
-
/* eslint-disable @typescript-eslint/no-
|
|
79
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
80
80
|
connectorName: require("../../package.json").name,
|
|
81
81
|
connectorVersion: require("../../package.json").version,
|
|
82
|
-
/* eslint-enable @typescript-eslint/no-
|
|
82
|
+
/* eslint-enable @typescript-eslint/no-require-imports */
|
|
83
83
|
});
|
|
84
84
|
const fedGuidLessElemsSql = `
|
|
85
85
|
SELECT ECInstanceId AS id
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BranchProvenanceInitializer.js","sourceRoot":"","sources":["../../src/BranchProvenanceInitializer.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 *--------------------------------------------------------------------------------------------*/\nimport {\n BriefcaseDb,\n ExternalSource,\n ExternalSourceIsInRepository,\n IModelDb,\n RepositoryLink,\n StandaloneDb,\n} from \"@itwin/core-backend\";\nimport { DbResult, Id64String, Logger, OpenMode } from \"@itwin/core-bentley\";\nimport {\n Code,\n ExternalSourceProps,\n RepositoryLinkProps,\n} from \"@itwin/core-common\";\nimport * as assert from \"assert\";\nimport { IModelTransformer } from \"./IModelTransformer\";\nimport { pathToFileURL } from \"url\";\n/**\n * @alpha\n */\nexport interface ProvenanceInitArgs {\n /** the master iModel which is the source of the provenance */\n master: IModelDb;\n /** the canonical url of the master iModel */\n masterUrl?: string;\n /** the description of the master iModel */\n masterDescription?: string;\n /**\n * @param {IModelDb} branchDb - the branch iModel which is the container of the provenance\n * Must be opened Read/Write\n */\n branch: IModelDb;\n /**\n * insert Federation Guids in all lacking elements in the master database, which will prevent\n * needing to insert External Source Aspects for provenance tracking\n * @note requires a read/write master\n * @note closes both the master and branch iModels to reset caches, so you must reopen them.\n * If you pass `\"keep-reopened-db\"`, this object's `master` and `branch` properties will\n * be set to new, open databases.\n */\n createFedGuidsForMaster?: true | false | \"keep-reopened-db\";\n}\n\n/**\n * @alpha\n */\nexport interface ProvenanceInitResult {\n targetScopeElementId: Id64String;\n masterExternalSourceId: Id64String;\n masterRepositoryLinkId: Id64String;\n}\n\n/**\n * @alpha\n */\nexport async function initializeBranchProvenance(\n args: ProvenanceInitArgs\n): Promise<ProvenanceInitResult> {\n if (args.createFedGuidsForMaster) {\n // FIXME<LOW>: Consider enforcing that the master and branch dbs passed as part of ProvenanceInitArgs to this function\n // are identical. https://github.com/iTwin/imodel-transformer/issues/138\n /* eslint-disable deprecation/deprecation */\n args.master.withSqliteStatement(\n `\n UPDATE bis_Element\n SET FederationGuid=randomblob(16)\n WHERE FederationGuid IS NULL\n `,\n // eslint-disable-next-line @itwin/no-internal\n (s) =>\n assert(s.step() === DbResult.BE_SQLITE_DONE, args.branch.getLastError())\n );\n const masterPath = args.master.pathName;\n const reopenMaster = makeDbReopener(args.master);\n args.master.close(); // prevent busy\n args.branch.withSqliteStatement(\n `ATTACH DATABASE '${pathToFileURL(`${masterPath}`)}?mode=ro' AS master`,\n // eslint-disable-next-line @itwin/no-internal\n (s) =>\n assert(s.step() === DbResult.BE_SQLITE_DONE, args.branch.getLastError())\n );\n args.branch.withSqliteStatement(\n `\n UPDATE main.bis_Element\n SET FederationGuid = (\n SELECT m.FederationGuid\n FROM master.bis_Element m\n WHERE m.Id=main.bis_Element.Id\n )`,\n\n // eslint-disable-next-line @itwin/no-internal\n (s) =>\n assert(s.step() === DbResult.BE_SQLITE_DONE, args.branch.getLastError())\n );\n args.branch.clearCaches(); // statements write lock attached db (clearing statement cache does not fix this)\n args.branch.saveChanges();\n args.branch.withSqliteStatement(\"DETACH DATABASE master\", (s) => {\n const res = s.step();\n if (res !== DbResult.BE_SQLITE_DONE)\n Logger.logTrace(\n \"initializeBranchProvenance\",\n `Error detaching db (we will close anyway): ${args.branch.getLastError()}`\n );\n // this is the case until native side changes\n // eslint-disable-next-line @itwin/no-internal\n assert(res === DbResult.BE_SQLITE_ERROR, args.branch.getLastError());\n });\n /* eslint-enable deprecation/deprecation */\n args.branch.performCheckpoint();\n\n const reopenBranch = makeDbReopener(args.branch);\n // close dbs because element cache could be invalid\n args.branch.close();\n [args.master, args.branch] = await Promise.all([\n reopenMaster(),\n reopenBranch(),\n ]);\n }\n\n // create an external source and owning repository link to use as our *Target Scope Element* for future synchronizations\n const masterRepoLinkId = args.branch.elements.insertElement({\n classFullName: RepositoryLink.classFullName,\n code: RepositoryLink.createCode(\n args.branch,\n IModelDb.repositoryModelId,\n \"example-code-value\"\n ),\n model: IModelDb.repositoryModelId,\n url: args.masterUrl,\n format: \"iModel\",\n repositoryGuid: args.master.iModelId,\n description: args.masterDescription,\n } as RepositoryLinkProps);\n\n const masterExternalSourceId = args.branch.elements.insertElement({\n classFullName: ExternalSource.classFullName,\n model: IModelDb.rootSubjectId,\n code: Code.createEmpty(),\n repository: new ExternalSourceIsInRepository(masterRepoLinkId),\n /* eslint-disable @typescript-eslint/no-var-requires */\n connectorName: require(\"../../package.json\").name,\n connectorVersion: require(\"../../package.json\").version,\n /* eslint-enable @typescript-eslint/no-var-requires */\n } as ExternalSourceProps);\n\n const fedGuidLessElemsSql = `\n SELECT ECInstanceId AS id\n FROM Bis.Element\n WHERE FederationGuid IS NULL\n AND ECInstanceId NOT IN (0x1, 0xe, 0x10) /* ignore special elems */\n `;\n const elemReader = args.branch.createQueryReader(\n fedGuidLessElemsSql,\n undefined,\n { usePrimaryConn: true }\n );\n while (await elemReader.step()) {\n const id: string = elemReader.current.toRow().id;\n const aspectProps = IModelTransformer.initElementProvenanceOptions(id, id, {\n isReverseSynchronization: false,\n targetScopeElementId: masterExternalSourceId,\n sourceDb: args.master,\n targetDb: args.branch,\n });\n args.branch.elements.insertAspect(aspectProps);\n }\n\n const fedGuidLessRelsSql = `\n SELECT erte.ECInstanceId as id\n FROM Bis.ElementRefersToElements erte\n JOIN bis.Element se\n ON se.ECInstanceId=erte.SourceECInstanceId\n JOIN bis.Element te\n ON te.ECInstanceId=erte.TargetECInstanceId\n WHERE se.FederationGuid IS NULL\n OR te.FederationGuid IS NULL`;\n const relReader = args.branch.createQueryReader(\n fedGuidLessRelsSql,\n undefined,\n { usePrimaryConn: true }\n );\n while (await relReader.step()) {\n const id: string = relReader.current.toRow().id;\n const aspectProps = IModelTransformer.initRelationshipProvenanceOptions(\n id,\n id,\n {\n isReverseSynchronization: false,\n targetScopeElementId: masterExternalSourceId,\n sourceDb: args.master,\n targetDb: args.branch,\n forceOldRelationshipProvenanceMethod: false,\n }\n );\n args.branch.elements.insertAspect(aspectProps);\n }\n\n if (args.createFedGuidsForMaster === true) {\n args.master.close();\n args.branch.close();\n }\n\n return {\n targetScopeElementId: masterExternalSourceId,\n masterExternalSourceId,\n masterRepositoryLinkId: masterRepoLinkId,\n };\n}\n\nfunction makeDbReopener(db: IModelDb) {\n const originalMode = db.isReadonly ? OpenMode.Readonly : OpenMode.ReadWrite;\n const dbPath = db.pathName;\n let reopenDb: (mode?: OpenMode) => IModelDb | Promise<IModelDb>;\n if (db instanceof BriefcaseDb)\n reopenDb = async (mode = originalMode) =>\n BriefcaseDb.open({\n fileName: dbPath,\n readonly: mode === OpenMode.Readonly,\n });\n else if (db instanceof StandaloneDb)\n reopenDb = (mode = originalMode) => StandaloneDb.openFile(dbPath, mode);\n else assert(false, `db type '${db.constructor.name}' not supported`);\n return reopenDb;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"BranchProvenanceInitializer.js","sourceRoot":"","sources":["../../src/BranchProvenanceInitializer.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 *--------------------------------------------------------------------------------------------*/\nimport {\n BriefcaseDb,\n ExternalSource,\n ExternalSourceIsInRepository,\n IModelDb,\n RepositoryLink,\n StandaloneDb,\n} from \"@itwin/core-backend\";\nimport { DbResult, Id64String, Logger, OpenMode } from \"@itwin/core-bentley\";\nimport {\n Code,\n ExternalSourceProps,\n RepositoryLinkProps,\n} from \"@itwin/core-common\";\nimport * as assert from \"assert\";\nimport { IModelTransformer } from \"./IModelTransformer\";\nimport { pathToFileURL } from \"url\";\n/**\n * @alpha\n */\nexport interface ProvenanceInitArgs {\n /** the master iModel which is the source of the provenance */\n master: IModelDb;\n /** the canonical url of the master iModel */\n masterUrl?: string;\n /** the description of the master iModel */\n masterDescription?: string;\n /**\n * @param {IModelDb} branchDb - the branch iModel which is the container of the provenance\n * Must be opened Read/Write\n */\n branch: IModelDb;\n /**\n * insert Federation Guids in all lacking elements in the master database, which will prevent\n * needing to insert External Source Aspects for provenance tracking\n * @note requires a read/write master\n * @note closes both the master and branch iModels to reset caches, so you must reopen them.\n * If you pass `\"keep-reopened-db\"`, this object's `master` and `branch` properties will\n * be set to new, open databases.\n */\n createFedGuidsForMaster?: true | false | \"keep-reopened-db\";\n}\n\n/**\n * @alpha\n */\nexport interface ProvenanceInitResult {\n targetScopeElementId: Id64String;\n masterExternalSourceId: Id64String;\n masterRepositoryLinkId: Id64String;\n}\n\n/**\n * @alpha\n */\nexport async function initializeBranchProvenance(\n args: ProvenanceInitArgs\n): Promise<ProvenanceInitResult> {\n if (args.createFedGuidsForMaster) {\n // FIXME<LOW>: Consider enforcing that the master and branch dbs passed as part of ProvenanceInitArgs to this function\n // are identical. https://github.com/iTwin/imodel-transformer/issues/138\n /* eslint-disable @typescript-eslint/no-deprecated */\n args.master.withSqliteStatement(\n `\n UPDATE bis_Element\n SET FederationGuid=randomblob(16)\n WHERE FederationGuid IS NULL\n `,\n // eslint-disable-next-line @itwin/no-internal\n (s) =>\n assert(s.step() === DbResult.BE_SQLITE_DONE, args.branch.getLastError())\n );\n const masterPath = args.master.pathName;\n const reopenMaster = makeDbReopener(args.master);\n args.master.close(); // prevent busy\n args.branch.withSqliteStatement(\n `ATTACH DATABASE '${pathToFileURL(`${masterPath}`)}?mode=ro' AS master`,\n // eslint-disable-next-line @itwin/no-internal\n (s) =>\n assert(s.step() === DbResult.BE_SQLITE_DONE, args.branch.getLastError())\n );\n args.branch.withSqliteStatement(\n `\n UPDATE main.bis_Element\n SET FederationGuid = (\n SELECT m.FederationGuid\n FROM master.bis_Element m\n WHERE m.Id=main.bis_Element.Id\n )`,\n\n // eslint-disable-next-line @itwin/no-internal\n (s) =>\n assert(s.step() === DbResult.BE_SQLITE_DONE, args.branch.getLastError())\n );\n args.branch.clearCaches(); // statements write lock attached db (clearing statement cache does not fix this)\n args.branch.saveChanges();\n args.branch.withSqliteStatement(\"DETACH DATABASE master\", (s) => {\n const res = s.step();\n if (res !== DbResult.BE_SQLITE_DONE)\n Logger.logTrace(\n \"initializeBranchProvenance\",\n `Error detaching db (we will close anyway): ${args.branch.getLastError()}`\n );\n // this is the case until native side changes\n // eslint-disable-next-line @itwin/no-internal\n assert(res === DbResult.BE_SQLITE_ERROR, args.branch.getLastError());\n });\n /* eslint-enable @typescript-eslint/no-deprecated */\n args.branch.performCheckpoint();\n\n const reopenBranch = makeDbReopener(args.branch);\n // close dbs because element cache could be invalid\n args.branch.close();\n [args.master, args.branch] = await Promise.all([\n reopenMaster(),\n reopenBranch(),\n ]);\n }\n\n // create an external source and owning repository link to use as our *Target Scope Element* for future synchronizations\n const masterRepoLinkId = args.branch.elements.insertElement({\n classFullName: RepositoryLink.classFullName,\n code: RepositoryLink.createCode(\n args.branch,\n IModelDb.repositoryModelId,\n \"example-code-value\"\n ),\n model: IModelDb.repositoryModelId,\n url: args.masterUrl,\n format: \"iModel\",\n repositoryGuid: args.master.iModelId,\n description: args.masterDescription,\n } as RepositoryLinkProps);\n\n const masterExternalSourceId = args.branch.elements.insertElement({\n classFullName: ExternalSource.classFullName,\n model: IModelDb.rootSubjectId,\n code: Code.createEmpty(),\n repository: new ExternalSourceIsInRepository(masterRepoLinkId),\n /* eslint-disable @typescript-eslint/no-require-imports */\n connectorName: require(\"../../package.json\").name,\n connectorVersion: require(\"../../package.json\").version,\n /* eslint-enable @typescript-eslint/no-require-imports */\n } as ExternalSourceProps);\n\n const fedGuidLessElemsSql = `\n SELECT ECInstanceId AS id\n FROM Bis.Element\n WHERE FederationGuid IS NULL\n AND ECInstanceId NOT IN (0x1, 0xe, 0x10) /* ignore special elems */\n `;\n const elemReader = args.branch.createQueryReader(\n fedGuidLessElemsSql,\n undefined,\n { usePrimaryConn: true }\n );\n while (await elemReader.step()) {\n const id: string = elemReader.current.toRow().id;\n const aspectProps = IModelTransformer.initElementProvenanceOptions(id, id, {\n isReverseSynchronization: false,\n targetScopeElementId: masterExternalSourceId,\n sourceDb: args.master,\n targetDb: args.branch,\n });\n args.branch.elements.insertAspect(aspectProps);\n }\n\n const fedGuidLessRelsSql = `\n SELECT erte.ECInstanceId as id\n FROM Bis.ElementRefersToElements erte\n JOIN bis.Element se\n ON se.ECInstanceId=erte.SourceECInstanceId\n JOIN bis.Element te\n ON te.ECInstanceId=erte.TargetECInstanceId\n WHERE se.FederationGuid IS NULL\n OR te.FederationGuid IS NULL`;\n const relReader = args.branch.createQueryReader(\n fedGuidLessRelsSql,\n undefined,\n { usePrimaryConn: true }\n );\n while (await relReader.step()) {\n const id: string = relReader.current.toRow().id;\n const aspectProps = IModelTransformer.initRelationshipProvenanceOptions(\n id,\n id,\n {\n isReverseSynchronization: false,\n targetScopeElementId: masterExternalSourceId,\n sourceDb: args.master,\n targetDb: args.branch,\n forceOldRelationshipProvenanceMethod: false,\n }\n );\n args.branch.elements.insertAspect(aspectProps);\n }\n\n if (args.createFedGuidsForMaster === true) {\n args.master.close();\n args.branch.close();\n }\n\n return {\n targetScopeElementId: masterExternalSourceId,\n masterExternalSourceId,\n masterRepositoryLinkId: masterRepoLinkId,\n };\n}\n\nfunction makeDbReopener(db: IModelDb) {\n const originalMode = db.isReadonly ? OpenMode.Readonly : OpenMode.ReadWrite;\n const dbPath = db.pathName;\n let reopenDb: (mode?: OpenMode) => IModelDb | Promise<IModelDb>;\n if (db instanceof BriefcaseDb)\n reopenDb = async (mode = originalMode) =>\n BriefcaseDb.open({\n fileName: dbPath,\n readonly: mode === OpenMode.Readonly,\n });\n else if (db instanceof StandaloneDb)\n reopenDb = (mode = originalMode) => StandaloneDb.openFile(dbPath, mode);\n else assert(false, `db type '${db.constructor.name}' not supported`);\n return reopenDb;\n}\n"]}
|
|
@@ -22,6 +22,9 @@ export declare class ECReferenceTypesCache {
|
|
|
22
22
|
private _propQualifierToRefType;
|
|
23
23
|
private _relClassNameEndToRefTypes;
|
|
24
24
|
private _initedSchemas;
|
|
25
|
+
private _rootBisClassCache;
|
|
26
|
+
private _relationshipInfoCache;
|
|
27
|
+
private _constraintClassCache;
|
|
25
28
|
private static bisRootClassToRefType;
|
|
26
29
|
private getRootBisClass;
|
|
27
30
|
private getAbstractConstraintClass;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ECReferenceTypesCache.d.ts","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EACL,mBAAmB,EAEnB,WAAW,EACZ,MAAM,oBAAoB,CAAC;AAY5B,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"ECReferenceTypesCache.d.ts","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EACL,mBAAmB,EAEnB,WAAW,EACZ,MAAM,oBAAoB,CAAC;AAY5B,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;;CAI7C;AAED;;;;;;;GAOG;AACH,qBAAa,qBAAqB;IAChC,uGAAuG;IACvG,OAAO,CAAC,uBAAuB,CAG3B;IACJ,OAAO,CAAC,0BAA0B,CAG9B;IACJ,OAAO,CAAC,cAAc,CAAgC;IAGtD,OAAO,CAAC,kBAAkB,CAA8B;IACxD,OAAO,CAAC,sBAAsB,CAA8C;IAC5E,OAAO,CAAC,qBAAqB,CAA8B;IAE3D,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAalC;YAEY,eAAe;YAmCf,0BAA0B;IAqBxC,8CAA8C;IACjC,sBAAsB,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;YAuDtD,kBAAkB;YAalB,UAAU;YAwFV,mBAAmB;IA4D1B,iBAAiB,CACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,SAAS,GAAG,mBAAmB;IAS3B,sBAAsB,CAC3B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,SAAS,GAAG,WAAW;IAQnB,KAAK;CAQb"}
|
|
@@ -12,6 +12,7 @@ const core_bentley_1 = require("@itwin/core-bentley");
|
|
|
12
12
|
const core_common_1 = require("@itwin/core-common");
|
|
13
13
|
const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
|
|
14
14
|
const assert = require("assert");
|
|
15
|
+
const TransformerLoggerCategory_1 = require("./TransformerLoggerCategory");
|
|
15
16
|
/** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel.
|
|
16
17
|
* @internal
|
|
17
18
|
*/
|
|
@@ -34,6 +35,10 @@ class ECReferenceTypesCache {
|
|
|
34
35
|
_propQualifierToRefType = new core_bentley_1.TupleKeyedMap();
|
|
35
36
|
_relClassNameEndToRefTypes = new core_bentley_1.TupleKeyedMap();
|
|
36
37
|
_initedSchemas = new Map();
|
|
38
|
+
// Performance optimization caches
|
|
39
|
+
_rootBisClassCache = new Map();
|
|
40
|
+
_relationshipInfoCache = new Map();
|
|
41
|
+
_constraintClassCache = new Map();
|
|
37
42
|
static bisRootClassToRefType = {
|
|
38
43
|
/* eslint-disable quote-props, @typescript-eslint/naming-convention */
|
|
39
44
|
Element: core_common_1.ConcreteEntityTypes.Element,
|
|
@@ -46,6 +51,11 @@ class ECReferenceTypesCache {
|
|
|
46
51
|
/* eslint-enable quote-props, @typescript-eslint/naming-convention */
|
|
47
52
|
};
|
|
48
53
|
async getRootBisClass(ecclass) {
|
|
54
|
+
const cacheKey = ecclass.fullName;
|
|
55
|
+
const cached = this._rootBisClassCache.get(cacheKey);
|
|
56
|
+
if (cached) {
|
|
57
|
+
return cached;
|
|
58
|
+
}
|
|
49
59
|
let bisRootForConstraint = ecclass;
|
|
50
60
|
await ecclass.traverseBaseClasses((baseClass) => {
|
|
51
61
|
// The depth first traversal will descend all the way to the root class before making any lateral traversal
|
|
@@ -64,21 +74,28 @@ class ECReferenceTypesCache {
|
|
|
64
74
|
assert(bisRootForConstraint.appliesTo !== undefined, "The referenced AppliesToEntityClass could not be found, how did it pass schema validation?");
|
|
65
75
|
bisRootForConstraint = await this.getRootBisClass(await bisRootForConstraint.appliesTo);
|
|
66
76
|
}
|
|
77
|
+
this._rootBisClassCache.set(cacheKey, bisRootForConstraint);
|
|
67
78
|
return bisRootForConstraint;
|
|
68
79
|
}
|
|
69
80
|
async getAbstractConstraintClass(constraint) {
|
|
81
|
+
const cacheKey = `${constraint.fullName}_${constraint.constraintClasses?.[0]?.fullName || "abstract"}`;
|
|
82
|
+
const cached = this._constraintClassCache.get(cacheKey);
|
|
83
|
+
if (cached) {
|
|
84
|
+
return cached;
|
|
85
|
+
}
|
|
70
86
|
// constraint classes must share a base so we can get the root from any of them, just use the first
|
|
71
87
|
const ecclass = await (constraint.constraintClasses?.[0] ||
|
|
72
88
|
constraint.abstractConstraint);
|
|
73
89
|
assert(ecclass !== undefined, "At least one constraint class or an abstract constraint must have been defined, the constraint is not valid");
|
|
90
|
+
this._constraintClassCache.set(cacheKey, ecclass);
|
|
74
91
|
return ecclass;
|
|
75
92
|
}
|
|
76
93
|
/** initialize from an imodel with metadata */
|
|
77
94
|
async initAllSchemasInIModel(imodel) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
95
|
+
let totalSchemaCount = 0;
|
|
96
|
+
let schemaCompletedCount = 0;
|
|
97
|
+
const initStartTime = performance.now();
|
|
98
|
+
const query = `
|
|
82
99
|
WITH RECURSIVE refs(SchemaId) AS (
|
|
83
100
|
SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'
|
|
84
101
|
UNION ALL
|
|
@@ -86,21 +103,31 @@ class ECReferenceTypesCache {
|
|
|
86
103
|
FROM ECDbMeta.SchemaHasSchemaReferences sr
|
|
87
104
|
JOIN refs ON sr.TargetECInstanceId = refs.SchemaId
|
|
88
105
|
)
|
|
89
|
-
SELECT s.Name
|
|
106
|
+
SELECT DISTINCT s.Name as name
|
|
90
107
|
FROM refs
|
|
91
108
|
JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId
|
|
92
109
|
-- ensure schema dependency order
|
|
93
|
-
ORDER BY ECInstanceId
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
110
|
+
ORDER BY s.ECInstanceId
|
|
111
|
+
`;
|
|
112
|
+
for await (const row of imodel.createQueryReader(query)) {
|
|
113
|
+
const schemaName = row.name;
|
|
114
|
+
const startTime = performance.now();
|
|
115
|
+
core_bentley_1.Logger.logInfo(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Loading schema: ${schemaName}`);
|
|
116
|
+
const schemaItemKey = new ecschema_metadata_1.SchemaKey(schemaName);
|
|
117
|
+
const schema = await imodel.schemaContext.getSchema(schemaItemKey);
|
|
118
|
+
if (schema) {
|
|
99
119
|
await this.considerInitSchema(schema);
|
|
120
|
+
const endTime = performance.now();
|
|
121
|
+
core_bentley_1.Logger.logInfo(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Completed schema: ${schemaName} in ${(endTime - startTime).toFixed(2)}ms`);
|
|
122
|
+
schemaCompletedCount++;
|
|
100
123
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
124
|
+
else {
|
|
125
|
+
core_bentley_1.Logger.logInfo(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Did not load schema: ${schemaName}`);
|
|
126
|
+
}
|
|
127
|
+
totalSchemaCount++;
|
|
128
|
+
}
|
|
129
|
+
const initEndTime = performance.now();
|
|
130
|
+
core_bentley_1.Logger.logInfo(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Schemas completed out of total: ${schemaCompletedCount} / ${totalSchemaCount} in ${(initEndTime - initStartTime).toFixed(2)}ms`);
|
|
104
131
|
}
|
|
105
132
|
async considerInitSchema(schema) {
|
|
106
133
|
if (this._initedSchemas.has(schema.name)) {
|
|
@@ -114,33 +141,66 @@ class ECReferenceTypesCache {
|
|
|
114
141
|
return this.initSchema(schema);
|
|
115
142
|
}
|
|
116
143
|
async initSchema(schema) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
144
|
+
const schemaNameLower = schema.name.toLowerCase();
|
|
145
|
+
// Pre-collect all items to reduce iterator overhead
|
|
146
|
+
const allItems = Array.from(schema.getItems());
|
|
147
|
+
const ecClasses = [];
|
|
148
|
+
const relationshipClasses = [];
|
|
149
|
+
// Single pass through items with type checking
|
|
150
|
+
for (const item of allItems) {
|
|
151
|
+
// eslint-disable-next-line @itwin/no-internal
|
|
152
|
+
if (!ecschema_metadata_1.ECClass.isECClass(item))
|
|
122
153
|
continue;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const relClass = await prop.relationshipClass;
|
|
127
|
-
const relInfo = await this.relInfoFromRelClass(relClass);
|
|
128
|
-
if (relInfo === undefined)
|
|
129
|
-
continue;
|
|
130
|
-
const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward
|
|
131
|
-
? relInfo.target
|
|
132
|
-
: relInfo.source;
|
|
133
|
-
this._propQualifierToRefType.set([
|
|
134
|
-
schema.name.toLowerCase(),
|
|
135
|
-
ecclass.name.toLowerCase(),
|
|
136
|
-
prop.name.toLowerCase(),
|
|
137
|
-
], navPropRefType);
|
|
154
|
+
ecClasses.push(item);
|
|
155
|
+
if (item instanceof ecschema_metadata_1.RelationshipClass) {
|
|
156
|
+
relationshipClasses.push(item);
|
|
138
157
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
158
|
+
}
|
|
159
|
+
// Process relationship classes in parallel and populate global cache
|
|
160
|
+
const relInfoPromises = relationshipClasses.map(async (relClass) => {
|
|
161
|
+
const relInfo = await this.relInfoFromRelClass(relClass);
|
|
162
|
+
this._relationshipInfoCache.set(relClass.fullName, relInfo);
|
|
163
|
+
if (relInfo) {
|
|
164
|
+
this._relClassNameEndToRefTypes.set([schemaNameLower, relClass.name.toLowerCase()], relInfo);
|
|
143
165
|
}
|
|
166
|
+
return relInfo;
|
|
167
|
+
});
|
|
168
|
+
// Wait for all relationship info to be cached
|
|
169
|
+
await Promise.all(relInfoPromises);
|
|
170
|
+
// Process navigation properties with optimized batching
|
|
171
|
+
const propertyBatchSize = 25;
|
|
172
|
+
for (let i = 0; i < ecClasses.length; i += propertyBatchSize) {
|
|
173
|
+
const classBatch = ecClasses.slice(i, i + propertyBatchSize);
|
|
174
|
+
const classPromises = classBatch.map(async (ecclass) => {
|
|
175
|
+
const properties = await ecclass.getProperties();
|
|
176
|
+
if (!properties)
|
|
177
|
+
return;
|
|
178
|
+
const classNameLower = ecclass.name.toLowerCase();
|
|
179
|
+
// Efficiently filter navigation properties
|
|
180
|
+
const navProps = Array.from(properties).filter((prop) => prop.isNavigation());
|
|
181
|
+
if (navProps.length === 0)
|
|
182
|
+
return;
|
|
183
|
+
const navPropPromises = navProps.map(async (prop) => {
|
|
184
|
+
const relClass = await prop.relationshipClass;
|
|
185
|
+
// Use cached relation info
|
|
186
|
+
let relInfo = this._relationshipInfoCache.get(relClass.fullName);
|
|
187
|
+
if (relInfo === undefined &&
|
|
188
|
+
!this._relationshipInfoCache.has(relClass.fullName)) {
|
|
189
|
+
relInfo = await this.relInfoFromRelClass(relClass);
|
|
190
|
+
this._relationshipInfoCache.set(relClass.fullName, relInfo);
|
|
191
|
+
}
|
|
192
|
+
if (relInfo === undefined)
|
|
193
|
+
return;
|
|
194
|
+
const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward
|
|
195
|
+
? // eslint-disable-next-line @itwin/no-internal
|
|
196
|
+
relInfo.target
|
|
197
|
+
: // eslint-disable-next-line @itwin/no-internal
|
|
198
|
+
relInfo.source;
|
|
199
|
+
this._propQualifierToRefType.set([schemaNameLower, classNameLower, prop.name.toLowerCase()], navPropRefType);
|
|
200
|
+
});
|
|
201
|
+
await Promise.all(navPropPromises);
|
|
202
|
+
});
|
|
203
|
+
await Promise.all(classPromises);
|
|
144
204
|
}
|
|
145
205
|
this._initedSchemas.set(schema.name, schema.schemaKey);
|
|
146
206
|
}
|
|
@@ -199,6 +259,10 @@ class ECReferenceTypesCache {
|
|
|
199
259
|
clear() {
|
|
200
260
|
this._initedSchemas.clear();
|
|
201
261
|
this._propQualifierToRefType.clear();
|
|
262
|
+
this._relClassNameEndToRefTypes.clear();
|
|
263
|
+
this._rootBisClassCache.clear();
|
|
264
|
+
this._relationshipInfoCache.clear();
|
|
265
|
+
this._constraintClassCache.clear();
|
|
202
266
|
}
|
|
203
267
|
}
|
|
204
268
|
exports.ECReferenceTypesCache = ECReferenceTypesCache;
|
|
@@ -1 +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 {\n ConcreteEntityTypes,\n IModelError,\n RelTypeInfo,\n} from \"@itwin/core-common\";\nimport {\n ECClass,\n Mixin,\n RelationshipClass,\n RelationshipConstraint,\n Schema,\n SchemaKey,\n SchemaLoader,\n StrengthDirection,\n} 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() {\n super(\"Schema was not in cache, initialize that schema\");\n }\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<\n [string, string, string],\n ConcreteEntityTypes\n >();\n private _relClassNameEndToRefTypes = new TupleKeyedMap<\n [string, string],\n RelTypeInfo\n >();\n private _initedSchemas = new Map<string, SchemaKey>();\n\n private static bisRootClassToRefType: Record<\n string,\n ConcreteEntityTypes | undefined\n > = {\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 =\n baseClass.name !== bisRootForConstraint.baseClass?.name;\n const stillTraversingRootPath = isFirstTest || !traversalSwitchedRootPath;\n if (!stillTraversingRootPath) 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(\n bisRootForConstraint.appliesTo !== undefined,\n \"The referenced AppliesToEntityClass could not be found, how did it pass schema validation?\"\n );\n bisRootForConstraint = await this.getRootBisClass(\n await bisRootForConstraint.appliesTo\n );\n }\n return bisRootForConstraint;\n }\n\n private async getAbstractConstraintClass(\n constraint: RelationshipConstraint\n ): 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] ||\n constraint.abstractConstraint);\n assert(\n ecclass !== undefined,\n \"At least one constraint class or an abstract constraint must have been defined, the constraint is not valid\"\n );\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) =>\n imodel.getSchemaProps(name)\n );\n // Issue for `createQueryReader` reported: https://github.com/iTwin/itwinjs-core/issues/7984\n // eslint-disable-next-line @itwin/no-internal, deprecation/deprecation\n await imodel.withPreparedStatement(\n `\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 `,\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\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 =\n 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.getItems()) {\n if (!ECClass.isECClass(ecclass)) continue;\n const properties = await ecclass.getProperties();\n if (properties === undefined) continue;\n for (const prop of properties) {\n if (!prop.isNavigation()) continue;\n const relClass = await prop.relationshipClass;\n const relInfo = await this.relInfoFromRelClass(relClass);\n if (relInfo === undefined) continue;\n const navPropRefType =\n prop.direction === StrengthDirection.Forward\n ? relInfo.target\n : relInfo.source;\n this._propQualifierToRefType.set(\n [\n schema.name.toLowerCase(),\n ecclass.name.toLowerCase(),\n prop.name.toLowerCase(),\n ],\n navPropRefType\n );\n }\n\n if (ecclass instanceof RelationshipClass) {\n const relInfo = await this.relInfoFromRelClass(ecclass);\n if (relInfo)\n this._relClassNameEndToRefTypes.set(\n [schema.name.toLowerCase(), ecclass.name.toLowerCase()],\n relInfo\n );\n }\n }\n\n this._initedSchemas.set(schema.name, schema.schemaKey);\n }\n\n private async relInfoFromRelClass(\n ecclass: RelationshipClass\n ): Promise<RelTypeInfo | undefined> {\n assert(ecclass.source.constraintClasses !== undefined);\n assert(ecclass.target.constraintClasses !== undefined);\n const [\n [sourceClass, sourceRootBisClass],\n [targetClass, targetRootBisClass],\n ] = await Promise.all([\n this.getAbstractConstraintClass(ecclass.source).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n this.getAbstractConstraintClass(ecclass.target).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n ]);\n\n if (\n sourceRootBisClass.name === \"CodeSpec\" ||\n targetRootBisClass.name === \"CodeSpec\"\n )\n return undefined;\n const sourceType =\n ECReferenceTypesCache.bisRootClassToRefType[sourceRootBisClass.name];\n const targetType =\n ECReferenceTypesCache.bisRootClassToRefType[targetRootBisClass.name];\n if (\n (!sourceType &&\n sourceRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\")) ||\n (!targetType &&\n targetRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\"))\n ) {\n // ECView elements are not \"real\" data and transformer does not need to process them.\n // Relationships that point to ECView elements can only be used in ECViews so the mapping is not needed.\n return undefined;\n }\n\n const makeAssertMsg = (root: ECClass, cls: ECClass) =>\n [\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(\n sourceType !== undefined,\n makeAssertMsg(sourceRootBisClass, sourceClass)\n );\n assert(\n targetType !== undefined,\n makeAssertMsg(targetRootBisClass, targetClass)\n );\n return { source: sourceType, target: targetType };\n }\n\n public getNavPropRefType(\n schemaName: string,\n className: string,\n propName: string\n ): undefined | ConcreteEntityTypes {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._propQualifierToRefType.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n propName.toLowerCase(),\n ]);\n }\n\n public getRelationshipEndType(\n schemaName: string,\n className: string\n ): undefined | RelTypeInfo {\n if (!this._initedSchemas.has(schemaName)) 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"]}
|
|
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, Logger, TupleKeyedMap } from \"@itwin/core-bentley\";\nimport {\n ConcreteEntityTypes,\n IModelError,\n RelTypeInfo,\n} from \"@itwin/core-common\";\nimport {\n ECClass,\n Mixin,\n RelationshipClass,\n RelationshipConstraint,\n Schema,\n SchemaKey,\n SchemaLoader,\n StrengthDirection,\n} from \"@itwin/ecschema-metadata\";\nimport * as assert from \"assert\";\nimport { IModelDb } from \"@itwin/core-backend\";\nimport { TransformerLoggerCategory } from \"./TransformerLoggerCategory\";\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() {\n super(\"Schema was not in cache, initialize that schema\");\n }\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<\n [string, string, string],\n ConcreteEntityTypes\n >();\n private _relClassNameEndToRefTypes = new TupleKeyedMap<\n [string, string],\n RelTypeInfo\n >();\n private _initedSchemas = new Map<string, SchemaKey>();\n\n // Performance optimization caches\n private _rootBisClassCache = new Map<string, ECClass>();\n private _relationshipInfoCache = new Map<string, RelTypeInfo | undefined>();\n private _constraintClassCache = new Map<string, ECClass>();\n\n private static bisRootClassToRefType: Record<\n string,\n ConcreteEntityTypes | undefined\n > = {\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 const cacheKey = ecclass.fullName;\n const cached = this._rootBisClassCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\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 =\n baseClass.name !== bisRootForConstraint.baseClass?.name;\n const stillTraversingRootPath = isFirstTest || !traversalSwitchedRootPath;\n if (!stillTraversingRootPath) 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(\n bisRootForConstraint.appliesTo !== undefined,\n \"The referenced AppliesToEntityClass could not be found, how did it pass schema validation?\"\n );\n bisRootForConstraint = await this.getRootBisClass(\n await bisRootForConstraint.appliesTo\n );\n }\n\n this._rootBisClassCache.set(cacheKey, bisRootForConstraint);\n return bisRootForConstraint;\n }\n\n private async getAbstractConstraintClass(\n constraint: RelationshipConstraint\n ): Promise<ECClass> {\n const cacheKey = `${constraint.fullName}_${constraint.constraintClasses?.[0]?.fullName || \"abstract\"}`;\n const cached = this._constraintClassCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\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] ||\n constraint.abstractConstraint);\n assert(\n ecclass !== undefined,\n \"At least one constraint class or an abstract constraint must have been defined, the constraint is not valid\"\n );\n\n this._constraintClassCache.set(cacheKey, ecclass);\n return ecclass;\n }\n\n /** initialize from an imodel with metadata */\n public async initAllSchemasInIModel(imodel: IModelDb): Promise<void> {\n let totalSchemaCount = 0;\n let schemaCompletedCount = 0;\n\n const initStartTime = performance.now();\n\n const query = `\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 DISTINCT s.Name as name\n FROM refs\n JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId\n -- ensure schema dependency order\n ORDER BY s.ECInstanceId\n `;\n\n for await (const row of imodel.createQueryReader(query)) {\n const schemaName = row.name;\n const startTime = performance.now();\n Logger.logInfo(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Loading schema: ${schemaName}`\n );\n const schemaItemKey = new SchemaKey(schemaName);\n const schema = await imodel.schemaContext.getSchema(schemaItemKey);\n if (schema) {\n await this.considerInitSchema(schema);\n const endTime = performance.now();\n Logger.logInfo(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Completed schema: ${schemaName} in ${(endTime - startTime).toFixed(2)}ms`\n );\n schemaCompletedCount++;\n } else {\n Logger.logInfo(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Did not load schema: ${schemaName}`\n );\n }\n\n totalSchemaCount++;\n }\n\n const initEndTime = performance.now();\n Logger.logInfo(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Schemas completed out of total: ${schemaCompletedCount} / ${totalSchemaCount} in ${(initEndTime - initStartTime).toFixed(2)}ms`\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 =\n 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 const schemaNameLower = schema.name.toLowerCase();\n\n // Pre-collect all items to reduce iterator overhead\n const allItems = Array.from(schema.getItems());\n const ecClasses: ECClass[] = [];\n const relationshipClasses: RelationshipClass[] = [];\n\n // Single pass through items with type checking\n for (const item of allItems) {\n // eslint-disable-next-line @itwin/no-internal\n if (!ECClass.isECClass(item)) continue;\n ecClasses.push(item);\n if (item instanceof RelationshipClass) {\n relationshipClasses.push(item);\n }\n }\n\n // Process relationship classes in parallel and populate global cache\n const relInfoPromises = relationshipClasses.map(async (relClass) => {\n const relInfo = await this.relInfoFromRelClass(relClass);\n this._relationshipInfoCache.set(relClass.fullName, relInfo);\n if (relInfo) {\n this._relClassNameEndToRefTypes.set(\n [schemaNameLower, relClass.name.toLowerCase()],\n relInfo\n );\n }\n return relInfo;\n });\n\n // Wait for all relationship info to be cached\n await Promise.all(relInfoPromises);\n\n // Process navigation properties with optimized batching\n const propertyBatchSize = 25;\n for (let i = 0; i < ecClasses.length; i += propertyBatchSize) {\n const classBatch = ecClasses.slice(i, i + propertyBatchSize);\n\n const classPromises = classBatch.map(async (ecclass) => {\n const properties = await ecclass.getProperties();\n if (!properties) return;\n\n const classNameLower = ecclass.name.toLowerCase();\n\n // Efficiently filter navigation properties\n const navProps = Array.from(properties).filter((prop) =>\n prop.isNavigation()\n );\n if (navProps.length === 0) return;\n\n const navPropPromises = navProps.map(async (prop) => {\n const relClass = await prop.relationshipClass;\n\n // Use cached relation info\n let relInfo = this._relationshipInfoCache.get(relClass.fullName);\n if (\n relInfo === undefined &&\n !this._relationshipInfoCache.has(relClass.fullName)\n ) {\n relInfo = await this.relInfoFromRelClass(relClass);\n this._relationshipInfoCache.set(relClass.fullName, relInfo);\n }\n\n if (relInfo === undefined) return;\n\n const navPropRefType =\n prop.direction === StrengthDirection.Forward\n ? // eslint-disable-next-line @itwin/no-internal\n relInfo.target\n : // eslint-disable-next-line @itwin/no-internal\n relInfo.source;\n\n this._propQualifierToRefType.set(\n [schemaNameLower, classNameLower, prop.name.toLowerCase()],\n navPropRefType\n );\n });\n\n await Promise.all(navPropPromises);\n });\n\n await Promise.all(classPromises);\n }\n\n this._initedSchemas.set(schema.name, schema.schemaKey);\n }\n\n private async relInfoFromRelClass(\n ecclass: RelationshipClass\n ): Promise<RelTypeInfo | undefined> {\n assert(ecclass.source.constraintClasses !== undefined);\n assert(ecclass.target.constraintClasses !== undefined);\n const [\n [sourceClass, sourceRootBisClass],\n [targetClass, targetRootBisClass],\n ] = await Promise.all([\n this.getAbstractConstraintClass(ecclass.source).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n this.getAbstractConstraintClass(ecclass.target).then(\n async (constraintClass) => [\n constraintClass,\n await this.getRootBisClass(constraintClass),\n ]\n ),\n ]);\n\n if (\n sourceRootBisClass.name === \"CodeSpec\" ||\n targetRootBisClass.name === \"CodeSpec\"\n )\n return undefined;\n const sourceType =\n ECReferenceTypesCache.bisRootClassToRefType[sourceRootBisClass.name];\n const targetType =\n ECReferenceTypesCache.bisRootClassToRefType[targetRootBisClass.name];\n if (\n (!sourceType &&\n sourceRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\")) ||\n (!targetType &&\n targetRootBisClass.customAttributes?.has(\"ECDbMap.QueryView\"))\n ) {\n // ECView elements are not \"real\" data and transformer does not need to process them.\n // Relationships that point to ECView elements can only be used in ECViews so the mapping is not needed.\n return undefined;\n }\n\n const makeAssertMsg = (root: ECClass, cls: ECClass) =>\n [\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(\n sourceType !== undefined,\n makeAssertMsg(sourceRootBisClass, sourceClass)\n );\n assert(\n targetType !== undefined,\n makeAssertMsg(targetRootBisClass, targetClass)\n );\n return { source: sourceType, target: targetType };\n }\n\n public getNavPropRefType(\n schemaName: string,\n className: string,\n propName: string\n ): undefined | ConcreteEntityTypes {\n if (!this._initedSchemas.has(schemaName)) throw new SchemaNotInCacheErr();\n return this._propQualifierToRefType.get([\n schemaName.toLowerCase(),\n className.toLowerCase(),\n propName.toLowerCase(),\n ]);\n }\n\n public getRelationshipEndType(\n schemaName: string,\n className: string\n ): undefined | RelTypeInfo {\n if (!this._initedSchemas.has(schemaName)) 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 this._relClassNameEndToRefTypes.clear();\n this._rootBisClassCache.clear();\n this._relationshipInfoCache.clear();\n this._constraintClassCache.clear();\n }\n}\n"]}
|
|
@@ -38,7 +38,7 @@ class ElementCascadingDeleter extends core_backend_1.ElementTreeDeleter {
|
|
|
38
38
|
/** Process code scope references */
|
|
39
39
|
_processCodeScopes(element, scope) {
|
|
40
40
|
const newScope = new core_backend_1.ElementTreeWalkerScope(scope, element);
|
|
41
|
-
// eslint-disable-next-line @itwin/no-internal,
|
|
41
|
+
// eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
|
|
42
42
|
this._iModel.withPreparedStatement(`
|
|
43
43
|
SELECT ECInstanceId
|
|
44
44
|
FROM bis.Element
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElementCascadingDeleter.js","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":";;;AAkBA,4DAOC;AAzBD;;;gGAGgG;AAChG;;GAEG;AACH,sDAI6B;AAC7B,sDAA2D;AAE3D;;;GAGG;AACH,SAAgB,wBAAwB,CACtC,MAAgB,EAChB,UAAsB;IAEtB,MAAM,GAAG,GAAG,IAAI,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChD,GAAG,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACrC,GAAG,CAAC,qBAAqB,EAAE,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAa,uBAAwB,SAAQ,iCAAkB;IACnD,qBAAqB,CAC7B,UAAsB,EACtB,MAA8B;QAE9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IAClB,kBAAkB,CACnC,OAAmB,EACnB,KAA6B;QAE7B,IAAI,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IACD,oCAAoC;IAC5B,kBAAkB,CACxB,OAAmB,EACnB,KAA6B;QAE7B,MAAM,QAAQ,GAAG,IAAI,qCAAsB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5D,
|
|
1
|
+
{"version":3,"file":"ElementCascadingDeleter.js","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":";;;AAkBA,4DAOC;AAzBD;;;gGAGgG;AAChG;;GAEG;AACH,sDAI6B;AAC7B,sDAA2D;AAE3D;;;GAGG;AACH,SAAgB,wBAAwB,CACtC,MAAgB,EAChB,UAAsB;IAEtB,MAAM,GAAG,GAAG,IAAI,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChD,GAAG,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACrC,GAAG,CAAC,qBAAqB,EAAE,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAa,uBAAwB,SAAQ,iCAAkB;IACnD,qBAAqB,CAC7B,UAAsB,EACtB,MAA8B;QAE9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IAClB,kBAAkB,CACnC,OAAmB,EACnB,KAA6B;QAE7B,IAAI,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IACD,oCAAoC;IAC5B,kBAAkB,CACxB,OAAmB,EACnB,KAA6B;QAE7B,MAAM,QAAQ,GAAG,IAAI,qCAAsB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5D,gFAAgF;QAChF,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAChC;;;;;KAKD,EACC,CAAC,IAAI,EAAE,EAAE;YACP,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACxB,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,uBAAQ,CAAC,aAAa,EAAE,CAAC;gBAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;gBAC3C,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;CACF;AAzCD,0DAyCC","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 {\n ElementTreeDeleter,\n ElementTreeWalkerScope,\n IModelDb,\n} from \"@itwin/core-backend\";\nimport { DbResult, Id64String } from \"@itwin/core-bentley\";\n\n/** Deletes an element tree and code scope references starting with the specified top element. The top element is also deleted. Uses ElementCascadeDeleter.\n * @param iModel The iModel\n * @param topElement The parent of the sub-tree\n */\nexport function deleteElementTreeCascade(\n iModel: IModelDb,\n topElement: Id64String\n): void {\n const del = new ElementCascadingDeleter(iModel);\n del.deleteNormalElements(topElement);\n del.deleteSpecialElements();\n}\n\n/** Deletes an entire element tree, including sub-models, child elements and code scope references.\n * Items are deleted in bottom-up order. Definitions and Subjects are deleted after normal elements.\n * Call deleteNormalElements on each tree. Then call deleteSpecialElements.\n */\nexport class ElementCascadingDeleter extends ElementTreeDeleter {\n protected shouldVisitCodeScopes(\n _elementId: Id64String,\n _scope: ElementTreeWalkerScope\n ) {\n return true;\n }\n\n /** The main tree-walking function */\n protected override processElementTree(\n element: Id64String,\n scope: ElementTreeWalkerScope\n ): void {\n if (this.shouldVisitCodeScopes(element, scope)) {\n this._processCodeScopes(element, scope);\n }\n super.processElementTree(element, scope);\n }\n /** Process code scope references */\n private _processCodeScopes(\n element: Id64String,\n scope: ElementTreeWalkerScope\n ) {\n const newScope = new ElementTreeWalkerScope(scope, element);\n // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated\n this._iModel.withPreparedStatement(\n `\n SELECT ECInstanceId\n FROM bis.Element\n WHERE CodeScope.id=?\n AND Parent.id IS NULL\n `,\n (stmt) => {\n stmt.bindId(1, element);\n while (stmt.step() === DbResult.BE_SQLITE_ROW) {\n const elementId = stmt.getValue(0).getId();\n this.processElementTree(elementId, newScope);\n }\n }\n );\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityUnifier.d.ts","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAGH,OAAO,EAEL,eAAe,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,mBAAmB,EAKnB,QAAQ,EAET,MAAM,qBAAqB,CAAC;AAG7B,gBAAgB;AAChB,yBAAiB,aAAa,CAAC;IAC7B,MAAM,UAAU,eAAe,CAAC,MAAM,EAAE,cAAc,yEAKrD;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,iBAc9D;IAED,MAAM,UAAU,MAAM,CACpB,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE;QAAE,MAAM,EAAE,cAAc,CAAA;KAAE,GAAG;QAAE,eAAe,EAAE,eAAe,CAAA;KAAE,
|
|
1
|
+
{"version":3,"file":"EntityUnifier.d.ts","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAGH,OAAO,EAEL,eAAe,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,mBAAmB,EAKnB,QAAQ,EAET,MAAM,qBAAqB,CAAC;AAG7B,gBAAgB;AAChB,yBAAiB,aAAa,CAAC;IAC7B,MAAM,UAAU,eAAe,CAAC,MAAM,EAAE,cAAc,yEAKrD;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,iBAc9D;IAED,MAAM,UAAU,MAAM,CACpB,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE;QAAE,MAAM,EAAE,cAAc,CAAA;KAAE,GAAG;QAAE,eAAe,EAAE,eAAe,CAAA;KAAE,WAyBvE;;CACF"}
|
package/lib/cjs/EntityUnifier.js
CHANGED
|
@@ -45,11 +45,12 @@ var EntityUnifier;
|
|
|
45
45
|
? core_backend_1.EntityReferences.split(arg.entityReference)
|
|
46
46
|
: [undefined, arg.entity.id];
|
|
47
47
|
const classFullName = "entityReference" in arg
|
|
48
|
-
?
|
|
48
|
+
? // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-non-null-assertion
|
|
49
|
+
core_common_1.ConcreteEntityTypes.toBisCoreRootClassFullName(type)
|
|
49
50
|
: `[${arg.entity.schemaName}].[${arg.entity.className}]`;
|
|
50
51
|
if (id === undefined || core_bentley_1.Id64.isInvalid(id))
|
|
51
52
|
return false;
|
|
52
|
-
// eslint-disable-next-line @itwin/no-internal,
|
|
53
|
+
// eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
|
|
53
54
|
return db.withPreparedStatement(`SELECT 1 FROM ${classFullName} WHERE ECInstanceId=?`, (stmt) => {
|
|
54
55
|
stmt.bindId(1, id);
|
|
55
56
|
const matchesResult = stmt.step();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityUnifier.js","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;AAChG;;;;GAIG;;;AAEH,iCAAiC;AACjC,oDAI4B;AAC5B,sDAS6B;AAC7B,sDAAqD;AAErD,gBAAgB;AAChB,IAAiB,aAAa,
|
|
1
|
+
{"version":3,"file":"EntityUnifier.js","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;AAChG;;;;GAIG;;;AAEH,iCAAiC;AACjC,oDAI4B;AAC5B,sDAS6B;AAC7B,sDAAqD;AAErD,gBAAgB;AAChB,IAAiB,aAAa,CAuD7B;AAvDD,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,6BAAe,kBAK9B,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,CACzC,EAAE,CAAC,aAAa,CACA,CAAC;aAChB,IAAI,MAAM,YAAY,4BAAa;YACtC,OAAO,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAkB,CAAC;;YAEnE,MAAM,CACJ,KAAK,EACL,4BAA4B,MAAM,CAAC,WAAW,CAAC,IAAI,kDAAkD,CACtG,CAAC;IACN,CAAC;IAde,wBAAU,aAczB,CAAA;IAED,SAAgB,MAAM,CACpB,EAAY,EACZ,GAAsE;QAEtE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GACd,iBAAiB,IAAI,GAAG;YACtB,CAAC,CAAC,+BAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC;YAC7C,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjC,MAAM,aAAa,GACjB,iBAAiB,IAAI,GAAG;YACtB,CAAC,CAAC,wFAAwF;gBACxF,iCAAmB,CAAC,0BAA0B,CAAC,IAAK,CAAC;YACvD,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC;QAE7D,IAAI,EAAE,KAAK,SAAS,IAAI,mBAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QAEzD,gFAAgF;QAChF,OAAO,EAAE,CAAC,qBAAqB,CAC7B,iBAAiB,aAAa,uBAAuB,EACrD,CAAC,IAAI,EAAE,EAAE;YACP,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,aAAa,KAAK,uBAAQ,CAAC,aAAa;gBAAE,OAAO,IAAI,CAAC;YAC1D,IAAI,aAAa,KAAK,uBAAQ,CAAC,cAAc;gBAAE,OAAO,KAAK,CAAC;;gBACvD,MAAM,IAAI,yBAAW,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;QAC5D,CAAC,CACF,CAAC;IACJ,CAAC;IA3Be,oBAAM,SA2BrB,CAAA;AACH,CAAC,EAvDgB,aAAa,6BAAb,aAAa,QAuD7B","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 * as assert from \"assert\";\nimport {\n ConcreteEntityTypes,\n EntityReference,\n IModelError,\n} from \"@itwin/core-common\";\nimport {\n ConcreteEntity,\n ConcreteEntityProps,\n // eslint-disable-next-line @typescript-eslint/no-redeclare\n Element,\n ElementAspect,\n EntityReferences,\n IModelDb,\n Relationship,\n} from \"@itwin/core-backend\";\nimport { DbResult, Id64 } from \"@itwin/core-bentley\";\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 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(\n db.relationships\n ) as EntityUpdater;\n else if (entity instanceof ElementAspect)\n return db.elements.updateAspect.bind(db.elements) as EntityUpdater;\n else\n assert(\n false,\n `unreachable; entity was '${entity.constructor.name}' not an Element, Relationship, or ElementAspect`\n );\n }\n\n export function exists(\n db: IModelDb,\n arg: { entity: ConcreteEntity } | { entityReference: EntityReference }\n ) {\n const [type, id] =\n \"entityReference\" in arg\n ? EntityReferences.split(arg.entityReference)\n : [undefined, arg.entity.id];\n const classFullName =\n \"entityReference\" in arg\n ? // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-non-null-assertion\n ConcreteEntityTypes.toBisCoreRootClassFullName(type!)\n : `[${arg.entity.schemaName}].[${arg.entity.className}]`;\n\n if (id === undefined || Id64.isInvalid(id)) return false;\n\n // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated\n return db.withPreparedStatement(\n `SELECT 1 FROM ${classFullName} WHERE ECInstanceId=?`,\n (stmt) => {\n stmt.bindId(1, id);\n const matchesResult = stmt.step();\n if (matchesResult === DbResult.BE_SQLITE_ROW) return true;\n if (matchesResult === DbResult.BE_SQLITE_DONE) return false;\n else throw new IModelError(matchesResult, \"query failed\");\n }\n );\n }\n}\n"]}
|
|
@@ -121,7 +121,7 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
|
|
|
121
121
|
ELSE 'error'
|
|
122
122
|
END
|
|
123
123
|
`;
|
|
124
|
-
// eslint-disable-next-line @itwin/no-internal,
|
|
124
|
+
// eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
|
|
125
125
|
const relInSource = this.sourceDb.withPreparedStatement(`
|
|
126
126
|
SELECT
|
|
127
127
|
SourceECInstanceId,
|
|
@@ -163,7 +163,7 @@ class IModelCloneContext extends core_backend_1.IModelElementCloneContext {
|
|
|
163
163
|
if (!core_backend_1.EntityReferences.isValid(relInTarget.sourceId) ||
|
|
164
164
|
!core_backend_1.EntityReferences.isValid(relInTarget.targetId))
|
|
165
165
|
break;
|
|
166
|
-
// eslint-disable-next-line @itwin/no-internal,
|
|
166
|
+
// eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
|
|
167
167
|
const relInTargetId = this.targetDb.withPreparedStatement(`
|
|
168
168
|
SELECT ECInstanceId
|
|
169
169
|
FROM BisCore:ElementRefersToElements
|