@itwin/core-backend 5.7.0-dev.13 → 5.7.0-dev.14

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 (57) hide show
  1. package/lib/cjs/BriefcaseManager.d.ts +138 -1
  2. package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
  3. package/lib/cjs/BriefcaseManager.js +336 -1
  4. package/lib/cjs/BriefcaseManager.js.map +1 -1
  5. package/lib/cjs/CloudSqlite.js +1 -1
  6. package/lib/cjs/CloudSqlite.js.map +1 -1
  7. package/lib/cjs/IModelDb.d.ts +14 -0
  8. package/lib/cjs/IModelDb.d.ts.map +1 -1
  9. package/lib/cjs/IModelDb.js +71 -6
  10. package/lib/cjs/IModelDb.js.map +1 -1
  11. package/lib/cjs/IModelHost.d.ts +15 -0
  12. package/lib/cjs/IModelHost.d.ts.map +1 -1
  13. package/lib/cjs/IModelHost.js +12 -0
  14. package/lib/cjs/IModelHost.js.map +1 -1
  15. package/lib/cjs/IModelJsFs.d.ts +2 -0
  16. package/lib/cjs/IModelJsFs.d.ts.map +1 -1
  17. package/lib/cjs/IModelJsFs.js +2 -0
  18. package/lib/cjs/IModelJsFs.js.map +1 -1
  19. package/lib/cjs/TxnManager.d.ts +39 -0
  20. package/lib/cjs/TxnManager.d.ts.map +1 -1
  21. package/lib/cjs/TxnManager.js +149 -0
  22. package/lib/cjs/TxnManager.js.map +1 -1
  23. package/lib/esm/BriefcaseManager.d.ts +138 -1
  24. package/lib/esm/BriefcaseManager.d.ts.map +1 -1
  25. package/lib/esm/BriefcaseManager.js +336 -1
  26. package/lib/esm/BriefcaseManager.js.map +1 -1
  27. package/lib/esm/CloudSqlite.js +1 -1
  28. package/lib/esm/CloudSqlite.js.map +1 -1
  29. package/lib/esm/IModelDb.d.ts +14 -0
  30. package/lib/esm/IModelDb.d.ts.map +1 -1
  31. package/lib/esm/IModelDb.js +71 -6
  32. package/lib/esm/IModelDb.js.map +1 -1
  33. package/lib/esm/IModelHost.d.ts +15 -0
  34. package/lib/esm/IModelHost.d.ts.map +1 -1
  35. package/lib/esm/IModelHost.js +12 -0
  36. package/lib/esm/IModelHost.js.map +1 -1
  37. package/lib/esm/IModelJsFs.d.ts +2 -0
  38. package/lib/esm/IModelJsFs.d.ts.map +1 -1
  39. package/lib/esm/IModelJsFs.js +2 -0
  40. package/lib/esm/IModelJsFs.js.map +1 -1
  41. package/lib/esm/TxnManager.d.ts +39 -0
  42. package/lib/esm/TxnManager.d.ts.map +1 -1
  43. package/lib/esm/TxnManager.js +150 -1
  44. package/lib/esm/TxnManager.js.map +1 -1
  45. package/lib/esm/test/SquashSchemaAndDataChanges.test.d.ts +2 -0
  46. package/lib/esm/test/SquashSchemaAndDataChanges.test.d.ts.map +1 -0
  47. package/lib/esm/test/SquashSchemaAndDataChanges.test.js +241 -0
  48. package/lib/esm/test/SquashSchemaAndDataChanges.test.js.map +1 -0
  49. package/lib/esm/test/hubaccess/Rebase.test.js +1575 -1568
  50. package/lib/esm/test/hubaccess/Rebase.test.js.map +1 -1
  51. package/lib/esm/test/hubaccess/SemanticRebase.test.d.ts +2 -0
  52. package/lib/esm/test/hubaccess/SemanticRebase.test.d.ts.map +1 -0
  53. package/lib/esm/test/hubaccess/SemanticRebase.test.js +1206 -0
  54. package/lib/esm/test/hubaccess/SemanticRebase.test.js.map +1 -0
  55. package/lib/esm/test/standalone/Workspace.test.js +5 -0
  56. package/lib/esm/test/standalone/Workspace.test.js.map +1 -1
  57. package/package.json +14 -14
@@ -742,7 +742,7 @@ class IModelDb extends core_common_1.IModel {
742
742
  saveChanges(descriptionOrArgs) {
743
743
  if (this.openMode === core_bentley_1.OpenMode.Readonly)
744
744
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.ReadOnly, "IModelDb was opened read-only");
745
- if (this instanceof BriefcaseDb) {
745
+ if (this.isBriefcaseDb()) {
746
746
  if (this.txns.isIndirectChanges) {
747
747
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot save changes while in an indirect change scope");
748
748
  }
@@ -795,6 +795,21 @@ class IModelDb extends core_common_1.IModel {
795
795
  restartTxnSession() {
796
796
  return this[Symbols_1._nativeDb].restartTxnSession();
797
797
  }
798
+ /**
799
+ * Get the class full name from a class Id.
800
+ * @param classId the Id of the class to look up
801
+ * @returns the full name of the class (e.g. "BisCore:Element")
802
+ * @throws IModelError if the classId is invalid or the class is not found.
803
+ * @internal
804
+ */
805
+ getClassNameFromId(classId) {
806
+ if (!core_bentley_1.Id64.isValid(classId))
807
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, `Class Id ${classId} is invalid`);
808
+ const name = this[Symbols_1._nativeDb].classIdToName(classId);
809
+ if (name === undefined)
810
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NotFound, `Class not found: ${classId}`);
811
+ return name;
812
+ }
798
813
  /** Removes unused schemas from the database.
799
814
  *
800
815
  * If the removal was successful, the database is automatically saved to disk.
@@ -856,6 +871,9 @@ class IModelDb extends core_common_1.IModel {
856
871
  }
857
872
  callbackResources.cachedData = callbackResult.cachedData;
858
873
  }
874
+ if (this.isBriefcaseDb() && IModelHost_1.IModelHost.useSemanticRebase) {
875
+ this.saveChanges("Save changes from schema import pre callback");
876
+ }
859
877
  }
860
878
  }
861
879
  catch (callbackError) {
@@ -875,6 +893,9 @@ class IModelDb extends core_common_1.IModel {
875
893
  try {
876
894
  if (callback?.postSchemaImportCallback)
877
895
  await callback.postSchemaImportCallback(context);
896
+ if (this.isBriefcaseDb() && IModelHost_1.IModelHost.useSemanticRebase) {
897
+ this.saveChanges("Save changes from schema import post callback");
898
+ }
878
899
  }
879
900
  catch (callbackError) {
880
901
  this.abandonChanges();
@@ -887,17 +908,31 @@ class IModelDb extends core_common_1.IModel {
887
908
  }
888
909
  /** Shared implementation for importing schemas from file or string. */
889
910
  async importSchemasInternal(schemas, options, nativeImportOp) {
890
- if (this instanceof BriefcaseDb) {
911
+ // BriefcaseDb-specific validation checks
912
+ if (this.isBriefcaseDb()) {
891
913
  if (this.txns.rebaser.isRebasing) {
892
914
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas while rebasing");
893
915
  }
894
916
  if (this.txns.isIndirectChanges) {
895
917
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas while in an indirect change scope");
896
918
  }
919
+ // Additional checks when semantic rebase is enabled
920
+ if (IModelHost_1.IModelHost.useSemanticRebase) {
921
+ if (this[Symbols_1._nativeDb].hasUnsavedChanges()) {
922
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas with unsaved changes when useSemanticRebase flag is on");
923
+ }
924
+ if (this[Symbols_1._nativeDb].schemaSyncEnabled()) {
925
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas when schema sync is enabled and also useSemanticRebase flag is on");
926
+ }
927
+ }
897
928
  }
898
929
  if (options?.channelUpgrade) {
899
930
  try {
900
931
  await this.channels.upgradeChannel(options.channelUpgrade, this, options.data);
932
+ // If semantic rebase is enabled and channel upgrade made changes, save them
933
+ if (this.isBriefcaseDb() && IModelHost_1.IModelHost.useSemanticRebase) {
934
+ this.saveChanges();
935
+ }
901
936
  }
902
937
  catch (error) {
903
938
  this.abandonChanges();
@@ -938,8 +973,16 @@ class IModelDb extends core_common_1.IModel {
938
973
  schemaLockHeld: true,
939
974
  ecSchemaXmlContext: maybeCustomNativeContext,
940
975
  };
941
- if (this[Symbols_1._nativeDb].getITwinId() !== core_bentley_1.Guid.empty) // if this iModel is associated with an iTwin, importing schema requires the schema lock
942
- await this.acquireSchemaLock();
976
+ // This check is different from isBriefcase in case of StandaloneDb, which is a briefcase but has no iTwinId.
977
+ if (this[Symbols_1._nativeDb].getITwinId() !== core_bentley_1.Guid.empty) { // if this iModel is associated with an iTwin, importing schema requires the schema lock
978
+ if (IModelHost_1.IModelHost.useSemanticRebase) {
979
+ // Use shared lock for semantic rebase to allow concurrent schema imports
980
+ await this.locks.acquireLocks({ shared: core_common_1.IModel.repositoryModelId });
981
+ }
982
+ else {
983
+ await this.acquireSchemaLock();
984
+ }
985
+ }
943
986
  try {
944
987
  nativeImportOp(schemas, nativeImportOptions);
945
988
  }
@@ -948,6 +991,17 @@ class IModelDb extends core_common_1.IModel {
948
991
  }
949
992
  }
950
993
  this.clearCaches();
994
+ // Store schemas for semantic rebase (BriefcaseDb only)
995
+ if (this.isBriefcaseDb() && IModelHost_1.IModelHost.useSemanticRebase) {
996
+ const lastSavedTxnProps = this.txns.getLastSavedTxnProps();
997
+ if (lastSavedTxnProps === undefined) {
998
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "After schema import, no last saved transaction found");
999
+ }
1000
+ if (lastSavedTxnProps.type !== "Schema" && lastSavedTxnProps.type !== "ECSchema") {
1001
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "After schema import, last saved transaction is not a Schema transaction");
1002
+ }
1003
+ BriefcaseManager_1.BriefcaseManager.storeSchemasForSemanticRebase(this, lastSavedTxnProps.id, schemas);
1004
+ }
951
1005
  if (options?.schemaImportCallbacks?.postSchemaImportCallback)
952
1006
  await this.postSchemaImportCallback(options.schemaImportCallbacks, { iModel: this, resources: preSchemaImportCallbackResult, data: options.data });
953
1007
  }
@@ -1433,7 +1487,7 @@ class IModelDb extends core_common_1.IModel {
1433
1487
  * @note This method should not be called from {TxnManager.withIndirectTxnModeAsync} or {TxnManager.withIndirectTxnMode}.
1434
1488
  */
1435
1489
  saveFileProperty(prop, strValue, blobVal) {
1436
- if (this instanceof BriefcaseDb) {
1490
+ if (this.isBriefcaseDb()) {
1437
1491
  if (this.txns.isIndirectChanges) {
1438
1492
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot save file property while in an indirect change scope");
1439
1493
  }
@@ -1445,7 +1499,7 @@ class IModelDb extends core_common_1.IModel {
1445
1499
  * @note This method should not be called from {TxnManager.withIndirectTxnModeAsync} or {TxnManager.withIndirectTxnMode}.
1446
1500
  */
1447
1501
  deleteFileProperty(prop) {
1448
- if (this instanceof BriefcaseDb) {
1502
+ if (this.isBriefcaseDb()) {
1449
1503
  if (this.txns.isIndirectChanges) {
1450
1504
  throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot delete file property while in an indirect change scope");
1451
1505
  }
@@ -2950,6 +3004,7 @@ class BriefcaseDb extends IModelDb {
2950
3004
  this.clearCaches();
2951
3005
  this[Symbols_1._nativeDb].discardLocalChanges();
2952
3006
  this[Symbols_1._resetIModelDb]();
3007
+ BriefcaseManager_1.BriefcaseManager.deleteRebaseFolders(this);
2953
3008
  if (args?.retainLocks) {
2954
3009
  return;
2955
3010
  }
@@ -3122,6 +3177,15 @@ class BriefcaseDb extends IModelDb {
3122
3177
  this.onOpened.raiseEvent(briefcaseDb, args);
3123
3178
  return briefcaseDb;
3124
3179
  }
3180
+ /**
3181
+ * Iterate through the existing transactions to see if any of them are schema transactions.
3182
+ * @returns true if any schema transactions exist.
3183
+ * @beta
3184
+ */
3185
+ checkIfSchemaTxnExists() {
3186
+ const txnProps = Array.from(this.txns.queryTxns());
3187
+ return txnProps.some((props) => props.type === "Schema" || props.type === "ECSchema");
3188
+ }
3125
3189
  /** This is called by native code when applying a changeset */
3126
3190
  onChangesetConflict(args) {
3127
3191
  // returning undefined will result in native handler to resolve conflict
@@ -3406,6 +3470,7 @@ class BriefcaseDb extends IModelDb {
3406
3470
  this.initializeIModelDb("pullMerge");
3407
3471
  });
3408
3472
  this.txns._onChangesPushed(this.changeset);
3473
+ BriefcaseManager_1.BriefcaseManager.deleteRebaseFolders(this);
3409
3474
  }
3410
3475
  close(options) {
3411
3476
  if (this.isBriefcase && this.isOpen && !this.isReadonly && this.txns.rebaser.inProgress()) {