@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.
Files changed (37) hide show
  1. package/CHANGELOG.md +26 -1
  2. package/lib/cjs/BranchProvenanceInitializer.d.ts +3 -10
  3. package/lib/cjs/BranchProvenanceInitializer.d.ts.map +1 -1
  4. package/lib/cjs/BranchProvenanceInitializer.js +13 -84
  5. package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
  6. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts +16 -0
  7. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +1 -0
  8. package/lib/cjs/DetachedExportElementAspectsStrategy.js +98 -0
  9. package/lib/cjs/DetachedExportElementAspectsStrategy.js.map +1 -0
  10. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts +19 -0
  11. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.d.ts.map +1 -0
  12. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js +43 -0
  13. package/lib/cjs/ECSqlReaderAsyncIterableIteratorAdapter.js.map +1 -0
  14. package/lib/cjs/ExportElementAspectsStrategy.d.ts +35 -0
  15. package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +1 -0
  16. package/lib/cjs/ExportElementAspectsStrategy.js +48 -0
  17. package/lib/cjs/ExportElementAspectsStrategy.js.map +1 -0
  18. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts +12 -0
  19. package/lib/cjs/ExportElementAspectsWithElementsStrategy.d.ts.map +1 -0
  20. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +43 -0
  21. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js.map +1 -0
  22. package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
  23. package/lib/cjs/IModelCloneContext.js +2 -0
  24. package/lib/cjs/IModelCloneContext.js.map +1 -1
  25. package/lib/cjs/IModelExporter.d.ts +15 -40
  26. package/lib/cjs/IModelExporter.d.ts.map +1 -1
  27. package/lib/cjs/IModelExporter.js +52 -125
  28. package/lib/cjs/IModelExporter.js.map +1 -1
  29. package/lib/cjs/IModelTransformer.d.ts +29 -161
  30. package/lib/cjs/IModelTransformer.d.ts.map +1 -1
  31. package/lib/cjs/IModelTransformer.js +286 -934
  32. package/lib/cjs/IModelTransformer.js.map +1 -1
  33. package/package.json +14 -14
  34. package/lib/cjs/Algo.d.ts +0 -7
  35. package/lib/cjs/Algo.d.ts.map +0 -1
  36. package/lib/cjs/Algo.js +0 -50
  37. 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 Tue, 11 Jul 2023 18:59:25 GMT and should not be manually modified.
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?: true | false | "keep-reopened-db";
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,EAA6D,QAAQ,EAA0D,MAAM,qBAAqB,CAAC;AAClK,OAAO,EAAY,UAAU,EAAoB,MAAM,qBAAqB,CAAC;AAK7E;;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,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAwHxG"}
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
- args.master.withSqliteStatement(`
15
- UPDATE bis_Element
16
- SET FederationGuid=randomblob(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 masterRepoLinkId = new core_backend_1.RepositoryLink({
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
- }, args.branch).insert();
56
- const masterExternalSourceId = new core_backend_1.ExternalSource({
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(masterRepoLinkId),
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
- }, args.branch).insert();
66
- const fedGuidLessElemsSql = `
67
- SELECT ECInstanceId AS id
68
- FROM Bis.Element
69
- WHERE FederationGuid IS NULL
70
- AND ECInstanceId NOT IN (0x1, 0xe, 0x10) /* ignore special elems */
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