@itwin/core-backend 5.7.0-dev.12 → 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 (65) 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/cjs/ViewDefinition.d.ts.map +1 -1
  24. package/lib/cjs/ViewDefinition.js +2 -0
  25. package/lib/cjs/ViewDefinition.js.map +1 -1
  26. package/lib/esm/BriefcaseManager.d.ts +138 -1
  27. package/lib/esm/BriefcaseManager.d.ts.map +1 -1
  28. package/lib/esm/BriefcaseManager.js +336 -1
  29. package/lib/esm/BriefcaseManager.js.map +1 -1
  30. package/lib/esm/CloudSqlite.js +1 -1
  31. package/lib/esm/CloudSqlite.js.map +1 -1
  32. package/lib/esm/IModelDb.d.ts +14 -0
  33. package/lib/esm/IModelDb.d.ts.map +1 -1
  34. package/lib/esm/IModelDb.js +71 -6
  35. package/lib/esm/IModelDb.js.map +1 -1
  36. package/lib/esm/IModelHost.d.ts +15 -0
  37. package/lib/esm/IModelHost.d.ts.map +1 -1
  38. package/lib/esm/IModelHost.js +12 -0
  39. package/lib/esm/IModelHost.js.map +1 -1
  40. package/lib/esm/IModelJsFs.d.ts +2 -0
  41. package/lib/esm/IModelJsFs.d.ts.map +1 -1
  42. package/lib/esm/IModelJsFs.js +2 -0
  43. package/lib/esm/IModelJsFs.js.map +1 -1
  44. package/lib/esm/TxnManager.d.ts +39 -0
  45. package/lib/esm/TxnManager.d.ts.map +1 -1
  46. package/lib/esm/TxnManager.js +150 -1
  47. package/lib/esm/TxnManager.js.map +1 -1
  48. package/lib/esm/ViewDefinition.d.ts.map +1 -1
  49. package/lib/esm/ViewDefinition.js +2 -0
  50. package/lib/esm/ViewDefinition.js.map +1 -1
  51. package/lib/esm/test/SquashSchemaAndDataChanges.test.d.ts +2 -0
  52. package/lib/esm/test/SquashSchemaAndDataChanges.test.d.ts.map +1 -0
  53. package/lib/esm/test/SquashSchemaAndDataChanges.test.js +241 -0
  54. package/lib/esm/test/SquashSchemaAndDataChanges.test.js.map +1 -0
  55. package/lib/esm/test/hubaccess/Rebase.test.js +1575 -1568
  56. package/lib/esm/test/hubaccess/Rebase.test.js.map +1 -1
  57. package/lib/esm/test/hubaccess/SemanticRebase.test.d.ts +2 -0
  58. package/lib/esm/test/hubaccess/SemanticRebase.test.d.ts.map +1 -0
  59. package/lib/esm/test/hubaccess/SemanticRebase.test.js +1206 -0
  60. package/lib/esm/test/hubaccess/SemanticRebase.test.js.map +1 -0
  61. package/lib/esm/test/standalone/ViewDefinition.test.js +14 -2
  62. package/lib/esm/test/standalone/ViewDefinition.test.js.map +1 -1
  63. package/lib/esm/test/standalone/Workspace.test.js +5 -0
  64. package/lib/esm/test/standalone/Workspace.test.js.map +1 -1
  65. package/package.json +13 -13
@@ -739,7 +739,7 @@ export class IModelDb extends IModel {
739
739
  saveChanges(descriptionOrArgs) {
740
740
  if (this.openMode === OpenMode.Readonly)
741
741
  throw new IModelError(IModelStatus.ReadOnly, "IModelDb was opened read-only");
742
- if (this instanceof BriefcaseDb) {
742
+ if (this.isBriefcaseDb()) {
743
743
  if (this.txns.isIndirectChanges) {
744
744
  throw new IModelError(IModelStatus.BadRequest, "Cannot save changes while in an indirect change scope");
745
745
  }
@@ -792,6 +792,21 @@ export class IModelDb extends IModel {
792
792
  restartTxnSession() {
793
793
  return this[_nativeDb].restartTxnSession();
794
794
  }
795
+ /**
796
+ * Get the class full name from a class Id.
797
+ * @param classId the Id of the class to look up
798
+ * @returns the full name of the class (e.g. "BisCore:Element")
799
+ * @throws IModelError if the classId is invalid or the class is not found.
800
+ * @internal
801
+ */
802
+ getClassNameFromId(classId) {
803
+ if (!Id64.isValid(classId))
804
+ throw new IModelError(IModelStatus.BadRequest, `Class Id ${classId} is invalid`);
805
+ const name = this[_nativeDb].classIdToName(classId);
806
+ if (name === undefined)
807
+ throw new IModelError(IModelStatus.NotFound, `Class not found: ${classId}`);
808
+ return name;
809
+ }
795
810
  /** Removes unused schemas from the database.
796
811
  *
797
812
  * If the removal was successful, the database is automatically saved to disk.
@@ -853,6 +868,9 @@ export class IModelDb extends IModel {
853
868
  }
854
869
  callbackResources.cachedData = callbackResult.cachedData;
855
870
  }
871
+ if (this.isBriefcaseDb() && IModelHost.useSemanticRebase) {
872
+ this.saveChanges("Save changes from schema import pre callback");
873
+ }
856
874
  }
857
875
  }
858
876
  catch (callbackError) {
@@ -872,6 +890,9 @@ export class IModelDb extends IModel {
872
890
  try {
873
891
  if (callback?.postSchemaImportCallback)
874
892
  await callback.postSchemaImportCallback(context);
893
+ if (this.isBriefcaseDb() && IModelHost.useSemanticRebase) {
894
+ this.saveChanges("Save changes from schema import post callback");
895
+ }
875
896
  }
876
897
  catch (callbackError) {
877
898
  this.abandonChanges();
@@ -884,17 +905,31 @@ export class IModelDb extends IModel {
884
905
  }
885
906
  /** Shared implementation for importing schemas from file or string. */
886
907
  async importSchemasInternal(schemas, options, nativeImportOp) {
887
- if (this instanceof BriefcaseDb) {
908
+ // BriefcaseDb-specific validation checks
909
+ if (this.isBriefcaseDb()) {
888
910
  if (this.txns.rebaser.isRebasing) {
889
911
  throw new IModelError(IModelStatus.BadRequest, "Cannot import schemas while rebasing");
890
912
  }
891
913
  if (this.txns.isIndirectChanges) {
892
914
  throw new IModelError(IModelStatus.BadRequest, "Cannot import schemas while in an indirect change scope");
893
915
  }
916
+ // Additional checks when semantic rebase is enabled
917
+ if (IModelHost.useSemanticRebase) {
918
+ if (this[_nativeDb].hasUnsavedChanges()) {
919
+ throw new IModelError(IModelStatus.BadRequest, "Cannot import schemas with unsaved changes when useSemanticRebase flag is on");
920
+ }
921
+ if (this[_nativeDb].schemaSyncEnabled()) {
922
+ throw new IModelError(IModelStatus.BadRequest, "Cannot import schemas when schema sync is enabled and also useSemanticRebase flag is on");
923
+ }
924
+ }
894
925
  }
895
926
  if (options?.channelUpgrade) {
896
927
  try {
897
928
  await this.channels.upgradeChannel(options.channelUpgrade, this, options.data);
929
+ // If semantic rebase is enabled and channel upgrade made changes, save them
930
+ if (this.isBriefcaseDb() && IModelHost.useSemanticRebase) {
931
+ this.saveChanges();
932
+ }
898
933
  }
899
934
  catch (error) {
900
935
  this.abandonChanges();
@@ -935,8 +970,16 @@ export class IModelDb extends IModel {
935
970
  schemaLockHeld: true,
936
971
  ecSchemaXmlContext: maybeCustomNativeContext,
937
972
  };
938
- if (this[_nativeDb].getITwinId() !== Guid.empty) // if this iModel is associated with an iTwin, importing schema requires the schema lock
939
- await this.acquireSchemaLock();
973
+ // This check is different from isBriefcase in case of StandaloneDb, which is a briefcase but has no iTwinId.
974
+ if (this[_nativeDb].getITwinId() !== Guid.empty) { // if this iModel is associated with an iTwin, importing schema requires the schema lock
975
+ if (IModelHost.useSemanticRebase) {
976
+ // Use shared lock for semantic rebase to allow concurrent schema imports
977
+ await this.locks.acquireLocks({ shared: IModel.repositoryModelId });
978
+ }
979
+ else {
980
+ await this.acquireSchemaLock();
981
+ }
982
+ }
940
983
  try {
941
984
  nativeImportOp(schemas, nativeImportOptions);
942
985
  }
@@ -945,6 +988,17 @@ export class IModelDb extends IModel {
945
988
  }
946
989
  }
947
990
  this.clearCaches();
991
+ // Store schemas for semantic rebase (BriefcaseDb only)
992
+ if (this.isBriefcaseDb() && IModelHost.useSemanticRebase) {
993
+ const lastSavedTxnProps = this.txns.getLastSavedTxnProps();
994
+ if (lastSavedTxnProps === undefined) {
995
+ throw new IModelError(IModelStatus.BadRequest, "After schema import, no last saved transaction found");
996
+ }
997
+ if (lastSavedTxnProps.type !== "Schema" && lastSavedTxnProps.type !== "ECSchema") {
998
+ throw new IModelError(IModelStatus.BadRequest, "After schema import, last saved transaction is not a Schema transaction");
999
+ }
1000
+ BriefcaseManager.storeSchemasForSemanticRebase(this, lastSavedTxnProps.id, schemas);
1001
+ }
948
1002
  if (options?.schemaImportCallbacks?.postSchemaImportCallback)
949
1003
  await this.postSchemaImportCallback(options.schemaImportCallbacks, { iModel: this, resources: preSchemaImportCallbackResult, data: options.data });
950
1004
  }
@@ -1430,7 +1484,7 @@ export class IModelDb extends IModel {
1430
1484
  * @note This method should not be called from {TxnManager.withIndirectTxnModeAsync} or {TxnManager.withIndirectTxnMode}.
1431
1485
  */
1432
1486
  saveFileProperty(prop, strValue, blobVal) {
1433
- if (this instanceof BriefcaseDb) {
1487
+ if (this.isBriefcaseDb()) {
1434
1488
  if (this.txns.isIndirectChanges) {
1435
1489
  throw new IModelError(IModelStatus.BadRequest, "Cannot save file property while in an indirect change scope");
1436
1490
  }
@@ -1442,7 +1496,7 @@ export class IModelDb extends IModel {
1442
1496
  * @note This method should not be called from {TxnManager.withIndirectTxnModeAsync} or {TxnManager.withIndirectTxnMode}.
1443
1497
  */
1444
1498
  deleteFileProperty(prop) {
1445
- if (this instanceof BriefcaseDb) {
1499
+ if (this.isBriefcaseDb()) {
1446
1500
  if (this.txns.isIndirectChanges) {
1447
1501
  throw new IModelError(IModelStatus.BadRequest, "Cannot delete file property while in an indirect change scope");
1448
1502
  }
@@ -2946,6 +3000,7 @@ export class BriefcaseDb extends IModelDb {
2946
3000
  this.clearCaches();
2947
3001
  this[_nativeDb].discardLocalChanges();
2948
3002
  this[_resetIModelDb]();
3003
+ BriefcaseManager.deleteRebaseFolders(this);
2949
3004
  if (args?.retainLocks) {
2950
3005
  return;
2951
3006
  }
@@ -3118,6 +3173,15 @@ export class BriefcaseDb extends IModelDb {
3118
3173
  this.onOpened.raiseEvent(briefcaseDb, args);
3119
3174
  return briefcaseDb;
3120
3175
  }
3176
+ /**
3177
+ * Iterate through the existing transactions to see if any of them are schema transactions.
3178
+ * @returns true if any schema transactions exist.
3179
+ * @beta
3180
+ */
3181
+ checkIfSchemaTxnExists() {
3182
+ const txnProps = Array.from(this.txns.queryTxns());
3183
+ return txnProps.some((props) => props.type === "Schema" || props.type === "ECSchema");
3184
+ }
3121
3185
  /** This is called by native code when applying a changeset */
3122
3186
  onChangesetConflict(args) {
3123
3187
  // returning undefined will result in native handler to resolve conflict
@@ -3402,6 +3466,7 @@ export class BriefcaseDb extends IModelDb {
3402
3466
  this.initializeIModelDb("pullMerge");
3403
3467
  });
3404
3468
  this.txns._onChangesPushed(this.changeset);
3469
+ BriefcaseManager.deleteRebaseFolders(this);
3405
3470
  }
3406
3471
  close(options) {
3407
3472
  if (this.isBriefcase && this.isOpen && !this.isReadonly && this.txns.rebaser.inProgress()) {