@itwin/imodel-transformer 2.0.0-dev.2 → 2.0.0-dev.20
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 +18 -15
- package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
- package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +1 -1
- package/lib/cjs/DetachedExportElementAspectsStrategy.js +8 -6
- package/lib/cjs/DetachedExportElementAspectsStrategy.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 +103 -40
- package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
- package/lib/cjs/ElementCascadingDeleter.d.ts.map +1 -1
- package/lib/cjs/ElementCascadingDeleter.js +10 -9
- package/lib/cjs/ElementCascadingDeleter.js.map +1 -1
- package/lib/cjs/EntityUnifier.d.ts +1 -1
- package/lib/cjs/EntityUnifier.d.ts.map +1 -1
- package/lib/cjs/EntityUnifier.js +11 -12
- package/lib/cjs/EntityUnifier.js.map +1 -1
- package/lib/cjs/ExportElementAspectsStrategy.d.ts +4 -4
- package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +1 -1
- package/lib/cjs/ExportElementAspectsStrategy.js +1 -1
- package/lib/cjs/ExportElementAspectsStrategy.js.map +1 -1
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts.map +1 -1
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +17 -16
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.js.map +1 -1
- package/lib/cjs/IModelCloneContext.d.ts +3 -3
- package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
- package/lib/cjs/IModelCloneContext.js +60 -52
- package/lib/cjs/IModelCloneContext.js.map +1 -1
- package/lib/cjs/IModelExporter.d.ts +28 -19
- package/lib/cjs/IModelExporter.d.ts.map +1 -1
- package/lib/cjs/IModelExporter.js +145 -119
- package/lib/cjs/IModelExporter.js.map +1 -1
- package/lib/cjs/IModelImporter.d.ts +21 -21
- package/lib/cjs/IModelImporter.d.ts.map +1 -1
- package/lib/cjs/IModelImporter.js +94 -74
- package/lib/cjs/IModelImporter.js.map +1 -1
- package/lib/cjs/IModelTransformer.d.ts +84 -178
- package/lib/cjs/IModelTransformer.d.ts.map +1 -1
- package/lib/cjs/IModelTransformer.js +371 -997
- package/lib/cjs/IModelTransformer.js.map +1 -1
- package/lib/cjs/ProvenanceManager.d.ts +159 -0
- package/lib/cjs/ProvenanceManager.d.ts.map +1 -0
- package/lib/cjs/ProvenanceManager.js +677 -0
- package/lib/cjs/ProvenanceManager.js.map +1 -0
- package/lib/cjs/SyncTypeResolver.d.ts +34 -0
- package/lib/cjs/SyncTypeResolver.d.ts.map +1 -0
- package/lib/cjs/SyncTypeResolver.js +84 -0
- package/lib/cjs/SyncTypeResolver.js.map +1 -0
- 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 +38 -33
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
|
|
@@ -9,7 +9,7 @@ const core_backend_1 = require("@itwin/core-backend");
|
|
|
9
9
|
const core_bentley_1 = require("@itwin/core-bentley");
|
|
10
10
|
const core_common_1 = require("@itwin/core-common");
|
|
11
11
|
const assert = require("assert");
|
|
12
|
-
const
|
|
12
|
+
const ProvenanceManager_1 = require("./ProvenanceManager");
|
|
13
13
|
const url_1 = require("url");
|
|
14
14
|
/**
|
|
15
15
|
* @alpha
|
|
@@ -18,7 +18,6 @@ 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 deprecation/deprecation */
|
|
22
21
|
args.master.withSqliteStatement(`
|
|
23
22
|
UPDATE bis_Element
|
|
24
23
|
SET FederationGuid=randomblob(16)
|
|
@@ -42,6 +41,7 @@ async function initializeBranchProvenance(args) {
|
|
|
42
41
|
// eslint-disable-next-line @itwin/no-internal
|
|
43
42
|
(s) => assert(s.step() === core_bentley_1.DbResult.BE_SQLITE_DONE, args.branch.getLastError()));
|
|
44
43
|
args.branch.clearCaches(); // statements write lock attached db (clearing statement cache does not fix this)
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
45
45
|
args.branch.saveChanges();
|
|
46
46
|
args.branch.withSqliteStatement("DETACH DATABASE master", (s) => {
|
|
47
47
|
const res = s.step();
|
|
@@ -51,7 +51,6 @@ 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 deprecation/deprecation */
|
|
55
54
|
args.branch.performCheckpoint();
|
|
56
55
|
const reopenBranch = makeDbReopener(args.branch);
|
|
57
56
|
// close dbs because element cache could be invalid
|
|
@@ -62,6 +61,7 @@ async function initializeBranchProvenance(args) {
|
|
|
62
61
|
]);
|
|
63
62
|
}
|
|
64
63
|
// create an external source and owning repository link to use as our *Target Scope Element* for future synchronizations
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
65
65
|
const masterRepoLinkId = args.branch.elements.insertElement({
|
|
66
66
|
classFullName: core_backend_1.RepositoryLink.classFullName,
|
|
67
67
|
code: core_backend_1.RepositoryLink.createCode(args.branch, core_backend_1.IModelDb.repositoryModelId, "example-code-value"),
|
|
@@ -71,34 +71,36 @@ async function initializeBranchProvenance(args) {
|
|
|
71
71
|
repositoryGuid: args.master.iModelId,
|
|
72
72
|
description: args.masterDescription,
|
|
73
73
|
});
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
74
75
|
const masterExternalSourceId = args.branch.elements.insertElement({
|
|
75
76
|
classFullName: core_backend_1.ExternalSource.classFullName,
|
|
76
77
|
model: core_backend_1.IModelDb.rootSubjectId,
|
|
77
78
|
code: core_common_1.Code.createEmpty(),
|
|
78
79
|
repository: new core_backend_1.ExternalSourceIsInRepository(masterRepoLinkId),
|
|
79
|
-
/* eslint-disable @typescript-eslint/no-
|
|
80
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
80
81
|
connectorName: require("../../package.json").name,
|
|
81
82
|
connectorVersion: require("../../package.json").version,
|
|
82
|
-
/* eslint-enable @typescript-eslint/no-
|
|
83
|
+
/* eslint-enable @typescript-eslint/no-require-imports */
|
|
83
84
|
});
|
|
84
|
-
const
|
|
85
|
+
const fedGuidlessElemsSql = `
|
|
85
86
|
SELECT ECInstanceId AS id
|
|
86
87
|
FROM Bis.Element
|
|
87
88
|
WHERE FederationGuid IS NULL
|
|
88
89
|
AND ECInstanceId NOT IN (0x1, 0xe, 0x10) /* ignore special elems */
|
|
89
90
|
`;
|
|
90
|
-
const elemReader = args.branch.createQueryReader(
|
|
91
|
-
|
|
92
|
-
const id =
|
|
93
|
-
const aspectProps =
|
|
91
|
+
const elemReader = args.branch.createQueryReader(fedGuidlessElemsSql, undefined, { usePrimaryConn: true });
|
|
92
|
+
for await (const row of elemReader) {
|
|
93
|
+
const id = row.id;
|
|
94
|
+
const aspectProps = ProvenanceManager_1.ProvenanceManager.initElementProvenanceOptions(id, id, {
|
|
94
95
|
isReverseSynchronization: false,
|
|
95
96
|
targetScopeElementId: masterExternalSourceId,
|
|
96
97
|
sourceDb: args.master,
|
|
97
98
|
targetDb: args.branch,
|
|
98
99
|
});
|
|
100
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
99
101
|
args.branch.elements.insertAspect(aspectProps);
|
|
100
102
|
}
|
|
101
|
-
const
|
|
103
|
+
const fedGuidlessRelsSql = `
|
|
102
104
|
SELECT erte.ECInstanceId as id
|
|
103
105
|
FROM Bis.ElementRefersToElements erte
|
|
104
106
|
JOIN bis.Element se
|
|
@@ -107,16 +109,17 @@ async function initializeBranchProvenance(args) {
|
|
|
107
109
|
ON te.ECInstanceId=erte.TargetECInstanceId
|
|
108
110
|
WHERE se.FederationGuid IS NULL
|
|
109
111
|
OR te.FederationGuid IS NULL`;
|
|
110
|
-
const relReader = args.branch.createQueryReader(
|
|
111
|
-
|
|
112
|
-
const id =
|
|
113
|
-
const aspectProps =
|
|
112
|
+
const relReader = args.branch.createQueryReader(fedGuidlessRelsSql, undefined, { usePrimaryConn: true });
|
|
113
|
+
for await (const row of relReader) {
|
|
114
|
+
const id = row.id;
|
|
115
|
+
const aspectProps = await ProvenanceManager_1.ProvenanceManager.initRelationshipProvenanceOptions(id, id, {
|
|
114
116
|
isReverseSynchronization: false,
|
|
115
117
|
targetScopeElementId: masterExternalSourceId,
|
|
116
118
|
sourceDb: args.master,
|
|
117
119
|
targetDb: args.branch,
|
|
118
120
|
forceOldRelationshipProvenanceMethod: false,
|
|
119
121
|
});
|
|
122
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
120
123
|
args.branch.elements.insertAspect(aspectProps);
|
|
121
124
|
}
|
|
122
125
|
if (args.createFedGuidsForMaster === true) {
|
|
@@ -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 { ProvenanceManager } from \"./ProvenanceManager\";\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 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 // eslint-disable-next-line @typescript-eslint/no-deprecated\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 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 // eslint-disable-next-line @typescript-eslint/no-deprecated\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 // eslint-disable-next-line @typescript-eslint/no-deprecated\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 for await (const row of elemReader) {\n const id: string = row.id;\n const aspectProps = ProvenanceManager.initElementProvenanceOptions(id, id, {\n isReverseSynchronization: false,\n targetScopeElementId: masterExternalSourceId,\n sourceDb: args.master,\n targetDb: args.branch,\n });\n // eslint-disable-next-line @typescript-eslint/no-deprecated\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 for await (const row of relReader) {\n const id: string = row.id;\n const aspectProps =\n await ProvenanceManager.initRelationshipProvenanceOptions(id, id, {\n isReverseSynchronization: false,\n targetScopeElementId: masterExternalSourceId,\n sourceDb: args.master,\n targetDb: args.branch,\n forceOldRelationshipProvenanceMethod: false,\n });\n // eslint-disable-next-line @typescript-eslint/no-deprecated\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DetachedExportElementAspectsStrategy.d.ts","sourceRoot":"","sources":["../../src/DetachedExportElementAspectsStrategy.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAQ9E;;;;;;;GAOG;AACH,qBAAa,oCAAqC,SAAQ,4BAA4B;IAC9D,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"DetachedExportElementAspectsStrategy.d.ts","sourceRoot":"","sources":["../../src/DetachedExportElementAspectsStrategy.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAQ9E;;;;;;;GAOG;AACH,qBAAa,oCAAqC,SAAQ,4BAA4B;IAC9D,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;YAsDhD,iBAAiB;YAahB,YAAY;IAgEL,8BAA8B,CAClD,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;CAGjB"}
|
|
@@ -25,7 +25,7 @@ class DetachedExportElementAspectsStrategy extends ExportElementAspectsStrategy_
|
|
|
25
25
|
const doExport = this.aspectChanges === undefined || isInsertChange || isUpdateChange;
|
|
26
26
|
if (doExport) {
|
|
27
27
|
const isKnownUpdate = this.aspectChanges ? isUpdateChange : undefined;
|
|
28
|
-
this.handler.onExportElementUniqueAspect(uniqueAspect, isKnownUpdate);
|
|
28
|
+
await this.handler.onExportElementUniqueAspect(uniqueAspect, isKnownUpdate);
|
|
29
29
|
await this.handler.trackProgress();
|
|
30
30
|
}
|
|
31
31
|
});
|
|
@@ -37,7 +37,7 @@ class DetachedExportElementAspectsStrategy extends ExportElementAspectsStrategy_
|
|
|
37
37
|
}
|
|
38
38
|
// element id changed so all element's aspects are in the array and can be exported
|
|
39
39
|
if (batchedElementMultiAspects[0].element.id !== multiAspect.element.id) {
|
|
40
|
-
this.handler.onExportElementMultiAspects(batchedElementMultiAspects);
|
|
40
|
+
await this.handler.onExportElementMultiAspects(batchedElementMultiAspects);
|
|
41
41
|
await this.handler.trackProgress();
|
|
42
42
|
batchedElementMultiAspects = [];
|
|
43
43
|
}
|
|
@@ -45,13 +45,13 @@ class DetachedExportElementAspectsStrategy extends ExportElementAspectsStrategy_
|
|
|
45
45
|
});
|
|
46
46
|
if (batchedElementMultiAspects.length > 0) {
|
|
47
47
|
// aspects that are left in the array have not been exported
|
|
48
|
-
this.handler.onExportElementMultiAspects(batchedElementMultiAspects);
|
|
48
|
+
await this.handler.onExportElementMultiAspects(batchedElementMultiAspects);
|
|
49
49
|
await this.handler.trackProgress();
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
async exportAspectsLoop(baseAspectClass, exportAspect) {
|
|
53
53
|
for await (const aspect of this.queryAspects(baseAspectClass)) {
|
|
54
|
-
if (!this.shouldExportElementAspect(aspect)) {
|
|
54
|
+
if (!(await this.shouldExportElementAspect(aspect))) {
|
|
55
55
|
continue;
|
|
56
56
|
}
|
|
57
57
|
await exportAspect(aspect);
|
|
@@ -65,7 +65,7 @@ class DetachedExportElementAspectsStrategy extends ExportElementAspectsStrategy_
|
|
|
65
65
|
JOIN ECDbMeta.ECClassDef c ON c.ECInstanceId = r.SourceECInstanceId
|
|
66
66
|
WHERE r.TargetECInstanceId = ec_classId(:baseClassName)
|
|
67
67
|
`;
|
|
68
|
-
const aspectClassesQueryReader = this.sourceDb.createQueryReader(optimizesAspectClassesSql, new core_common_1.QueryBinder().bindString("baseClassName", baseElementAspectClassFullName));
|
|
68
|
+
const aspectClassesQueryReader = this.sourceDb.createQueryReader(optimizesAspectClassesSql, new core_common_1.QueryBinder().bindString("baseClassName", baseElementAspectClassFullName), { usePrimaryConn: true });
|
|
69
69
|
const aspectClassesAsyncQueryReader = (0, ECSqlReaderAsyncIterableIteratorAdapter_1.ensureECSqlReaderIsAsyncIterableIterator)(aspectClassesQueryReader);
|
|
70
70
|
for await (const rowProxy of aspectClassesAsyncQueryReader) {
|
|
71
71
|
const row = rowProxy.toRow();
|
|
@@ -79,7 +79,9 @@ class DetachedExportElementAspectsStrategy extends ExportElementAspectsStrategy_
|
|
|
79
79
|
if (this.excludedElementAspectClassFullNames.has(classFullName))
|
|
80
80
|
continue;
|
|
81
81
|
const getAspectPropsSql = `SELECT * FROM [${schemaName}]:[${className}] WHERE ECClassId = :classId ORDER BY Element.Id`;
|
|
82
|
-
const aspectQueryReader = this.sourceDb.createQueryReader(getAspectPropsSql, new core_common_1.QueryBinder().bindId("classId", classId),
|
|
82
|
+
const aspectQueryReader = this.sourceDb.createQueryReader(getAspectPropsSql, new core_common_1.QueryBinder().bindId("classId", classId),
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
84
|
+
{ rowFormat: core_common_1.QueryRowFormat.UseJsPropertyNames, usePrimaryConn: true });
|
|
83
85
|
const aspectAsyncQueryReader = (0, ECSqlReaderAsyncIterableIteratorAdapter_1.ensureECSqlReaderIsAsyncIterableIterator)(aspectQueryReader);
|
|
84
86
|
let firstDone = false;
|
|
85
87
|
for await (const rowProxy of aspectAsyncQueryReader) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DetachedExportElementAspectsStrategy.js","sourceRoot":"","sources":["../../src/DetachedExportElementAspectsStrategy.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG,sDAI6B;AAE7B,iFAA8E;AAC9E,uGAAqG;AACrG,oDAI4B;AAE5B;;;;;;;GAOG;AACH,MAAa,oCAAqC,SAAQ,2DAA4B;IACpE,KAAK,CAAC,uBAAuB;QAC3C,MAAM,IAAI,CAAC,iBAAiB,CAC1B,kCAAmB,CAAC,aAAa,EACjC,KAAK,EAAE,YAAY,EAAE,EAAE;YACrB,MAAM,cAAc,GAClB,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC;YAC9D,MAAM,cAAc,GAClB,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC;YAC9D,MAAM,QAAQ,GACZ,IAAI,CAAC,aAAa,KAAK,SAAS,IAAI,cAAc,IAAI,cAAc,CAAC;YACvE,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;gBACtE,IAAI,CAAC,OAAO,CAAC,2BAA2B,
|
|
1
|
+
{"version":3,"file":"DetachedExportElementAspectsStrategy.js","sourceRoot":"","sources":["../../src/DetachedExportElementAspectsStrategy.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\nimport {\n ElementAspect,\n ElementMultiAspect,\n ElementUniqueAspect,\n} from \"@itwin/core-backend\";\nimport { Id64String } from \"@itwin/core-bentley\";\nimport { ExportElementAspectsStrategy } from \"./ExportElementAspectsStrategy\";\nimport { ensureECSqlReaderIsAsyncIterableIterator } from \"./ECSqlReaderAsyncIterableIteratorAdapter\";\nimport {\n ElementAspectProps,\n QueryBinder,\n QueryRowFormat,\n} from \"@itwin/core-common\";\n\n/**\n * Detached ElementAspect export strategy for [[IModelExporter]].\n * This strategy exports all ElementAspects separately from the Elements that own them.\n *\n * @note Since aspects are exported separately from elements that own them, this strategy will export aspects of filtered out elements by default and\n * this needs to be handled by ElementAspectHandler\n * @internal\n */\nexport class DetachedExportElementAspectsStrategy extends ExportElementAspectsStrategy {\n public override async exportAllElementAspects(): Promise<void> {\n await this.exportAspectsLoop<ElementUniqueAspect>(\n ElementUniqueAspect.classFullName,\n async (uniqueAspect) => {\n const isInsertChange =\n this.aspectChanges?.insertIds.has(uniqueAspect.id) ?? false;\n const isUpdateChange =\n this.aspectChanges?.updateIds.has(uniqueAspect.id) ?? false;\n const doExport =\n this.aspectChanges === undefined || isInsertChange || isUpdateChange;\n if (doExport) {\n const isKnownUpdate = this.aspectChanges ? isUpdateChange : undefined;\n await this.handler.onExportElementUniqueAspect(\n uniqueAspect,\n isKnownUpdate\n );\n await this.handler.trackProgress();\n }\n }\n );\n\n let batchedElementMultiAspects: ElementMultiAspect[] = [];\n await this.exportAspectsLoop<ElementMultiAspect>(\n ElementMultiAspect.classFullName,\n async (multiAspect) => {\n if (batchedElementMultiAspects.length === 0) {\n batchedElementMultiAspects.push(multiAspect);\n return;\n }\n\n // element id changed so all element's aspects are in the array and can be exported\n if (\n batchedElementMultiAspects[0].element.id !== multiAspect.element.id\n ) {\n await this.handler.onExportElementMultiAspects(\n batchedElementMultiAspects\n );\n await this.handler.trackProgress();\n batchedElementMultiAspects = [];\n }\n\n batchedElementMultiAspects.push(multiAspect);\n }\n );\n\n if (batchedElementMultiAspects.length > 0) {\n // aspects that are left in the array have not been exported\n await this.handler.onExportElementMultiAspects(\n batchedElementMultiAspects\n );\n await this.handler.trackProgress();\n }\n }\n\n private async exportAspectsLoop<T extends ElementAspect>(\n baseAspectClass: string,\n exportAspect: (aspect: T) => Promise<void>\n ) {\n for await (const aspect of this.queryAspects<T>(baseAspectClass)) {\n if (!(await this.shouldExportElementAspect(aspect))) {\n continue;\n }\n\n await exportAspect(aspect);\n }\n }\n\n private async *queryAspects<T extends ElementAspect>(\n baseElementAspectClassFullName: string\n ) {\n const aspectClassNameIdMap = new Map<\n Id64String,\n { schemaName: string; className: string }\n >();\n\n const optimizesAspectClassesSql = `\n SELECT c.ECInstanceId as classId, (ec_className(c.ECInstanceId, 's')) as schemaName, (ec_className(c.ECInstanceId, 'c')) as className\n FROM ECDbMeta.ClassHasAllBaseClasses r\n JOIN ECDbMeta.ECClassDef c ON c.ECInstanceId = r.SourceECInstanceId\n WHERE r.TargetECInstanceId = ec_classId(:baseClassName)\n `;\n const aspectClassesQueryReader = this.sourceDb.createQueryReader(\n optimizesAspectClassesSql,\n new QueryBinder().bindString(\n \"baseClassName\",\n baseElementAspectClassFullName\n ),\n { usePrimaryConn: true }\n );\n const aspectClassesAsyncQueryReader =\n ensureECSqlReaderIsAsyncIterableIterator(aspectClassesQueryReader);\n for await (const rowProxy of aspectClassesAsyncQueryReader) {\n const row = rowProxy.toRow();\n aspectClassNameIdMap.set(row.classId, {\n schemaName: row.schemaName,\n className: row.className,\n });\n }\n\n for (const [classId, { schemaName, className }] of aspectClassNameIdMap) {\n const classFullName = `${schemaName}:${className}`;\n if (this.excludedElementAspectClassFullNames.has(classFullName)) continue;\n\n const getAspectPropsSql = `SELECT * FROM [${schemaName}]:[${className}] WHERE ECClassId = :classId ORDER BY Element.Id`;\n const aspectQueryReader = this.sourceDb.createQueryReader(\n getAspectPropsSql,\n new QueryBinder().bindId(\"classId\", classId),\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n { rowFormat: QueryRowFormat.UseJsPropertyNames, usePrimaryConn: true }\n );\n const aspectAsyncQueryReader =\n ensureECSqlReaderIsAsyncIterableIterator(aspectQueryReader);\n let firstDone = false;\n for await (const rowProxy of aspectAsyncQueryReader) {\n const row = rowProxy.toRow();\n const aspectProps: ElementAspectProps = {\n ...row,\n classFullName,\n className: undefined,\n }; // add in property required by EntityProps\n if (!firstDone) {\n firstDone = true;\n }\n delete (aspectProps as any).className; // clear property from SELECT * that we don't want in the final instance\n const aspectEntity = this.sourceDb.constructEntity<T>(aspectProps);\n\n yield aspectEntity;\n }\n }\n }\n\n public override async exportElementAspectsForElement(\n _elementId: string\n ): Promise<void> {\n // All aspects are exported separately from their elements and don't need to be exported when element is exported.\n }\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,
|
|
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;AAWtE,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;YAkDtD,kBAAkB;YAalB,UAAU;YA4FV,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,43 +74,58 @@ 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.relationshipClass.fullName}:${constraint.isSource ? "Source" : "Target"}`;
|
|
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
|
-
await imodel.withPreparedStatement(`
|
|
95
|
+
let schemaCount = 0;
|
|
96
|
+
const initStartTime = performance.now();
|
|
97
|
+
const query = `
|
|
82
98
|
WITH RECURSIVE refs(SchemaId) AS (
|
|
83
99
|
SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'
|
|
84
|
-
UNION
|
|
100
|
+
UNION
|
|
85
101
|
SELECT sr.SourceECInstanceId
|
|
86
102
|
FROM ECDbMeta.SchemaHasSchemaReferences sr
|
|
87
103
|
JOIN refs ON sr.TargetECInstanceId = refs.SchemaId
|
|
88
104
|
)
|
|
89
|
-
SELECT s.Name
|
|
105
|
+
SELECT s.Name as name
|
|
90
106
|
FROM refs
|
|
91
107
|
JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId
|
|
92
108
|
-- ensure schema dependency order
|
|
93
|
-
ORDER BY ECInstanceId
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
109
|
+
ORDER BY s.ECInstanceId
|
|
110
|
+
`;
|
|
111
|
+
for await (const row of imodel.createQueryReader(query, undefined, {
|
|
112
|
+
usePrimaryConn: true,
|
|
113
|
+
})) {
|
|
114
|
+
const schemaName = row.name;
|
|
115
|
+
const startTime = performance.now();
|
|
116
|
+
core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Loading schema: ${schemaName}`);
|
|
117
|
+
const schemaItemKey = new ecschema_metadata_1.SchemaKey(schemaName);
|
|
118
|
+
const schema = await imodel.schemaContext.getSchema(schemaItemKey);
|
|
119
|
+
if (!schema) {
|
|
120
|
+
throw new Error(`Failed to load schema: ${schemaName}`);
|
|
100
121
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
122
|
+
await this.considerInitSchema(schema);
|
|
123
|
+
const endTime = performance.now();
|
|
124
|
+
core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Completed schema: ${schemaName} in ${(endTime - startTime).toFixed(2)}ms`);
|
|
125
|
+
schemaCount++;
|
|
126
|
+
}
|
|
127
|
+
const initEndTime = performance.now();
|
|
128
|
+
core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Completed ${schemaCount} schemas in ${(initEndTime - initStartTime).toFixed(2)}ms`);
|
|
104
129
|
}
|
|
105
130
|
async considerInitSchema(schema) {
|
|
106
131
|
if (this._initedSchemas.has(schema.name)) {
|
|
@@ -114,33 +139,67 @@ class ECReferenceTypesCache {
|
|
|
114
139
|
return this.initSchema(schema);
|
|
115
140
|
}
|
|
116
141
|
async initSchema(schema) {
|
|
117
|
-
|
|
118
|
-
|
|
142
|
+
core_bentley_1.Logger.logInfo(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Init Schema: ${schema.name}`);
|
|
143
|
+
const schemaNameLower = schema.name.toLowerCase();
|
|
144
|
+
// Pre-collect all items to reduce iterator overhead
|
|
145
|
+
const allItems = Array.from(schema.getItems());
|
|
146
|
+
const ecClasses = [];
|
|
147
|
+
const relationshipClasses = [];
|
|
148
|
+
// Single pass through items with type checking
|
|
149
|
+
for (const item of allItems) {
|
|
150
|
+
// eslint-disable-next-line @itwin/no-internal
|
|
151
|
+
if (!ecschema_metadata_1.ECClass.isECClass(item))
|
|
119
152
|
continue;
|
|
120
|
-
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
for (const prop of properties) {
|
|
124
|
-
if (!prop.isNavigation())
|
|
125
|
-
continue;
|
|
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);
|
|
153
|
+
ecClasses.push(item);
|
|
154
|
+
if (item instanceof ecschema_metadata_1.RelationshipClass) {
|
|
155
|
+
relationshipClasses.push(item);
|
|
138
156
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
157
|
+
}
|
|
158
|
+
// Process relationship classes in parallel and populate global cache
|
|
159
|
+
const relInfoPromises = relationshipClasses.map(async (relClass) => {
|
|
160
|
+
const relInfo = await this.relInfoFromRelClass(relClass);
|
|
161
|
+
this._relationshipInfoCache.set(relClass.fullName, relInfo);
|
|
162
|
+
if (relInfo) {
|
|
163
|
+
this._relClassNameEndToRefTypes.set([schemaNameLower, relClass.name.toLowerCase()], relInfo);
|
|
143
164
|
}
|
|
165
|
+
return relInfo;
|
|
166
|
+
});
|
|
167
|
+
// Wait for all relationship info to be cached
|
|
168
|
+
await Promise.all(relInfoPromises);
|
|
169
|
+
// Process navigation properties with optimized batching
|
|
170
|
+
const propertyBatchSize = 25;
|
|
171
|
+
for (let i = 0; i < ecClasses.length; i += propertyBatchSize) {
|
|
172
|
+
const classBatch = ecClasses.slice(i, i + propertyBatchSize);
|
|
173
|
+
const classPromises = classBatch.map(async (ecclass) => {
|
|
174
|
+
const properties = await ecclass.getProperties();
|
|
175
|
+
if (!properties)
|
|
176
|
+
return;
|
|
177
|
+
const classNameLower = ecclass.name.toLowerCase();
|
|
178
|
+
// Efficiently filter navigation properties
|
|
179
|
+
const navProps = Array.from(properties).filter((prop) => prop.isNavigation());
|
|
180
|
+
if (navProps.length === 0)
|
|
181
|
+
return;
|
|
182
|
+
const navPropPromises = navProps.map(async (prop) => {
|
|
183
|
+
const relClass = await prop.relationshipClass;
|
|
184
|
+
// Use cached relation info
|
|
185
|
+
let relInfo = this._relationshipInfoCache.get(relClass.fullName);
|
|
186
|
+
if (relInfo === undefined &&
|
|
187
|
+
!this._relationshipInfoCache.has(relClass.fullName)) {
|
|
188
|
+
relInfo = await this.relInfoFromRelClass(relClass);
|
|
189
|
+
this._relationshipInfoCache.set(relClass.fullName, relInfo);
|
|
190
|
+
}
|
|
191
|
+
if (relInfo === undefined)
|
|
192
|
+
return;
|
|
193
|
+
const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward
|
|
194
|
+
? // eslint-disable-next-line @itwin/no-internal
|
|
195
|
+
relInfo.target
|
|
196
|
+
: // eslint-disable-next-line @itwin/no-internal
|
|
197
|
+
relInfo.source;
|
|
198
|
+
this._propQualifierToRefType.set([schemaNameLower, classNameLower, prop.name.toLowerCase()], navPropRefType);
|
|
199
|
+
});
|
|
200
|
+
await Promise.all(navPropPromises);
|
|
201
|
+
});
|
|
202
|
+
await Promise.all(classPromises);
|
|
144
203
|
}
|
|
145
204
|
this._initedSchemas.set(schema.name, schema.schemaKey);
|
|
146
205
|
}
|
|
@@ -199,6 +258,10 @@ class ECReferenceTypesCache {
|
|
|
199
258
|
clear() {
|
|
200
259
|
this._initedSchemas.clear();
|
|
201
260
|
this._propQualifierToRefType.clear();
|
|
261
|
+
this._relClassNameEndToRefTypes.clear();
|
|
262
|
+
this._rootBisClassCache.clear();
|
|
263
|
+
this._relationshipInfoCache.clear();
|
|
264
|
+
this._constraintClassCache.clear();
|
|
202
265
|
}
|
|
203
266
|
}
|
|
204
267
|
exports.ECReferenceTypesCache = ECReferenceTypesCache;
|