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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/lib/cjs/BranchProvenanceInitializer.d.ts.map +1 -1
  2. package/lib/cjs/BranchProvenanceInitializer.js +1 -3
  3. package/lib/cjs/BranchProvenanceInitializer.js.map +1 -1
  4. package/lib/cjs/DetachedExportElementAspectsStrategy.d.ts.map +1 -1
  5. package/lib/cjs/DetachedExportElementAspectsStrategy.js +2 -2
  6. package/lib/cjs/DetachedExportElementAspectsStrategy.js.map +1 -1
  7. package/lib/cjs/ECReferenceTypesCache.d.ts.map +1 -1
  8. package/lib/cjs/ECReferenceTypesCache.js +4 -3
  9. package/lib/cjs/ECReferenceTypesCache.js.map +1 -1
  10. package/lib/cjs/ExportElementAspectsStrategy.d.ts +2 -2
  11. package/lib/cjs/ExportElementAspectsStrategy.d.ts.map +1 -1
  12. package/lib/cjs/ExportElementAspectsStrategy.js.map +1 -1
  13. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js +2 -2
  14. package/lib/cjs/ExportElementAspectsWithElementsStrategy.js.map +1 -1
  15. package/lib/cjs/IModelCloneContext.d.ts +2 -2
  16. package/lib/cjs/IModelCloneContext.d.ts.map +1 -1
  17. package/lib/cjs/IModelCloneContext.js +38 -37
  18. package/lib/cjs/IModelCloneContext.js.map +1 -1
  19. package/lib/cjs/IModelExporter.d.ts +16 -7
  20. package/lib/cjs/IModelExporter.d.ts.map +1 -1
  21. package/lib/cjs/IModelExporter.js +78 -83
  22. package/lib/cjs/IModelExporter.js.map +1 -1
  23. package/lib/cjs/IModelImporter.d.ts +2 -2
  24. package/lib/cjs/IModelImporter.d.ts.map +1 -1
  25. package/lib/cjs/IModelImporter.js +10 -13
  26. package/lib/cjs/IModelImporter.js.map +1 -1
  27. package/lib/cjs/IModelTransformer.d.ts +13 -13
  28. package/lib/cjs/IModelTransformer.d.ts.map +1 -1
  29. package/lib/cjs/IModelTransformer.js +243 -265
  30. package/lib/cjs/IModelTransformer.js.map +1 -1
  31. package/package.json +1 -1
@@ -120,6 +120,26 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
120
120
  AND Identifier=:identifier
121
121
  LIMIT 1
122
122
  `;
123
+ // if (aspectProps.scope === undefined) return undefined;
124
+ // const params = new QueryBinder().bindId("elementId", aspectProps.element.id);
125
+ // params.bindId("scopeId", aspectProps.scope.id);
126
+ // params.bindString("kind", aspectProps.kind);
127
+ // 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();
139
+ // return { aspectId, version, jsonProperties };
140
+ // }
141
+ // else
142
+ // return undefined;
123
143
  // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
124
144
  return dbToQuery.withPreparedStatement(sql, (statement) => {
125
145
  statement.bindId("elementId", aspectProps.element.id);
@@ -239,7 +259,6 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
239
259
  // non-falsy defaults
240
260
  cloneUsingBinaryGeometry: options?.cloneUsingBinaryGeometry ?? true,
241
261
  targetScopeElementId: options?.targetScopeElementId ?? core_common_1.IModel.rootSubjectId,
242
- // eslint-disable-next-line @typescript-eslint/no-deprecated
243
262
  danglingReferencesBehavior: options?.danglingReferencesBehavior ?? "reject",
244
263
  branchRelationshipDataBehavior: options?.branchRelationshipDataBehavior ?? "reject",
245
264
  skipPropagateChangesToRootElements: options?.skipPropagateChangesToRootElements ?? true,
@@ -332,7 +351,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
332
351
  /** Dispose any native resources associated with this IModelTransformer. */
333
352
  dispose() {
334
353
  core_bentley_1.Logger.logTrace(loggerCategory, "dispose()");
335
- this.context.dispose();
354
+ this.context[Symbol.dispose]();
336
355
  }
337
356
  /** Log current settings that affect IModelTransformer's behavior. */
338
357
  logSettings() {
@@ -385,7 +404,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
385
404
  };
386
405
  return aspectProps;
387
406
  }
388
- static initRelationshipProvenanceOptions(sourceRelInstanceId, targetRelInstanceId, args) {
407
+ static async initRelationshipProvenanceOptions(sourceRelInstanceId, targetRelInstanceId, args) {
389
408
  const provenanceDb = args.isReverseSynchronization
390
409
  ? args.sourceDb
391
410
  : args.targetDb;
@@ -395,12 +414,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
395
414
  const provenanceRelInstanceId = args.isReverseSynchronization
396
415
  ? sourceRelInstanceId
397
416
  : targetRelInstanceId;
398
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
399
- const elementId = provenanceDb.withPreparedStatement("SELECT SourceECInstanceId FROM bis.ElementRefersToElements WHERE ECInstanceId=?", (stmt) => {
400
- stmt.bindId(1, provenanceRelInstanceId);
401
- nodeAssert(stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW);
402
- return stmt.getValue(0).getId();
417
+ const sql = "SELECT SourceECInstanceId FROM bis.ElementRefersToElements WHERE ECInstanceId=?";
418
+ const params = new core_common_1.QueryBinder().bindId(1, provenanceRelInstanceId);
419
+ const reader = provenanceDb.createQueryReader(sql, params, {
420
+ usePrimaryConn: true,
403
421
  });
422
+ nodeAssert(await reader.step(), "relationship provenance query returned no rows");
423
+ const elementId = reader.current[0];
404
424
  const jsonProperties = args.forceOldRelationshipProvenanceMethod
405
425
  ? { targetRelInstanceId }
406
426
  : { provenanceRelInstanceId };
@@ -438,8 +458,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
438
458
  * The `identifier` property of the ExternalSourceAspect will be the ECInstanceId of the relationship in the master iModel.
439
459
  * The ECInstanceId of the relationship in the branch iModel will be stored in the JsonProperties of the ExternalSourceAspect.
440
460
  */
441
- initRelationshipProvenance(sourceRelationship, targetRelInstanceId) {
442
- return IModelTransformer.initRelationshipProvenanceOptions(sourceRelationship.id, targetRelInstanceId, {
461
+ async initRelationshipProvenance(sourceRelationship, targetRelInstanceId) {
462
+ return await IModelTransformer.initRelationshipProvenanceOptions(sourceRelationship.id, targetRelInstanceId, {
443
463
  sourceDb: this.sourceDb,
444
464
  targetDb: this.targetDb,
445
465
  isReverseSynchronization: this.isReverseSynchronization,
@@ -517,7 +537,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
517
537
  * @returns the last synced version (changesetId) on the target scope's external source aspect,
518
538
  * if this was a [BriefcaseDb]($backend)
519
539
  */
520
- initScopeProvenance() {
540
+ async initScopeProvenance() {
521
541
  const aspectProps = {
522
542
  id: undefined,
523
543
  version: undefined,
@@ -548,15 +568,14 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
548
568
  AND Kind=:kind
549
569
  LIMIT 1
550
570
  `;
551
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
552
- const hasConflictingScope = this.provenanceDb.withPreparedStatement(sql,
553
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
554
- (statement) => {
555
- statement.bindId("elementId", aspectProps.element.id);
556
- statement.bindId("scopeId", aspectProps.scope.id); // this scope.id can never be invalid, we create it above
557
- statement.bindString("kind", aspectProps.kind);
558
- return core_bentley_1.DbResult.BE_SQLITE_ROW === statement.step();
571
+ const params = new core_common_1.QueryBinder();
572
+ params.bindId("elementId", aspectProps.element.id);
573
+ params.bindId("scopeId", aspectProps.scope.id); // this scope.id can never be invalid, we create it above
574
+ params.bindString("kind", aspectProps.kind);
575
+ const reader = this.provenanceDb.createQueryReader(sql, params, {
576
+ usePrimaryConn: true,
559
577
  });
578
+ const hasConflictingScope = await reader.step();
560
579
  if (hasConflictingScope) {
561
580
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.InvalidId, "Provenance scope conflict");
562
581
  }
@@ -648,7 +667,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
648
667
  * @note provenance is done by federation guids where possible
649
668
  * @note this may execute on each element more than once! Only use in cases where that is handled
650
669
  */
651
- static forEachTrackedElement(args) {
670
+ static async forEachTrackedElement(args) {
652
671
  if (args.provenanceDb === args.provenanceSourceDb)
653
672
  return;
654
673
  if (!args.provenanceDb.containsClass(core_backend_1.ExternalSourceAspect.classFullName)) {
@@ -673,42 +692,28 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
673
692
  // NOTE: if we exposed the native attach database support,
674
693
  // we could get the intersection of fed guids in one query, not sure if it would be faster
675
694
  // OR we could do a raw sqlite query...
676
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
677
- sourceDb.withStatement(elementIdByFedGuidQuery, (sourceStmt) =>
678
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
679
- targetDb.withStatement(elementIdByFedGuidQuery, (targetStmt) => {
680
- if (sourceStmt.step() !== core_bentley_1.DbResult.BE_SQLITE_ROW)
681
- return;
682
- let sourceRow = sourceStmt.getRow();
683
- if (targetStmt.step() !== core_bentley_1.DbResult.BE_SQLITE_ROW)
684
- return;
685
- let targetRow = targetStmt.getRow();
686
- // NOTE: these comparisons rely upon the lowercase of the guid,
687
- // and the fact that '0' < '9' < a' < 'f' in ascii/utf8
688
- while (true) {
689
- const currSourceRow = sourceRow, currTargetRow = targetRow;
690
- if (currSourceRow.federationGuid !== undefined &&
691
- currTargetRow.federationGuid !== undefined &&
692
- currSourceRow.federationGuid === currTargetRow.federationGuid) {
693
- // data flow direction is always sourceDb -> targetDb and it does not depend on where the explicit element provenance is stored
694
- args.fn(sourceRow.id, targetRow.id);
695
- }
696
- if (currTargetRow.federationGuid === undefined ||
697
- (currSourceRow.federationGuid !== undefined &&
698
- currSourceRow.federationGuid >= currTargetRow.federationGuid)) {
699
- if (targetStmt.step() !== core_bentley_1.DbResult.BE_SQLITE_ROW)
700
- return;
701
- targetRow = targetStmt.getRow();
702
- }
703
- if (currSourceRow.federationGuid === undefined ||
704
- (currTargetRow.federationGuid !== undefined &&
705
- currSourceRow.federationGuid <= currTargetRow.federationGuid)) {
706
- if (sourceStmt.step() !== core_bentley_1.DbResult.BE_SQLITE_ROW)
707
- return;
708
- sourceRow = sourceStmt.getRow();
709
- }
695
+ const sourceReader = sourceDb.createQueryReader(elementIdByFedGuidQuery);
696
+ const targetReader = targetDb.createQueryReader(elementIdByFedGuidQuery);
697
+ let hasSourceRow = await sourceReader.step();
698
+ let hasTargetRow = await targetReader.step();
699
+ while (hasSourceRow && hasTargetRow) {
700
+ const sourceFedGuid = sourceReader.current.federationGuid;
701
+ const targetFedGuid = targetReader.current.federationGuid;
702
+ if (sourceFedGuid !== undefined &&
703
+ targetFedGuid !== undefined &&
704
+ sourceFedGuid === targetFedGuid) {
705
+ // data flow direction is always sourceDb -> targetDb and it does not depend on where the explicit element provenance is stored
706
+ args.fn(sourceReader.current.id, targetReader.current.id);
707
+ }
708
+ if (targetFedGuid === undefined ||
709
+ (sourceFedGuid !== undefined && sourceFedGuid >= targetFedGuid)) {
710
+ hasTargetRow = await targetReader.step();
710
711
  }
711
- }));
712
+ if (sourceFedGuid === undefined ||
713
+ (targetFedGuid !== undefined && sourceFedGuid <= targetFedGuid)) {
714
+ hasSourceRow = await sourceReader.step();
715
+ }
716
+ }
712
717
  // query for provenanceDb
713
718
  const provenanceAspectsQuery = `
714
719
  SELECT esa.Identifier, Element.Id
@@ -719,23 +724,22 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
719
724
  // Technically this will a second time call the function (as documented) on
720
725
  // victims of the old provenance method that have both fedguids and an inserted aspect.
721
726
  // But this is a private function with one known caller where that doesn't matter
722
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
723
- args.provenanceDb.withPreparedStatement(provenanceAspectsQuery, (stmt) => {
724
- const runFnInDataFlowDirection = (sourceId, targetId) => args.isReverseSynchronization
725
- ? args.fn(sourceId, targetId)
726
- : args.fn(targetId, sourceId);
727
- stmt.bindId("scopeId", args.targetScopeElementId);
728
- stmt.bindString("kind", core_backend_1.ExternalSourceAspect.Kind.Element);
729
- while (core_bentley_1.DbResult.BE_SQLITE_ROW === stmt.step()) {
730
- // ExternalSourceAspect.Identifier is of type string
731
- const aspectIdentifier = stmt.getValue(0).getString();
732
- const elementId = stmt.getValue(1).getId();
733
- runFnInDataFlowDirection(elementId, aspectIdentifier);
734
- }
735
- });
736
- }
737
- forEachTrackedElement(fn) {
738
- return IModelTransformer.forEachTrackedElement({
727
+ const runFnInDataFlowDirection = (sourceId, targetId) => args.isReverseSynchronization
728
+ ? args.fn(sourceId, targetId)
729
+ : args.fn(targetId, sourceId);
730
+ const params = new core_common_1.QueryBinder();
731
+ params.bindId("scopeId", args.targetScopeElementId);
732
+ params.bindString("kind", core_backend_1.ExternalSourceAspect.Kind.Element);
733
+ const provenanceReader = args.provenanceDb.createQueryReader(provenanceAspectsQuery, params);
734
+ for await (const row of provenanceReader) {
735
+ // ExternalSourceAspect.Identifier is of type string
736
+ const aspectIdentifier = row[0];
737
+ const elementId = row.id;
738
+ runFnInDataFlowDirection(elementId, aspectIdentifier);
739
+ }
740
+ }
741
+ async forEachTrackedElement(fn) {
742
+ return await IModelTransformer.forEachTrackedElement({
739
743
  provenanceSourceDb: this.provenanceSourceDb,
740
744
  provenanceDb: this.provenanceDb,
741
745
  targetScopeElementId: this.targetScopeElementId,
@@ -751,23 +755,25 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
751
755
  * @param entityInProvenanceSourceId
752
756
  * @returns the elementId that the ESA is stored on, esa.Element.Id
753
757
  */
754
- _queryProvenanceForElement(entityInProvenanceSourceId) {
758
+ async _queryProvenanceForElement(entityInProvenanceSourceId) {
755
759
  // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
756
- return this.provenanceDb.withPreparedStatement(`
760
+ const sql = `
757
761
  SELECT esa.Element.Id
758
762
  FROM Bis.ExternalSourceAspect esa
759
763
  WHERE esa.Kind=?
760
764
  AND esa.Scope.Id=?
761
765
  AND esa.Identifier=?
762
- `, (stmt) => {
763
- stmt.bindString(1, core_backend_1.ExternalSourceAspect.Kind.Element);
764
- stmt.bindId(2, this.targetScopeElementId);
765
- stmt.bindString(3, entityInProvenanceSourceId);
766
- if (stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW)
767
- return stmt.getValue(0).getId();
768
- else
769
- return undefined;
770
- });
766
+ `;
767
+ const params = new core_common_1.QueryBinder();
768
+ params.bindString(1, core_backend_1.ExternalSourceAspect.Kind.Element);
769
+ params.bindId(2, this.targetScopeElementId);
770
+ params.bindString(3, entityInProvenanceSourceId);
771
+ const result = this.provenanceDb.createQueryReader(sql, params);
772
+ if (await result.step()) {
773
+ return result.current.id;
774
+ }
775
+ else
776
+ return undefined;
771
777
  }
772
778
  /**
773
779
  * Queries the provenanceDb for an ESA whose identifier is equal to the provided 'entityInProvenanceSourceId'.
@@ -776,35 +782,36 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
776
782
  * @param entityInProvenanceSourceId
777
783
  * @returns
778
784
  */
779
- _queryProvenanceForRelationship(entityInProvenanceSourceId, sourceRelInfo) {
780
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
781
- return this.provenanceDb.withPreparedStatement(`
782
- SELECT
783
- ECInstanceId,
784
- JSON_EXTRACT(JsonProperties, '$.targetRelInstanceId'),
785
- JSON_EXTRACT(JsonProperties, '$.provenanceRelInstanceId')
786
- FROM Bis.ExternalSourceAspect
787
- WHERE Kind=?
788
- AND Scope.Id=?
789
- AND Identifier=?
790
- `, (stmt) => {
791
- stmt.bindString(1, core_backend_1.ExternalSourceAspect.Kind.Relationship);
792
- stmt.bindId(2, this.targetScopeElementId);
793
- stmt.bindString(3, entityInProvenanceSourceId);
794
- if (stmt.step() !== core_bentley_1.DbResult.BE_SQLITE_ROW)
795
- return undefined;
796
- const aspectId = stmt.getValue(0).getId();
797
- const provenanceRelInstIdVal = stmt.getValue(2);
798
- const provenanceRelInstanceId = !provenanceRelInstIdVal.isNull
799
- ? provenanceRelInstIdVal.getString()
800
- : this._queryTargetRelId(sourceRelInfo);
785
+ async _queryProvenanceForRelationship(entityInProvenanceSourceId, sourceRelInfo) {
786
+ const sql = `
787
+ SELECT
788
+ ECInstanceId,
789
+ JSON_EXTRACT(JsonProperties, '$.provenanceRelInstanceId') AS provenanceRelInstId
790
+ FROM Bis.ExternalSourceAspect
791
+ WHERE Kind=?
792
+ AND Scope.Id=?
793
+ AND Identifier=?
794
+ `;
795
+ const params = new core_common_1.QueryBinder();
796
+ params.bindString(1, core_backend_1.ExternalSourceAspect.Kind.Relationship);
797
+ params.bindId(2, this.targetScopeElementId);
798
+ params.bindString(3, entityInProvenanceSourceId);
799
+ const result = this.provenanceDb.createQueryReader(sql, params);
800
+ if (await result.step()) {
801
+ const aspectId = result.current.id;
802
+ const provenanceRelInstId = result.current.provenanceRelInstId;
803
+ const provenanceRelInstanceId = provenanceRelInstId !== undefined
804
+ ? provenanceRelInstId
805
+ : await this._queryTargetRelId(sourceRelInfo);
801
806
  return {
802
807
  aspectId,
803
808
  relationshipId: provenanceRelInstanceId,
804
809
  };
805
- });
810
+ }
811
+ else
812
+ return undefined;
806
813
  }
807
- _queryTargetRelId(sourceRelInfo) {
814
+ async _queryTargetRelId(sourceRelInfo) {
808
815
  const targetRelInfo = {
809
816
  sourceId: this.context.findTargetElementId(sourceRelInfo.sourceId),
810
817
  targetId: this.context.findTargetElementId(sourceRelInfo.targetId),
@@ -812,60 +819,61 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
812
819
  if (targetRelInfo.sourceId === undefined ||
813
820
  targetRelInfo.targetId === undefined)
814
821
  return undefined; // couldn't find an element, rel is invalid or deleted
815
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
816
- return this.targetDb.withPreparedStatement(`
817
- SELECT ECInstanceId
818
- FROM bis.ElementRefersToElements
819
- WHERE SourceECInstanceId=?
820
- AND TargetECInstanceId=?
821
- AND ECClassId=?
822
- `, (stmt) => {
823
- stmt.bindId(1, targetRelInfo.sourceId);
824
- stmt.bindId(2, targetRelInfo.targetId);
825
- stmt.bindId(3, this._targetClassNameToClassId(sourceRelInfo.classFullName));
826
- if (stmt.step() !== core_bentley_1.DbResult.BE_SQLITE_ROW)
827
- return undefined;
828
- return stmt.getValue(0).getId();
829
- });
822
+ const sql = `
823
+ select ecinstanceid
824
+ from bis.elementreferstoelements
825
+ where sourceecinstanceid=?
826
+ and targetecinstanceid=?
827
+ and ecclassid=?
828
+ `;
829
+ const params = new core_common_1.QueryBinder();
830
+ params.bindId(1, targetRelInfo.sourceId);
831
+ params.bindId(2, targetRelInfo.targetId);
832
+ params.bindId(3, await this._targetClassNameToClassId(sourceRelInfo.classFullName));
833
+ const result = this.targetDb.createQueryReader(sql, params);
834
+ if (await result.step())
835
+ return result.current.id;
836
+ else
837
+ return undefined;
830
838
  }
831
839
  _targetClassNameToClassIdCache = new Map();
832
- _targetClassNameToClassId(classFullName) {
840
+ async _targetClassNameToClassId(classFullName) {
833
841
  let classId = this._targetClassNameToClassIdCache.get(classFullName);
834
842
  if (classId === undefined) {
835
- classId = this._getRelClassId(this.targetDb, classFullName);
843
+ classId = await this._getRelClassId(this.targetDb, classFullName);
836
844
  this._targetClassNameToClassIdCache.set(classFullName, classId);
837
845
  }
838
846
  return classId;
839
847
  }
840
848
  // NOTE: this doesn't handle remapped element classes,
841
849
  // but is only used for relationships rn
842
- _getRelClassId(db, classFullName) {
843
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
844
- return db.withPreparedStatement(`
850
+ async _getRelClassId(db, classFullName) {
851
+ const sql = `
845
852
  SELECT c.ECInstanceId
846
853
  FROM ECDbMeta.ECClassDef c
847
854
  JOIN ECDbMeta.ECSchemaDef s ON c.Schema.Id=s.ECInstanceId
848
855
  WHERE s.Name=? AND c.Name=?
849
- `, (stmt) => {
850
- const [schemaName, className] = classFullName.indexOf(".") !== -1
851
- ? classFullName.split(".")
852
- : classFullName.split(":");
853
- stmt.bindString(1, schemaName);
854
- stmt.bindString(2, className);
855
- if (stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW)
856
- return stmt.getValue(0).getId();
857
- (0, core_bentley_1.assert)(false, "relationship was not found");
858
- });
859
- }
860
- _queryElemIdByFedGuid(db, fedGuid) {
861
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
862
- return db.withPreparedStatement("SELECT ECInstanceId FROM Bis.Element WHERE FederationGuid=?", (stmt) => {
863
- stmt.bindGuid(1, fedGuid);
864
- if (stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW)
865
- return stmt.getValue(0).getId();
866
- else
867
- return undefined;
868
- });
856
+ `;
857
+ const params = new core_common_1.QueryBinder();
858
+ const [schemaName, className] = classFullName.indexOf(".") !== -1
859
+ ? classFullName.split(".")
860
+ : classFullName.split(":");
861
+ params.bindString(1, schemaName);
862
+ params.bindString(2, className);
863
+ const result = db.createQueryReader(sql, params);
864
+ if (await result.step())
865
+ return result.current.id;
866
+ (0, core_bentley_1.assert)(false, "relationship was not found");
867
+ }
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;
869
877
  }
870
878
  /** Returns `true` if *brute force* delete detections should be run.
871
879
  * @note This is only called if [[IModelTransformOptions.forceExternalSourceAspectProvenance]] option is true
@@ -919,7 +927,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
919
927
  * @note A subclass can override this method to provide custom transform behavior.
920
928
  * @note This can be called more than once for an element in arbitrary order, so it should not have side-effects.
921
929
  */
922
- onTransformElement(sourceElement) {
930
+ async onTransformElement(sourceElement) {
923
931
  core_bentley_1.Logger.logTrace(loggerCategory, `onTransformElement(${sourceElement.id}) "${sourceElement.getDisplayLabel()}"`);
924
932
  const targetElementProps = this.context.cloneElement(sourceElement, { binaryGeometry: this._options.cloneUsingBinaryGeometry });
925
933
  // Special case: source element is the root subject
@@ -1035,7 +1043,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1035
1043
  sourceDbChanges.element.insertIds.has(sourceElement.id) ||
1036
1044
  sourceDbChanges.element.updateIds.has(sourceElement.id));
1037
1045
  }
1038
- completePartiallyCommittedElements() {
1046
+ async completePartiallyCommittedElements() {
1039
1047
  for (const sourceElementId of this._partiallyCommittedElementIds) {
1040
1048
  const sourceElement = this.sourceDb.elements.getElement({
1041
1049
  id: sourceElementId,
@@ -1046,25 +1054,25 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1046
1054
  if (core_bentley_1.Id64.isInvalid(targetId)) {
1047
1055
  throw new Error(`source-target element mapping not found for element "${sourceElementId}" when completing partially committed elements. This is a bug.`);
1048
1056
  }
1049
- const targetProps = this.onTransformElement(sourceElement);
1057
+ const targetProps = await this.onTransformElement(sourceElement);
1050
1058
  this.targetDb.elements.updateElement({ ...targetProps, id: targetId });
1051
1059
  }
1052
1060
  }
1053
- completePartiallyCommittedAspects() {
1061
+ async completePartiallyCommittedAspects() {
1054
1062
  for (const sourceAspectId of this._partiallyCommittedAspectIds) {
1055
1063
  const sourceAspect = this.sourceDb.elements.getAspect(sourceAspectId);
1056
1064
  const targetAspectId = this.context.findTargetAspectId(sourceAspectId);
1057
1065
  if (core_bentley_1.Id64.isInvalid(targetAspectId)) {
1058
1066
  throw new Error(`source-target aspect mapping not found for aspect "${sourceAspectId}" when completing partially committed aspects. This is a bug.`);
1059
1067
  }
1060
- const targetAspectProps = this.onTransformElementAspect(sourceAspect);
1068
+ const targetAspectProps = await this.onTransformElementAspect(sourceAspect);
1061
1069
  this.targetDb.elements.updateAspect({
1062
1070
  ...targetAspectProps,
1063
1071
  id: targetAspectId,
1064
1072
  });
1065
1073
  }
1066
1074
  }
1067
- doAllReferencesExistInTarget(entity) {
1075
+ async doAllReferencesExistInTarget(entity) {
1068
1076
  let allReferencesExist = true;
1069
1077
  for (const referenceId of entity.getReferenceIds()) {
1070
1078
  const referencedEntityId = core_backend_1.EntityReferences.toId64(referenceId);
@@ -1074,7 +1082,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1074
1082
  continue;
1075
1083
  }
1076
1084
  if (allReferencesExist &&
1077
- !core_backend_1.EntityReferences.isValid(this.context.findTargetEntityId(referenceId))) {
1085
+ !core_backend_1.EntityReferences.isValid(await this.context.findTargetEntityId(referenceId))) {
1078
1086
  // if we care about references existing then we cannot return early and must check all other references.
1079
1087
  if (this._options.danglingReferencesBehavior === "ignore") {
1080
1088
  return false;
@@ -1130,6 +1138,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1130
1138
  * @internal do not call, override or implement this, it will be removed
1131
1139
  */
1132
1140
  async preExportElement(sourceElement) {
1141
+ if (!this.hasElementChanged(sourceElement)) {
1142
+ core_bentley_1.Logger.logTrace(loggerCategory, `Skipping unchanged element (${sourceElement.id}, ${sourceElement.getDisplayLabel()}).`);
1143
+ return;
1144
+ }
1133
1145
  const elemClass = sourceElement.constructor;
1134
1146
  const unresolvedReferences = elemClass.requiredReferenceKeys
1135
1147
  .map((referenceKey) => {
@@ -1188,8 +1200,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1188
1200
  /** Override of [IModelExportHandler.onExportElement]($transformer) that imports an element into the target iModel when it is exported from the source iModel.
1189
1201
  * This override calls [[onTransformElement]] and then [IModelImporter.importElement]($transformer) to update the target iModel.
1190
1202
  */
1191
- onExportElement(sourceElement) {
1192
- let targetElementId;
1203
+ async onExportElement(sourceElement) {
1204
+ let targetElementId = core_bentley_1.Id64.invalid;
1193
1205
  let targetElementProps;
1194
1206
  if (this._options.wasSourceIModelCopiedToTarget) {
1195
1207
  targetElementId = sourceElement.id;
@@ -1198,14 +1210,14 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1198
1210
  }
1199
1211
  else {
1200
1212
  targetElementId = this.context.findTargetElementId(sourceElement.id);
1201
- targetElementProps = this.onTransformElement(sourceElement);
1213
+ targetElementProps = await this.onTransformElement(sourceElement);
1202
1214
  }
1203
1215
  // if an existing remapping was not yet found, check by FederationGuid
1204
1216
  if (this.context.isBetweenIModels &&
1205
1217
  !core_bentley_1.Id64.isValid(targetElementId) &&
1206
1218
  sourceElement.federationGuid !== undefined) {
1207
1219
  targetElementId =
1208
- this._queryElemIdByFedGuid(this.targetDb, sourceElement.federationGuid) ?? core_bentley_1.Id64.invalid;
1220
+ this.targetDb.elements.getIdFromFederationGuid(sourceElement.federationGuid) ?? core_bentley_1.Id64.invalid;
1209
1221
  if (core_bentley_1.Id64.isValid(targetElementId))
1210
1222
  this.context.remapElement(sourceElement.id, targetElementId); // record that the targetElement was found
1211
1223
  }
@@ -1232,7 +1244,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1232
1244
  core_bentley_1.Logger.logTrace(loggerCategory, `Skipping unchanged element (${sourceElement.id}, ${sourceElement.getDisplayLabel()}).`);
1233
1245
  return;
1234
1246
  }
1235
- if (!this.doAllReferencesExistInTarget(sourceElement)) {
1247
+ if (!(await this.doAllReferencesExistInTarget(sourceElement))) {
1236
1248
  this._partiallyCommittedElementIds.add(sourceElement.id);
1237
1249
  }
1238
1250
  // targetElementId will be valid (indicating update) or undefined (indicating insert)
@@ -1322,7 +1334,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1322
1334
  this.importer.importModel(targetModelProps);
1323
1335
  }
1324
1336
  /** Override of [IModelExportHandler.onDeleteModel]($transformer) that is called when [IModelExporter]($transformer) detects that a [Model]($backend) has been deleted from the source iModel. */
1325
- onDeleteModel(sourceModelId) {
1337
+ async onDeleteModel(sourceModelId) {
1326
1338
  // It is possible and apparently occasionally sensical to delete a model without deleting its underlying element.
1327
1339
  // - If only the model is deleted, [[initFromExternalSourceAspects]] will have already remapped the underlying element since it still exists.
1328
1340
  // - If both were deleted, [[remapDeletedSourceEntities]] will find and remap the deleted element making this operation valid
@@ -1339,19 +1351,9 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1339
1351
  WHERE ECInstanceId=:targetModelId
1340
1352
  `;
1341
1353
  if (this.exporter.sourceDbChanges?.element.deleteIds.has(sourceModelId)) {
1342
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
1343
- const isDefinitionPartition = this.targetDb.withPreparedStatement(sql, (stmt) => {
1344
- stmt.bindId("targetModelId", targetModelId);
1345
- const val = stmt.step();
1346
- switch (val) {
1347
- case core_bentley_1.DbResult.BE_SQLITE_ROW:
1348
- return true;
1349
- case core_bentley_1.DbResult.BE_SQLITE_DONE:
1350
- return false;
1351
- default:
1352
- (0, core_bentley_1.assert)(false, `unexpected db result: '${JSON.stringify(stmt)}'`);
1353
- }
1354
- });
1354
+ const params = new core_common_1.QueryBinder().bindId("targetModelId", targetModelId);
1355
+ const reader = this.targetDb.createQueryReader(sql, params);
1356
+ const isDefinitionPartition = await reader.step();
1355
1357
  if (isDefinitionPartition) {
1356
1358
  // Skipping model deletion because model's partition will also be deleted.
1357
1359
  // It expects that model will be present and will fail if it's missing.
@@ -1360,7 +1362,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1360
1362
  }
1361
1363
  }
1362
1364
  try {
1363
- this.importer.deleteModel(targetModelId);
1365
+ await this.importer.deleteModel(targetModelId);
1364
1366
  }
1365
1367
  catch (error) {
1366
1368
  const isDeletionProhibitedErr = error instanceof core_common_1.IModelError &&
@@ -1407,41 +1409,24 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1407
1409
  await this.initialize();
1408
1410
  // import DefinitionModels first
1409
1411
  const childDefinitionPartitionSql = `SELECT ECInstanceId FROM ${core_backend_1.DefinitionPartition.classFullName} WHERE Parent.Id=:subjectId`;
1410
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
1411
- await this.sourceDb.withPreparedStatement(childDefinitionPartitionSql,
1412
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
1413
- async (statement) => {
1414
- statement.bindId("subjectId", sourceSubjectId);
1415
- while (core_bentley_1.DbResult.BE_SQLITE_ROW === statement.step()) {
1416
- await this.processModel(statement.getValue(0).getId());
1417
- }
1418
- });
1412
+ const params = new core_common_1.QueryBinder().bindId("subjectId", sourceSubjectId);
1413
+ for await (const row of this.sourceDb.createQueryReader(childDefinitionPartitionSql, params)) {
1414
+ await this.processModel(row.id);
1415
+ }
1419
1416
  // import other partitions next
1420
1417
  const childPartitionSql = `SELECT ECInstanceId FROM ${core_backend_1.InformationPartitionElement.classFullName} WHERE Parent.Id=:subjectId`;
1421
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
1422
- await this.sourceDb.withPreparedStatement(childPartitionSql,
1423
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
1424
- async (statement) => {
1425
- statement.bindId("subjectId", sourceSubjectId);
1426
- while (core_bentley_1.DbResult.BE_SQLITE_ROW === statement.step()) {
1427
- const modelId = statement.getValue(0).getId();
1428
- const model = this.sourceDb.models.getModel(modelId);
1429
- if (!(model instanceof core_backend_1.DefinitionModel)) {
1430
- await this.processModel(modelId);
1431
- }
1418
+ for await (const row of this.sourceDb.createQueryReader(childPartitionSql, params)) {
1419
+ const modelId = row.id;
1420
+ const model = this.sourceDb.models.getModel(modelId);
1421
+ if (!(model instanceof core_backend_1.DefinitionModel)) {
1422
+ await this.processModel(modelId);
1432
1423
  }
1433
- });
1424
+ }
1434
1425
  // recurse into child Subjects
1435
1426
  const childSubjectSql = `SELECT ECInstanceId FROM ${core_backend_1.Subject.classFullName} WHERE Parent.Id=:subjectId`;
1436
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
1437
- await this.sourceDb.withPreparedStatement(childSubjectSql,
1438
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
1439
- async (statement) => {
1440
- statement.bindId("subjectId", sourceSubjectId);
1441
- while (core_bentley_1.DbResult.BE_SQLITE_ROW === statement.step()) {
1442
- await this.processSubjectSubModels(statement.getValue(0).getId());
1443
- }
1444
- });
1427
+ for await (const row of this.sourceDb.createQueryReader(childSubjectSql, params)) {
1428
+ await this.processSubjectSubModels(row.id);
1429
+ }
1445
1430
  }
1446
1431
  /** Transform the specified sourceModel into ModelProps for the target iModel.
1447
1432
  * @param sourceModel The Model from the source iModel to be transformed.
@@ -1588,9 +1573,9 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1588
1573
  /** Override of [IModelExportHandler.onExportRelationship]($transformer) that imports a relationship into the target iModel when it is exported from the source iModel.
1589
1574
  * This override calls [[onTransformRelationship]] and then [IModelImporter.importRelationship]($transformer) to update the target iModel.
1590
1575
  */
1591
- onExportRelationship(sourceRelationship) {
1592
- const sourceFedGuid = queryElemFedGuid(this.sourceDb, sourceRelationship.sourceId);
1593
- const targetFedGuid = queryElemFedGuid(this.sourceDb, sourceRelationship.targetId);
1576
+ async onExportRelationship(sourceRelationship) {
1577
+ const sourceFedGuid = this.sourceDb.elements.getFederationGuidFromId(sourceRelationship.sourceId);
1578
+ const targetFedGuid = this.sourceDb.elements.getFederationGuidFromId(sourceRelationship.targetId);
1594
1579
  const targetRelationshipProps = this.onTransformRelationship(sourceRelationship);
1595
1580
  const targetRelationshipInstanceId = this.importer.importRelationship(targetRelationshipProps);
1596
1581
  if (!this._options.noProvenance &&
@@ -1599,7 +1584,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1599
1584
  ? sourceFedGuid && targetFedGuid && `${sourceFedGuid}/${targetFedGuid}`
1600
1585
  : undefined;
1601
1586
  if (!provenance) {
1602
- const aspectProps = this.initRelationshipProvenance(sourceRelationship, targetRelationshipInstanceId);
1587
+ const aspectProps = await this.initRelationshipProvenance(sourceRelationship, targetRelationshipInstanceId);
1603
1588
  const foundEsaProps = IModelTransformer.queryScopeExternalSourceAspect(this.provenanceDb, aspectProps);
1604
1589
  // 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).
1605
1590
  if (undefined === foundEsaProps) {
@@ -1662,32 +1647,27 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1662
1647
  WHERE aspect.Scope.Id=:scopeId
1663
1648
  AND aspect.Kind=:kind
1664
1649
  `;
1665
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
1666
- await this.targetDb.withPreparedStatement(sql,
1667
- // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
1668
- async (statement) => {
1669
- statement.bindId("scopeId", this.targetScopeElementId);
1670
- statement.bindString("kind", core_backend_1.ExternalSourceAspect.Kind.Relationship);
1671
- while (core_bentley_1.DbResult.BE_SQLITE_ROW === statement.step()) {
1672
- const sourceRelInstanceId = core_bentley_1.Id64.fromJSON(statement.getValue(1).getString());
1673
- if (undefined ===
1674
- this.sourceDb.relationships.tryGetInstanceProps(core_backend_1.ElementRefersToElements.classFullName, sourceRelInstanceId)) {
1675
- // this function exists only to support some in-imodel transformations, which must
1676
- // use the old (external source aspect) provenance method anyway so we don't need to support
1677
- // new provenance
1678
- const json = JSON.parse(statement.getValue(2).getString());
1679
- const targetRelInstanceId = json.targetRelInstanceId ?? json.provenanceRelInstanceId;
1680
- if (targetRelInstanceId) {
1681
- this.importer.deleteRelationship({
1682
- id: targetRelInstanceId,
1683
- classFullName: core_backend_1.ElementRefersToElements.classFullName,
1684
- });
1685
- }
1686
- aspectDeleteIds.push(statement.getValue(0).getId());
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
+ });
1687
1666
  }
1688
- await this._yieldManager.allowYield();
1667
+ aspectDeleteIds.push(row.id);
1689
1668
  }
1690
- });
1669
+ await this._yieldManager.allowYield();
1670
+ }
1691
1671
  this.targetDb.elements.deleteAspect(aspectDeleteIds);
1692
1672
  }
1693
1673
  /** Transform the specified sourceRelationship into RelationshipProps for the target iModel.
@@ -1700,11 +1680,10 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1700
1680
  targetRelationshipProps.sourceId = this.context.findTargetElementId(sourceRelationship.sourceId);
1701
1681
  targetRelationshipProps.targetId = this.context.findTargetElementId(sourceRelationship.targetId);
1702
1682
  // TODO: move to cloneRelationship in IModelCloneContext
1703
- sourceRelationship.forEachProperty((propertyName, propertyMetaData) => {
1704
- if (core_common_1.PrimitiveTypeCode.Long === propertyMetaData.primitiveType &&
1705
- "Id" === propertyMetaData.extendedType) {
1706
- targetRelationshipProps[propertyName] =
1707
- this.context.findTargetElementId(sourceRelationship.asAny[propertyName]);
1683
+ sourceRelationship.forEach((propertyName, property) => {
1684
+ if (property.isPrimitive() && "Id" === property.extendedTypeName) {
1685
+ targetRelationshipProps[core_common_1.ECJsNames.toJsName(propertyName)] =
1686
+ this.context.findTargetElementId(sourceRelationship.asAny[core_common_1.ECJsNames.toJsName(propertyName)]);
1708
1687
  }
1709
1688
  });
1710
1689
  return targetRelationshipProps;
@@ -1717,9 +1696,9 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1717
1696
  /** Override of [IModelExportHandler.onExportElementUniqueAspect]($transformer) that imports an ElementUniqueAspect into the target iModel when it is exported from the source iModel.
1718
1697
  * This override calls [[onTransformElementAspect]] and then [IModelImporter.importElementUniqueAspect]($transformer) to update the target iModel.
1719
1698
  */
1720
- onExportElementUniqueAspect(sourceAspect) {
1721
- const targetAspectProps = this.onTransformElementAspect(sourceAspect);
1722
- if (!this.doAllReferencesExistInTarget(sourceAspect)) {
1699
+ async onExportElementUniqueAspect(sourceAspect) {
1700
+ const targetAspectProps = await this.onTransformElementAspect(sourceAspect);
1701
+ if (!(await this.doAllReferencesExistInTarget(sourceAspect))) {
1723
1702
  this._partiallyCommittedAspectIds.add(sourceAspect.id);
1724
1703
  }
1725
1704
  const targetId = this.importer.importElementUniqueAspect(targetAspectProps);
@@ -1729,16 +1708,16 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1729
1708
  * This override calls [[onTransformElementAspect]] for each ElementMultiAspect and then [IModelImporter.importElementMultiAspects]($transformer) to update the target iModel.
1730
1709
  * @note ElementMultiAspects are handled as a group to make it easier to differentiate between insert, update, and delete.
1731
1710
  */
1732
- onExportElementMultiAspects(sourceAspects) {
1711
+ async onExportElementMultiAspects(sourceAspects) {
1733
1712
  // Transform source ElementMultiAspects into target ElementAspectProps
1734
- const targetAspectPropsArray = sourceAspects.map((srcA) => this.onTransformElementAspect(srcA));
1735
- sourceAspects.forEach((a) => {
1736
- if (!this.doAllReferencesExistInTarget(a)) {
1713
+ const targetAspectPropsArray = sourceAspects.map(async (srcA) => await this.onTransformElementAspect(srcA));
1714
+ sourceAspects.forEach(async (a) => {
1715
+ if (!(await this.doAllReferencesExistInTarget(a))) {
1737
1716
  this._partiallyCommittedAspectIds.add(a.id);
1738
1717
  }
1739
1718
  });
1740
1719
  // const targetAspectsToImport = targetAspectPropsArray.filter((targetAspect, i) => hasEntityChanged(sourceAspects[i], targetAspect));
1741
- const targetIds = this.importer.importElementMultiAspects(targetAspectPropsArray, (a) => {
1720
+ const targetIds = this.importer.importElementMultiAspects(await Promise.all(targetAspectPropsArray), (a) => {
1742
1721
  const isExternalSourceAspectFromTransformer = a instanceof core_backend_1.ExternalSourceAspect &&
1743
1722
  a.scope?.id === this.targetScopeElementId;
1744
1723
  return (!this._options.includeSourceProvenance ||
@@ -1753,8 +1732,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1753
1732
  * @returns ElementAspectProps for the target iModel.
1754
1733
  * @note A subclass can override this method to provide custom transform behavior.
1755
1734
  */
1756
- onTransformElementAspect(sourceElementAspect) {
1757
- const targetElementAspectProps = this.context.cloneElementAspect(sourceElementAspect);
1735
+ async onTransformElementAspect(sourceElementAspect) {
1736
+ const targetElementAspectProps = await this.context.cloneElementAspect(sourceElementAspect);
1758
1737
  return targetElementAspectProps;
1759
1738
  }
1760
1739
  /** The directory where schemas will be exported, a random temporary directory */
@@ -1796,7 +1775,6 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1796
1775
  nodeAssert(schemaFileName.length <= systemMaxPathSegmentSize, "Schema name was still long. This is a bug.");
1797
1776
  this._longNamedSchemasMap.set(schema.name, schemaFileName);
1798
1777
  }
1799
- /* eslint-disable-next-line @typescript-eslint/no-deprecated */
1800
1778
  this.sourceDb.exportSchema({
1801
1779
  schemaName: schema.name,
1802
1780
  outputDirectory: this._schemaExportDir,
@@ -1884,8 +1862,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1884
1862
  this.context.remapElement(sourceSubjectId, targetSubjectId);
1885
1863
  await this.processChildElements(sourceSubjectId);
1886
1864
  await this.processSubjectSubModels(sourceSubjectId);
1887
- this.completePartiallyCommittedElements();
1888
- this.completePartiallyCommittedAspects();
1865
+ await this.completePartiallyCommittedElements();
1866
+ await this.completePartiallyCommittedAspects();
1889
1867
  }
1890
1868
  /** state to prevent reinitialization, @see [[initialize]] */
1891
1869
  _initialized = false;
@@ -1901,7 +1879,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1901
1879
  async initialize() {
1902
1880
  if (this._initialized)
1903
1881
  return;
1904
- this.initScopeProvenance();
1882
+ await this.initScopeProvenance();
1905
1883
  await this._tryInitChangesetData(this._options.argsForProcessChanges);
1906
1884
  await this.context.initialize();
1907
1885
  // need exporter initialized to do remapdeletedsourceentities.
@@ -1917,7 +1895,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1917
1895
  * @returns void
1918
1896
  */
1919
1897
  async processChangesets() {
1920
- this.forEachTrackedElement((sourceElementId, targetElementId) => {
1898
+ await this.forEachTrackedElement((sourceElementId, targetElementId) => {
1921
1899
  this.context.remapElement(sourceElementId, targetElementId);
1922
1900
  });
1923
1901
  if (this.exporter.sourceDbChanges)
@@ -2055,7 +2033,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2055
2033
  }
2056
2034
  // Check for targetId using sourceId's fedguid if we didn't find an esa.
2057
2035
  if (fedGuid) {
2058
- const targetId = this._queryElemIdByFedGuid(this.targetDb, fedGuid);
2036
+ const targetId = this.targetDb.elements.getIdFromFederationGuid(fedGuid);
2059
2037
  return targetId;
2060
2038
  }
2061
2039
  return undefined;
@@ -2075,7 +2053,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2075
2053
  });
2076
2054
  }
2077
2055
  else if (this.sourceDb === this.provenanceSourceDb) {
2078
- const relProvenance = this._queryProvenanceForRelationship(changedInstanceId, {
2056
+ const relProvenance = await this._queryProvenanceForRelationship(changedInstanceId, {
2079
2057
  classFullName: classFullName ?? "",
2080
2058
  sourceId: sourceIdOfRelationshipInSource,
2081
2059
  targetId: targetIdOfRelationshipInSource,
@@ -2091,7 +2069,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2091
2069
  else {
2092
2070
  let targetId = await getTargetIdFromSourceId(changedInstanceId);
2093
2071
  if (targetId === undefined && this.sourceDb === this.provenanceSourceDb) {
2094
- targetId = this._queryProvenanceForElement(changedInstanceId);
2072
+ targetId = await this._queryProvenanceForElement(changedInstanceId);
2095
2073
  }
2096
2074
  // since we are processing one changeset at a time, we can see local source deletes
2097
2075
  // of entities that were never synced and can be safely ignored
@@ -2136,7 +2114,6 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2136
2114
  ? indexOrId
2137
2115
  : core_backend_1.BriefcaseManager.queryChangeset({
2138
2116
  iModelId: this.sourceDb.iModelId,
2139
- // eslint-disable-next-line @typescript-eslint/no-deprecated
2140
2117
  changeset: { id: indexOrId },
2141
2118
  }).then((changeset) => changeset.index)));
2142
2119
  const missingChangesets = startChangesetIndex > this.synchronizationVersion.index + 1;
@@ -2221,9 +2198,9 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2221
2198
  else {
2222
2199
  await this.exporter.exportModel(core_common_1.IModel.repositoryModelId);
2223
2200
  }
2224
- this.completePartiallyCommittedElements();
2201
+ await this.completePartiallyCommittedElements();
2225
2202
  await this.exporter["exportAllAspects"](); // eslint-disable-line @typescript-eslint/dot-notation
2226
- this.completePartiallyCommittedAspects();
2203
+ await this.completePartiallyCommittedAspects();
2227
2204
  await this.exporter.exportRelationships(core_backend_1.ElementRefersToElements.classFullName);
2228
2205
  if (this._options.forceExternalSourceAspectProvenance &&
2229
2206
  this.shouldDetectDeletes()) {
@@ -2264,8 +2241,8 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
2264
2241
  async processChanges(options) {
2265
2242
  // must wait for initialization of synchronization provenance data
2266
2243
  await this.exporter.exportChanges(this.getExportInitOpts(options));
2267
- this.completePartiallyCommittedElements();
2268
- this.completePartiallyCommittedAspects();
2244
+ await this.completePartiallyCommittedElements();
2245
+ await this.completePartiallyCommittedAspects();
2269
2246
  if (this._options.optimizeGeometry)
2270
2247
  this.importer.optimizeGeometry(this._options.optimizeGeometry);
2271
2248
  this.importer.computeProjectExtents();
@@ -2373,11 +2350,11 @@ class TemplateModelCloner extends IModelTransformer {
2373
2350
  return this._sourceIdToTargetIdMap; // return the sourceElementId -> targetElementId Map in case further post-processing is required.
2374
2351
  }
2375
2352
  /** Cloning from a template requires this override of onTransformElement. */
2376
- onTransformElement(sourceElement) {
2353
+ async onTransformElement(sourceElement) {
2377
2354
  const referenceIds = sourceElement.getReferenceIds();
2378
- referenceIds.forEach((referenceId) => {
2355
+ for (const referenceId of referenceIds) {
2379
2356
  // TODO: consider going through all definition elements at once and remapping them to themselves
2380
- if (!core_backend_1.EntityReferences.isValid(this.context.findTargetEntityId(referenceId))) {
2357
+ if (!core_backend_1.EntityReferences.isValid(await this.context.findTargetEntityId(referenceId))) {
2381
2358
  if (this.context.isBetweenIModels) {
2382
2359
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, `Remapping for source dependency ${referenceId} not found for target iModel`);
2383
2360
  }
@@ -2392,8 +2369,8 @@ class TemplateModelCloner extends IModelTransformer {
2392
2369
  }
2393
2370
  }
2394
2371
  }
2395
- });
2396
- const targetElementProps = super.onTransformElement(sourceElement);
2372
+ }
2373
+ const targetElementProps = await super.onTransformElement(sourceElement);
2397
2374
  targetElementProps.federationGuid = core_bentley_1.Guid.createValue(); // clone from template should create a new federationGuid
2398
2375
  targetElementProps.code = core_common_1.Code.createEmpty(); // clone from template should not maintain codes
2399
2376
  if (sourceElement instanceof core_backend_1.GeometricElement) {
@@ -2411,6 +2388,7 @@ class TemplateModelCloner extends IModelTransformer {
2411
2388
  }
2412
2389
  }
2413
2390
  exports.TemplateModelCloner = TemplateModelCloner;
2391
+ //Deprecate in preference of imodeldb.elements.getFederationGuidFromId()?
2414
2392
  function queryElemFedGuid(db, elemId) {
2415
2393
  // eslint-disable-next-line @itwin/no-internal, @typescript-eslint/no-deprecated
2416
2394
  return db.withPreparedStatement(`