@itwin/imodel-transformer 2.0.0-dev.6 → 2.0.0-dev.8

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.
@@ -110,7 +110,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
110
110
  * @param dbToQuery db to run the query on for scope external source
111
111
  * @param aspectProps aspectProps to search for @see ExternalSourceAspectProps
112
112
  */
113
- static queryScopeExternalSourceAspect(dbToQuery, aspectProps) {
113
+ static async queryScopeExternalSourceAspect(dbToQuery, aspectProps) {
114
114
  const sql = `
115
115
  SELECT ECInstanceId, Version, JsonProperties
116
116
  FROM ${core_backend_1.ExternalSourceAspect.classFullName}
@@ -121,25 +121,19 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
121
121
  LIMIT 1
122
122
  `;
123
123
  // if (aspectProps.scope === undefined) return undefined;
124
- // const params = new QueryBinder().bindId("elementId", aspectProps.element.id);
124
+ // const params = new QueryBinder();
125
+ // params.bindId("elementId", aspectProps.element.id);
125
126
  // params.bindId("scopeId", aspectProps.scope.id);
126
127
  // params.bindString("kind", aspectProps.kind);
127
128
  // params.bindString("identifier", aspectProps.identifier);
128
- // const result = await dbToQuery.createQueryReader(sql);
129
- // if (result) {
130
- // const aspectId = result.current.id;
131
- // const versionValue = result.current[1];
132
- // const version = versionValue.isNull
133
- // ? undefined
134
- // : versionValue.getString();
135
- // const jsonPropsValue = result.current[2];
136
- // const jsonProperties = jsonPropsValue.isNull
137
- // ? undefined
138
- // : jsonPropsValue.getString();
129
+ // const reader = dbToQuery.createQueryReader(sql, params, {usePrimaryConn: true});
130
+ // if (await reader.step()) {
131
+ // const aspectId = reader.current.id;
132
+ // const version = reader.current.version as string | undefined;
133
+ // const jsonProperties = reader.current.jsonProperties as string | undefined;
139
134
  // return { aspectId, version, jsonProperties };
140
135
  // }
141
- // else
142
- // return undefined;
136
+ // return undefined;
143
137
  // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
144
138
  return dbToQuery.withPreparedStatement(sql, (statement) => {
145
139
  statement.bindId("elementId", aspectProps.element.id);
@@ -169,7 +163,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
169
163
  * @throws if no scoping ESA can be found in either the sourceDb or targetDb which describes a master branch relationship between the two databases.
170
164
  * @returns "forward" or "reverse"
171
165
  */
172
- static determineSyncType(sourceDb, targetDb,
166
+ static async determineSyncType(sourceDb, targetDb,
173
167
  /** @see [[IModelTransformOptions.targetScopeElementId]] */
174
168
  targetScopeElementId) {
175
169
  const aspectProps = {
@@ -186,19 +180,19 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
186
180
  jsonProperties: undefined,
187
181
  };
188
182
  /** First check if the targetDb is the branch (branch is the @see provenanceDb) */
189
- const esaPropsFromTargetDb = this.queryScopeExternalSourceAspect(targetDb, aspectProps);
183
+ const esaPropsFromTargetDb = await this.queryScopeExternalSourceAspect(targetDb, aspectProps);
190
184
  if (esaPropsFromTargetDb !== undefined) {
191
185
  return "forward"; // we found an esa assuming targetDb is the provenanceDb/branch so this is a forward sync.
192
186
  }
193
187
  // Now check if the sourceDb is the branch
194
188
  aspectProps.identifier = targetDb.iModelId;
195
- const esaPropsFromSourceDb = this.queryScopeExternalSourceAspect(sourceDb, aspectProps);
189
+ const esaPropsFromSourceDb = await this.queryScopeExternalSourceAspect(sourceDb, aspectProps);
196
190
  if (esaPropsFromSourceDb !== undefined) {
197
191
  return "reverse"; // we found an esa assuming sourceDb is the provenanceDb/branch so this is a reverse sync.
198
192
  }
199
193
  throw new Error(this.noEsaSyncDirectionErrorMessage);
200
194
  }
201
- determineSyncType() {
195
+ async determineSyncType() {
202
196
  if (this._isProvenanceInitTransform) {
203
197
  return "forward";
204
198
  }
@@ -206,7 +200,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
206
200
  return "not-sync";
207
201
  }
208
202
  try {
209
- return IModelTransformer.determineSyncType(this.sourceDb, this.targetDb, this.targetScopeElementId);
203
+ return await IModelTransformer.determineSyncType(this.sourceDb, this.targetDb, this.targetScopeElementId);
210
204
  }
211
205
  catch (err) {
212
206
  if (err instanceof Error &&
@@ -217,14 +211,14 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
217
211
  throw err;
218
212
  }
219
213
  }
220
- get isReverseSynchronization() {
214
+ async getIsReverseSynchronization() {
221
215
  if (this._syncType === undefined)
222
- this._syncType = this.determineSyncType();
216
+ this._syncType = await this.determineSyncType();
223
217
  return this._syncType === "reverse";
224
218
  }
225
- get isForwardSynchronization() {
219
+ async getIsForwardSynchronization() {
226
220
  if (this._syncType === undefined)
227
- this._syncType = this.determineSyncType();
221
+ this._syncType = await this.determineSyncType();
228
222
  return this._syncType === "forward";
229
223
  }
230
224
  _changesetRanges = undefined;
@@ -371,14 +365,18 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
371
365
  /** Return the IModelDb where IModelTransformer will store its provenance.
372
366
  * @note This will be [[targetDb]] except when it is a reverse synchronization. In that case it be [[sourceDb]].
373
367
  */
374
- get provenanceDb() {
375
- return this.isReverseSynchronization ? this.sourceDb : this.targetDb;
368
+ async getProvenanceDb() {
369
+ return (await this.getIsReverseSynchronization())
370
+ ? this.sourceDb
371
+ : this.targetDb;
376
372
  }
377
373
  /** Return the IModelDb where IModelTransformer looks for entities referred to by stored provenance.
378
374
  * @note This will be [[sourceDb]] except when it is a reverse synchronization. In that case it be [[targetDb]].
379
375
  */
380
- get provenanceSourceDb() {
381
- return this.isReverseSynchronization ? this.targetDb : this.sourceDb;
376
+ async getProvenanceSourceDb() {
377
+ return (await this.getIsReverseSynchronization())
378
+ ? this.targetDb
379
+ : this.sourceDb;
382
380
  }
383
381
  /** Create an ExternalSourceAspectProps in a standard way for an Element in an iModel --> iModel transformation. */
384
382
  static initElementProvenanceOptions(sourceElementId, targetElementId, args) {
@@ -445,9 +443,9 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
445
443
  */
446
444
  _forceOldRelationshipProvenanceMethod = false;
447
445
  /** Create an ExternalSourceAspectProps in a standard way for an Element in an iModel --> iModel transformation. */
448
- initElementProvenance(sourceElementId, targetElementId) {
446
+ async initElementProvenance(sourceElementId, targetElementId) {
449
447
  return IModelTransformer.initElementProvenanceOptions(sourceElementId, targetElementId, {
450
- isReverseSynchronization: this.isReverseSynchronization,
448
+ isReverseSynchronization: await this.getIsReverseSynchronization(),
451
449
  targetScopeElementId: this.targetScopeElementId,
452
450
  sourceDb: this.sourceDb,
453
451
  targetDb: this.targetDb,
@@ -459,10 +457,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
459
457
  * The ECInstanceId of the relationship in the branch iModel will be stored in the JsonProperties of the ExternalSourceAspect.
460
458
  */
461
459
  async initRelationshipProvenance(sourceRelationship, targetRelInstanceId) {
462
- return await IModelTransformer.initRelationshipProvenanceOptions(sourceRelationship.id, targetRelInstanceId, {
460
+ return IModelTransformer.initRelationshipProvenanceOptions(sourceRelationship.id, targetRelInstanceId, {
463
461
  sourceDb: this.sourceDb,
464
462
  targetDb: this.targetDb,
465
- isReverseSynchronization: this.isReverseSynchronization,
463
+ isReverseSynchronization: await this.getIsReverseSynchronization(),
466
464
  targetScopeElementId: this.targetScopeElementId,
467
465
  forceOldRelationshipProvenanceMethod: this._forceOldRelationshipProvenanceMethod,
468
466
  });
@@ -490,13 +488,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
490
488
  * @note empty string and -1 for changeset and index if it was transformed before federation guid update (pre 1.x) and @see [[IModelTransformOptions.branchRelationshipDataBehavior]] === "unsafe-migrate".
491
489
  * @throws if the version is not found in a preexisting scope aspect and @see [[IModelTransformOptions.branchRelationshipDataBehavior]] !== "unsafe-migrate"
492
490
  */
493
- get synchronizationVersion() {
491
+ async getSynchronizationVersion() {
494
492
  if (this._cachedSynchronizationVersion === undefined) {
495
- const provenanceScopeAspect = this.tryGetProvenanceScopeAspect();
493
+ const provenanceScopeAspect = await this.tryGetProvenanceScopeAspect();
496
494
  if (!provenanceScopeAspect) {
497
495
  return { index: -1, id: "" }; // first synchronization.
498
496
  }
499
- const version = this.isReverseSynchronization
497
+ const version = (await this.getIsReverseSynchronization())
500
498
  ? JSON.parse(provenanceScopeAspect.jsonProperties ?? "{}").reverseSyncVersion
501
499
  : provenanceScopeAspect.version;
502
500
  if (!version &&
@@ -518,17 +516,17 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
518
516
  * @returns provenance scope aspect if it exists in the provenanceDb.
519
517
  * Provenance scope aspect is created and inserted into provenanceDb when [[initScopeProvenance]] is invoked.
520
518
  */
521
- tryGetProvenanceScopeAspect() {
522
- const scopeProvenanceAspectProps = IModelTransformer.queryScopeExternalSourceAspect(this.provenanceDb, {
519
+ async tryGetProvenanceScopeAspect() {
520
+ const scopeProvenanceAspectProps = await IModelTransformer.queryScopeExternalSourceAspect(await this.getProvenanceDb(), {
523
521
  id: undefined,
524
522
  classFullName: core_backend_1.ExternalSourceAspect.classFullName,
525
523
  scope: { id: core_common_1.IModel.rootSubjectId },
526
524
  kind: core_backend_1.ExternalSourceAspect.Kind.Scope,
527
525
  element: { id: this.targetScopeElementId ?? core_common_1.IModel.rootSubjectId },
528
- identifier: this.provenanceSourceDb.iModelId,
526
+ identifier: (await this.getProvenanceSourceDb()).iModelId,
529
527
  });
530
528
  return scopeProvenanceAspectProps !== undefined
531
- ? this.provenanceDb.elements.getAspect(scopeProvenanceAspectProps.aspectId)
529
+ ? (await this.getProvenanceDb()).elements.getAspect(scopeProvenanceAspectProps.aspectId)
532
530
  : undefined;
533
531
  }
534
532
  /**
@@ -538,6 +536,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
538
536
  * if this was a [BriefcaseDb]($backend)
539
537
  */
540
538
  async initScopeProvenance() {
539
+ const provenanceDb = await this.getProvenanceDb();
540
+ const sourceProvenanceDb = await this.getProvenanceSourceDb();
541
541
  const aspectProps = {
542
542
  id: undefined,
543
543
  version: undefined,
@@ -547,11 +547,11 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
547
547
  relClassName: core_backend_1.ElementOwnsExternalSourceAspects.classFullName,
548
548
  },
549
549
  scope: { id: core_common_1.IModel.rootSubjectId }, // the root Subject scopes scope elements
550
- identifier: this.provenanceSourceDb.iModelId,
550
+ identifier: sourceProvenanceDb.iModelId,
551
551
  kind: core_backend_1.ExternalSourceAspect.Kind.Scope,
552
552
  jsonProperties: undefined,
553
553
  };
554
- const foundEsaProps = IModelTransformer.queryScopeExternalSourceAspect(this.provenanceDb, aspectProps); // this query includes "identifier"
554
+ const foundEsaProps = await IModelTransformer.queryScopeExternalSourceAspect(provenanceDb, aspectProps); // this query includes "identifier"
555
555
  if (foundEsaProps === undefined) {
556
556
  aspectProps.version = ""; // empty since never before transformed. Will be updated in [[finalizeTransformation]]
557
557
  aspectProps.jsonProperties = {
@@ -572,7 +572,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
572
572
  params.bindId("elementId", aspectProps.element.id);
573
573
  params.bindId("scopeId", aspectProps.scope.id); // this scope.id can never be invalid, we create it above
574
574
  params.bindString("kind", aspectProps.kind);
575
- const reader = this.provenanceDb.createQueryReader(sql, params, {
575
+ const reader = provenanceDb.createQueryReader(sql, params, {
576
576
  usePrimaryConn: true,
577
577
  });
578
578
  const hasConflictingScope = await reader.step();
@@ -580,7 +580,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
580
580
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.InvalidId, "Provenance scope conflict");
581
581
  }
582
582
  if (!this._options.noProvenance) {
583
- const id = this.provenanceDb.elements.insertAspect({
583
+ const id = provenanceDb.elements.insertAspect({
584
584
  ...aspectProps,
585
585
  jsonProperties: JSON.stringify(aspectProps.jsonProperties),
586
586
  });
@@ -600,7 +600,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
600
600
  const oldProps = JSON.parse(JSON.stringify(aspectProps));
601
601
  if (this.handleUnsafeMigrate(aspectProps)) {
602
602
  core_bentley_1.Logger.logInfo(loggerCategory, "Unsafe migrate made a change to the target scope's external source aspect. Updating aspect in database.", { oldProps, newProps: aspectProps });
603
- this.provenanceDb.elements.updateAspect({
603
+ provenanceDb.elements.updateAspect({
604
604
  ...aspectProps,
605
605
  jsonProperties: JSON.stringify(aspectProps.jsonProperties),
606
606
  });
@@ -692,8 +692,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
692
692
  // NOTE: if we exposed the native attach database support,
693
693
  // we could get the intersection of fed guids in one query, not sure if it would be faster
694
694
  // OR we could do a raw sqlite query...
695
- const sourceReader = sourceDb.createQueryReader(elementIdByFedGuidQuery);
696
- const targetReader = targetDb.createQueryReader(elementIdByFedGuidQuery);
695
+ const sourceReader = sourceDb.createQueryReader(elementIdByFedGuidQuery, undefined, { usePrimaryConn: true });
696
+ const targetReader = targetDb.createQueryReader(elementIdByFedGuidQuery, undefined, { usePrimaryConn: true });
697
697
  let hasSourceRow = await sourceReader.step();
698
698
  let hasTargetRow = await targetReader.step();
699
699
  while (hasSourceRow && hasTargetRow) {
@@ -730,7 +730,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
730
730
  const params = new core_common_1.QueryBinder();
731
731
  params.bindId("scopeId", args.targetScopeElementId);
732
732
  params.bindString("kind", core_backend_1.ExternalSourceAspect.Kind.Element);
733
- const provenanceReader = args.provenanceDb.createQueryReader(provenanceAspectsQuery, params);
733
+ const provenanceReader = args.provenanceDb.createQueryReader(provenanceAspectsQuery, params, { usePrimaryConn: true });
734
734
  for await (const row of provenanceReader) {
735
735
  // ExternalSourceAspect.Identifier is of type string
736
736
  const aspectIdentifier = row[0];
@@ -739,11 +739,11 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
739
739
  }
740
740
  }
741
741
  async forEachTrackedElement(fn) {
742
- return await IModelTransformer.forEachTrackedElement({
743
- provenanceSourceDb: this.provenanceSourceDb,
744
- provenanceDb: this.provenanceDb,
742
+ return IModelTransformer.forEachTrackedElement({
743
+ provenanceSourceDb: await this.getProvenanceSourceDb(),
744
+ provenanceDb: await this.getProvenanceDb(),
745
745
  targetScopeElementId: this.targetScopeElementId,
746
- isReverseSynchronization: this.isReverseSynchronization,
746
+ isReverseSynchronization: await this.getIsReverseSynchronization(),
747
747
  fn,
748
748
  skipPropagateChangesToRootElements: this._options.skipPropagateChangesToRootElements ?? true,
749
749
  });
@@ -756,7 +756,6 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
756
756
  * @returns the elementId that the ESA is stored on, esa.Element.Id
757
757
  */
758
758
  async _queryProvenanceForElement(entityInProvenanceSourceId) {
759
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
760
759
  const sql = `
761
760
  SELECT esa.Element.Id
762
761
  FROM Bis.ExternalSourceAspect esa
@@ -768,7 +767,9 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
768
767
  params.bindString(1, core_backend_1.ExternalSourceAspect.Kind.Element);
769
768
  params.bindId(2, this.targetScopeElementId);
770
769
  params.bindString(3, entityInProvenanceSourceId);
771
- const result = this.provenanceDb.createQueryReader(sql, params);
770
+ const result = (await this.getProvenanceDb()).createQueryReader(sql, params, {
771
+ usePrimaryConn: true,
772
+ });
772
773
  if (await result.step()) {
773
774
  return result.current.id;
774
775
  }
@@ -796,7 +797,9 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
796
797
  params.bindString(1, core_backend_1.ExternalSourceAspect.Kind.Relationship);
797
798
  params.bindId(2, this.targetScopeElementId);
798
799
  params.bindString(3, entityInProvenanceSourceId);
799
- const result = this.provenanceDb.createQueryReader(sql, params);
800
+ const result = (await this.getProvenanceDb()).createQueryReader(sql, params, {
801
+ usePrimaryConn: true,
802
+ });
800
803
  if (await result.step()) {
801
804
  const aspectId = result.current.id;
802
805
  const provenanceRelInstId = result.current.provenanceRelInstId;
@@ -830,7 +833,9 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
830
833
  params.bindId(1, targetRelInfo.sourceId);
831
834
  params.bindId(2, targetRelInfo.targetId);
832
835
  params.bindId(3, await this._targetClassNameToClassId(sourceRelInfo.classFullName));
833
- const result = this.targetDb.createQueryReader(sql, params);
836
+ const result = this.targetDb.createQueryReader(sql, params, {
837
+ usePrimaryConn: true,
838
+ });
834
839
  if (await result.step())
835
840
  return result.current.id;
836
841
  else
@@ -860,21 +865,11 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
860
865
  : classFullName.split(":");
861
866
  params.bindString(1, schemaName);
862
867
  params.bindString(2, className);
863
- const result = db.createQueryReader(sql, params);
868
+ const result = db.createQueryReader(sql, params, { usePrimaryConn: true });
864
869
  if (await result.step())
865
870
  return result.current.id;
866
871
  (0, core_bentley_1.assert)(false, "relationship was not found");
867
872
  }
868
- // Deprecate?
869
- async _queryElemIdByFedGuid(db, fedGuid) {
870
- const sql = "SELECT ECInstanceId FROM Bis.Element WHERE FederationGuid=:fedGuid";
871
- const params = new core_common_1.QueryBinder().bindString("fedGuid", fedGuid);
872
- const reader = db.createQueryReader(sql, params);
873
- if (await reader.step()) {
874
- return reader.current.ecinstanceid;
875
- }
876
- return undefined;
877
- }
878
873
  /** Returns `true` if *brute force* delete detections should be run.
879
874
  * @note This is only called if [[IModelTransformOptions.forceExternalSourceAspectProvenance]] option is true
880
875
  * @note Not relevant for [[process]] when [[IModelTransformOptions.argsForProcessChanges]] are provided and change history is known.
@@ -883,44 +878,6 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
883
878
  nodeAssert(this._syncType !== undefined);
884
879
  return this._syncType === "not-sync";
885
880
  }
886
- /**
887
- * Detect Element deletes using ExternalSourceAspects in the target iModel and a *brute force* comparison against Elements
888
- * in the source iModel.
889
- * @deprecated in 1.x. Do not use this. // FIXME<MIKE>: how to better explain this?
890
- * This method is only called during [[process]] when [[IModelTransformOptions.argsForProcessChanges]] is undefined and the option
891
- * [[IModelTransformOptions.forceExternalSourceAspectProvenance]] is enabled. It is not
892
- * necessary when calling [[process]] with [[IModelTransformOptions.argsForProcessChanges]] defined, since changeset information is sufficient.
893
- * @note you do not need to call this directly unless processing a subset of an iModel.
894
- * @throws [[IModelError]] If the required provenance information is not available to detect deletes.
895
- */
896
- async detectElementDeletes() {
897
- const sql = `
898
- SELECT Identifier, Element.Id
899
- FROM BisCore.ExternalSourceAspect
900
- WHERE Scope.Id=:scopeId
901
- AND Kind=:kind
902
- `;
903
- nodeAssert(!this.isReverseSynchronization, "synchronizations with processChanges already detect element deletes, don't call detectElementDeletes");
904
- // Reported issue: https://github.com/iTwin/itwinjs-core/issues/7989
905
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
906
- this.provenanceDb.withPreparedStatement(sql, (stmt) => {
907
- stmt.bindId("scopeId", this.targetScopeElementId);
908
- stmt.bindString("kind", core_backend_1.ExternalSourceAspect.Kind.Element);
909
- while (core_bentley_1.DbResult.BE_SQLITE_ROW === stmt.step()) {
910
- // ExternalSourceAspect.Identifier is of type string
911
- const aspectIdentifier = stmt.getValue(0).getString();
912
- if (!core_bentley_1.Id64.isValidId64(aspectIdentifier)) {
913
- continue;
914
- }
915
- const targetElemId = stmt.getValue(1).getId();
916
- const wasDeletedInSource = !EntityUnifier_1.EntityUnifier.exists(this.sourceDb, {
917
- entityReference: `e${aspectIdentifier}`,
918
- });
919
- if (wasDeletedInSource)
920
- this.importer.deleteElement(targetElemId);
921
- }
922
- });
923
- }
924
881
  /** Transform the specified sourceElement into ElementProps for the target iModel.
925
882
  * @param sourceElement The Element from the source iModel to transform.
926
883
  * @returns ElementProps for the target iModel.
@@ -929,7 +886,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
929
886
  */
930
887
  async onTransformElement(sourceElement) {
931
888
  core_bentley_1.Logger.logTrace(loggerCategory, `onTransformElement(${sourceElement.id}) "${sourceElement.getDisplayLabel()}"`);
932
- const targetElementProps = this.context.cloneElement(sourceElement, { binaryGeometry: this._options.cloneUsingBinaryGeometry });
889
+ const targetElementProps = await this.context.cloneElement(sourceElement, { binaryGeometry: this._options.cloneUsingBinaryGeometry });
933
890
  // Special case: source element is the root subject
934
891
  if (sourceElement.id === core_common_1.IModel.rootSubjectId) {
935
892
  const targetElementId = this.context.findTargetElementId(sourceElement.id);
@@ -1090,13 +1047,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1090
1047
  allReferencesExist = false;
1091
1048
  }
1092
1049
  if (this._options.danglingReferencesBehavior === "reject") {
1093
- this.assertReferenceExistsInSource(referenceId, entity);
1050
+ await this.assertReferenceExistsInSource(referenceId, entity);
1094
1051
  }
1095
1052
  }
1096
1053
  return allReferencesExist;
1097
1054
  }
1098
- assertReferenceExistsInSource(referenceId, entity) {
1099
- const referencedExistsInSource = EntityUnifier_1.EntityUnifier.exists(this.sourceDb, {
1055
+ async assertReferenceExistsInSource(referenceId, entity) {
1056
+ const referencedExistsInSource = await EntityUnifier_1.EntityUnifier.exists(this.sourceDb, {
1100
1057
  entityReference: referenceId,
1101
1058
  });
1102
1059
  if (!referencedExistsInSource) {
@@ -1176,7 +1133,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1176
1133
  .flat();
1177
1134
  if (unresolvedReferences.length > 0) {
1178
1135
  for (const reference of unresolvedReferences) {
1179
- const processState = this.getElemTransformState(reference);
1136
+ const processState = await this.getElemTransformState(reference);
1180
1137
  // must export element first
1181
1138
  if (processState.needsElemImport)
1182
1139
  await this.exporter.exportElement(reference);
@@ -1185,16 +1142,16 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1185
1142
  }
1186
1143
  }
1187
1144
  }
1188
- getElemTransformState(elementId) {
1189
- const dbHasModel = (db, id) => {
1145
+ async getElemTransformState(elementId) {
1146
+ const dbHasModel = async (db, id) => {
1190
1147
  const maybeModelId = core_backend_1.EntityReferences.fromEntityType(id, core_common_1.ConcreteEntityTypes.Model);
1191
1148
  return EntityUnifier_1.EntityUnifier.exists(db, { entityReference: maybeModelId });
1192
1149
  };
1193
- const isSubModeled = dbHasModel(this.sourceDb, elementId);
1150
+ const isSubModeled = await dbHasModel(this.sourceDb, elementId);
1194
1151
  const idOfElemInTarget = this.context.findTargetElementId(elementId);
1195
1152
  const isElemInTarget = core_bentley_1.Id64.invalid !== idOfElemInTarget;
1196
1153
  const needsModelImport = isSubModeled &&
1197
- (!isElemInTarget || !dbHasModel(this.targetDb, idOfElemInTarget));
1154
+ (!isElemInTarget || !(await dbHasModel(this.targetDb, idOfElemInTarget)));
1198
1155
  return { needsElemImport: !isElemInTarget, needsModelImport };
1199
1156
  }
1200
1157
  /** Override of [IModelExportHandler.onExportElement]($transformer) that imports an element into the target iModel when it is exported from the source iModel.
@@ -1288,20 +1245,21 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1288
1245
  // physical consolidation is an example of a 'joining' transform
1289
1246
  // FIXME: verify at finalization time that we don't lose provenance on new elements
1290
1247
  // FIXME: make public and improve `initElementProvenance` API for usage by consolidators
1248
+ const provenanceDb = await this.getProvenanceDb();
1291
1249
  if (!this._options.noProvenance) {
1292
1250
  let provenance = this._options.forceExternalSourceAspectProvenance ||
1293
1251
  this._elementsWithExplicitlyTrackedProvenance.has(sourceElement.id)
1294
1252
  ? undefined
1295
1253
  : sourceElement.federationGuid;
1296
1254
  if (!provenance) {
1297
- const aspectProps = this.initElementProvenance(sourceElement.id, targetElementProps.id);
1298
- const foundEsaProps = IModelTransformer.queryScopeExternalSourceAspect(this.provenanceDb, aspectProps);
1255
+ const aspectProps = await this.initElementProvenance(sourceElement.id, targetElementProps.id);
1256
+ const foundEsaProps = await IModelTransformer.queryScopeExternalSourceAspect(provenanceDb, aspectProps);
1299
1257
  if (foundEsaProps === undefined)
1300
- aspectProps.id = this.provenanceDb.elements.insertAspect(aspectProps);
1258
+ aspectProps.id = provenanceDb.elements.insertAspect(aspectProps);
1301
1259
  else {
1302
1260
  // Since initElementProvenance sets a property 'version' on the aspectProps that we wish to persist in the provenanceDb, only grab the id from the foundEsaProps.
1303
1261
  aspectProps.id = foundEsaProps.aspectId;
1304
- this.provenanceDb.elements.updateAspect(aspectProps);
1262
+ provenanceDb.elements.updateAspect(aspectProps);
1305
1263
  }
1306
1264
  provenance = aspectProps;
1307
1265
  }
@@ -1352,7 +1310,9 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1352
1310
  `;
1353
1311
  if (this.exporter.sourceDbChanges?.element.deleteIds.has(sourceModelId)) {
1354
1312
  const params = new core_common_1.QueryBinder().bindId("targetModelId", targetModelId);
1355
- const reader = this.targetDb.createQueryReader(sql, params);
1313
+ const reader = this.targetDb.createQueryReader(sql, params, {
1314
+ usePrimaryConn: true,
1315
+ });
1356
1316
  const isDefinitionPartition = await reader.step();
1357
1317
  if (isDefinitionPartition) {
1358
1318
  // Skipping model deletion because model's partition will also be deleted.
@@ -1410,12 +1370,12 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1410
1370
  // import DefinitionModels first
1411
1371
  const childDefinitionPartitionSql = `SELECT ECInstanceId FROM ${core_backend_1.DefinitionPartition.classFullName} WHERE Parent.Id=:subjectId`;
1412
1372
  const params = new core_common_1.QueryBinder().bindId("subjectId", sourceSubjectId);
1413
- for await (const row of this.sourceDb.createQueryReader(childDefinitionPartitionSql, params)) {
1373
+ for await (const row of this.sourceDb.createQueryReader(childDefinitionPartitionSql, params, { usePrimaryConn: true })) {
1414
1374
  await this.processModel(row.id);
1415
1375
  }
1416
1376
  // import other partitions next
1417
1377
  const childPartitionSql = `SELECT ECInstanceId FROM ${core_backend_1.InformationPartitionElement.classFullName} WHERE Parent.Id=:subjectId`;
1418
- for await (const row of this.sourceDb.createQueryReader(childPartitionSql, params)) {
1378
+ for await (const row of this.sourceDb.createQueryReader(childPartitionSql, params, { usePrimaryConn: true })) {
1419
1379
  const modelId = row.id;
1420
1380
  const model = this.sourceDb.models.getModel(modelId);
1421
1381
  if (!(model instanceof core_backend_1.DefinitionModel)) {
@@ -1424,7 +1384,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1424
1384
  }
1425
1385
  // recurse into child Subjects
1426
1386
  const childSubjectSql = `SELECT ECInstanceId FROM ${core_backend_1.Subject.classFullName} WHERE Parent.Id=:subjectId`;
1427
- for await (const row of this.sourceDb.createQueryReader(childSubjectSql, params)) {
1387
+ for await (const row of this.sourceDb.createQueryReader(childSubjectSql, params, { usePrimaryConn: true })) {
1428
1388
  await this.processSubjectSubModels(row.id);
1429
1389
  }
1430
1390
  }
@@ -1466,7 +1426,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1466
1426
  * Note that typically, the reverseSyncVersion is saved as the last changeset merged from the branch into master.
1467
1427
  * Setting initializeReverseSyncVersion to true during a forward transformation could overwrite this correct reverseSyncVersion and should only be done during the first transformation between a master and branch iModel.
1468
1428
  */
1469
- updateSynchronizationVersion({ initializeReverseSyncVersion = false, } = {}) {
1429
+ async updateSynchronizationVersion({ initializeReverseSyncVersion = false, } = {}) {
1470
1430
  const shouldSkipSyncVersionUpdate = !initializeReverseSyncVersion &&
1471
1431
  this._sourceChangeDataState !== "has-changes";
1472
1432
  if (shouldSkipSyncVersionUpdate)
@@ -1474,7 +1434,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1474
1434
  nodeAssert(this._targetScopeProvenanceProps);
1475
1435
  const sourceVersion = `${this.sourceDb.changeset.id};${this.sourceDb.changeset.index}`;
1476
1436
  const targetVersion = `${this.targetDb.changeset.id};${this.targetDb.changeset.index}`;
1477
- if (this.isReverseSynchronization) {
1437
+ if (await this.getIsReverseSynchronization()) {
1478
1438
  const oldVersion = this._targetScopeProvenanceProps.jsonProperties.reverseSyncVersion;
1479
1439
  core_bentley_1.Logger.logInfo(loggerCategory, `updating reverse version from ${oldVersion} to ${sourceVersion}`);
1480
1440
  this._targetScopeProvenanceProps.jsonProperties.reverseSyncVersion =
@@ -1504,7 +1464,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1504
1464
  // Determine which keys to clear and update based on the synchronization direction
1505
1465
  let syncChangesetsToClearKey;
1506
1466
  let syncChangesetsToUpdateKey;
1507
- if (this.isReverseSynchronization) {
1467
+ if (await this.getIsReverseSynchronization()) {
1508
1468
  syncChangesetsToClearKey = pendingReverseSyncChangesetIndicesKey;
1509
1469
  syncChangesetsToUpdateKey = pendingSyncChangesetIndicesKey;
1510
1470
  }
@@ -1523,7 +1483,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1523
1483
  return csIndex > startingChangesetIndices.source;
1524
1484
  });
1525
1485
  // if reverse sync then we may have received provenance changes which should be marked as sync changes
1526
- if (this.isReverseSynchronization) {
1486
+ if (await this.getIsReverseSynchronization()) {
1527
1487
  nodeAssert(this.sourceDb.changeset.index !== undefined, "changeset didn't exist");
1528
1488
  for (let i = startingChangesetIndices.source + 1; i <= this.sourceDb.changeset.index + 1; i++)
1529
1489
  jsonProps.pendingReverseSyncChangesetIndices.push(i);
@@ -1531,16 +1491,16 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1531
1491
  core_bentley_1.Logger.logTrace(loggerCategory, `new pendingReverseSyncChanges: ${jsonProps.pendingReverseSyncChangesetIndices}`);
1532
1492
  core_bentley_1.Logger.logTrace(loggerCategory, `new pendingSyncChanges: ${jsonProps.pendingSyncChangesetIndices}`);
1533
1493
  }
1534
- this.provenanceDb.elements.updateAspect({
1494
+ (await this.getProvenanceDb()).elements.updateAspect({
1535
1495
  ...this._targetScopeProvenanceProps,
1536
1496
  jsonProperties: JSON.stringify(this._targetScopeProvenanceProps.jsonProperties),
1537
1497
  });
1538
1498
  this.clearCachedSynchronizationVersion();
1539
1499
  }
1540
1500
  // FIXME<MIKE>: is this necessary when manually using low level transform APIs? (document if so)
1541
- finalizeTransformation() {
1501
+ async finalizeTransformation() {
1542
1502
  this.importer.finalize();
1543
- this.updateSynchronizationVersion({
1503
+ await this.updateSynchronizationVersion({
1544
1504
  initializeReverseSyncVersion: this._isProvenanceInitTransform,
1545
1505
  });
1546
1506
  // TODO: ignore if we remove change cache usage
@@ -1578,6 +1538,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1578
1538
  const targetFedGuid = this.sourceDb.elements.getFederationGuidFromId(sourceRelationship.targetId);
1579
1539
  const targetRelationshipProps = this.onTransformRelationship(sourceRelationship);
1580
1540
  const targetRelationshipInstanceId = this.importer.importRelationship(targetRelationshipProps);
1541
+ const provenanceDb = await this.getProvenanceDb();
1581
1542
  if (!this._options.noProvenance &&
1582
1543
  core_bentley_1.Id64.isValid(targetRelationshipInstanceId)) {
1583
1544
  let provenance = !this._options.forceExternalSourceAspectProvenance
@@ -1585,10 +1546,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1585
1546
  : undefined;
1586
1547
  if (!provenance) {
1587
1548
  const aspectProps = await this.initRelationshipProvenance(sourceRelationship, targetRelationshipInstanceId);
1588
- const foundEsaProps = IModelTransformer.queryScopeExternalSourceAspect(this.provenanceDb, aspectProps);
1549
+ const foundEsaProps = await IModelTransformer.queryScopeExternalSourceAspect(provenanceDb, aspectProps);
1589
1550
  // onExportRelationship doesn't need to call updateAspect if esaProps were found, because relationship provenance doesn't have the same concept of a version as element provenance (which uses last mod time on the elements).
1590
1551
  if (undefined === foundEsaProps) {
1591
- aspectProps.id = this.provenanceDb.elements.insertAspect(aspectProps);
1552
+ aspectProps.id = provenanceDb.elements.insertAspect(aspectProps);
1592
1553
  }
1593
1554
  provenance = aspectProps;
1594
1555
  }
@@ -1598,7 +1559,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1598
1559
  /** Override of [IModelExportHandler.onDeleteRelationship]($transformer) that is called when [IModelExporter]($transformer) detects that a [Relationship]($backend) has been deleted from the source iModel.
1599
1560
  * This override propagates the delete to the target iModel via [IModelImporter.deleteRelationship]($transformer).
1600
1561
  */
1601
- onDeleteRelationship(sourceRelInstanceId) {
1562
+ async onDeleteRelationship(sourceRelInstanceId) {
1602
1563
  nodeAssert(this._deletedSourceRelationshipData, "should be defined at initialization by now");
1603
1564
  const deletedRelData = this._deletedSourceRelationshipData.get(sourceRelInstanceId);
1604
1565
  if (!deletedRelData) {
@@ -1619,7 +1580,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1619
1580
  }
1620
1581
  if (deletedRelData.provenanceAspectId) {
1621
1582
  try {
1622
- this.provenanceDb.elements.deleteAspect(deletedRelData.provenanceAspectId);
1583
+ (await this.getProvenanceDb()).elements.deleteAspect(deletedRelData.provenanceAspectId);
1623
1584
  }
1624
1585
  catch (error) {
1625
1586
  // This aspect may no longer exist if it was deleted at some other point during the transformation. This is fine.
@@ -1630,46 +1591,6 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1630
1591
  }
1631
1592
  }
1632
1593
  _yieldManager = new core_bentley_1.YieldManager();
1633
- /** Detect Relationship deletes using ExternalSourceAspects in the target iModel and a *brute force* comparison against relationships in the source iModel.
1634
- * @deprecated in 1.x. Don't use this anymore
1635
- * @see [[process]] with [[IModelTransformOptions.argsForProcessChanges]] provided.
1636
- * @note This method is called from [[process]] when [[IModelTransformOptions.argsForProcessChanges]] are undefined, so it only needs to be called directly when processing a subset of an iModel.
1637
- * @throws [[IModelError]] If the required provenance information is not available to detect deletes.
1638
- */
1639
- async detectRelationshipDeletes() {
1640
- if (this.isReverseSynchronization) {
1641
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot detect deletes when isReverseSynchronization=true");
1642
- }
1643
- const aspectDeleteIds = [];
1644
- const sql = `
1645
- SELECT ECInstanceId, Identifier, JsonProperties
1646
- FROM ${core_backend_1.ExternalSourceAspect.classFullName} aspect
1647
- WHERE aspect.Scope.Id=:scopeId
1648
- AND aspect.Kind=:kind
1649
- `;
1650
- const params = new core_common_1.QueryBinder().bindId("scopeId", this.targetScopeElementId);
1651
- params.bindString("kind", core_backend_1.ExternalSourceAspect.Kind.Relationship);
1652
- for await (const row of this.targetDb.createQueryReader(sql, params)) {
1653
- const sourceRelInstanceId = core_bentley_1.Id64.fromJSON(row[1]);
1654
- if (undefined ===
1655
- this.sourceDb.relationships.tryGetInstanceProps(core_backend_1.ElementRefersToElements.classFullName, sourceRelInstanceId)) {
1656
- // this function exists only to support some in-imodel transformations, which must
1657
- // use the old (external source aspect) provenance method anyway so we don't need to support
1658
- // new provenance
1659
- const json = JSON.parse(row[2]);
1660
- const targetRelInstanceId = json.targetRelInstanceId ?? json.provenanceRelInstanceId;
1661
- if (targetRelInstanceId) {
1662
- this.importer.deleteRelationship({
1663
- id: targetRelInstanceId,
1664
- classFullName: core_backend_1.ElementRefersToElements.classFullName,
1665
- });
1666
- }
1667
- aspectDeleteIds.push(row.id);
1668
- }
1669
- await this._yieldManager.allowYield();
1670
- }
1671
- this.targetDb.elements.deleteAspect(aspectDeleteIds);
1672
- }
1673
1594
  /** Transform the specified sourceRelationship into RelationshipProps for the target iModel.
1674
1595
  * @param sourceRelationship The Relationship from the source iModel to be transformed.
1675
1596
  * @returns RelationshipProps for the target iModel.
@@ -1710,7 +1631,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1710
1631
  */
1711
1632
  async onExportElementMultiAspects(sourceAspects) {
1712
1633
  // Transform source ElementMultiAspects into target ElementAspectProps
1713
- const targetAspectPropsArray = sourceAspects.map(async (srcA) => await this.onTransformElementAspect(srcA));
1634
+ const targetAspectPropsArray = sourceAspects.map(async (srcA) => this.onTransformElementAspect(srcA));
1714
1635
  sourceAspects.forEach(async (a) => {
1715
1636
  if (!(await this.doAllReferencesExistInTarget(a))) {
1716
1637
  this._partiallyCommittedAspectIds.add(a.id);
@@ -1883,7 +1804,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1883
1804
  await this._tryInitChangesetData(this._options.argsForProcessChanges);
1884
1805
  await this.context.initialize();
1885
1806
  // need exporter initialized to do remapdeletedsourceentities.
1886
- await this.exporter.initialize(this.getExportInitOpts(this._options.argsForProcessChanges ?? {}));
1807
+ await this.exporter.initialize(await this.getExportInitOpts(this._options.argsForProcessChanges ?? {}));
1887
1808
  // Exporter must be initialized prior to processing changesets in order to properly handle entity recreations (an entity delete followed by an insert of that same entity).
1888
1809
  await this.processChangesets();
1889
1810
  this._initialized = true;
@@ -1909,11 +1830,11 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1909
1830
  this._sourceChangeDataState = "has-changes";
1910
1831
  }
1911
1832
  const relationshipECClassIdsToSkip = new Set();
1912
- for await (const row of this.sourceDb.createQueryReader("SELECT ECInstanceId FROM ECDbMeta.ECClassDef where ECInstanceId IS (BisCore.ElementDrivesElement)")) {
1833
+ for await (const row of this.sourceDb.createQueryReader("SELECT ECInstanceId FROM ECDbMeta.ECClassDef where ECInstanceId IS (BisCore.ElementDrivesElement)", undefined, { usePrimaryConn: true })) {
1913
1834
  relationshipECClassIdsToSkip.add(row.ECInstanceId);
1914
1835
  }
1915
1836
  const relationshipECClassIds = new Set();
1916
- for await (const row of this.sourceDb.createQueryReader("SELECT ECInstanceId FROM ECDbMeta.ECClassDef where ECInstanceId IS (BisCore.ElementRefersToElements)")) {
1837
+ for await (const row of this.sourceDb.createQueryReader("SELECT ECInstanceId FROM ECDbMeta.ECClassDef where ECInstanceId IS (BisCore.ElementRefersToElements)", undefined, { usePrimaryConn: true })) {
1917
1838
  relationshipECClassIds.add(row.ECInstanceId);
1918
1839
  }
1919
1840
  // For later use when processing deletes.
@@ -1995,7 +1916,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1995
1916
  async processDeletedOp(change, mapOfDeletedElemIdToScopeEsas, isRelationship, alreadyImportedElementInserts, alreadyImportedModelInserts) {
1996
1917
  // we need a connected iModel with changes to remap elements with deletions
1997
1918
  const notConnectedModel = this.sourceDb.iTwinId === undefined;
1998
- const noChanges = this.synchronizationVersion.index === this.sourceDb.changeset.index &&
1919
+ const noChanges = (await this.getSynchronizationVersion()).index ===
1920
+ this.sourceDb.changeset.index &&
1999
1921
  (this.exporter.sourceDbChanges === undefined ||
2000
1922
  !this.exporter.sourceDbChanges.hasChanges);
2001
1923
  if (notConnectedModel || noChanges)
@@ -2004,7 +1926,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2004
1926
  * if our ChangedECInstance is in the provenanceDb, then we can use the ids we find in the ChangedECInstance to query for ESAs.
2005
1927
  * This is because the ESAs are stored on an element Id thats present in the provenanceDb.
2006
1928
  */
2007
- const changeDataInProvenanceDb = this.sourceDb === this.provenanceDb;
1929
+ const changeDataInProvenanceDb = this.sourceDb === (await this.getProvenanceDb());
2008
1930
  const getTargetIdFromSourceId = async (id) => {
2009
1931
  let identifierValue;
2010
1932
  let element;
@@ -2020,7 +1942,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2020
1942
  this.targetScopeElementId,
2021
1943
  core_backend_1.ExternalSourceAspect.Kind.Element,
2022
1944
  id,
2023
- ]))) {
1945
+ ]), { usePrimaryConn: true })) {
2024
1946
  identifierValue = row.Identifier;
2025
1947
  }
2026
1948
  identifierValue =
@@ -2052,7 +1974,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2052
1974
  targetIdInTarget: targetIdOfRelationshipInTarget,
2053
1975
  });
2054
1976
  }
2055
- else if (this.sourceDb === this.provenanceSourceDb) {
1977
+ else if (this.sourceDb === (await this.getProvenanceSourceDb())) {
2056
1978
  const relProvenance = await this._queryProvenanceForRelationship(changedInstanceId, {
2057
1979
  classFullName: classFullName ?? "",
2058
1980
  sourceId: sourceIdOfRelationshipInSource,
@@ -2068,7 +1990,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2068
1990
  }
2069
1991
  else {
2070
1992
  let targetId = await getTargetIdFromSourceId(changedInstanceId);
2071
- if (targetId === undefined && this.sourceDb === this.provenanceSourceDb) {
1993
+ if (targetId === undefined &&
1994
+ this.sourceDb === (await this.getProvenanceSourceDb())) {
2072
1995
  targetId = await this._queryProvenanceForElement(changedInstanceId);
2073
1996
  }
2074
1997
  // since we are processing one changeset at a time, we can see local source deletes
@@ -2077,7 +2000,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2077
2000
  if (deletionNotInTarget)
2078
2001
  return;
2079
2002
  if (targetId === undefined) {
2080
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadElement, "targetId should aquired from source id or element provenance");
2003
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadElement, "targetId should be acquired from source id or element provenance");
2081
2004
  }
2082
2005
  this.context.remapElement(changedInstanceId, targetId);
2083
2006
  // If an entity insert and an entity delete both point to the same entity in target iModel, that means that entity was recreated.
@@ -2097,7 +2020,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2097
2020
  this._sourceChangeDataState = "unconnected";
2098
2021
  return;
2099
2022
  }
2100
- const noChanges = this.synchronizationVersion.index === this.sourceDb.changeset.index;
2023
+ const syncVersion = await this.getSynchronizationVersion();
2024
+ const noChanges = syncVersion.index === this.sourceDb.changeset.index;
2101
2025
  if (noChanges) {
2102
2026
  this._sourceChangeDataState = "no-changes";
2103
2027
  this._csFileProps = [];
@@ -2106,9 +2030,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2106
2030
  const startChangeset = "startChangeset" in args ? args.startChangeset : undefined;
2107
2031
  // NOTE: that we do NOT download the changesummary for the last transformed version, we want
2108
2032
  // to ignore those already processed changes
2109
- const startChangesetIndexOrId = startChangeset?.index ??
2110
- startChangeset?.id ??
2111
- this.synchronizationVersion.index + 1;
2033
+ const startChangesetIndexOrId = startChangeset?.index ?? startChangeset?.id ?? syncVersion.index + 1;
2112
2034
  const endChangesetId = this.sourceDb.changeset.id;
2113
2035
  const [startChangesetIndex, endChangesetIndex] = await Promise.all([startChangesetIndexOrId, endChangesetId].map(async (indexOrId) => typeof indexOrId === "number"
2114
2036
  ? indexOrId
@@ -2116,21 +2038,21 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2116
2038
  iModelId: this.sourceDb.iModelId,
2117
2039
  changeset: { id: indexOrId },
2118
2040
  }).then((changeset) => changeset.index)));
2119
- const missingChangesets = startChangesetIndex > this.synchronizationVersion.index + 1;
2041
+ const missingChangesets = startChangesetIndex > syncVersion.index + 1;
2120
2042
  if (!this._options.argsForProcessChanges
2121
2043
  ?.ignoreMissingChangesetsInSynchronizations &&
2122
- startChangesetIndex !== this.synchronizationVersion.index + 1 &&
2123
- this.synchronizationVersion.index !== -1) {
2044
+ startChangesetIndex !== syncVersion.index + 1 &&
2045
+ syncVersion.index !== -1) {
2124
2046
  throw Error(`synchronization is ${missingChangesets ? "missing changesets" : ""},` +
2125
2047
  " startChangesetId should be" +
2126
2048
  " exactly the first changeset *after* the previous synchronization to not miss data." +
2127
2049
  ` You specified '${startChangesetIndexOrId}' which is changeset #${startChangesetIndex}` +
2128
- ` but the previous synchronization for this targetScopeElement was '${this.synchronizationVersion.id}'` +
2129
- ` which is changeset #${this.synchronizationVersion.index}. The transformer expected` +
2130
- ` #${this.synchronizationVersion.index + 1}.`);
2050
+ ` but the previous synchronization for this targetScopeElem ${syncVersion.id}'` +
2051
+ ` which is changeset #${syncVersion.index}. The transformer expected` +
2052
+ ` #${syncVersion.index + 1}.`);
2131
2053
  }
2132
2054
  nodeAssert(this._targetScopeProvenanceProps, "_targetScopeProvenanceProps should be set by now");
2133
- const changesetsToSkip = this.isReverseSynchronization
2055
+ const changesetsToSkip = (await this.getIsReverseSynchronization())
2134
2056
  ? this._targetScopeProvenanceProps.jsonProperties
2135
2057
  .pendingReverseSyncChangesetIndices
2136
2058
  : this._targetScopeProvenanceProps.jsonProperties
@@ -2204,15 +2126,12 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2204
2126
  await this.exporter.exportRelationships(core_backend_1.ElementRefersToElements.classFullName);
2205
2127
  if (this._options.forceExternalSourceAspectProvenance &&
2206
2128
  this.shouldDetectDeletes()) {
2207
- // eslint-disable-next-line @typescript-eslint/no-deprecated
2208
- await this.detectElementDeletes();
2209
- // eslint-disable-next-line @typescript-eslint/no-deprecated
2210
- await this.detectRelationshipDeletes();
2129
+ core_bentley_1.Logger.logWarning(loggerCategory, "This workflows was deprecated in v1 and is no longer supported");
2211
2130
  }
2212
2131
  if (this._options.optimizeGeometry)
2213
2132
  this.importer.optimizeGeometry(this._options.optimizeGeometry);
2214
2133
  this.importer.computeProjectExtents();
2215
- this.finalizeTransformation();
2134
+ await this.finalizeTransformation();
2216
2135
  }
2217
2136
  /** previous provenance, either a federation guid, a `${sourceFedGuid}/${targetFedGuid}` pair, or required aspect props */
2218
2137
  _lastProvenanceEntityInfo = nullLastProvenanceEntityInfo;
@@ -2240,13 +2159,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2240
2159
  */
2241
2160
  async processChanges(options) {
2242
2161
  // must wait for initialization of synchronization provenance data
2243
- await this.exporter.exportChanges(this.getExportInitOpts(options));
2162
+ await this.exporter.exportChanges(await this.getExportInitOpts(options));
2244
2163
  await this.completePartiallyCommittedElements();
2245
2164
  await this.completePartiallyCommittedAspects();
2246
2165
  if (this._options.optimizeGeometry)
2247
2166
  this.importer.optimizeGeometry(this._options.optimizeGeometry);
2248
2167
  this.importer.computeProjectExtents();
2249
- this.finalizeTransformation();
2168
+ await this.finalizeTransformation();
2250
2169
  const defaultSaveTargetChanges = () => {
2251
2170
  this.targetDb.saveChanges();
2252
2171
  };
@@ -2255,7 +2174,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2255
2174
  /** Changeset data must be initialized in order to build correct changeOptions.
2256
2175
  * Call [[IModelTransformer.initialize]] for initialization of synchronization provenance data
2257
2176
  */
2258
- getExportInitOpts(opts) {
2177
+ async getExportInitOpts(opts) {
2259
2178
  if (!this._options.argsForProcessChanges)
2260
2179
  return {};
2261
2180
  const startChangeset = "startChangeset" in opts ? opts.startChangeset : undefined;
@@ -2269,7 +2188,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2269
2188
  ? { startChangeset }
2270
2189
  : {
2271
2190
  startChangeset: {
2272
- index: this.synchronizationVersion.index + 1,
2191
+ index: (await this.getSynchronizationVersion()).index + 1,
2273
2192
  },
2274
2193
  }),
2275
2194
  };
@@ -2388,19 +2307,4 @@ class TemplateModelCloner extends IModelTransformer {
2388
2307
  }
2389
2308
  }
2390
2309
  exports.TemplateModelCloner = TemplateModelCloner;
2391
- //Deprecate in preference of imodeldb.elements.getFederationGuidFromId()?
2392
- function queryElemFedGuid(db, elemId) {
2393
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
2394
- return db.withPreparedStatement(`
2395
- SELECT FederationGuid
2396
- FROM bis.Element
2397
- WHERE ECInstanceId=?
2398
- `, (stmt) => {
2399
- stmt.bindId(1, elemId);
2400
- (0, core_bentley_1.assert)(stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW);
2401
- const result = stmt.getValue(0).getGuid();
2402
- (0, core_bentley_1.assert)(stmt.step() === core_bentley_1.DbResult.BE_SQLITE_DONE);
2403
- return result;
2404
- });
2405
- }
2406
2310
  //# sourceMappingURL=IModelTransformer.js.map