@itwin/imodel-transformer 2.0.0-dev.20 → 2.0.0-dev.22
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/lib/cjs/BranchProvenanceInitializer.d.ts.map +1 -1
- package/lib/cjs/BranchProvenanceInitializer.js +13 -10
- package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
- package/lib/cjs/ECReferenceTypesCache.d.ts +0 -3
- package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -1
- package/lib/cjs/ECReferenceTypesCache.js +38 -86
- package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
- package/lib/cjs/ElementCascadingDeleter.d.ts +3 -3
- package/lib/cjs/ElementCascadingDeleter.d.ts.map +1 -1
- package/lib/cjs/ElementCascadingDeleter.js +3 -4
- package/lib/cjs/ElementCascadingDeleter.js.map +1 -1
- package/lib/cjs/EntityUnifier.d.ts +3 -7
- package/lib/cjs/EntityUnifier.d.ts.map +1 -1
- package/lib/cjs/EntityUnifier.js +0 -16
- package/lib/cjs/EntityUnifier.js.map +1 -1
- package/lib/cjs/IModelImporter.d.ts +11 -3
- package/lib/cjs/IModelImporter.d.ts.map +1 -1
- package/lib/cjs/IModelImporter.js +28 -31
- package/lib/cjs/IModelImporter.js.map +1 -1
- package/lib/cjs/IModelTransformer.d.ts +33 -9
- package/lib/cjs/IModelTransformer.d.ts.map +1 -1
- package/lib/cjs/IModelTransformer.js +41 -26
- package/lib/cjs/IModelTransformer.js.map +1 -1
- package/lib/cjs/ProvenanceManager.d.ts +9 -3
- package/lib/cjs/ProvenanceManager.d.ts.map +1 -1
- package/lib/cjs/ProvenanceManager.js +23 -8
- package/lib/cjs/ProvenanceManager.js.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BranchProvenanceInitializer.d.ts","sourceRoot":"","sources":["../../src/BranchProvenanceInitializer.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"BranchProvenanceInitializer.d.ts","sourceRoot":"","sources":["../../src/BranchProvenanceInitializer.ts"],"names":[],"mappings":"AAIA,OAAO,EAKL,QAAQ,EAGT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAY,UAAU,EAAoB,MAAM,qBAAqB,CAAC;AAS7E;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,MAAM,EAAE,QAAQ,CAAC;IACjB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,MAAM,EAAE,QAAQ,CAAC;IACjB;;;;;;;OAOG;IACH,uBAAuB,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,kBAAkB,CAAC;CAC7D;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,oBAAoB,EAAE,UAAU,CAAC;IACjC,sBAAsB,EAAE,UAAU,CAAC;IACnC,sBAAsB,EAAE,UAAU,CAAC;CACpC;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,oBAAoB,CAAC,CA2J/B"}
|
|
@@ -15,6 +15,8 @@ const url_1 = require("url");
|
|
|
15
15
|
* @alpha
|
|
16
16
|
*/
|
|
17
17
|
async function initializeBranchProvenance(args) {
|
|
18
|
+
let editTxn = new core_backend_1.EditTxn(args.branch, "initializeBranchProvenance");
|
|
19
|
+
editTxn.start();
|
|
18
20
|
if (args.createFedGuidsForMaster) {
|
|
19
21
|
// FIXME<LOW>: Consider enforcing that the master and branch dbs passed as part of ProvenanceInitArgs to this function
|
|
20
22
|
// are identical. https://github.com/iTwin/imodel-transformer/issues/138
|
|
@@ -41,8 +43,8 @@ async function initializeBranchProvenance(args) {
|
|
|
41
43
|
// eslint-disable-next-line @itwin/no-internal
|
|
42
44
|
(s) => assert(s.step() === core_bentley_1.DbResult.BE_SQLITE_DONE, args.branch.getLastError()));
|
|
43
45
|
args.branch.clearCaches(); // statements write lock attached db (clearing statement cache does not fix this)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
editTxn.saveChanges();
|
|
47
|
+
editTxn.end();
|
|
46
48
|
args.branch.withSqliteStatement("DETACH DATABASE master", (s) => {
|
|
47
49
|
const res = s.step();
|
|
48
50
|
if (res !== core_bentley_1.DbResult.BE_SQLITE_DONE)
|
|
@@ -59,10 +61,12 @@ async function initializeBranchProvenance(args) {
|
|
|
59
61
|
reopenMaster(),
|
|
60
62
|
reopenBranch(),
|
|
61
63
|
]);
|
|
64
|
+
// Recreate editTxn on the reopened branch db
|
|
65
|
+
editTxn = new core_backend_1.EditTxn(args.branch, "initializeBranchProvenance");
|
|
66
|
+
editTxn.start();
|
|
62
67
|
}
|
|
63
68
|
// create an external source and owning repository link to use as our *Target Scope Element* for future synchronizations
|
|
64
|
-
|
|
65
|
-
const masterRepoLinkId = args.branch.elements.insertElement({
|
|
69
|
+
const masterRepoLinkId = editTxn.insertElement({
|
|
66
70
|
classFullName: core_backend_1.RepositoryLink.classFullName,
|
|
67
71
|
code: core_backend_1.RepositoryLink.createCode(args.branch, core_backend_1.IModelDb.repositoryModelId, "example-code-value"),
|
|
68
72
|
model: core_backend_1.IModelDb.repositoryModelId,
|
|
@@ -71,8 +75,7 @@ async function initializeBranchProvenance(args) {
|
|
|
71
75
|
repositoryGuid: args.master.iModelId,
|
|
72
76
|
description: args.masterDescription,
|
|
73
77
|
});
|
|
74
|
-
|
|
75
|
-
const masterExternalSourceId = args.branch.elements.insertElement({
|
|
78
|
+
const masterExternalSourceId = editTxn.insertElement({
|
|
76
79
|
classFullName: core_backend_1.ExternalSource.classFullName,
|
|
77
80
|
model: core_backend_1.IModelDb.rootSubjectId,
|
|
78
81
|
code: core_common_1.Code.createEmpty(),
|
|
@@ -97,8 +100,7 @@ async function initializeBranchProvenance(args) {
|
|
|
97
100
|
sourceDb: args.master,
|
|
98
101
|
targetDb: args.branch,
|
|
99
102
|
});
|
|
100
|
-
|
|
101
|
-
args.branch.elements.insertAspect(aspectProps);
|
|
103
|
+
editTxn.insertAspect(aspectProps);
|
|
102
104
|
}
|
|
103
105
|
const fedGuidlessRelsSql = `
|
|
104
106
|
SELECT erte.ECInstanceId as id
|
|
@@ -119,9 +121,10 @@ async function initializeBranchProvenance(args) {
|
|
|
119
121
|
targetDb: args.branch,
|
|
120
122
|
forceOldRelationshipProvenanceMethod: false,
|
|
121
123
|
});
|
|
122
|
-
|
|
123
|
-
args.branch.elements.insertAspect(aspectProps);
|
|
124
|
+
editTxn.insertAspect(aspectProps);
|
|
124
125
|
}
|
|
126
|
+
editTxn.saveChanges();
|
|
127
|
+
editTxn.end();
|
|
125
128
|
if (args.createFedGuidsForMaster === true) {
|
|
126
129
|
args.master.close();
|
|
127
130
|
args.branch.close();
|
|
@@ -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 { 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
|
+
{"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 EditTxn,\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 let editTxn = new EditTxn(args.branch, \"initializeBranchProvenance\");\n editTxn.start();\n\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 editTxn.saveChanges();\n editTxn.end();\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 // Recreate editTxn on the reopened branch db\n editTxn = new EditTxn(args.branch, \"initializeBranchProvenance\");\n editTxn.start();\n }\n\n // create an external source and owning repository link to use as our *Target Scope Element* for future synchronizations\n const masterRepoLinkId = editTxn.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 = editTxn.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 editTxn.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 editTxn.insertAspect(aspectProps);\n }\n\n editTxn.saveChanges();\n editTxn.end();\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,9 +22,6 @@ 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;
|
|
28
25
|
private static bisRootClassToRefType;
|
|
29
26
|
private getRootBisClass;
|
|
30
27
|
private getAbstractConstraintClass;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ECReferenceTypesCache.d.ts","sourceRoot":"","sources":["../../src/ECReferenceTypesCache.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
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;AAYtE,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;IAEtD,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAalC;YAEY,eAAe;YA2Bf,0BAA0B;IAaxC,8CAA8C;IACjC,sBAAsB,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;YA2BtD,kBAAkB;YAalB,UAAU;YAoEV,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;CAKb"}
|
|
@@ -35,10 +35,6 @@ class ECReferenceTypesCache {
|
|
|
35
35
|
_propQualifierToRefType = new core_bentley_1.TupleKeyedMap();
|
|
36
36
|
_relClassNameEndToRefTypes = new core_bentley_1.TupleKeyedMap();
|
|
37
37
|
_initedSchemas = new Map();
|
|
38
|
-
// Performance optimization caches
|
|
39
|
-
_rootBisClassCache = new Map();
|
|
40
|
-
_relationshipInfoCache = new Map();
|
|
41
|
-
_constraintClassCache = new Map();
|
|
42
38
|
static bisRootClassToRefType = {
|
|
43
39
|
/* eslint-disable quote-props, @typescript-eslint/naming-convention */
|
|
44
40
|
Element: core_common_1.ConcreteEntityTypes.Element,
|
|
@@ -51,11 +47,6 @@ class ECReferenceTypesCache {
|
|
|
51
47
|
/* eslint-enable quote-props, @typescript-eslint/naming-convention */
|
|
52
48
|
};
|
|
53
49
|
async getRootBisClass(ecclass) {
|
|
54
|
-
const cacheKey = ecclass.fullName;
|
|
55
|
-
const cached = this._rootBisClassCache.get(cacheKey);
|
|
56
|
-
if (cached) {
|
|
57
|
-
return cached;
|
|
58
|
-
}
|
|
59
50
|
let bisRootForConstraint = ecclass;
|
|
60
51
|
await ecclass.traverseBaseClasses((baseClass) => {
|
|
61
52
|
// The depth first traversal will descend all the way to the root class before making any lateral traversal
|
|
@@ -74,26 +65,17 @@ class ECReferenceTypesCache {
|
|
|
74
65
|
assert(bisRootForConstraint.appliesTo !== undefined, "The referenced AppliesToEntityClass could not be found, how did it pass schema validation?");
|
|
75
66
|
bisRootForConstraint = await this.getRootBisClass(await bisRootForConstraint.appliesTo);
|
|
76
67
|
}
|
|
77
|
-
this._rootBisClassCache.set(cacheKey, bisRootForConstraint);
|
|
78
68
|
return bisRootForConstraint;
|
|
79
69
|
}
|
|
80
70
|
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
|
-
}
|
|
86
71
|
// constraint classes must share a base so we can get the root from any of them, just use the first
|
|
87
72
|
const ecclass = await (constraint.constraintClasses?.[0] ||
|
|
88
73
|
constraint.abstractConstraint);
|
|
89
74
|
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);
|
|
91
75
|
return ecclass;
|
|
92
76
|
}
|
|
93
77
|
/** initialize from an imodel with metadata */
|
|
94
78
|
async initAllSchemasInIModel(imodel) {
|
|
95
|
-
let schemaCount = 0;
|
|
96
|
-
const initStartTime = performance.now();
|
|
97
79
|
const query = `
|
|
98
80
|
WITH RECURSIVE refs(SchemaId) AS (
|
|
99
81
|
SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'
|
|
@@ -105,27 +87,18 @@ class ECReferenceTypesCache {
|
|
|
105
87
|
SELECT s.Name as name
|
|
106
88
|
FROM refs
|
|
107
89
|
JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId
|
|
108
|
-
-- ensure schema dependency order
|
|
109
|
-
ORDER BY s.ECInstanceId
|
|
110
90
|
`;
|
|
111
91
|
for await (const row of imodel.createQueryReader(query, undefined, {
|
|
112
92
|
usePrimaryConn: true,
|
|
113
93
|
})) {
|
|
114
94
|
const schemaName = row.name;
|
|
115
|
-
const startTime = performance.now();
|
|
116
|
-
core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Loading schema: ${schemaName}`);
|
|
117
95
|
const schemaItemKey = new ecschema_metadata_1.SchemaKey(schemaName);
|
|
118
96
|
const schema = await imodel.schemaContext.getSchema(schemaItemKey);
|
|
119
97
|
if (!schema) {
|
|
120
98
|
throw new Error(`Failed to load schema: ${schemaName}`);
|
|
121
99
|
}
|
|
122
100
|
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
101
|
}
|
|
127
|
-
const initEndTime = performance.now();
|
|
128
|
-
core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `Completed ${schemaCount} schemas in ${(initEndTime - initStartTime).toFixed(2)}ms`);
|
|
129
102
|
}
|
|
130
103
|
async considerInitSchema(schema) {
|
|
131
104
|
if (this._initedSchemas.has(schema.name)) {
|
|
@@ -139,69 +112,51 @@ class ECReferenceTypesCache {
|
|
|
139
112
|
return this.initSchema(schema);
|
|
140
113
|
}
|
|
141
114
|
async initSchema(schema) {
|
|
142
|
-
core_bentley_1.Logger.
|
|
115
|
+
core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `initSchema started for ${schema.name}`);
|
|
143
116
|
const schemaNameLower = schema.name.toLowerCase();
|
|
144
|
-
//
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (!ecschema_metadata_1.ECClass.isECClass(item))
|
|
152
|
-
continue;
|
|
153
|
-
ecClasses.push(item);
|
|
154
|
-
if (item instanceof ecschema_metadata_1.RelationshipClass) {
|
|
155
|
-
relationshipClasses.push(item);
|
|
117
|
+
// Local dedup map — scoped to this single initSchema call, not persisted
|
|
118
|
+
const localRelInfoMap = new Map();
|
|
119
|
+
const getRelInfo = async (relClass) => {
|
|
120
|
+
let promise = localRelInfoMap.get(relClass.fullName);
|
|
121
|
+
if (!promise) {
|
|
122
|
+
promise = this.relInfoFromRelClass(relClass);
|
|
123
|
+
localRelInfoMap.set(relClass.fullName, promise);
|
|
156
124
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
125
|
+
return promise;
|
|
126
|
+
};
|
|
127
|
+
// Process all classes concurrently
|
|
128
|
+
const classPromises = Array.from(schema.getItems())
|
|
129
|
+
.filter((item) => ecschema_metadata_1.ECClass.isECClass(item))
|
|
130
|
+
.map(async (ecclass) => {
|
|
131
|
+
// Handle relationship end types
|
|
132
|
+
if (ecclass instanceof ecschema_metadata_1.RelationshipClass) {
|
|
133
|
+
const relInfo = await getRelInfo(ecclass);
|
|
134
|
+
if (relInfo) {
|
|
135
|
+
this._relClassNameEndToRefTypes.set([schemaNameLower, ecclass.name.toLowerCase()], relInfo);
|
|
136
|
+
}
|
|
164
137
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const classBatch = ecClasses.slice(i, i + propertyBatchSize);
|
|
173
|
-
const classPromises = classBatch.map(async (ecclass) => {
|
|
174
|
-
const properties = await ecclass.getProperties();
|
|
175
|
-
if (!properties)
|
|
138
|
+
// Handle nav props
|
|
139
|
+
const properties = await ecclass.getProperties();
|
|
140
|
+
const classNameLower = ecclass.name.toLowerCase();
|
|
141
|
+
const navPropPromises = Array.from(properties)
|
|
142
|
+
.filter((prop) => prop.isNavigation())
|
|
143
|
+
.map(async (prop) => {
|
|
144
|
+
if (!prop.isNavigation())
|
|
176
145
|
return;
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (navProps.length === 0)
|
|
146
|
+
const relClass = await prop.relationshipClass;
|
|
147
|
+
const relInfo = await getRelInfo(relClass);
|
|
148
|
+
if (relInfo === undefined)
|
|
181
149
|
return;
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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);
|
|
150
|
+
const navPropRefType = prop.direction === ecschema_metadata_1.StrengthDirection.Forward
|
|
151
|
+
? relInfo.target
|
|
152
|
+
: relInfo.source;
|
|
153
|
+
this._propQualifierToRefType.set([schemaNameLower, classNameLower, prop.name.toLowerCase()], navPropRefType);
|
|
201
154
|
});
|
|
202
|
-
await Promise.all(
|
|
203
|
-
}
|
|
155
|
+
await Promise.all(navPropPromises);
|
|
156
|
+
});
|
|
157
|
+
await Promise.all(classPromises);
|
|
204
158
|
this._initedSchemas.set(schema.name, schema.schemaKey);
|
|
159
|
+
core_bentley_1.Logger.logTrace(TransformerLoggerCategory_1.TransformerLoggerCategory.ECReferenceTypesCache, `initSchema completed for ${schema.name}`);
|
|
205
160
|
}
|
|
206
161
|
async relInfoFromRelClass(ecclass) {
|
|
207
162
|
assert(ecclass.source.constraintClasses !== undefined);
|
|
@@ -259,9 +214,6 @@ class ECReferenceTypesCache {
|
|
|
259
214
|
this._initedSchemas.clear();
|
|
260
215
|
this._propQualifierToRefType.clear();
|
|
261
216
|
this._relClassNameEndToRefTypes.clear();
|
|
262
|
-
this._rootBisClassCache.clear();
|
|
263
|
-
this._relationshipInfoCache.clear();
|
|
264
|
-
this._constraintClassCache.clear();
|
|
265
217
|
}
|
|
266
218
|
}
|
|
267
219
|
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 { Logger, TupleKeyedMap } from \"@itwin/core-bentley\";\nimport { ConcreteEntityTypes, RelTypeInfo } from \"@itwin/core-common\";\nimport {\n ECClass,\n Mixin,\n RelationshipClass,\n RelationshipConstraint,\n Schema,\n SchemaKey,\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.relationshipClass.fullName}:${constraint.isSource ? \"Source\" : \"Target\"}`;\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 schemaCount = 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\n SELECT sr.SourceECInstanceId\n FROM ECDbMeta.SchemaHasSchemaReferences sr\n JOIN refs ON sr.TargetECInstanceId = refs.SchemaId\n )\n SELECT 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, undefined, {\n usePrimaryConn: true,\n })) {\n const schemaName = row.name;\n const startTime = performance.now();\n Logger.logTrace(\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 throw new Error(`Failed to load schema: ${schemaName}`);\n }\n await this.considerInitSchema(schema);\n const endTime = performance.now();\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Completed schema: ${schemaName} in ${(endTime - startTime).toFixed(2)}ms`\n );\n schemaCount++;\n }\n\n const initEndTime = performance.now();\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Completed ${schemaCount} schemas 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 Logger.logInfo(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `Init Schema: ${schema.name}`\n );\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"]}
|
|
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 { Logger, TupleKeyedMap } from \"@itwin/core-bentley\";\nimport { ConcreteEntityTypes, RelTypeInfo } from \"@itwin/core-common\";\nimport {\n ECClass,\n Mixin,\n Property,\n RelationshipClass,\n RelationshipConstraint,\n Schema,\n SchemaKey,\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 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 query = `\n WITH RECURSIVE refs(SchemaId) AS (\n SELECT ECInstanceId FROM ECDbMeta.ECSchemaDef WHERE Name='BisCore'\n UNION\n SELECT sr.SourceECInstanceId\n FROM ECDbMeta.SchemaHasSchemaReferences sr\n JOIN refs ON sr.TargetECInstanceId = refs.SchemaId\n )\n SELECT s.Name as name\n FROM refs\n JOIN ECDbMeta.ECSchemaDef s ON refs.SchemaId=s.ECInstanceId\n `;\n\n for await (const row of imodel.createQueryReader(query, undefined, {\n usePrimaryConn: true,\n })) {\n const schemaName = row.name;\n const schemaItemKey = new SchemaKey(schemaName);\n const schema = await imodel.schemaContext.getSchema(schemaItemKey);\n if (!schema) {\n throw new Error(`Failed to load schema: ${schemaName}`);\n }\n await this.considerInitSchema(schema);\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 Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `initSchema started for ${schema.name}`\n );\n const schemaNameLower = schema.name.toLowerCase();\n\n // Local dedup map — scoped to this single initSchema call, not persisted\n const localRelInfoMap = new Map<string, Promise<RelTypeInfo | undefined>>();\n\n const getRelInfo = async (relClass: RelationshipClass) => {\n let promise = localRelInfoMap.get(relClass.fullName);\n if (!promise) {\n promise = this.relInfoFromRelClass(relClass);\n localRelInfoMap.set(relClass.fullName, promise);\n }\n return promise;\n };\n\n // Process all classes concurrently\n const classPromises = Array.from(schema.getItems())\n .filter((item): item is ECClass => ECClass.isECClass(item))\n .map(async (ecclass) => {\n // Handle relationship end types\n if (ecclass instanceof RelationshipClass) {\n const relInfo = await getRelInfo(ecclass);\n if (relInfo) {\n this._relClassNameEndToRefTypes.set(\n [schemaNameLower, ecclass.name.toLowerCase()],\n relInfo\n );\n }\n }\n\n // Handle nav props\n const properties = await ecclass.getProperties();\n const classNameLower = ecclass.name.toLowerCase();\n\n const navPropPromises = Array.from(properties)\n .filter((prop: Property) => prop.isNavigation())\n .map(async (prop: Property) => {\n if (!prop.isNavigation()) return;\n const relClass = await prop.relationshipClass;\n const relInfo = await getRelInfo(relClass);\n if (relInfo === undefined) return;\n\n const navPropRefType =\n prop.direction === StrengthDirection.Forward\n ? relInfo.target\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 this._initedSchemas.set(schema.name, schema.schemaKey);\n Logger.logTrace(\n TransformerLoggerCategory.ECReferenceTypesCache,\n `initSchema completed for ${schema.name}`\n );\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 }\n}\n"]}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/** @packageDocumentation
|
|
2
2
|
* @module iModels
|
|
3
3
|
*/
|
|
4
|
-
import { ElementTreeDeleter, ElementTreeWalkerScope
|
|
4
|
+
import { EditTxn, ElementTreeDeleter, ElementTreeWalkerScope } from "@itwin/core-backend";
|
|
5
5
|
import { Id64String } from "@itwin/core-bentley";
|
|
6
6
|
/** Deletes an element tree and code scope references starting with the specified top element. The top element is also deleted. Uses ElementCascadeDeleter.
|
|
7
|
-
* @param
|
|
7
|
+
* @param editTxn The active EditTxn for the iModel
|
|
8
8
|
* @param topElement The parent of the sub-tree
|
|
9
9
|
*/
|
|
10
|
-
export declare function deleteElementTreeCascade(
|
|
10
|
+
export declare function deleteElementTreeCascade(editTxn: EditTxn, topElement: Id64String): void;
|
|
11
11
|
/** Deletes an entire element tree, including sub-models, child elements and code scope references.
|
|
12
12
|
* Items are deleted in bottom-up order. Definitions and Subjects are deleted after normal elements.
|
|
13
13
|
* Call deleteNormalElements on each tree. Then call deleteSpecialElements.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElementCascadingDeleter.d.ts","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,OAAO,EACL,kBAAkB,EAClB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"ElementCascadingDeleter.d.ts","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,OAAO,EACL,OAAO,EACP,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,GACrB,IAAI,CAIN;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,kBAAkB;IAC7D,SAAS,CAAC,qBAAqB,CAC7B,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,sBAAsB;IAKhC,qCAAqC;cAClB,kBAAkB,CACnC,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,sBAAsB,GAC5B,IAAI;IAMP,oCAAoC;IACpC,OAAO,CAAC,kBAAkB;CAyB3B"}
|
|
@@ -12,12 +12,11 @@ exports.deleteElementTreeCascade = deleteElementTreeCascade;
|
|
|
12
12
|
const core_backend_1 = require("@itwin/core-backend");
|
|
13
13
|
const core_common_1 = require("@itwin/core-common");
|
|
14
14
|
/** Deletes an element tree and code scope references starting with the specified top element. The top element is also deleted. Uses ElementCascadeDeleter.
|
|
15
|
-
* @param
|
|
15
|
+
* @param editTxn The active EditTxn for the iModel
|
|
16
16
|
* @param topElement The parent of the sub-tree
|
|
17
17
|
*/
|
|
18
|
-
function deleteElementTreeCascade(
|
|
19
|
-
|
|
20
|
-
const del = new ElementCascadingDeleter(iModel);
|
|
18
|
+
function deleteElementTreeCascade(editTxn, topElement) {
|
|
19
|
+
const del = new ElementCascadingDeleter(editTxn);
|
|
21
20
|
del.deleteNormalElements(topElement);
|
|
22
21
|
del.deleteSpecialElements();
|
|
23
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElementCascadingDeleter.js","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":";;;AAmBA,
|
|
1
|
+
{"version":3,"file":"ElementCascadingDeleter.js","sourceRoot":"","sources":["../../src/ElementCascadingDeleter.ts"],"names":[],"mappings":";;;AAmBA,4DAOC;AA1BD;;;gGAGgG;AAChG;;GAEG;AACH,sDAI6B;AAE7B,oDAAiD;AAEjD;;;GAGG;AACH,SAAgB,wBAAwB,CACtC,OAAgB,EAChB,UAAsB;IAEtB,MAAM,GAAG,GAAG,IAAI,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjD,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,MAAM,KAAK,GAAG;;;;;KAKb,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,yBAAW,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAE5D,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAC7B,KAAK,EACL,CAAC,MAAM,EAAE,EAAE;YACT,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;gBACzB,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,CAAe,CAAC;gBACvC,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC,EACD,MAAM,CACP,CAAC;IACJ,CAAC;CACF;AA5CD,0DA4CC","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 EditTxn,\n ElementTreeDeleter,\n ElementTreeWalkerScope,\n} from \"@itwin/core-backend\";\nimport { Id64String } from \"@itwin/core-bentley\";\nimport { QueryBinder } from \"@itwin/core-common\";\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 editTxn The active EditTxn for the iModel\n * @param topElement The parent of the sub-tree\n */\nexport function deleteElementTreeCascade(\n editTxn: EditTxn,\n topElement: Id64String\n): void {\n const del = new ElementCascadingDeleter(editTxn);\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 const query = `\n SELECT ECInstanceId\n FROM bis.Element\n WHERE CodeScope.id=:scopeId\n AND Parent.id IS NULL\n `;\n\n const params = new QueryBinder().bindId(\"scopeId\", element);\n\n this.txn.iModel.withQueryReader(\n query,\n (reader) => {\n for (const row of reader) {\n const elementId = row[0] as Id64String;\n this.processElementTree(elementId, newScope);\n }\n },\n params\n );\n }\n}\n"]}
|
|
@@ -4,18 +4,14 @@
|
|
|
4
4
|
* for entity-generic operations in the transformer
|
|
5
5
|
*/
|
|
6
6
|
import { EntityReference } from "@itwin/core-common";
|
|
7
|
-
import { ConcreteEntity,
|
|
7
|
+
import { ConcreteEntity, IModelDb } from "@itwin/core-backend";
|
|
8
8
|
/** @internal */
|
|
9
9
|
export declare namespace EntityUnifier {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/** needs to return a widened type otherwise typescript complains when result is used with a narrow type */
|
|
13
|
-
export function updaterFor(db: IModelDb, entity: ConcreteEntity): EntityUpdater;
|
|
14
|
-
export function exists(db: IModelDb, arg: {
|
|
10
|
+
function getReadableType(entity: ConcreteEntity): "element" | "element aspect" | "relationship" | "unknown entity type";
|
|
11
|
+
function exists(db: IModelDb, arg: {
|
|
15
12
|
entity: ConcreteEntity;
|
|
16
13
|
} | {
|
|
17
14
|
entityReference: EntityReference;
|
|
18
15
|
}): Promise<boolean>;
|
|
19
|
-
export {};
|
|
20
16
|
}
|
|
21
17
|
//# sourceMappingURL=EntityUnifier.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityUnifier.d.ts","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":"AAIA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"EntityUnifier.d.ts","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,EAEL,eAAe,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EAKd,QAAQ,EAET,MAAM,qBAAqB,CAAC;AAG7B,gBAAgB;AAChB,yBAAiB,aAAa,CAAC;IAC7B,SAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,yEAKrD;IAED,SAAsB,MAAM,CAC1B,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE;QAAE,MAAM,EAAE,cAAc,CAAA;KAAE,GAAG;QAAE,eAAe,EAAE,eAAe,CAAA;KAAE,oBAoBvE;CACF"}
|
package/lib/cjs/EntityUnifier.js
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.EntityUnifier = void 0;
|
|
13
|
-
const assert = require("assert");
|
|
14
13
|
const core_common_1 = require("@itwin/core-common");
|
|
15
14
|
const core_backend_1 = require("@itwin/core-backend");
|
|
16
15
|
const core_bentley_1 = require("@itwin/core-bentley");
|
|
@@ -28,21 +27,6 @@ var EntityUnifier;
|
|
|
28
27
|
return "unknown entity type";
|
|
29
28
|
}
|
|
30
29
|
EntityUnifier.getReadableType = getReadableType;
|
|
31
|
-
/** needs to return a widened type otherwise typescript complains when result is used with a narrow type */
|
|
32
|
-
function updaterFor(db, entity) {
|
|
33
|
-
if (entity instanceof core_backend_1.Element)
|
|
34
|
-
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
35
|
-
return db.elements.updateElement.bind(db.elements);
|
|
36
|
-
else if (entity instanceof core_backend_1.Relationship)
|
|
37
|
-
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
38
|
-
return db.relationships.updateInstance.bind(db.relationships);
|
|
39
|
-
else if (entity instanceof core_backend_1.ElementAspect)
|
|
40
|
-
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
41
|
-
return db.elements.updateAspect.bind(db.elements);
|
|
42
|
-
else
|
|
43
|
-
assert(false, `unreachable; entity was '${entity.constructor.name}' not an Element, Relationship, or ElementAspect`);
|
|
44
|
-
}
|
|
45
|
-
EntityUnifier.updaterFor = updaterFor;
|
|
46
30
|
async function exists(db, arg) {
|
|
47
31
|
const [type, id] = "entityReference" in arg
|
|
48
32
|
? core_backend_1.EntityReferences.split(arg.entityReference)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityUnifier.js","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;AAChG;;;;GAIG;;;AAEH,
|
|
1
|
+
{"version":3,"file":"EntityUnifier.js","sourceRoot":"","sources":["../../src/EntityUnifier.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;AAChG;;;;GAIG;;;AAEH,oDAI4B;AAC5B,sDAQ6B;AAC7B,sDAA2C;AAE3C,gBAAgB;AAChB,IAAiB,aAAa,CA+B7B;AA/BD,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;IAEM,KAAK,UAAU,MAAM,CAC1B,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,MAAM,KAAK,GAAG,iBAAiB,aAAa,yBAAyB,CAAC;QACtE,MAAM,MAAM,GAAG,IAAI,yBAAW,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;YACjD,cAAc,EAAE,IAAI;SACrB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAtBqB,oBAAM,SAsB3B,CAAA;AACH,CAAC,EA/BgB,aAAa,6BAAb,aAAa,QA+B7B","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Utils\n * utilities that unify operations, especially CRUD operations, on entities\n * for entity-generic operations in the transformer\n */\n\nimport {\n ConcreteEntityTypes,\n EntityReference,\n QueryBinder,\n} from \"@itwin/core-common\";\nimport {\n ConcreteEntity,\n // eslint-disable-next-line @typescript-eslint/no-redeclare\n Element,\n ElementAspect,\n EntityReferences,\n IModelDb,\n Relationship,\n} from \"@itwin/core-backend\";\nimport { 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 export async 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 const query = `SELECT 1 FROM ${classFullName} WHERE ECInstanceId=:id`;\n const params = new QueryBinder().bindId(\"id\", id);\n const reader = db.createQueryReader(query, params, {\n usePrimaryConn: true,\n });\n return reader.step();\n }\n}\n"]}
|