@itwin/imodel-transformer 0.3.18-fedguidopt.7 → 0.4.1-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -1
- package/lib/cjs/BranchProvenanceInitializer.d.ts +3 -10
- package/lib/cjs/BranchProvenanceInitializer.d.ts.map +1 -1
- package/lib/cjs/BranchProvenanceInitializer.js +13 -84
- package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
- package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts +16 -0
- package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +1 -0
- package/lib/cjs/DetachedExportElementAspectsStrategy.js +98 -0
- package/lib/cjs/DetachedExportElementAspectsStrategy.js.map +1 -0
- package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts +19 -0
- package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +1 -0
- package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js +43 -0
- package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js.map +1 -0
- package/lib/cjs/ExportElementAspectsStrategy.d.ts +35 -0
- package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +1 -0
- package/lib/cjs/ExportElementAspectsStrategy.js +48 -0
- package/lib/cjs/ExportElementAspectsStrategy.js.map +1 -0
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts +12 -0
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts.map +1 -0
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +43 -0
- package/lib/cjs/ExportElementAspectsWithElementsStrategy.js.map +1 -0
- package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
- package/lib/cjs/IModelCloneContext.js +2 -0
- package/lib/cjs/IModelCloneContext.js.map +1 -1
- package/lib/cjs/IModelExporter.d.ts +15 -40
- package/lib/cjs/IModelExporter.d.ts.map +1 -1
- package/lib/cjs/IModelExporter.js +52 -125
- package/lib/cjs/IModelExporter.js.map +1 -1
- package/lib/cjs/IModelTransformer.d.ts +29 -161
- package/lib/cjs/IModelTransformer.d.ts.map +1 -1
- package/lib/cjs/IModelTransformer.js +286 -934
- package/lib/cjs/IModelTransformer.js.map +1 -1
- package/package.json +14 -14
- package/lib/cjs/Algo.d.ts +0 -7
- package/lib/cjs/Algo.d.ts.map +0 -1
- package/lib/cjs/Algo.js +0 -50
- package/lib/cjs/Algo.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
# Change Log - @itwin/imodel-transformer
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Mon, 11 Sep 2023 12:37:44 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 0.4.0
|
|
8
|
+
|
|
9
|
+
Mon, 11 Sep 2023 12:37:44 GMT
|
|
10
|
+
|
|
11
|
+
### Minor changes
|
|
12
|
+
|
|
13
|
+
- Add detached ElementAspect exporting ([commit](https://github.com/iTwin/transformer/commit/4c404f3980ec7f4e6a3f3a0b746701e4c6f77d92))
|
|
14
|
+
|
|
15
|
+
## 0.3.2
|
|
16
|
+
|
|
17
|
+
Fri, 18 Aug 2023 23:12:28 GMT
|
|
18
|
+
|
|
19
|
+
### Patches
|
|
20
|
+
|
|
21
|
+
- Added a fix for "Missing id" and "ForeignKey constraint" errors while using onDeleteModel ([commit](https://github.com/iTwin/transformer/commit/8cda406d158b46f57acfc97d7f4be03a4143414f))
|
|
22
|
+
- bump dependencies to allow all itwin.js 4.x ([commit](https://github.com/iTwin/transformer/commit/8cda406d158b46f57acfc97d7f4be03a4143414f))
|
|
23
|
+
|
|
24
|
+
## 0.3.1
|
|
25
|
+
|
|
26
|
+
Thu, 27 Jul 2023 13:07:39 GMT
|
|
27
|
+
|
|
28
|
+
### Patches
|
|
29
|
+
|
|
30
|
+
- Changed shouldDetectDeletes from private to protected ([commit](https://github.com/iTwin/transformer/commit/88fd8d15b82bc45e962eedd6fe16323498aa732f))
|
|
31
|
+
|
|
7
32
|
## 0.3.0
|
|
8
33
|
|
|
9
34
|
Tue, 11 Jul 2023 18:59:25 GMT
|
|
@@ -19,22 +19,15 @@ export interface ProvenanceInitArgs {
|
|
|
19
19
|
* insert Federation Guids in all lacking elements in the master database, which will prevent
|
|
20
20
|
* needing to insert External Source Aspects for provenance tracking
|
|
21
21
|
* @note requires a read/write master
|
|
22
|
-
* @note closes both the master and branch iModels to reset caches, so you must reopen them.
|
|
23
|
-
* If you pass `"keep-reopened-db"`, this object's `master` and `branch` properties will
|
|
24
|
-
* be set to new, open databases.
|
|
25
22
|
*/
|
|
26
|
-
createFedGuidsForMaster?:
|
|
23
|
+
createFedGuidsForMaster?: boolean;
|
|
27
24
|
}
|
|
28
|
-
|
|
29
|
-
* @alpha
|
|
30
|
-
*/
|
|
31
|
-
export interface ProvenanceInitResult {
|
|
25
|
+
interface ProvenanceInitResult {
|
|
32
26
|
targetScopeElementId: Id64String;
|
|
33
|
-
masterExternalSourceId: Id64String;
|
|
34
|
-
masterRepositoryLinkId: Id64String;
|
|
35
27
|
}
|
|
36
28
|
/**
|
|
37
29
|
* @alpha
|
|
38
30
|
*/
|
|
39
31
|
export declare function initializeBranchProvenance(args: ProvenanceInitArgs): Promise<ProvenanceInitResult>;
|
|
32
|
+
export {};
|
|
40
33
|
//# sourceMappingURL=BranchProvenanceInitializer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BranchProvenanceInitializer.d.ts","sourceRoot":"","sources":["../../src/BranchProvenanceInitializer.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"BranchProvenanceInitializer.d.ts","sourceRoot":"","sources":["../../src/BranchProvenanceInitializer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgD,QAAQ,EAAkB,MAAM,qBAAqB,CAAC;AAC7G,OAAO,EAAY,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAK3D;;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;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,UAAU,oBAAoB;IAC5B,oBAAoB,EAAE,UAAU,CAAC;CAClC;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA6CxG"}
|
|
@@ -11,40 +11,13 @@ const IModelTransformer_1 = require("./IModelTransformer");
|
|
|
11
11
|
*/
|
|
12
12
|
async function initializeBranchProvenance(args) {
|
|
13
13
|
if (args.createFedGuidsForMaster) {
|
|
14
|
-
|
|
15
|
-
UPDATE bis_Element
|
|
16
|
-
|
|
17
|
-
WHERE FederationGuid IS NULL
|
|
18
|
-
AND Id NOT IN (0x1, 0xe, 0x10) -- ignore special elems
|
|
19
|
-
`, (s) => assert(s.step() === core_bentley_1.DbResult.BE_SQLITE_DONE));
|
|
20
|
-
const masterPath = args.master.pathName;
|
|
21
|
-
const reopenMaster = makeDbReopener(args.master);
|
|
22
|
-
args.master.close(); // prevent busy
|
|
23
|
-
args.branch.withSqliteStatement(`ATTACH DATABASE 'file://${masterPath}?mode=ro' AS master`, (s) => assert(s.step() === core_bentley_1.DbResult.BE_SQLITE_DONE));
|
|
24
|
-
args.branch.withSqliteStatement(`
|
|
25
|
-
UPDATE main.bis_Element
|
|
26
|
-
SET FederationGuid = (
|
|
27
|
-
SELECT m.FederationGuid
|
|
28
|
-
FROM master.bis_Element m
|
|
29
|
-
WHERE m.Id=main.bis_Element.Id
|
|
30
|
-
)`, (s) => assert(s.step() === core_bentley_1.DbResult.BE_SQLITE_DONE));
|
|
31
|
-
args.branch.clearCaches(); // statements write lock attached db (clearing statement cache does not fix this)
|
|
32
|
-
args.branch.saveChanges();
|
|
33
|
-
args.branch.withSqliteStatement(`DETACH DATABASE master`, (s) => {
|
|
34
|
-
const res = s.step();
|
|
35
|
-
if (res !== core_bentley_1.DbResult.BE_SQLITE_DONE)
|
|
36
|
-
core_bentley_1.Logger.logTrace("initializeBranchProvenance", `Error detaching db (we will close anyway): ${args.branch.nativeDb.getLastError()}`);
|
|
37
|
-
// this is the case until native side changes
|
|
38
|
-
assert(res === core_bentley_1.DbResult.BE_SQLITE_ERROR);
|
|
14
|
+
// FIXME: elements in the cache could be wrong after this so need to purge cache somehow, maybe close the iModel
|
|
15
|
+
args.master.withSqliteStatement("UPDATE bis_Element SET FederationGuid=randomblob(16) WHERE FederationGuid IS NULL", (s) => {
|
|
16
|
+
assert(s.step() === core_bentley_1.DbResult.BE_SQLITE_DONE);
|
|
39
17
|
});
|
|
40
|
-
args.branch.performCheckpoint();
|
|
41
|
-
const reopenBranch = makeDbReopener(args.branch);
|
|
42
|
-
// close dbs because element cache could be invalid
|
|
43
|
-
args.branch.close();
|
|
44
|
-
[args.master, args.branch] = await Promise.all([reopenMaster(), reopenBranch()]);
|
|
45
18
|
}
|
|
46
19
|
// create an external source and owning repository link to use as our *Target Scope Element* for future synchronizations
|
|
47
|
-
const
|
|
20
|
+
const masterLinkRepoId = args.branch.elements.insertElement({
|
|
48
21
|
classFullName: core_backend_1.RepositoryLink.classFullName,
|
|
49
22
|
code: core_backend_1.RepositoryLink.createCode(args.branch, core_backend_1.IModelDb.repositoryModelId, "example-code-value"),
|
|
50
23
|
model: core_backend_1.IModelDb.repositoryModelId,
|
|
@@ -52,75 +25,31 @@ async function initializeBranchProvenance(args) {
|
|
|
52
25
|
format: "iModel",
|
|
53
26
|
repositoryGuid: args.master.iModelId,
|
|
54
27
|
description: args.masterDescription,
|
|
55
|
-
}
|
|
56
|
-
const masterExternalSourceId =
|
|
28
|
+
});
|
|
29
|
+
const masterExternalSourceId = args.branch.elements.insertElement({
|
|
57
30
|
classFullName: core_backend_1.ExternalSource.classFullName,
|
|
58
31
|
model: core_backend_1.IModelDb.rootSubjectId,
|
|
59
32
|
code: core_common_1.Code.createEmpty(),
|
|
60
|
-
repository: new core_backend_1.ExternalSourceIsInRepository(
|
|
33
|
+
repository: new core_backend_1.ExternalSourceIsInRepository(masterLinkRepoId),
|
|
61
34
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
62
35
|
connectorName: require("../../package.json").name,
|
|
63
36
|
connectorVersion: require("../../package.json").version,
|
|
64
37
|
/* eslint-enable @typescript-eslint/no-var-requires */
|
|
65
|
-
}
|
|
66
|
-
const fedGuidLessElemsSql =
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
`;
|
|
72
|
-
const elemReader = args.branch.createQueryReader(fedGuidLessElemsSql, undefined, { usePrimaryConn: true });
|
|
73
|
-
while (await elemReader.step()) {
|
|
74
|
-
const id = elemReader.current.toRow().id;
|
|
75
|
-
const aspectProps = IModelTransformer_1.IModelTransformer.initElementProvenanceOptions(id, id, {
|
|
76
|
-
isReverseSynchronization: false,
|
|
77
|
-
targetScopeElementId: masterExternalSourceId,
|
|
78
|
-
sourceDb: args.master,
|
|
79
|
-
});
|
|
80
|
-
args.branch.elements.insertAspect(aspectProps);
|
|
81
|
-
}
|
|
82
|
-
const fedGuidLessRelsSql = `
|
|
83
|
-
SELECT erte.ECInstanceId as id
|
|
84
|
-
FROM Bis.ElementRefersToElements erte
|
|
85
|
-
JOIN bis.Element se
|
|
86
|
-
ON se.ECInstanceId=erte.SourceECInstanceId
|
|
87
|
-
JOIN bis.Element te
|
|
88
|
-
ON te.ECInstanceId=erte.TargetECInstanceId
|
|
89
|
-
WHERE se.FederationGuid IS NULL
|
|
90
|
-
OR te.FederationGuid IS NULL`;
|
|
91
|
-
const relReader = args.branch.createQueryReader(fedGuidLessRelsSql, undefined, { usePrimaryConn: true });
|
|
92
|
-
while (await relReader.step()) {
|
|
93
|
-
const id = relReader.current.toRow().id;
|
|
94
|
-
const aspectProps = IModelTransformer_1.IModelTransformer.initRelationshipProvenanceOptions(id, id, {
|
|
38
|
+
});
|
|
39
|
+
const fedGuidLessElemsSql = "SELECT ECInstanceId as id FROM Bis.Element WHERE FederationGuid IS NULL";
|
|
40
|
+
const reader = args.branch.createQueryReader(fedGuidLessElemsSql);
|
|
41
|
+
while (await reader.step()) {
|
|
42
|
+
const id = reader.current.toRow().id;
|
|
43
|
+
IModelTransformer_1.IModelTransformer.initElementProvenanceOptions(id, id, {
|
|
95
44
|
isReverseSynchronization: false,
|
|
96
45
|
targetScopeElementId: masterExternalSourceId,
|
|
97
46
|
sourceDb: args.master,
|
|
98
47
|
targetDb: args.branch,
|
|
99
|
-
forceOldRelationshipProvenanceMethod: false,
|
|
100
48
|
});
|
|
101
|
-
args.branch.elements.insertAspect(aspectProps);
|
|
102
|
-
}
|
|
103
|
-
if (args.createFedGuidsForMaster === true) {
|
|
104
|
-
args.master.close();
|
|
105
|
-
args.branch.close();
|
|
106
49
|
}
|
|
107
50
|
return {
|
|
108
51
|
targetScopeElementId: masterExternalSourceId,
|
|
109
|
-
masterExternalSourceId,
|
|
110
|
-
masterRepositoryLinkId: masterRepoLinkId,
|
|
111
52
|
};
|
|
112
53
|
}
|
|
113
54
|
exports.initializeBranchProvenance = initializeBranchProvenance;
|
|
114
|
-
function makeDbReopener(db) {
|
|
115
|
-
const originalMode = db.isReadonly ? core_bentley_1.OpenMode.Readonly : core_bentley_1.OpenMode.ReadWrite;
|
|
116
|
-
const dbPath = db.pathName;
|
|
117
|
-
let reopenDb;
|
|
118
|
-
if (db instanceof core_backend_1.BriefcaseDb)
|
|
119
|
-
reopenDb = async (mode = originalMode) => core_backend_1.BriefcaseDb.open({ fileName: dbPath, readonly: mode === core_bentley_1.OpenMode.Readonly });
|
|
120
|
-
else if (db instanceof core_backend_1.StandaloneDb)
|
|
121
|
-
reopenDb = (mode = originalMode) => core_backend_1.StandaloneDb.openFile(dbPath, mode);
|
|
122
|
-
else
|
|
123
|
-
assert(false, `db type '${db.constructor.name}' not supported`);
|
|
124
|
-
return reopenDb;
|
|
125
|
-
}
|
|
126
55
|
//# sourceMappingURL=BranchProvenanceInitializer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BranchProvenanceInitializer.js","sourceRoot":"","sources":["../../src/BranchProvenanceInitializer.ts"],"names":[],"mappings":"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","sourcesContent":["import { BriefcaseDb, ExternalSource, ExternalSourceIsInRepository, IModelDb, Relationship, RepositoryLink, SnapshotDb, StandaloneDb } from \"@itwin/core-backend\";\nimport { DbResult, Id64String, Logger, OpenMode } from \"@itwin/core-bentley\";\nimport { Code } from \"@itwin/core-common\";\nimport assert = require(\"assert\");\nimport { IModelTransformer } from \"./IModelTransformer\";\n\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(args: ProvenanceInitArgs): Promise<ProvenanceInitResult> {\n if (args.createFedGuidsForMaster) {\n args.master.withSqliteStatement(`\n UPDATE bis_Element\n SET FederationGuid=randomblob(16)\n WHERE FederationGuid IS NULL\n AND Id NOT IN (0x1, 0xe, 0x10) -- ignore special elems\n `,\n (s) => assert(s.step() === DbResult.BE_SQLITE_DONE),\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 'file://${masterPath}?mode=ro' AS master`,\n (s) => assert(s.step() === DbResult.BE_SQLITE_DONE),\n );\n args.branch.withSqliteStatement(`\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 (s) => assert(s.step() === DbResult.BE_SQLITE_DONE)\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(\n `DETACH DATABASE master`,\n (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.nativeDb.getLastError()}`\n );\n // this is the case until native side changes\n assert(res === DbResult.BE_SQLITE_ERROR);\n }\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([reopenMaster(), reopenBranch()]);\n }\n\n // create an external source and owning repository link to use as our *Target Scope Element* for future synchronizations\n const masterRepoLinkId = new RepositoryLink({\n classFullName: RepositoryLink.classFullName,\n code: RepositoryLink.createCode(args.branch, IModelDb.repositoryModelId, \"example-code-value\"),\n model: IModelDb.repositoryModelId,\n url: args.masterUrl,\n format: \"iModel\",\n repositoryGuid: args.master.iModelId,\n description: args.masterDescription,\n }, args.branch).insert();\n\n const masterExternalSourceId = new ExternalSource({\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 }, args.branch).insert();\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(fedGuidLessElemsSql, undefined, { usePrimaryConn: true });\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 });\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(fedGuidLessRelsSql, undefined, { usePrimaryConn: true });\n while (await relReader.step()) {\n const id: string = relReader.current.toRow().id;\n const aspectProps = IModelTransformer.initRelationshipProvenanceOptions(id, id, {\n isReverseSynchronization: false,\n targetScopeElementId: masterExternalSourceId,\n sourceDb: args.master,\n targetDb: args.branch,\n forceOldRelationshipProvenanceMethod: false,\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) => BriefcaseDb.open({ fileName: dbPath, readonly: mode === OpenMode.Readonly });\n else if (db instanceof StandaloneDb)\n reopenDb = (mode = originalMode) => StandaloneDb.openFile(dbPath, mode);\n else\n assert(false, `db type '${db.constructor.name}' not supported`);\n return reopenDb;\n}\n\n"]}
|
|
1
|
+
{"version":3,"file":"BranchProvenanceInitializer.js","sourceRoot":"","sources":["../../src/BranchProvenanceInitializer.ts"],"names":[],"mappings":";;;AAAA,sDAA6G;AAC7G,sDAA2D;AAC3D,oDAAoF;AACpF,iCAAkC;AAClC,2DAAwD;AA6BxD;;GAEG;AACI,KAAK,UAAU,0BAA0B,CAAC,IAAwB;IACvE,IAAI,IAAI,CAAC,uBAAuB,EAAE;QAChC,gHAAgH;QAChH,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,mFAAmF,EAAE,CAAC,CAAC,EAAE,EAAE;YACzH,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,uBAAQ,CAAC,cAAc,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;KACJ;IAED,wHAAwH;IACxH,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC1D,aAAa,EAAE,6BAAc,CAAC,aAAa;QAC3C,IAAI,EAAE,6BAAc,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,uBAAQ,CAAC,iBAAiB,EAAE,oBAAoB,CAAC;QAC9F,KAAK,EAAE,uBAAQ,CAAC,iBAAiB;QACjC,GAAG,EAAE,IAAI,CAAC,SAAS;QACnB,MAAM,EAAE,QAAQ;QAChB,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;QACpC,WAAW,EAAE,IAAI,CAAC,iBAAiB;KACb,CAAC,CAAC;IAE1B,MAAM,sBAAsB,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC;QAChE,aAAa,EAAE,6BAAc,CAAC,aAAa;QAC3C,KAAK,EAAE,uBAAQ,CAAC,aAAa;QAC7B,IAAI,EAAE,kBAAI,CAAC,WAAW,EAAE;QACxB,UAAU,EAAE,IAAI,2CAA4B,CAAC,gBAAgB,CAAC;QAC9D,uDAAuD;QACvD,aAAa,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC,IAAI;QACjD,gBAAgB,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC,OAAO;QACvD,sDAAsD;KAChC,CAAC,CAAC;IAE1B,MAAM,mBAAmB,GAAG,yEAAyE,CAAC;IACtG,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CAAC;IAClE,OAAO,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE;QAC1B,MAAM,EAAE,GAAW,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;QAC7C,qCAAiB,CAAC,4BAA4B,CAAC,EAAE,EAAE,EAAE,EAAE;YACrD,wBAAwB,EAAE,KAAK;YAC/B,oBAAoB,EAAE,sBAAsB;YAC5C,QAAQ,EAAE,IAAI,CAAC,MAAM;YACrB,QAAQ,EAAE,IAAI,CAAC,MAAM;SACtB,CAAC,CAAC;KACJ;IAED,OAAO;QACL,oBAAoB,EAAE,sBAAsB;KAC7C,CAAC;AACJ,CAAC;AA7CD,gEA6CC","sourcesContent":["import { ExternalSource, ExternalSourceIsInRepository, IModelDb, RepositoryLink } from \"@itwin/core-backend\";\nimport { DbResult, Id64String } from \"@itwin/core-bentley\";\nimport { Code, ExternalSourceProps, RepositoryLinkProps } from \"@itwin/core-common\";\nimport assert = require(\"assert\");\nimport { IModelTransformer } from \"./IModelTransformer\";\n\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 */\n createFedGuidsForMaster?: boolean;\n}\n\ninterface ProvenanceInitResult {\n targetScopeElementId: Id64String;\n}\n\n/**\n * @alpha\n */\nexport async function initializeBranchProvenance(args: ProvenanceInitArgs): Promise<ProvenanceInitResult> {\n if (args.createFedGuidsForMaster) {\n // FIXME: elements in the cache could be wrong after this so need to purge cache somehow, maybe close the iModel\n args.master.withSqliteStatement(\"UPDATE bis_Element SET FederationGuid=randomblob(16) WHERE FederationGuid IS NULL\", (s) => {\n assert(s.step() === DbResult.BE_SQLITE_DONE);\n });\n }\n\n // create an external source and owning repository link to use as our *Target Scope Element* for future synchronizations\n const masterLinkRepoId = args.branch.elements.insertElement({\n classFullName: RepositoryLink.classFullName,\n code: RepositoryLink.createCode(args.branch, IModelDb.repositoryModelId, \"example-code-value\"),\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(masterLinkRepoId),\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 = \"SELECT ECInstanceId as id FROM Bis.Element WHERE FederationGuid IS NULL\";\n const reader = args.branch.createQueryReader(fedGuidLessElemsSql);\n while (await reader.step()) {\n const id: string = reader.current.toRow().id;\n IModelTransformer.initElementProvenanceOptions(id, id, {\n isReverseSynchronization: false,\n targetScopeElementId: masterExternalSourceId,\n sourceDb: args.master,\n targetDb: args.branch,\n });\n }\n\n return {\n targetScopeElementId: masterExternalSourceId,\n };\n}\n\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ExportElementAspectsStrategy } from "./ExportElementAspectsStrategy";
|
|
2
|
+
/**
|
|
3
|
+
* Detached ElementAspect export strategy for [[IModelExporter]].
|
|
4
|
+
* This strategy exports all ElementAspects separately from the Elements that own them.
|
|
5
|
+
*
|
|
6
|
+
* @note Since aspects are exported separately from elements that own them, this strategy will export aspects of filtered out elements by default and
|
|
7
|
+
* this needs to be handled by ElementAspectHandler
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export declare class DetachedExportElementAspectsStrategy extends ExportElementAspectsStrategy {
|
|
11
|
+
exportAllElementAspects(): Promise<void>;
|
|
12
|
+
private exportAspectsLoop;
|
|
13
|
+
private queryAspects;
|
|
14
|
+
exportElementAspectsForElement(_elementId: string): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=DetachedExportElementAspectsStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DetachedExportElementAspectsStrategy.d.ts","sourceRoot":"","sources":["../../src/DetachedExportElementAspectsStrategy.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAI9E;;;;;;;GAOG;AACH,qBAAa,oCAAqC,SAAQ,4BAA4B;IAC9D,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;YAoChD,iBAAiB;YAUhB,YAAY;IAsCL,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGxF"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.DetachedExportElementAspectsStrategy = void 0;
|
|
8
|
+
const core_backend_1 = require("@itwin/core-backend");
|
|
9
|
+
const ExportElementAspectsStrategy_1 = require("./ExportElementAspectsStrategy");
|
|
10
|
+
const ECSqlReaderAsyncIterableIteratorAdapter_1 = require("./ECSqlReaderAsyncIterableIteratorAdapter");
|
|
11
|
+
const core_common_1 = require("@itwin/core-common");
|
|
12
|
+
/**
|
|
13
|
+
* Detached ElementAspect export strategy for [[IModelExporter]].
|
|
14
|
+
* This strategy exports all ElementAspects separately from the Elements that own them.
|
|
15
|
+
*
|
|
16
|
+
* @note Since aspects are exported separately from elements that own them, this strategy will export aspects of filtered out elements by default and
|
|
17
|
+
* this needs to be handled by ElementAspectHandler
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
class DetachedExportElementAspectsStrategy extends ExportElementAspectsStrategy_1.ExportElementAspectsStrategy {
|
|
21
|
+
async exportAllElementAspects() {
|
|
22
|
+
await this.exportAspectsLoop(core_backend_1.ElementUniqueAspect.classFullName, async (uniqueAspect) => {
|
|
23
|
+
const isInsertChange = this.aspectChanges?.insertIds.has(uniqueAspect.id) ?? false;
|
|
24
|
+
const isUpdateChange = this.aspectChanges?.updateIds.has(uniqueAspect.id) ?? false;
|
|
25
|
+
const doExport = this.aspectChanges === undefined || isInsertChange || isUpdateChange;
|
|
26
|
+
if (doExport) {
|
|
27
|
+
const isKnownUpdate = this.aspectChanges ? isUpdateChange : undefined;
|
|
28
|
+
this.handler.onExportElementUniqueAspect(uniqueAspect, isKnownUpdate);
|
|
29
|
+
await this.handler.trackProgress();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
let batchedElementMultiAspects = [];
|
|
33
|
+
await this.exportAspectsLoop(core_backend_1.ElementMultiAspect.classFullName, async (multiAspect) => {
|
|
34
|
+
if (batchedElementMultiAspects.length === 0) {
|
|
35
|
+
batchedElementMultiAspects.push(multiAspect);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
// element id changed so all element's aspects are in the array and can be exported
|
|
39
|
+
if (batchedElementMultiAspects[0].element.id !== multiAspect.element.id) {
|
|
40
|
+
this.handler.onExportElementMultiAspects(batchedElementMultiAspects);
|
|
41
|
+
await this.handler.trackProgress();
|
|
42
|
+
batchedElementMultiAspects = [];
|
|
43
|
+
}
|
|
44
|
+
batchedElementMultiAspects.push(multiAspect);
|
|
45
|
+
});
|
|
46
|
+
if (batchedElementMultiAspects.length > 0) {
|
|
47
|
+
// aspects that are left in the array have not been exported
|
|
48
|
+
this.handler.onExportElementMultiAspects(batchedElementMultiAspects);
|
|
49
|
+
await this.handler.trackProgress();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async exportAspectsLoop(baseAspectClass, exportAspect) {
|
|
53
|
+
for await (const aspect of this.queryAspects(baseAspectClass)) {
|
|
54
|
+
if (!this.shouldExportElementAspect(aspect)) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
await exportAspect(aspect);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async *queryAspects(baseElementAspectClassFullName) {
|
|
61
|
+
const aspectClassNameIdMap = new Map();
|
|
62
|
+
const optimizesAspectClassesSql = `
|
|
63
|
+
SELECT c.ECInstanceId as classId, (ec_className(c.ECInstanceId, 's:c')) as className
|
|
64
|
+
FROM ECDbMeta.ClassHasAllBaseClasses r
|
|
65
|
+
JOIN ECDbMeta.ECClassDef c ON c.ECInstanceId = r.SourceECInstanceId
|
|
66
|
+
WHERE r.TargetECInstanceId = ec_classId(:baseClassName)
|
|
67
|
+
`;
|
|
68
|
+
const aspectClassesQueryReader = this.sourceDb.createQueryReader(optimizesAspectClassesSql, new core_common_1.QueryBinder().bindString("baseClassName", baseElementAspectClassFullName));
|
|
69
|
+
const aspectClassesAsyncQueryReader = (0, ECSqlReaderAsyncIterableIteratorAdapter_1.ensureECSqlReaderIsAsyncIterableIterator)(aspectClassesQueryReader);
|
|
70
|
+
for await (const rowProxy of aspectClassesAsyncQueryReader) {
|
|
71
|
+
const row = rowProxy.toRow();
|
|
72
|
+
aspectClassNameIdMap.set(row.className, row.classId);
|
|
73
|
+
}
|
|
74
|
+
for (const [className, classId] of aspectClassNameIdMap) {
|
|
75
|
+
if (this.excludedElementAspectClassFullNames.has(className))
|
|
76
|
+
continue;
|
|
77
|
+
const getAspectPropsSql = `SELECT * FROM ${className} WHERE ECClassId = :classId ORDER BY Element.Id`;
|
|
78
|
+
const aspectQueryReader = this.sourceDb.createQueryReader(getAspectPropsSql, new core_common_1.QueryBinder().bindId("classId", classId), { rowFormat: core_common_1.QueryRowFormat.UseJsPropertyNames });
|
|
79
|
+
const aspectAsyncQueryReader = (0, ECSqlReaderAsyncIterableIteratorAdapter_1.ensureECSqlReaderIsAsyncIterableIterator)(aspectQueryReader);
|
|
80
|
+
let firstDone = false;
|
|
81
|
+
for await (const rowProxy of aspectAsyncQueryReader) {
|
|
82
|
+
const row = rowProxy.toRow();
|
|
83
|
+
const aspectProps = { ...row, classFullName: className, className: undefined }; // add in property required by EntityProps
|
|
84
|
+
if (!firstDone) {
|
|
85
|
+
firstDone = true;
|
|
86
|
+
}
|
|
87
|
+
delete aspectProps.className; // clear property from SELECT * that we don't want in the final instance
|
|
88
|
+
const aspectEntity = this.sourceDb.constructEntity(aspectProps);
|
|
89
|
+
yield aspectEntity;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async exportElementAspectsForElement(_elementId) {
|
|
94
|
+
// All aspects are exported separately from their elements and don't need to be exported when element is exported.
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.DetachedExportElementAspectsStrategy = DetachedExportElementAspectsStrategy;
|
|
98
|
+
//# sourceMappingURL=DetachedExportElementAspectsStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 { ElementAspect, ElementMultiAspect, ElementUniqueAspect } from \"@itwin/core-backend\";\nimport { Id64String } from \"@itwin/core-bentley\";\nimport { ExportElementAspectsStrategy } from \"./ExportElementAspectsStrategy\";\nimport { ensureECSqlReaderIsAsyncIterableIterator } from \"./ECSqlReaderAsyncIterableIteratorAdapter\";\nimport { ElementAspectProps, QueryBinder, QueryRowFormat } 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>(ElementUniqueAspect.classFullName, async (uniqueAspect) => {\n const isInsertChange = this.aspectChanges?.insertIds.has(uniqueAspect.id) ?? false;\n const isUpdateChange = this.aspectChanges?.updateIds.has(uniqueAspect.id) ?? false;\n const doExport = this.aspectChanges === undefined || isInsertChange || isUpdateChange;\n if (doExport) {\n const isKnownUpdate = this.aspectChanges ? isUpdateChange : undefined;\n this.handler.onExportElementUniqueAspect(uniqueAspect, isKnownUpdate);\n await this.handler.trackProgress();\n }\n });\n\n let batchedElementMultiAspects: ElementMultiAspect[] = [];\n await this.exportAspectsLoop<ElementMultiAspect>(ElementMultiAspect.classFullName, 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 (batchedElementMultiAspects[0].element.id !== multiAspect.element.id) {\n this.handler.onExportElementMultiAspects(batchedElementMultiAspects);\n await this.handler.trackProgress();\n batchedElementMultiAspects = [];\n }\n\n batchedElementMultiAspects.push(multiAspect);\n });\n\n if (batchedElementMultiAspects.length > 0) {\n // aspects that are left in the array have not been exported\n this.handler.onExportElementMultiAspects(batchedElementMultiAspects);\n await this.handler.trackProgress();\n }\n }\n\n private async exportAspectsLoop<T extends ElementAspect>(baseAspectClass: string, exportAspect: (aspect: T) => Promise<void>) {\n for await (const aspect of this.queryAspects<T>(baseAspectClass)) {\n if (!this.shouldExportElementAspect(aspect)) {\n continue;\n }\n\n await exportAspect(aspect);\n }\n }\n\n private async *queryAspects<T extends ElementAspect>(baseElementAspectClassFullName: string) {\n const aspectClassNameIdMap = new Map<string, Id64String>();\n\n const optimizesAspectClassesSql = `\n SELECT c.ECInstanceId as classId, (ec_className(c.ECInstanceId, 's: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(optimizesAspectClassesSql, new QueryBinder().bindString(\"baseClassName\", baseElementAspectClassFullName));\n const aspectClassesAsyncQueryReader = ensureECSqlReaderIsAsyncIterableIterator(aspectClassesQueryReader);\n for await (const rowProxy of aspectClassesAsyncQueryReader) {\n const row = rowProxy.toRow();\n aspectClassNameIdMap.set(row.className, row.classId);\n }\n\n for (const [className, classId] of aspectClassNameIdMap) {\n if(this.excludedElementAspectClassFullNames.has(className))\n continue;\n\n const getAspectPropsSql = `SELECT * FROM ${className} WHERE ECClassId = :classId ORDER BY Element.Id`;\n const aspectQueryReader = this.sourceDb.createQueryReader(getAspectPropsSql, new QueryBinder().bindId(\"classId\", classId), { rowFormat: QueryRowFormat.UseJsPropertyNames });\n const aspectAsyncQueryReader = ensureECSqlReaderIsAsyncIterableIterator(aspectQueryReader);\n let firstDone = false;\n for await (const rowProxy of aspectAsyncQueryReader) {\n const row = rowProxy.toRow();\n const aspectProps: ElementAspectProps = { ...row, classFullName: className, className: undefined }; // 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(_elementId: string): 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"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ECSqlReader, QueryRowProxy } from "@itwin/core-common";
|
|
2
|
+
/**
|
|
3
|
+
* Adapter class for ECSqlReader for AsyncIterableIterator interface.
|
|
4
|
+
* It allows to iterate through query results in itwin 3.x using for await() syntax like using itwin 4.x version.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export declare class ECSqlReaderAsyncIterableIteratorAdapter implements AsyncIterableIterator<QueryRowProxy> {
|
|
8
|
+
private _ecSqlReader;
|
|
9
|
+
constructor(_ecSqlReader: ECSqlReader);
|
|
10
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<QueryRowProxy>;
|
|
11
|
+
next(): Promise<IteratorResult<QueryRowProxy, any>>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Wraps ECSqlReader with ECSqlReaderAsyncIterableIteratorAdapter if it's needed.
|
|
15
|
+
* @param ecSqlReader ECSqlReader isntance from itwin 3.x or 4.x version
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare function ensureECSqlReaderIsAsyncIterableIterator(ecSqlReader: ECSqlReader & AsyncIterableIterator<QueryRowProxy> | Omit<ECSqlReader, keyof AsyncIterableIterator<QueryRowProxy>>): AsyncIterableIterator<QueryRowProxy>;
|
|
19
|
+
//# sourceMappingURL=ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.d.ts","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;;;GAIG;AACH,qBAAa,uCAAwC,YAAW,qBAAqB,CAAC,aAAa,CAAC;IAE/E,OAAO,CAAC,YAAY;gBAAZ,YAAY,EAAE,WAAW;IAE7C,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,aAAa,CAAC;IAIxD,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;CAOjE;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,CAAC,WAAW,EAAE,WAAW,GAAG,qBAAqB,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,qBAAqB,CAAC,aAAa,CAAC,CAAC,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAM9N"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ensureECSqlReaderIsAsyncIterableIterator = exports.ECSqlReaderAsyncIterableIteratorAdapter = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* Adapter class for ECSqlReader for AsyncIterableIterator interface.
|
|
10
|
+
* It allows to iterate through query results in itwin 3.x using for await() syntax like using itwin 4.x version.
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
class ECSqlReaderAsyncIterableIteratorAdapter {
|
|
14
|
+
constructor(_ecSqlReader) {
|
|
15
|
+
this._ecSqlReader = _ecSqlReader;
|
|
16
|
+
}
|
|
17
|
+
[Symbol.asyncIterator]() {
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
async next() {
|
|
21
|
+
const done = !(await this._ecSqlReader.step());
|
|
22
|
+
return {
|
|
23
|
+
done,
|
|
24
|
+
value: this._ecSqlReader.current,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.ECSqlReaderAsyncIterableIteratorAdapter = ECSqlReaderAsyncIterableIteratorAdapter;
|
|
29
|
+
/**
|
|
30
|
+
* Wraps ECSqlReader with ECSqlReaderAsyncIterableIteratorAdapter if it's needed.
|
|
31
|
+
* @param ecSqlReader ECSqlReader isntance from itwin 3.x or 4.x version
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
function ensureECSqlReaderIsAsyncIterableIterator(ecSqlReader) {
|
|
35
|
+
if (Symbol.asyncIterator in ecSqlReader) { // using itwin 4.x
|
|
36
|
+
return ecSqlReader;
|
|
37
|
+
}
|
|
38
|
+
else { // using itwin 3.x
|
|
39
|
+
return new ECSqlReaderAsyncIterableIteratorAdapter(ecSqlReader);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.ensureECSqlReaderIsAsyncIterableIterator = ensureECSqlReaderIsAsyncIterableIterator;
|
|
43
|
+
//# sourceMappingURL=ECSqlReaderAsyncIterableIteratorAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ECSqlReaderAsyncIterableIteratorAdapter.js","sourceRoot":"","sources":["../../src/ECSqlReaderAsyncIterableIteratorAdapter.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAI/F;;;;GAIG;AACH,MAAa,uCAAuC;IAElD,YAA2B,YAAyB;QAAzB,iBAAY,GAAZ,YAAY,CAAa;IAAI,CAAC;IAElD,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,OAAO;YACL,IAAI;YACJ,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO;SACjC,CAAC;IACJ,CAAC;CACF;AAfD,0FAeC;AAED;;;;GAIG;AACH,SAAgB,wCAAwC,CAAC,WAA+H;IACtL,IAAI,MAAM,CAAC,aAAa,IAAI,WAAW,EAAE,EAAE,kBAAkB;QAC3D,OAAO,WAAW,CAAC;KACpB;SAAM,EAAE,kBAAkB;QACzB,OAAO,IAAI,uCAAuC,CAAC,WAA0B,CAAC,CAAC;KAChF;AACH,CAAC;AAND,4FAMC","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 { ECSqlReader, QueryRowProxy } from \"@itwin/core-common\";\n\n/**\n * Adapter class for ECSqlReader for AsyncIterableIterator interface.\n * It allows to iterate through query results in itwin 3.x using for await() syntax like using itwin 4.x version.\n * @internal\n */\nexport class ECSqlReaderAsyncIterableIteratorAdapter implements AsyncIterableIterator<QueryRowProxy> {\n\n public constructor(private _ecSqlReader: ECSqlReader) { }\n\n public [Symbol.asyncIterator](): AsyncIterableIterator<QueryRowProxy> {\n return this;\n }\n\n public async next(): Promise<IteratorResult<QueryRowProxy, any>> {\n const done = !(await this._ecSqlReader.step());\n return {\n done,\n value: this._ecSqlReader.current,\n };\n }\n}\n\n/**\n * Wraps ECSqlReader with ECSqlReaderAsyncIterableIteratorAdapter if it's needed.\n * @param ecSqlReader ECSqlReader isntance from itwin 3.x or 4.x version\n * @internal\n */\nexport function ensureECSqlReaderIsAsyncIterableIterator(ecSqlReader: ECSqlReader & AsyncIterableIterator<QueryRowProxy> | Omit<ECSqlReader, keyof AsyncIterableIterator<QueryRowProxy>>): AsyncIterableIterator<QueryRowProxy> {\n if (Symbol.asyncIterator in ecSqlReader) { // using itwin 4.x\n return ecSqlReader;\n } else { // using itwin 3.x\n return new ECSqlReaderAsyncIterableIteratorAdapter(ecSqlReader as ECSqlReader);\n }\n}\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ElementAspect, ElementMultiAspect, ElementUniqueAspect, IModelDb } from "@itwin/core-backend";
|
|
2
|
+
import { Id64String } from "@itwin/core-bentley";
|
|
3
|
+
import { ChangedInstanceOps } from "./IModelExporter";
|
|
4
|
+
/**
|
|
5
|
+
* Handler for [[ExportElementAspectsStrategy]]
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export interface ElementAspectsHandler {
|
|
9
|
+
shouldExportElementAspect(aspect: ElementAspect): boolean;
|
|
10
|
+
onExportElementUniqueAspect(uniqueAspect: ElementUniqueAspect, isUpdate?: boolean | undefined): void;
|
|
11
|
+
onExportElementMultiAspects(multiAspects: ElementMultiAspect[]): void;
|
|
12
|
+
trackProgress: () => Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Base ElementAspect export strategy. Base export strategy includes state saving and loading and
|
|
16
|
+
* ElementAspect filtering.
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export declare abstract class ExportElementAspectsStrategy {
|
|
20
|
+
/** The set of classes of ElementAspects that will be excluded (polymorphically) from transformation to the target iModel. */
|
|
21
|
+
protected _excludedElementAspectClasses: Set<typeof ElementAspect>;
|
|
22
|
+
/** The set of classFullNames for ElementAspects that will be excluded from transformation to the target iModel. */
|
|
23
|
+
readonly excludedElementAspectClassFullNames: Set<string>;
|
|
24
|
+
protected sourceDb: IModelDb;
|
|
25
|
+
protected aspectChanges: ChangedInstanceOps | undefined;
|
|
26
|
+
protected handler: ElementAspectsHandler;
|
|
27
|
+
constructor(sourceDb: IModelDb, handler: ElementAspectsHandler);
|
|
28
|
+
abstract exportElementAspectsForElement(_elementId: Id64String): Promise<void>;
|
|
29
|
+
abstract exportAllElementAspects(): Promise<void>;
|
|
30
|
+
protected shouldExportElementAspect(aspect: ElementAspect): boolean;
|
|
31
|
+
setAspectChanges(aspectChanges?: ChangedInstanceOps): void;
|
|
32
|
+
loadExcludedElementAspectClasses(excludedElementAspectClassFullNames: string[]): void;
|
|
33
|
+
excludeElementAspectClass(classFullName: string): void;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=ExportElementAspectsStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportElementAspectsStrategy.d.ts","sourceRoot":"","sources":["../../src/ExportElementAspectsStrategy.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACvG,OAAO,EAAE,UAAU,EAAU,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAItD;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,yBAAyB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC;IAC1D,2BAA2B,CAAC,YAAY,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC;IACrG,2BAA2B,CAAC,YAAY,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACtE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED;;;;GAIG;AACH,8BAAsB,4BAA4B;IAChD,6HAA6H;IAC7H,SAAS,CAAC,6BAA6B,4BAAmC;IAC1E,mHAAmH;IACnH,SAAgB,mCAAmC,cAAqB;IAExE,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE7B,SAAS,CAAC,aAAa,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAExD,SAAS,CAAC,OAAO,EAAE,qBAAqB,CAAC;gBAEtB,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB;aAKrD,8BAA8B,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;aACrE,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;IAExD,SAAS,CAAC,yBAAyB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO;IAW5D,gBAAgB,CAAC,aAAa,CAAC,EAAE,kBAAkB;IAInD,gCAAgC,CAAC,mCAAmC,EAAE,MAAM,EAAE,GAAG,IAAI;IAKrF,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;CAI9D"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ExportElementAspectsStrategy = void 0;
|
|
8
|
+
const core_bentley_1 = require("@itwin/core-bentley");
|
|
9
|
+
const TransformerLoggerCategory_1 = require("./TransformerLoggerCategory");
|
|
10
|
+
const loggerCategory = TransformerLoggerCategory_1.TransformerLoggerCategory.IModelExporter;
|
|
11
|
+
/**
|
|
12
|
+
* Base ElementAspect export strategy. Base export strategy includes state saving and loading and
|
|
13
|
+
* ElementAspect filtering.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
class ExportElementAspectsStrategy {
|
|
17
|
+
constructor(sourceDb, handler) {
|
|
18
|
+
/** The set of classes of ElementAspects that will be excluded (polymorphically) from transformation to the target iModel. */
|
|
19
|
+
this._excludedElementAspectClasses = new Set();
|
|
20
|
+
/** The set of classFullNames for ElementAspects that will be excluded from transformation to the target iModel. */
|
|
21
|
+
this.excludedElementAspectClassFullNames = new Set();
|
|
22
|
+
this.sourceDb = sourceDb;
|
|
23
|
+
this.handler = handler;
|
|
24
|
+
}
|
|
25
|
+
shouldExportElementAspect(aspect) {
|
|
26
|
+
for (const excludedElementAspectClass of this._excludedElementAspectClasses) {
|
|
27
|
+
if (aspect instanceof excludedElementAspectClass) {
|
|
28
|
+
core_bentley_1.Logger.logInfo(loggerCategory, `Excluded ElementAspect by class: ${aspect.classFullName}`);
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// ElementAspect has passed standard exclusion rules, now give handler a chance to accept/reject
|
|
33
|
+
return this.handler.shouldExportElementAspect(aspect);
|
|
34
|
+
}
|
|
35
|
+
setAspectChanges(aspectChanges) {
|
|
36
|
+
this.aspectChanges = aspectChanges;
|
|
37
|
+
}
|
|
38
|
+
loadExcludedElementAspectClasses(excludedElementAspectClassFullNames) {
|
|
39
|
+
this.excludedElementAspectClassFullNames = new Set(excludedElementAspectClassFullNames);
|
|
40
|
+
this._excludedElementAspectClasses = new Set(excludedElementAspectClassFullNames.map((c) => this.sourceDb.getJsClass(c)));
|
|
41
|
+
}
|
|
42
|
+
excludeElementAspectClass(classFullName) {
|
|
43
|
+
this.excludedElementAspectClassFullNames.add(classFullName); // allows non-polymorphic exclusion before query
|
|
44
|
+
this._excludedElementAspectClasses.add(this.sourceDb.getJsClass(classFullName)); // allows polymorphic exclusion after query/load
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.ExportElementAspectsStrategy = ExportElementAspectsStrategy;
|
|
48
|
+
//# sourceMappingURL=ExportElementAspectsStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportElementAspectsStrategy.js","sourceRoot":"","sources":["../../src/ExportElementAspectsStrategy.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAG/F,sDAAyD;AACzD,2EAAwE;AAGxE,MAAM,cAAc,GAAG,qDAAyB,CAAC,cAAc,CAAC;AAahE;;;;GAIG;AACH,MAAsB,4BAA4B;IAYhD,YAAmB,QAAkB,EAAE,OAA8B;QAXrE,6HAA6H;QACnH,kCAA6B,GAAG,IAAI,GAAG,EAAwB,CAAC;QAC1E,mHAAmH;QACnG,wCAAmC,GAAG,IAAI,GAAG,EAAU,CAAC;QAStE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAKS,yBAAyB,CAAC,MAAqB;QACvD,KAAK,MAAM,0BAA0B,IAAI,IAAI,CAAC,6BAA6B,EAAE;YAC3E,IAAI,MAAM,YAAY,0BAA0B,EAAE;gBAChD,qBAAM,CAAC,OAAO,CAAC,cAAc,EAAE,oCAAoC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;gBAC3F,OAAO,KAAK,CAAC;aACd;SACF;QACD,gGAAgG;QAChG,OAAO,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;IACxD,CAAC;IAEM,gBAAgB,CAAC,aAAkC;QACxD,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;IAEM,gCAAgC,CAAC,mCAA6C;QAClF,IAAI,CAAC,mCAA2C,GAAG,IAAI,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACjG,IAAI,CAAC,6BAA6B,GAAG,IAAI,GAAG,CAAC,mCAAmC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5H,CAAC;IAEM,yBAAyB,CAAC,aAAqB;QACpD,IAAI,CAAC,mCAAmC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,gDAAgD;QAC7G,IAAI,CAAC,6BAA6B,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAuB,aAAa,CAAC,CAAC,CAAC,CAAC,gDAAgD;IACzJ,CAAC;CACF;AA5CD,oEA4CC","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 { ElementAspect, ElementMultiAspect, ElementUniqueAspect, IModelDb } from \"@itwin/core-backend\";\nimport { Id64String, Logger } from \"@itwin/core-bentley\";\nimport { TransformerLoggerCategory } from \"./TransformerLoggerCategory\";\nimport { ChangedInstanceOps } from \"./IModelExporter\";\n\nconst loggerCategory = TransformerLoggerCategory.IModelExporter;\n\n/**\n * Handler for [[ExportElementAspectsStrategy]]\n * @internal\n */\nexport interface ElementAspectsHandler {\n shouldExportElementAspect(aspect: ElementAspect): boolean;\n onExportElementUniqueAspect(uniqueAspect: ElementUniqueAspect, isUpdate?: boolean | undefined): void;\n onExportElementMultiAspects(multiAspects: ElementMultiAspect[]): void;\n trackProgress: () => Promise<void>;\n}\n\n/**\n * Base ElementAspect export strategy. Base export strategy includes state saving and loading and\n * ElementAspect filtering.\n * @internal\n */\nexport abstract class ExportElementAspectsStrategy {\n /** The set of classes of ElementAspects that will be excluded (polymorphically) from transformation to the target iModel. */\n protected _excludedElementAspectClasses = new Set<typeof ElementAspect>();\n /** The set of classFullNames for ElementAspects that will be excluded from transformation to the target iModel. */\n public readonly excludedElementAspectClassFullNames = new Set<string>();\n\n protected sourceDb: IModelDb;\n\n protected aspectChanges: ChangedInstanceOps | undefined;\n\n protected handler: ElementAspectsHandler;\n\n public constructor(sourceDb: IModelDb, handler: ElementAspectsHandler) {\n this.sourceDb = sourceDb;\n this.handler = handler;\n }\n\n public abstract exportElementAspectsForElement(_elementId: Id64String): Promise<void>;\n public abstract exportAllElementAspects(): Promise<void>;\n\n protected shouldExportElementAspect(aspect: ElementAspect): boolean {\n for (const excludedElementAspectClass of this._excludedElementAspectClasses) {\n if (aspect instanceof excludedElementAspectClass) {\n Logger.logInfo(loggerCategory, `Excluded ElementAspect by class: ${aspect.classFullName}`);\n return false;\n }\n }\n // ElementAspect has passed standard exclusion rules, now give handler a chance to accept/reject\n return this.handler.shouldExportElementAspect(aspect);\n }\n\n public setAspectChanges(aspectChanges?: ChangedInstanceOps) {\n this.aspectChanges = aspectChanges;\n }\n\n public loadExcludedElementAspectClasses(excludedElementAspectClassFullNames: string[]): void {\n (this.excludedElementAspectClassFullNames as any) = new Set(excludedElementAspectClassFullNames);\n this._excludedElementAspectClasses = new Set(excludedElementAspectClassFullNames.map((c) => this.sourceDb.getJsClass(c)));\n }\n\n public excludeElementAspectClass(classFullName: string): void {\n this.excludedElementAspectClassFullNames.add(classFullName); // allows non-polymorphic exclusion before query\n this._excludedElementAspectClasses.add(this.sourceDb.getJsClass<typeof ElementAspect>(classFullName)); // allows polymorphic exclusion after query/load\n }\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Id64String } from "@itwin/core-bentley";
|
|
2
|
+
import { ExportElementAspectsStrategy } from "./ExportElementAspectsStrategy";
|
|
3
|
+
/**
|
|
4
|
+
* ElementAspect export strategy for [[IModelExporter]].
|
|
5
|
+
* This strategy exports ElementAspects together with their Elements.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export declare class ExportElementAspectsWithElementsStrategy extends ExportElementAspectsStrategy {
|
|
9
|
+
exportElementAspectsForElement(elementId: Id64String): Promise<void>;
|
|
10
|
+
exportAllElementAspects(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=ExportElementAspectsWithElementsStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportElementAspectsWithElementsStrategy.d.ts","sourceRoot":"","sources":["../../src/ExportElementAspectsWithElementsStrategy.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAE9E;;;;GAIG;AACH,qBAAa,wCAAyC,SAAQ,4BAA4B;IAClE,8BAA8B,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBpE,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/D"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ExportElementAspectsWithElementsStrategy = void 0;
|
|
8
|
+
const core_backend_1 = require("@itwin/core-backend");
|
|
9
|
+
const ExportElementAspectsStrategy_1 = require("./ExportElementAspectsStrategy");
|
|
10
|
+
/**
|
|
11
|
+
* ElementAspect export strategy for [[IModelExporter]].
|
|
12
|
+
* This strategy exports ElementAspects together with their Elements.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
class ExportElementAspectsWithElementsStrategy extends ExportElementAspectsStrategy_1.ExportElementAspectsStrategy {
|
|
16
|
+
async exportElementAspectsForElement(elementId) {
|
|
17
|
+
const _uniqueAspects = await Promise.all(this.sourceDb.elements
|
|
18
|
+
._queryAspects(elementId, core_backend_1.ElementUniqueAspect.classFullName, this.excludedElementAspectClassFullNames)
|
|
19
|
+
.filter((a) => this.shouldExportElementAspect(a))
|
|
20
|
+
.map(async (uniqueAspect) => {
|
|
21
|
+
const isInsertChange = this.aspectChanges?.insertIds.has(uniqueAspect.id) ?? false;
|
|
22
|
+
const isUpdateChange = this.aspectChanges?.updateIds.has(uniqueAspect.id) ?? false;
|
|
23
|
+
const doExport = this.aspectChanges === undefined || isInsertChange || isUpdateChange;
|
|
24
|
+
if (doExport) {
|
|
25
|
+
const isKnownUpdate = this.aspectChanges ? isUpdateChange : undefined;
|
|
26
|
+
this.handler.onExportElementUniqueAspect(uniqueAspect, isKnownUpdate);
|
|
27
|
+
await this.handler.trackProgress();
|
|
28
|
+
}
|
|
29
|
+
}));
|
|
30
|
+
const multiAspects = this.sourceDb.elements
|
|
31
|
+
._queryAspects(elementId, core_backend_1.ElementMultiAspect.classFullName, this.excludedElementAspectClassFullNames)
|
|
32
|
+
.filter((a) => this.shouldExportElementAspect(a));
|
|
33
|
+
if (multiAspects.length > 0) {
|
|
34
|
+
this.handler.onExportElementMultiAspects(multiAspects);
|
|
35
|
+
return this.handler.trackProgress();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async exportAllElementAspects() {
|
|
39
|
+
// All aspects are exported with their owning elements and don't need to be exported separately.
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.ExportElementAspectsWithElementsStrategy = ExportElementAspectsWithElementsStrategy;
|
|
43
|
+
//# sourceMappingURL=ExportElementAspectsWithElementsStrategy.js.map
|