@itwin/imodel-transformer 0.3.18-fedguidopt.5 → 0.3.18-fedguidopt.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/BranchProvenanceInitializer.d.ts +10 -3
- package/lib/cjs/BranchProvenanceInitializer.d.ts.map +1 -1
- package/lib/cjs/BranchProvenanceInitializer.js +82 -10
- package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
- package/lib/cjs/IModelTransformer.d.ts +20 -4
- package/lib/cjs/IModelTransformer.d.ts.map +1 -1
- package/lib/cjs/IModelTransformer.js +93 -53
- package/lib/cjs/IModelTransformer.js.map +1 -1
- package/package.json +1 -1
|
@@ -19,15 +19,22 @@ 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.
|
|
22
25
|
*/
|
|
23
|
-
createFedGuidsForMaster?:
|
|
26
|
+
createFedGuidsForMaster?: true | false | "keep-reopened-db";
|
|
24
27
|
}
|
|
25
|
-
|
|
28
|
+
/**
|
|
29
|
+
* @alpha
|
|
30
|
+
*/
|
|
31
|
+
export interface ProvenanceInitResult {
|
|
26
32
|
targetScopeElementId: Id64String;
|
|
33
|
+
masterExternalSourceId: Id64String;
|
|
34
|
+
masterRepositoryLinkId: Id64String;
|
|
27
35
|
}
|
|
28
36
|
/**
|
|
29
37
|
* @alpha
|
|
30
38
|
*/
|
|
31
39
|
export declare function initializeBranchProvenance(args: ProvenanceInitArgs): Promise<ProvenanceInitResult>;
|
|
32
|
-
export {};
|
|
33
40
|
//# sourceMappingURL=BranchProvenanceInitializer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BranchProvenanceInitializer.d.ts","sourceRoot":"","sources":["../../src/BranchProvenanceInitializer.ts"],"names":[],"mappings":"
|
|
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"}
|
|
@@ -11,13 +11,40 @@ const IModelTransformer_1 = require("./IModelTransformer");
|
|
|
11
11
|
*/
|
|
12
12
|
async function initializeBranchProvenance(args) {
|
|
13
13
|
if (args.createFedGuidsForMaster) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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);
|
|
17
39
|
});
|
|
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()]);
|
|
18
45
|
}
|
|
19
46
|
// create an external source and owning repository link to use as our *Target Scope Element* for future synchronizations
|
|
20
|
-
const
|
|
47
|
+
const masterRepoLinkId = new core_backend_1.RepositoryLink({
|
|
21
48
|
classFullName: core_backend_1.RepositoryLink.classFullName,
|
|
22
49
|
code: core_backend_1.RepositoryLink.createCode(args.branch, core_backend_1.IModelDb.repositoryModelId, "example-code-value"),
|
|
23
50
|
model: core_backend_1.IModelDb.repositoryModelId,
|
|
@@ -30,25 +57,70 @@ async function initializeBranchProvenance(args) {
|
|
|
30
57
|
classFullName: core_backend_1.ExternalSource.classFullName,
|
|
31
58
|
model: core_backend_1.IModelDb.rootSubjectId,
|
|
32
59
|
code: core_common_1.Code.createEmpty(),
|
|
33
|
-
repository: new core_backend_1.ExternalSourceIsInRepository(
|
|
60
|
+
repository: new core_backend_1.ExternalSourceIsInRepository(masterRepoLinkId),
|
|
34
61
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
35
62
|
connectorName: require("../../package.json").name,
|
|
36
63
|
connectorVersion: require("../../package.json").version,
|
|
37
64
|
/* eslint-enable @typescript-eslint/no-var-requires */
|
|
38
65
|
}, args.branch).insert();
|
|
39
|
-
const fedGuidLessElemsSql =
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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, {
|
|
44
76
|
isReverseSynchronization: false,
|
|
45
77
|
targetScopeElementId: masterExternalSourceId,
|
|
46
78
|
sourceDb: args.master,
|
|
47
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, {
|
|
95
|
+
isReverseSynchronization: false,
|
|
96
|
+
targetScopeElementId: masterExternalSourceId,
|
|
97
|
+
sourceDb: args.master,
|
|
98
|
+
targetDb: args.branch,
|
|
99
|
+
forceOldRelationshipProvenanceMethod: false,
|
|
100
|
+
});
|
|
101
|
+
args.branch.elements.insertAspect(aspectProps);
|
|
102
|
+
}
|
|
103
|
+
if (args.createFedGuidsForMaster === true) {
|
|
104
|
+
args.master.close();
|
|
105
|
+
args.branch.close();
|
|
48
106
|
}
|
|
49
107
|
return {
|
|
50
108
|
targetScopeElementId: masterExternalSourceId,
|
|
109
|
+
masterExternalSourceId,
|
|
110
|
+
masterRepositoryLinkId: masterRepoLinkId,
|
|
51
111
|
};
|
|
52
112
|
}
|
|
53
113
|
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
|
+
}
|
|
54
126
|
//# sourceMappingURL=BranchProvenanceInitializer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BranchProvenanceInitializer.js","sourceRoot":"","sources":["../../src/BranchProvenanceInitializer.ts"],"names":[],"mappings":";;;AACA,sDAA6G;AAC7G,sDAA2D;AAC3D,oDAA0C;AAC1C,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,6BAAc,CAAC;QAC1C,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;KACpC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;IAEzB,MAAM,sBAAsB,GAAG,IAAI,6BAAc,CAAC;QAChD,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;KACvD,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;IAEzB,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;SACtB,CAAC,CAAC;KACJ;IAED,OAAO;QACL,oBAAoB,EAAE,sBAAsB;KAC7C,CAAC;AACJ,CAAC;AA5CD,gEA4CC","sourcesContent":["\nimport { ExternalSource, ExternalSourceIsInRepository, IModelDb, RepositoryLink } from \"@itwin/core-backend\";\nimport { DbResult, Id64String } 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 */\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 = 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(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 }, args.branch).insert();\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 });\n }\n\n return {\n targetScopeElementId: masterExternalSourceId,\n };\n}\n\n"]}
|
|
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"]}
|
|
@@ -237,6 +237,13 @@ export declare class IModelTransformer extends IModelExportHandler {
|
|
|
237
237
|
isReverseSynchronization: boolean;
|
|
238
238
|
targetScopeElementId: Id64String;
|
|
239
239
|
}): ExternalSourceAspectProps;
|
|
240
|
+
static initRelationshipProvenanceOptions(sourceRelInstanceId: Id64String, targetRelInstanceId: Id64String, args: {
|
|
241
|
+
sourceDb: IModelDb;
|
|
242
|
+
targetDb: IModelDb;
|
|
243
|
+
isReverseSynchronization: boolean;
|
|
244
|
+
targetScopeElementId: Id64String;
|
|
245
|
+
forceOldRelationshipProvenanceMethod: boolean;
|
|
246
|
+
}): ExternalSourceAspectProps;
|
|
240
247
|
/**
|
|
241
248
|
* Previously the transformer would insert provenance always pointing to the "target" relationship.
|
|
242
249
|
* It should (and now by default does) instead insert provenance pointing to the provenanceSource
|
|
@@ -258,7 +265,7 @@ export declare class IModelTransformer extends IModelExportHandler {
|
|
|
258
265
|
* Index of the changeset that the transformer was at when the transformation begins (was constructed).
|
|
259
266
|
* Used to determine at the end which changesets were part of a synchronization.
|
|
260
267
|
*/
|
|
261
|
-
private
|
|
268
|
+
private _startingChangesetIndices;
|
|
262
269
|
private _cachedSynchronizationVersion;
|
|
263
270
|
/** the changeset in the scoping element's source version found for this transformation
|
|
264
271
|
* @note: the version depends on whether this is a reverse synchronization or not, as
|
|
@@ -417,9 +424,17 @@ export declare class IModelTransformer extends IModelExportHandler {
|
|
|
417
424
|
processDeferredElements(_numRetries?: number): Promise<void>;
|
|
418
425
|
/** called at the end ([[finalizeTransformation]]) of a transformation,
|
|
419
426
|
* updates the target scope element to say that transformation up through the
|
|
420
|
-
* source's changeset has been performed.
|
|
427
|
+
* source's changeset has been performed. Also stores all changesets that occurred
|
|
428
|
+
* during the transformation as "pending synchronization changeset indices"
|
|
429
|
+
*
|
|
430
|
+
* You generally should not call this function yourself and use [[processChanges]] instead.
|
|
431
|
+
* It is public for unsupported use cases of custom synchronization transforms.
|
|
432
|
+
* @note if you are not running processChanges in this transformation, this will fail
|
|
433
|
+
* without setting the `force` option to `true`
|
|
421
434
|
*/
|
|
422
|
-
|
|
435
|
+
updateSynchronizationVersion({ force }?: {
|
|
436
|
+
force?: boolean | undefined;
|
|
437
|
+
}): void;
|
|
423
438
|
private finalizeTransformation;
|
|
424
439
|
/** Imports all relationships that subclass from the specified base class.
|
|
425
440
|
* @param baseRelClassFullName The specified base relationship class.
|
|
@@ -595,7 +610,8 @@ export declare class IModelTransformer extends IModelExportHandler {
|
|
|
595
610
|
* data loss in future branch operations
|
|
596
611
|
* @param accessToken A valid access token string
|
|
597
612
|
* @param startChangesetId Include changes from this changeset up through and including the current changeset.
|
|
598
|
-
*
|
|
613
|
+
* @note if no startChangesetId or startChangeset option is provided, the next unsynchronized changeset
|
|
614
|
+
* will automatically be determined and used
|
|
599
615
|
* @note To form a range of versions to process, set `startChangesetId` for the start (inclusive) of the desired range and open the source iModel as of the end (inclusive) of the desired range.
|
|
600
616
|
*/
|
|
601
617
|
processChanges(options: ProcessChangesOptions): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IModelTransformer.d.ts","sourceRoot":"","sources":["../../src/IModelTransformer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"IModelTransformer.d.ts","sourceRoot":"","sources":["../../src/IModelTransformer.ts"],"names":[],"mappings":"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"}
|
|
@@ -143,7 +143,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
143
143
|
* Index of the changeset that the transformer was at when the transformation begins (was constructed).
|
|
144
144
|
* Used to determine at the end which changesets were part of a synchronization.
|
|
145
145
|
*/
|
|
146
|
-
this.
|
|
146
|
+
this._startingChangesetIndices = undefined;
|
|
147
147
|
this._cachedSynchronizationVersion = undefined;
|
|
148
148
|
this._targetClassNameToClassIdCache = new Map();
|
|
149
149
|
// if undefined, it can be initialized by calling [[this._cacheSourceChanges]]
|
|
@@ -206,7 +206,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
206
206
|
this.targetDb = this.importer.targetDb;
|
|
207
207
|
// create the IModelCloneContext, it must be initialized later
|
|
208
208
|
this.context = new IModelCloneContext_1.IModelCloneContext(this.sourceDb, this.targetDb);
|
|
209
|
-
this.
|
|
209
|
+
if (this.sourceDb.isBriefcase && this.targetDb.isBriefcase) {
|
|
210
|
+
nodeAssert(this.sourceDb.changeset.index !== undefined && this.targetDb.changeset.index !== undefined, "database has no changeset index");
|
|
211
|
+
this._startingChangesetIndices = {
|
|
212
|
+
target: this.targetDb.changeset.index,
|
|
213
|
+
source: this.sourceDb.changeset.index,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
210
216
|
}
|
|
211
217
|
/** Dispose any native resources associated with this IModelTransformer. */
|
|
212
218
|
dispose() {
|
|
@@ -255,6 +261,28 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
255
261
|
};
|
|
256
262
|
return aspectProps;
|
|
257
263
|
}
|
|
264
|
+
static initRelationshipProvenanceOptions(sourceRelInstanceId, targetRelInstanceId, args) {
|
|
265
|
+
const provenanceDb = args.isReverseSynchronization ? args.sourceDb : args.targetDb;
|
|
266
|
+
const aspectIdentifier = args.isReverseSynchronization ? targetRelInstanceId : sourceRelInstanceId;
|
|
267
|
+
const provenanceRelInstanceId = args.isReverseSynchronization ? sourceRelInstanceId : targetRelInstanceId;
|
|
268
|
+
const elementId = provenanceDb.withPreparedStatement("SELECT SourceECInstanceId FROM bis.ElementRefersToElements WHERE ECInstanceId=?", (stmt) => {
|
|
269
|
+
stmt.bindId(1, provenanceRelInstanceId);
|
|
270
|
+
nodeAssert(stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW);
|
|
271
|
+
return stmt.getValue(0).getId();
|
|
272
|
+
});
|
|
273
|
+
const jsonProperties = args.forceOldRelationshipProvenanceMethod
|
|
274
|
+
? { targetRelInstanceId }
|
|
275
|
+
: { provenanceRelInstanceId };
|
|
276
|
+
const aspectProps = {
|
|
277
|
+
classFullName: core_backend_1.ExternalSourceAspect.classFullName,
|
|
278
|
+
element: { id: elementId, relClassName: core_backend_1.ElementOwnsExternalSourceAspects.classFullName },
|
|
279
|
+
scope: { id: args.targetScopeElementId },
|
|
280
|
+
identifier: aspectIdentifier,
|
|
281
|
+
kind: core_backend_1.ExternalSourceAspect.Kind.Relationship,
|
|
282
|
+
jsonProperties: JSON.stringify(jsonProperties),
|
|
283
|
+
};
|
|
284
|
+
return aspectProps;
|
|
285
|
+
}
|
|
258
286
|
/** Create an ExternalSourceAspectProps in a standard way for an Element in an iModel --> iModel transformation. */
|
|
259
287
|
initElementProvenance(sourceElementId, targetElementId) {
|
|
260
288
|
return IModelTransformer.initElementProvenanceOptions(sourceElementId, targetElementId, {
|
|
@@ -270,29 +298,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
270
298
|
* The ECInstanceId of the relationship in the target iModel will be stored in the JsonProperties of the ExternalSourceAspect.
|
|
271
299
|
*/
|
|
272
300
|
initRelationshipProvenance(sourceRelationship, targetRelInstanceId) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
: this.targetDb
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
const aspectIdentifier = this._options.isReverseSynchronization ? targetRelInstanceId : sourceRelationship.id;
|
|
281
|
-
const jsonProperties = this._forceOldRelationshipProvenanceMethod
|
|
282
|
-
? { targetRelInstanceId }
|
|
283
|
-
: { provenanceRelInstanceId: this._isReverseSynchronization
|
|
284
|
-
? sourceRelationship.id
|
|
285
|
-
: targetRelInstanceId,
|
|
286
|
-
};
|
|
287
|
-
const aspectProps = {
|
|
288
|
-
classFullName: core_backend_1.ExternalSourceAspect.classFullName,
|
|
289
|
-
element: { id: elementId, relClassName: core_backend_1.ElementOwnsExternalSourceAspects.classFullName },
|
|
290
|
-
scope: { id: this.targetScopeElementId },
|
|
291
|
-
identifier: aspectIdentifier,
|
|
292
|
-
kind: core_backend_1.ExternalSourceAspect.Kind.Relationship,
|
|
293
|
-
jsonProperties: JSON.stringify(jsonProperties),
|
|
294
|
-
};
|
|
295
|
-
return aspectProps;
|
|
301
|
+
return IModelTransformer.initRelationshipProvenanceOptions(sourceRelationship.id, targetRelInstanceId, {
|
|
302
|
+
sourceDb: this.sourceDb,
|
|
303
|
+
targetDb: this.targetDb,
|
|
304
|
+
isReverseSynchronization: !!this._options.isReverseSynchronization,
|
|
305
|
+
targetScopeElementId: this.targetScopeElementId,
|
|
306
|
+
forceOldRelationshipProvenanceMethod: this._forceOldRelationshipProvenanceMethod,
|
|
307
|
+
});
|
|
296
308
|
}
|
|
297
309
|
/** the changeset in the scoping element's source version found for this transformation
|
|
298
310
|
* @note: the version depends on whether this is a reverse synchronization or not, as
|
|
@@ -543,8 +555,18 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
543
555
|
NULL AS FedGuid2,
|
|
544
556
|
ic.ChangedInstance.ClassId AS ClassId
|
|
545
557
|
${queryCanAccessProvenance ? `
|
|
546
|
-
|
|
547
|
-
,
|
|
558
|
+
/*
|
|
559
|
+
-- can't coalesce these due to a bug, so do it in JS
|
|
560
|
+
, coalesce(
|
|
561
|
+
IIF(esa.Scope.Id=:targetScopeElement, esa.Identifier, NULL),
|
|
562
|
+
IIF(esac.Scope.Id=:targetScopeElement, esac.Identifier, NULL)
|
|
563
|
+
) AS Identifier1
|
|
564
|
+
*/
|
|
565
|
+
, CASE WHEN esa.Scope.Id = ${this.targetScopeElementId} THEN esa.Identifier ELSE NULL END AS Identifier1A
|
|
566
|
+
-- FIXME: using :targetScopeElement parameter in this second potential identifier breaks ecsql
|
|
567
|
+
, CASE WHEN esac.Scope.Id = ${this.targetScopeElementId} THEN esac.Identifier ELSE NULL END AS Identifier1B
|
|
568
|
+
, NULL AS Identifier2A
|
|
569
|
+
, NULL AS Identifier2B
|
|
548
570
|
` : ""}
|
|
549
571
|
FROM ecchange.change.InstanceChange ic
|
|
550
572
|
LEFT JOIN bis.Element.Changes(:changeSummaryId, 'BeforeDelete') ec
|
|
@@ -558,12 +580,6 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
558
580
|
WHERE ic.OpCode=:opDelete
|
|
559
581
|
AND ic.Summary.Id=:changeSummaryId
|
|
560
582
|
AND ic.ChangedInstance.ClassId IS (BisCore.Element)
|
|
561
|
-
${queryCanAccessProvenance ? `
|
|
562
|
-
AND (esa.Scope.Id=:targetScopeElement OR esa.Scope.Id IS NULL)
|
|
563
|
-
AND (esa.Kind='Element' OR esa.Kind IS NULL)
|
|
564
|
-
AND (esac.Scope.Id=:targetScopeElement OR esac.Scope.Id IS NULL)
|
|
565
|
-
AND (esac.Kind='Element' OR esac.Kind IS NULL)
|
|
566
|
-
` : ""}
|
|
567
583
|
|
|
568
584
|
UNION ALL
|
|
569
585
|
|
|
@@ -576,8 +592,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
576
592
|
coalesce(te.FederationGuid, tec.FederationGuid) AS FedGuid2,
|
|
577
593
|
ic.ChangedInstance.ClassId AS ClassId
|
|
578
594
|
${queryCanAccessProvenance ? `
|
|
579
|
-
,
|
|
580
|
-
,
|
|
595
|
+
, sesa.Identifier AS Identifier1A
|
|
596
|
+
, sesac.Identifier AS Identifier1B
|
|
597
|
+
, tesa.Identifier AS Identifier2A
|
|
598
|
+
, tesac.Identifier AS Identifier2B
|
|
581
599
|
` : ""}
|
|
582
600
|
FROM ecchange.change.InstanceChange ic
|
|
583
601
|
LEFT JOIN bis.ElementRefersToElements.Changes(:changeSummaryId, 'BeforeDelete') ertec
|
|
@@ -630,10 +648,15 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
630
648
|
const sourceElemFedGuid = stmt.getValue(4).getGuid();
|
|
631
649
|
// "Identifier" is a string, so null value returns '' which doesn't work with ??, and I don't like ||
|
|
632
650
|
let identifierValue;
|
|
651
|
+
// identifier must be coalesced in JS due to an ESCQL bug, so there are multiple columns
|
|
652
|
+
if (queryCanAccessProvenance) {
|
|
653
|
+
identifierValue = stmt.getValue(7);
|
|
654
|
+
if (identifierValue.isNull)
|
|
655
|
+
identifierValue = stmt.getValue(8);
|
|
656
|
+
}
|
|
633
657
|
// TODO: if I could attach the second db, will probably be much faster to get target id
|
|
634
658
|
// as part of the whole query rather than with _queryElemIdByFedGuid
|
|
635
|
-
const targetId = (queryCanAccessProvenance
|
|
636
|
-
&& (identifierValue = stmt.getValue(7))
|
|
659
|
+
const targetId = (queryCanAccessProvenance && identifierValue
|
|
637
660
|
&& !identifierValue.isNull
|
|
638
661
|
&& identifierValue.getString())
|
|
639
662
|
// maybe batching these queries would perform better but we should
|
|
@@ -659,14 +682,20 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
659
682
|
else { // is deleted relationship
|
|
660
683
|
const classFullName = stmt.getValue(6).getClassNameForClassId();
|
|
661
684
|
const [sourceIdInTarget, targetIdInTarget] = [
|
|
662
|
-
|
|
663
|
-
{ guidColumn:
|
|
664
|
-
|
|
685
|
+
// identifier must be coalesced in JS due to an ESCQL bug, so there are multiple columns
|
|
686
|
+
{ guidColumn: 4, identifierColumns: { a: 7, b: 8 }, isTarget: false },
|
|
687
|
+
{ guidColumn: 5, identifierColumns: { a: 9, b: 10 }, isTarget: true },
|
|
688
|
+
].map(({ guidColumn, identifierColumns }) => {
|
|
665
689
|
const fedGuid = stmt.getValue(guidColumn).getGuid();
|
|
666
690
|
let identifierValue;
|
|
667
|
-
|
|
691
|
+
// identifier must be coalesced in JS due to an ESCQL bug, so there are multiple columns
|
|
692
|
+
if (queryCanAccessProvenance) {
|
|
693
|
+
identifierValue = stmt.getValue(identifierColumns.a);
|
|
694
|
+
if (identifierValue.isNull)
|
|
695
|
+
identifierValue = stmt.getValue(identifierColumns.b);
|
|
696
|
+
}
|
|
697
|
+
return ((queryCanAccessProvenance && identifierValue
|
|
668
698
|
// FIXME: this is really far from idiomatic, try to undo that
|
|
669
|
-
&& (identifierValue = stmt.getValue(identifierColumn))
|
|
670
699
|
&& !identifierValue.isNull
|
|
671
700
|
&& identifierValue.getString())
|
|
672
701
|
// maybe batching these queries would perform better but we should
|
|
@@ -1284,15 +1313,21 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1284
1313
|
async processDeferredElements(_numRetries = 3) { }
|
|
1285
1314
|
/** called at the end ([[finalizeTransformation]]) of a transformation,
|
|
1286
1315
|
* updates the target scope element to say that transformation up through the
|
|
1287
|
-
* source's changeset has been performed.
|
|
1316
|
+
* source's changeset has been performed. Also stores all changesets that occurred
|
|
1317
|
+
* during the transformation as "pending synchronization changeset indices"
|
|
1318
|
+
*
|
|
1319
|
+
* You generally should not call this function yourself and use [[processChanges]] instead.
|
|
1320
|
+
* It is public for unsupported use cases of custom synchronization transforms.
|
|
1321
|
+
* @note if you are not running processChanges in this transformation, this will fail
|
|
1322
|
+
* without setting the `force` option to `true`
|
|
1288
1323
|
*/
|
|
1289
|
-
|
|
1290
|
-
if (this._sourceChangeDataState !== "has-changes" && !this._isFirstSynchronization)
|
|
1324
|
+
updateSynchronizationVersion({ force = false } = {}) {
|
|
1325
|
+
if (!force && (this._sourceChangeDataState !== "has-changes" && !this._isFirstSynchronization))
|
|
1291
1326
|
return;
|
|
1292
1327
|
nodeAssert(this._targetScopeProvenanceProps);
|
|
1293
1328
|
const sourceVersion = `${this.sourceDb.changeset.id};${this.sourceDb.changeset.index}`;
|
|
1329
|
+
const targetVersion = `${this.targetDb.changeset.id};${this.targetDb.changeset.index}`;
|
|
1294
1330
|
if (this._isFirstSynchronization) {
|
|
1295
|
-
const targetVersion = `${this.targetDb.changeset.id};${this.targetDb.changeset.index}`;
|
|
1296
1331
|
this._targetScopeProvenanceProps.version = sourceVersion;
|
|
1297
1332
|
this._targetScopeProvenanceProps.jsonProperties.reverseSyncVersion = targetVersion;
|
|
1298
1333
|
}
|
|
@@ -1306,7 +1341,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1306
1341
|
this._targetScopeProvenanceProps.version = sourceVersion;
|
|
1307
1342
|
}
|
|
1308
1343
|
if (this._isSynchronization) {
|
|
1309
|
-
(0, core_bentley_1.assert)(this.targetDb.changeset.index !== undefined && this.
|
|
1344
|
+
(0, core_bentley_1.assert)(this.targetDb.changeset.index !== undefined && this._startingChangesetIndices !== undefined, "updateSynchronizationVersion was called without change history");
|
|
1310
1345
|
const jsonProps = this._targetScopeProvenanceProps.jsonProperties;
|
|
1311
1346
|
core_bentley_1.Logger.logTrace(loggerCategory, `previous pendingReverseSyncChanges: ${jsonProps.pendingReverseSyncChangesetIndices}`);
|
|
1312
1347
|
core_bentley_1.Logger.logTrace(loggerCategory, `previous pendingSyncChanges: ${jsonProps.pendingSyncChangesetIndices}`);
|
|
@@ -1318,9 +1353,15 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1318
1353
|
// just marked this changeset as a synchronization to ignore, and the user can add other
|
|
1319
1354
|
// stuff to it which would break future synchronizations
|
|
1320
1355
|
// FIXME: force save for the user to prevent that
|
|
1321
|
-
for (let i = this.
|
|
1356
|
+
for (let i = this._startingChangesetIndices.target + 1; i <= this.targetDb.changeset.index + 1; i++)
|
|
1322
1357
|
syncChangesetsToUpdate.push(i);
|
|
1323
1358
|
syncChangesetsToClear.length = 0;
|
|
1359
|
+
// if reverse sync then we may have received provenance changes which should be marked as sync changes
|
|
1360
|
+
if (this._isReverseSynchronization) {
|
|
1361
|
+
nodeAssert(this.sourceDb.changeset.index, "changeset didn't exist");
|
|
1362
|
+
for (let i = this._startingChangesetIndices.source + 1; i <= this.sourceDb.changeset.index + 1; i++)
|
|
1363
|
+
jsonProps.pendingReverseSyncChangesetIndices.push(i);
|
|
1364
|
+
}
|
|
1324
1365
|
core_bentley_1.Logger.logTrace(loggerCategory, `new pendingReverseSyncChanges: ${jsonProps.pendingReverseSyncChangesetIndices}`);
|
|
1325
1366
|
core_bentley_1.Logger.logTrace(loggerCategory, `new pendingSyncChanges: ${jsonProps.pendingSyncChangesetIndices}`);
|
|
1326
1367
|
}
|
|
@@ -1331,7 +1372,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1331
1372
|
}
|
|
1332
1373
|
// FIXME: is this necessary when manually using lowlevel transform APIs?
|
|
1333
1374
|
finalizeTransformation() {
|
|
1334
|
-
this.
|
|
1375
|
+
this.updateSynchronizationVersion();
|
|
1335
1376
|
if (this._partiallyCommittedEntities.size > 0) {
|
|
1336
1377
|
core_bentley_1.Logger.logWarning(loggerCategory, [
|
|
1337
1378
|
"The following elements were never fully resolved:",
|
|
@@ -1662,7 +1703,6 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1662
1703
|
})
|
|
1663
1704
|
.then((changeset) => changeset.index)));
|
|
1664
1705
|
const missingChangesets = startChangesetIndex > this._synchronizationVersion.index + 1;
|
|
1665
|
-
// FIXME: add an option to ignore this check
|
|
1666
1706
|
if (!this._options.ignoreMissingChangesetsInSynchronizations
|
|
1667
1707
|
&& startChangesetIndex !== this._synchronizationVersion.index + 1
|
|
1668
1708
|
&& this._synchronizationVersion.index !== -1) {
|
|
@@ -1920,17 +1960,17 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
|
|
|
1920
1960
|
}
|
|
1921
1961
|
async processChanges(optionsOrAccessToken, startChangesetId) {
|
|
1922
1962
|
this._isSynchronization = true;
|
|
1963
|
+
// FIXME: we used to validateScopeProvenance... does initing it cover that?
|
|
1964
|
+
this.initScopeProvenance();
|
|
1923
1965
|
const args = typeof optionsOrAccessToken === "string"
|
|
1924
1966
|
? {
|
|
1925
1967
|
accessToken: optionsOrAccessToken,
|
|
1926
1968
|
startChangeset: startChangesetId
|
|
1927
1969
|
? { id: startChangesetId }
|
|
1928
|
-
: this.
|
|
1970
|
+
: { index: this._synchronizationVersion.index + 1 },
|
|
1929
1971
|
}
|
|
1930
1972
|
: optionsOrAccessToken;
|
|
1931
1973
|
this.logSettings();
|
|
1932
|
-
// FIXME: we used to validateScopeProvenance... does initing it cover that?
|
|
1933
|
-
this.initScopeProvenance();
|
|
1934
1974
|
await this.initialize(args);
|
|
1935
1975
|
// must wait for initialization of synchronization provenance data
|
|
1936
1976
|
await this.exporter.exportChanges(this.getExportInitOpts(args));
|