@itwin/core-backend 5.13.0-dev.9 → 5.13.0

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 (261) hide show
  1. package/CHANGELOG.md +53 -1
  2. package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
  3. package/lib/cjs/BriefcaseManager.js +11 -5
  4. package/lib/cjs/BriefcaseManager.js.map +1 -1
  5. package/lib/cjs/Category.d.ts +4 -4
  6. package/lib/cjs/Category.js.map +1 -1
  7. package/lib/cjs/ChangesetECAdaptor.d.ts +5 -0
  8. package/lib/cjs/ChangesetECAdaptor.d.ts.map +1 -1
  9. package/lib/cjs/ChangesetECAdaptor.js +13 -3
  10. package/lib/cjs/ChangesetECAdaptor.js.map +1 -1
  11. package/lib/cjs/CloudSqlite.d.ts.map +1 -1
  12. package/lib/cjs/CloudSqlite.js +9 -2
  13. package/lib/cjs/CloudSqlite.js.map +1 -1
  14. package/lib/cjs/CodeSpecs.d.ts +3 -3
  15. package/lib/cjs/CodeSpecs.js.map +1 -1
  16. package/lib/cjs/DisplayStyle.d.ts +2 -2
  17. package/lib/cjs/DisplayStyle.js.map +1 -1
  18. package/lib/cjs/ECDb.d.ts.map +1 -1
  19. package/lib/cjs/ECDb.js +1 -0
  20. package/lib/cjs/ECDb.js.map +1 -1
  21. package/lib/cjs/EditTxn.d.ts.map +1 -1
  22. package/lib/cjs/EditTxn.js +1 -0
  23. package/lib/cjs/EditTxn.js.map +1 -1
  24. package/lib/cjs/Element.d.ts +48 -12
  25. package/lib/cjs/Element.d.ts.map +1 -1
  26. package/lib/cjs/Element.js +120 -24
  27. package/lib/cjs/Element.js.map +1 -1
  28. package/lib/cjs/IModelDb.d.ts +72 -22
  29. package/lib/cjs/IModelDb.d.ts.map +1 -1
  30. package/lib/cjs/IModelDb.js +226 -89
  31. package/lib/cjs/IModelDb.js.map +1 -1
  32. package/lib/cjs/Model.d.ts +5 -5
  33. package/lib/cjs/Model.d.ts.map +1 -1
  34. package/lib/cjs/Model.js.map +1 -1
  35. package/lib/cjs/PropertyStore.js +1 -1
  36. package/lib/cjs/PropertyStore.js.map +1 -1
  37. package/lib/cjs/SchemaSync.d.ts +158 -22
  38. package/lib/cjs/SchemaSync.d.ts.map +1 -1
  39. package/lib/cjs/SchemaSync.js +417 -76
  40. package/lib/cjs/SchemaSync.js.map +1 -1
  41. package/lib/cjs/SynchronousChannel.d.ts +72 -0
  42. package/lib/cjs/SynchronousChannel.d.ts.map +1 -0
  43. package/lib/cjs/SynchronousChannel.js +11 -0
  44. package/lib/cjs/SynchronousChannel.js.map +1 -0
  45. package/lib/cjs/Texture.d.ts +1 -1
  46. package/lib/cjs/Texture.js.map +1 -1
  47. package/lib/cjs/TxnManager.d.ts +44 -4
  48. package/lib/cjs/TxnManager.d.ts.map +1 -1
  49. package/lib/cjs/TxnManager.js +80 -19
  50. package/lib/cjs/TxnManager.js.map +1 -1
  51. package/lib/cjs/ViewDefinition.d.ts +6 -6
  52. package/lib/cjs/ViewDefinition.d.ts.map +1 -1
  53. package/lib/cjs/ViewDefinition.js.map +1 -1
  54. package/lib/cjs/annotations/LeaderGeometry.d.ts +22 -7
  55. package/lib/cjs/annotations/LeaderGeometry.d.ts.map +1 -1
  56. package/lib/cjs/annotations/LeaderGeometry.js +104 -36
  57. package/lib/cjs/annotations/LeaderGeometry.js.map +1 -1
  58. package/lib/cjs/annotations/TextAnnotationElement.d.ts +1 -1
  59. package/lib/cjs/annotations/TextAnnotationElement.d.ts.map +1 -1
  60. package/lib/cjs/annotations/TextAnnotationElement.js +25 -10
  61. package/lib/cjs/annotations/TextAnnotationElement.js.map +1 -1
  62. package/lib/cjs/core-backend.d.ts +1 -0
  63. package/lib/cjs/core-backend.d.ts.map +1 -1
  64. package/lib/cjs/core-backend.js +1 -0
  65. package/lib/cjs/core-backend.js.map +1 -1
  66. package/lib/cjs/internal/IntegrityCheck.d.ts +22 -0
  67. package/lib/cjs/internal/IntegrityCheck.d.ts.map +1 -1
  68. package/lib/cjs/internal/IntegrityCheck.js +13 -0
  69. package/lib/cjs/internal/IntegrityCheck.js.map +1 -1
  70. package/lib/cjs/internal/NoReservations.d.ts +6 -0
  71. package/lib/cjs/internal/NoReservations.d.ts.map +1 -0
  72. package/lib/cjs/internal/NoReservations.js +21 -0
  73. package/lib/cjs/internal/NoReservations.js.map +1 -0
  74. package/lib/cjs/internal/SchemaSyncReservations.d.ts +4 -0
  75. package/lib/cjs/internal/SchemaSyncReservations.d.ts.map +1 -0
  76. package/lib/cjs/internal/SchemaSyncReservations.js +128 -0
  77. package/lib/cjs/internal/SchemaSyncReservations.js.map +1 -0
  78. package/lib/cjs/internal/Symbols.d.ts +1 -0
  79. package/lib/cjs/internal/Symbols.d.ts.map +1 -1
  80. package/lib/cjs/internal/Symbols.js +2 -1
  81. package/lib/cjs/internal/Symbols.js.map +1 -1
  82. package/lib/esm/BriefcaseManager.d.ts.map +1 -1
  83. package/lib/esm/BriefcaseManager.js +11 -5
  84. package/lib/esm/BriefcaseManager.js.map +1 -1
  85. package/lib/esm/Category.d.ts +4 -4
  86. package/lib/esm/Category.js.map +1 -1
  87. package/lib/esm/ChangesetECAdaptor.d.ts +5 -0
  88. package/lib/esm/ChangesetECAdaptor.d.ts.map +1 -1
  89. package/lib/esm/ChangesetECAdaptor.js +13 -3
  90. package/lib/esm/ChangesetECAdaptor.js.map +1 -1
  91. package/lib/esm/CloudSqlite.d.ts.map +1 -1
  92. package/lib/esm/CloudSqlite.js +10 -3
  93. package/lib/esm/CloudSqlite.js.map +1 -1
  94. package/lib/esm/CodeSpecs.d.ts +3 -3
  95. package/lib/esm/CodeSpecs.js.map +1 -1
  96. package/lib/esm/DisplayStyle.d.ts +2 -2
  97. package/lib/esm/DisplayStyle.js.map +1 -1
  98. package/lib/esm/ECDb.d.ts.map +1 -1
  99. package/lib/esm/ECDb.js +1 -0
  100. package/lib/esm/ECDb.js.map +1 -1
  101. package/lib/esm/EditTxn.d.ts.map +1 -1
  102. package/lib/esm/EditTxn.js +1 -0
  103. package/lib/esm/EditTxn.js.map +1 -1
  104. package/lib/esm/Element.d.ts +48 -12
  105. package/lib/esm/Element.d.ts.map +1 -1
  106. package/lib/esm/Element.js +121 -25
  107. package/lib/esm/Element.js.map +1 -1
  108. package/lib/esm/IModelDb.d.ts +72 -22
  109. package/lib/esm/IModelDb.d.ts.map +1 -1
  110. package/lib/esm/IModelDb.js +227 -90
  111. package/lib/esm/IModelDb.js.map +1 -1
  112. package/lib/esm/Model.d.ts +5 -5
  113. package/lib/esm/Model.d.ts.map +1 -1
  114. package/lib/esm/Model.js.map +1 -1
  115. package/lib/esm/PropertyStore.js +1 -1
  116. package/lib/esm/PropertyStore.js.map +1 -1
  117. package/lib/esm/SchemaSync.d.ts +158 -22
  118. package/lib/esm/SchemaSync.d.ts.map +1 -1
  119. package/lib/esm/SchemaSync.js +419 -78
  120. package/lib/esm/SchemaSync.js.map +1 -1
  121. package/lib/esm/SynchronousChannel.d.ts +72 -0
  122. package/lib/esm/SynchronousChannel.d.ts.map +1 -0
  123. package/lib/esm/SynchronousChannel.js +9 -0
  124. package/lib/esm/SynchronousChannel.js.map +1 -0
  125. package/lib/esm/Texture.d.ts +1 -1
  126. package/lib/esm/Texture.js.map +1 -1
  127. package/lib/esm/TxnManager.d.ts +44 -4
  128. package/lib/esm/TxnManager.d.ts.map +1 -1
  129. package/lib/esm/TxnManager.js +81 -20
  130. package/lib/esm/TxnManager.js.map +1 -1
  131. package/lib/esm/ViewDefinition.d.ts +6 -6
  132. package/lib/esm/ViewDefinition.d.ts.map +1 -1
  133. package/lib/esm/ViewDefinition.js.map +1 -1
  134. package/lib/esm/annotations/LeaderGeometry.d.ts +22 -7
  135. package/lib/esm/annotations/LeaderGeometry.d.ts.map +1 -1
  136. package/lib/esm/annotations/LeaderGeometry.js +104 -36
  137. package/lib/esm/annotations/LeaderGeometry.js.map +1 -1
  138. package/lib/esm/annotations/TextAnnotationElement.d.ts +1 -1
  139. package/lib/esm/annotations/TextAnnotationElement.d.ts.map +1 -1
  140. package/lib/esm/annotations/TextAnnotationElement.js +25 -10
  141. package/lib/esm/annotations/TextAnnotationElement.js.map +1 -1
  142. package/lib/esm/core-backend.d.ts +1 -0
  143. package/lib/esm/core-backend.d.ts.map +1 -1
  144. package/lib/esm/core-backend.js +1 -0
  145. package/lib/esm/core-backend.js.map +1 -1
  146. package/lib/esm/internal/IntegrityCheck.d.ts +22 -0
  147. package/lib/esm/internal/IntegrityCheck.d.ts.map +1 -1
  148. package/lib/esm/internal/IntegrityCheck.js +13 -0
  149. package/lib/esm/internal/IntegrityCheck.js.map +1 -1
  150. package/lib/esm/internal/NoReservations.d.ts +6 -0
  151. package/lib/esm/internal/NoReservations.d.ts.map +1 -0
  152. package/lib/esm/internal/NoReservations.js +18 -0
  153. package/lib/esm/internal/NoReservations.js.map +1 -0
  154. package/lib/esm/internal/SchemaSyncReservations.d.ts +4 -0
  155. package/lib/esm/internal/SchemaSyncReservations.d.ts.map +1 -0
  156. package/lib/esm/internal/SchemaSyncReservations.js +125 -0
  157. package/lib/esm/internal/SchemaSyncReservations.js.map +1 -0
  158. package/lib/esm/internal/Symbols.d.ts +1 -0
  159. package/lib/esm/internal/Symbols.d.ts.map +1 -1
  160. package/lib/esm/internal/Symbols.js +1 -0
  161. package/lib/esm/internal/Symbols.js.map +1 -1
  162. package/lib/esm/test/IModelTestUtils.d.ts +1 -1
  163. package/lib/esm/test/IModelTestUtils.d.ts.map +1 -1
  164. package/lib/esm/test/IModelTestUtils.js +8 -3
  165. package/lib/esm/test/IModelTestUtils.js.map +1 -1
  166. package/lib/esm/test/annotations/LeaderGeometry.test.js +178 -2
  167. package/lib/esm/test/annotations/LeaderGeometry.test.js.map +1 -1
  168. package/lib/esm/test/annotations/TextAnnotation.test.js +48 -18
  169. package/lib/esm/test/annotations/TextAnnotation.test.js.map +1 -1
  170. package/lib/esm/test/ecdb/ECSqlStatement.test.js +177 -0
  171. package/lib/esm/test/ecdb/ECSqlStatement.test.js.map +1 -1
  172. package/lib/esm/test/ecdb/QueryReaders.test.js +2 -16
  173. package/lib/esm/test/ecdb/QueryReaders.test.js.map +1 -1
  174. package/lib/esm/test/ecsql/src/ECSqlTestRunner.test.js +2 -2
  175. package/lib/esm/test/ecsql/src/ECSqlTestRunner.test.js.map +1 -1
  176. package/lib/esm/test/element/ElementRoundTrip.test.js +80 -2
  177. package/lib/esm/test/element/ElementRoundTrip.test.js.map +1 -1
  178. package/lib/esm/test/hubaccess/Rebase.test.js +3 -1
  179. package/lib/esm/test/hubaccess/Rebase.test.js.map +1 -1
  180. package/lib/esm/test/hubaccess/SemanticRebase.test.js +29 -28
  181. package/lib/esm/test/hubaccess/SemanticRebase.test.js.map +1 -1
  182. package/lib/esm/test/hubaccess/SemanticRebaseTestUtils.d.ts +3 -0
  183. package/lib/esm/test/hubaccess/SemanticRebaseTestUtils.d.ts.map +1 -0
  184. package/lib/esm/test/hubaccess/SemanticRebaseTestUtils.js +15 -0
  185. package/lib/esm/test/hubaccess/SemanticRebaseTestUtils.js.map +1 -0
  186. package/lib/esm/test/imodel/IModelECSql.test.d.ts +2 -0
  187. package/lib/esm/test/imodel/IModelECSql.test.d.ts.map +1 -0
  188. package/lib/esm/test/imodel/IModelECSql.test.js +367 -0
  189. package/lib/esm/test/imodel/IModelECSql.test.js.map +1 -0
  190. package/lib/esm/test/imodel/IModelElements.test.d.ts +2 -0
  191. package/lib/esm/test/imodel/IModelElements.test.d.ts.map +1 -0
  192. package/lib/esm/test/imodel/IModelElements.test.js +969 -0
  193. package/lib/esm/test/imodel/IModelElements.test.js.map +1 -0
  194. package/lib/esm/test/imodel/IModelGeolocation.test.d.ts +2 -0
  195. package/lib/esm/test/imodel/IModelGeolocation.test.d.ts.map +1 -0
  196. package/lib/esm/test/imodel/IModelGeolocation.test.js +539 -0
  197. package/lib/esm/test/imodel/IModelGeolocation.test.js.map +1 -0
  198. package/lib/esm/test/imodel/IModelLifecycle.test.d.ts +2 -0
  199. package/lib/esm/test/imodel/IModelLifecycle.test.d.ts.map +1 -0
  200. package/lib/esm/test/imodel/IModelLifecycle.test.js +499 -0
  201. package/lib/esm/test/imodel/IModelLifecycle.test.js.map +1 -0
  202. package/lib/esm/test/imodel/IModelMetadata.test.d.ts +2 -0
  203. package/lib/esm/test/imodel/IModelMetadata.test.d.ts.map +1 -0
  204. package/lib/esm/test/imodel/IModelMetadata.test.js +274 -0
  205. package/lib/esm/test/imodel/IModelMetadata.test.js.map +1 -0
  206. package/lib/esm/test/imodel/IModelModels.test.d.ts +2 -0
  207. package/lib/esm/test/imodel/IModelModels.test.d.ts.map +1 -0
  208. package/lib/esm/test/imodel/IModelModels.test.js +357 -0
  209. package/lib/esm/test/imodel/IModelModels.test.js.map +1 -0
  210. package/lib/esm/test/imodel/IModelRelationships.test.d.ts +2 -0
  211. package/lib/esm/test/imodel/IModelRelationships.test.d.ts.map +1 -0
  212. package/lib/esm/test/imodel/IModelRelationships.test.js +407 -0
  213. package/lib/esm/test/imodel/IModelRelationships.test.js.map +1 -0
  214. package/lib/esm/test/imodel/IModelTestFixtures.d.ts +53 -0
  215. package/lib/esm/test/imodel/IModelTestFixtures.d.ts.map +1 -0
  216. package/lib/esm/test/imodel/IModelTestFixtures.js +107 -0
  217. package/lib/esm/test/imodel/IModelTestFixtures.js.map +1 -0
  218. package/lib/esm/test/imodel/IModelViews.test.d.ts +2 -0
  219. package/lib/esm/test/imodel/IModelViews.test.d.ts.map +1 -0
  220. package/lib/esm/test/imodel/IModelViews.test.js +199 -0
  221. package/lib/esm/test/imodel/IModelViews.test.js.map +1 -0
  222. package/lib/esm/test/index.d.ts +0 -1
  223. package/lib/esm/test/index.d.ts.map +1 -1
  224. package/lib/esm/test/index.js +0 -1
  225. package/lib/esm/test/index.js.map +1 -1
  226. package/lib/esm/test/standalone/ChangesetReader.test.js +8 -26
  227. package/lib/esm/test/standalone/ChangesetReader.test.js.map +1 -1
  228. package/lib/esm/test/standalone/DgnDomainMergeConflict.test.d.ts +2 -0
  229. package/lib/esm/test/standalone/DgnDomainMergeConflict.test.d.ts.map +1 -0
  230. package/lib/esm/test/standalone/DgnDomainMergeConflict.test.js +263 -0
  231. package/lib/esm/test/standalone/DgnDomainMergeConflict.test.js.map +1 -0
  232. package/lib/esm/test/standalone/GeometryStream.test.js +1 -3
  233. package/lib/esm/test/standalone/GeometryStream.test.js.map +1 -1
  234. package/lib/esm/test/standalone/IModelWrite.test.d.ts.map +1 -1
  235. package/lib/esm/test/standalone/IModelWrite.test.js +78 -1
  236. package/lib/esm/test/standalone/IModelWrite.test.js.map +1 -1
  237. package/lib/esm/test/standalone/IntegrityCheck.test.js +29 -10
  238. package/lib/esm/test/standalone/IntegrityCheck.test.js.map +1 -1
  239. package/lib/esm/test/standalone/SQliteChangesetReaderAndChangesetECAdaptor.test.js +23 -0
  240. package/lib/esm/test/standalone/SQliteChangesetReaderAndChangesetECAdaptor.test.js.map +1 -1
  241. package/lib/esm/test/standalone/SchemaSyncDb.test.d.ts +2 -0
  242. package/lib/esm/test/standalone/SchemaSyncDb.test.d.ts.map +1 -0
  243. package/lib/esm/test/standalone/SchemaSyncDb.test.js +201 -0
  244. package/lib/esm/test/standalone/SchemaSyncDb.test.js.map +1 -0
  245. package/lib/esm/test/standalone/SchemaSyncElementReservation.test.d.ts +2 -0
  246. package/lib/esm/test/standalone/SchemaSyncElementReservation.test.d.ts.map +1 -0
  247. package/lib/esm/test/standalone/SchemaSyncElementReservation.test.js +460 -0
  248. package/lib/esm/test/standalone/SchemaSyncElementReservation.test.js.map +1 -0
  249. package/lib/esm/test/standalone/SnapshotDb.test.js +1 -0
  250. package/lib/esm/test/standalone/SnapshotDb.test.js.map +1 -1
  251. package/lib/esm/test/standalone/TxnManager.test.js +108 -8
  252. package/lib/esm/test/standalone/TxnManager.test.js.map +1 -1
  253. package/package.json +13 -16
  254. package/lib/esm/test/RevisionUtility.d.ts +0 -33
  255. package/lib/esm/test/RevisionUtility.d.ts.map +0 -1
  256. package/lib/esm/test/RevisionUtility.js +0 -52
  257. package/lib/esm/test/RevisionUtility.js.map +0 -1
  258. package/lib/esm/test/imodel/IModel.test.d.ts +0 -2
  259. package/lib/esm/test/imodel/IModel.test.d.ts.map +0 -1
  260. package/lib/esm/test/imodel/IModel.test.js +0 -3277
  261. package/lib/esm/test/imodel/IModel.test.js.map +0 -1
@@ -48,7 +48,9 @@ const WorkspaceImpl_1 = require("./internal/workspace/WorkspaceImpl");
48
48
  const SettingsImpl_1 = require("./internal/workspace/SettingsImpl");
49
49
  const NativePlatform_1 = require("./internal/NativePlatform");
50
50
  const NoLocks_1 = require("./internal/NoLocks");
51
+ const NoReservations_1 = require("./internal/NoReservations");
51
52
  const IModelDbFontsImpl_1 = require("./internal/IModelDbFontsImpl");
53
+ const SchemaSyncReservations_1 = require("./internal/SchemaSyncReservations");
52
54
  const Symbols_1 = require("./internal/Symbols");
53
55
  const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
54
56
  const Schema_1 = require("./Schema");
@@ -178,6 +180,8 @@ class IModelDb extends core_common_1.IModel {
178
180
  /** @internal */
179
181
  _locks = (0, NoLocks_1.createNoOpLockControl)();
180
182
  /** @internal */
183
+ _reservations = (0, NoReservations_1.createNoOpReservations)();
184
+ /** @internal */
181
185
  _codeService;
182
186
  /**
183
187
  * The always-available implicit transaction for this iModel.
@@ -206,6 +210,16 @@ class IModelDb extends core_common_1.IModel {
206
210
  get codeService() { return this._codeService; }
207
211
  /** The [[LockControl]] that orchestrates [concurrent editing]($docs/learning/backend/ConcurrencyControl.md) of this iModel. */
208
212
  get locks() { return this._locks; } // eslint-disable-line @typescript-eslint/no-non-null-assertion
213
+ /** @beta The [[SynchronousChannel.Reservations]] that orchestrates [concurrent editing]($docs/learning/backend/ConcurrencyControl.md) of this iModel. */
214
+ get reservations() { return this._reservations; } // eslint-disable-line @typescript-eslint/no-non-null-assertion
215
+ /** @internal */
216
+ async initializeSharedElementReservations() {
217
+ this._reservations?.[Symbols_1._close]();
218
+ if (SchemaSync_1.SchemaSync.isEnabled(this))
219
+ this._reservations = await (0, SchemaSyncReservations_1.createSchemaSyncReservations)(this);
220
+ else
221
+ this._reservations = (0, NoReservations_1.createNoOpReservations)();
222
+ }
209
223
  /** Provides methods for interacting with [font-related information]($docs/learning/backend/Fonts.md) stored in this iModel.
210
224
  * @beta
211
225
  */
@@ -306,7 +320,9 @@ class IModelDb extends core_common_1.IModel {
306
320
  db[Symbols_1._nativeDb].abandonChanges();
307
321
  db.close();
308
322
  }
309
- catch { }
323
+ catch {
324
+ return;
325
+ }
310
326
  });
311
327
  });
312
328
  }
@@ -366,16 +382,26 @@ class IModelDb extends core_common_1.IModel {
366
382
  this.views[Symbols_1._close]();
367
383
  this.locks[Symbols_1._close]();
368
384
  this._locks = undefined;
385
+ this.reservations[Symbols_1._close]();
386
+ this._reservations = undefined;
369
387
  this._codeService?.close();
370
388
  this._codeService = undefined;
371
389
  this[Symbols_1._nativeDb].closeFile();
372
390
  }
391
+ /**
392
+ * Save any unsaved schema changes in this iModel.
393
+ * @internal
394
+ */
373
395
  saveSchemaChanges(args) {
374
396
  if (!this[Symbols_1._nativeDb].hasUnsavedChanges())
375
397
  return;
376
398
  const saveArgs = typeof args === "string" ? { description: args } : args;
377
399
  saveArgs === undefined ? this[Symbols_1._nativeDb].saveChanges() : this[Symbols_1._nativeDb].saveChanges(JSON.stringify(saveArgs));
378
400
  }
401
+ /**
402
+ * Abandon any unsaved schema changes in this iModel.
403
+ * @internal
404
+ */
379
405
  abandonSchemaChanges() {
380
406
  if (!this[Symbols_1._nativeDb].hasUnsavedChanges())
381
407
  return;
@@ -922,7 +948,7 @@ class IModelDb extends core_common_1.IModel {
922
948
  async dropSchemas(schemaNames) {
923
949
  if (schemaNames.length === 0)
924
950
  return;
925
- if (this[Symbols_1._nativeDb].schemaSyncEnabled())
951
+ if (SchemaSync_1.SchemaSync.isEnabled(this))
926
952
  throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, "Cannot drop schemas when schema sync is enabled");
927
953
  if (this[Symbols_1._nativeDb].hasUnsavedChanges())
928
954
  throw new core_common_1.IModelError(core_bentley_1.ChangeSetStatus.HasUncommittedChanges, "Cannot drop schemas with unsaved changes");
@@ -1008,26 +1034,34 @@ class IModelDb extends core_common_1.IModel {
1008
1034
  this.cleanupSnapshot(context.resources);
1009
1035
  }
1010
1036
  }
1011
- /** Shared implementation for importing schemas from file or string. */
1012
- async importSchemasInternal(schemas, options, nativeImportOp) {
1013
- // BriefcaseDb-specific validation checks
1014
- if (this.isBriefcaseDb()) {
1015
- if (this.txns.rebaser.isRebasing) {
1016
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas while rebasing");
1017
- }
1018
- if (this.txns.isIndirectChanges) {
1019
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas while in an indirect change scope");
1020
- }
1021
- // Additional checks when semantic rebase is enabled
1022
- if (IModelHost_1.IModelHost.useSemanticRebase) {
1023
- if (this[Symbols_1._nativeDb].hasUnsavedChanges()) {
1024
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas with unsaved changes when useSemanticRebase flag is on");
1025
- }
1026
- if (this[Symbols_1._nativeDb].schemaSyncEnabled()) {
1027
- 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");
1028
- }
1037
+ /** Refuse a schema import this briefcase is in no state to run. Shared by [[importSchemas]] and
1038
+ * [[BriefcaseDb.upgradeSchemas]], which reach the native importer by different routes.
1039
+ * @internal
1040
+ */
1041
+ assertCanImportSchemas() {
1042
+ if (!this.isBriefcaseDb())
1043
+ return;
1044
+ if (this.txns.rebaser.isRebasing) {
1045
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas while rebasing");
1046
+ }
1047
+ if (this.txns.isIndirectChanges) {
1048
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas while in an indirect change scope");
1049
+ }
1050
+ // Additional checks when semantic rebase is enabled
1051
+ if (IModelHost_1.IModelHost.useSemanticRebase) {
1052
+ if (this[Symbols_1._nativeDb].hasUnsavedChanges()) {
1053
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Cannot import schemas with unsaved changes when useSemanticRebase flag is on");
1054
+ }
1055
+ if (SchemaSync_1.SchemaSync.isEnabled(this)) {
1056
+ 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");
1029
1057
  }
1030
1058
  }
1059
+ }
1060
+ /** Shared implementation for importing schemas from file or string.
1061
+ * @internal
1062
+ */
1063
+ async importSchemasInternal(schemas, options, nativeImportOp) {
1064
+ this.assertCanImportSchemas();
1031
1065
  if (options?.channelUpgrade) {
1032
1066
  const channelUpgrade = options.channelUpgrade;
1033
1067
  try {
@@ -1045,30 +1079,52 @@ class IModelDb extends core_common_1.IModel {
1045
1079
  if (options?.schemaImportCallbacks?.preSchemaImportCallback)
1046
1080
  preSchemaImportCallbackResult = await this.preSchemaImportCallback(options.schemaImportCallbacks, { iModel: this, data: options.data, schemaData: schemas });
1047
1081
  const maybeCustomNativeContext = options?.ecSchemaXmlContext?.nativeContext;
1048
- if (this[Symbols_1._nativeDb].schemaSyncEnabled()) {
1049
- await SchemaSync_1.SchemaSync.withLockedAccess(this, { openMode: core_bentley_1.OpenMode.Readonly, operationName: "schema sync" }, async (syncAccess) => {
1050
- const schemaSyncDbUri = syncAccess.getUri();
1051
- this.saveSchemaChanges();
1052
- try {
1053
- nativeImportOp(schemas, { schemaLockHeld: false, ecSchemaXmlContext: maybeCustomNativeContext, schemaSyncDbUri });
1054
- }
1055
- catch (outerErr) {
1056
- if (core_bentley_1.DbResult.BE_SQLITE_ERROR_DataTransformRequired === outerErr.errorNumber) {
1057
- this.abandonSchemaChanges();
1058
- if (this[Symbols_1._nativeDb].getITwinId() !== core_bentley_1.Guid.empty)
1059
- await this.acquireSchemaLock();
1060
- try {
1061
- nativeImportOp(schemas, { schemaLockHeld: true, ecSchemaXmlContext: maybeCustomNativeContext, schemaSyncDbUri });
1062
- }
1063
- catch (innerErr) {
1064
- throw new core_common_1.IModelError(innerErr.errorNumber, innerErr.message);
1065
- }
1082
+ if (SchemaSync_1.SchemaSync.isEnabled(this)) {
1083
+ // The shared lock lets concurrent updates through while blocking anyone taking the exclusive lock for an upgrade.
1084
+ if (this[Symbols_1._nativeDb].getITwinId() !== core_bentley_1.Guid.empty)
1085
+ await this.locks.acquireLocks({ shared: core_common_1.IModel.repositoryModelId });
1086
+ // The native import adopts rows from the attached SchemaSyncDb. Attach and detach commit
1087
+ // implicitly, so abandoning changes cannot undo the adoption. A later failure must roll the
1088
+ // briefcase back before those ec_ rows can be pushed.
1089
+ let txnBeforeAdopt;
1090
+ // Set once the caller's own work is committed. Getting a token or the container write lock happens
1091
+ // before that, and abandonSchemaChanges discards every unsaved change rather than only this import's,
1092
+ // so abandoning on a failure from that window would throw away work the import never touched.
1093
+ let callerChangesSaved = false;
1094
+ try {
1095
+ await SchemaSync_1.SchemaSync.withLockedAccess(this, { openMode: core_bentley_1.OpenMode.Readonly, operationName: "schema sync" }, async (syncAccess) => {
1096
+ const schemaSyncDbUri = syncAccess.getUri();
1097
+ this.saveSchemaChanges();
1098
+ callerChangesSaved = true;
1099
+ // After saveSchemaChanges, so rolling back cannot reach the caller's own work.
1100
+ if (this.isBriefcaseDb())
1101
+ txnBeforeAdopt = this.txns.getCurrentTxnId();
1102
+ try {
1103
+ nativeImportOp(schemas, { schemaLockHeld: false, ecSchemaXmlContext: maybeCustomNativeContext, schemaSyncDbUri });
1066
1104
  }
1067
- else {
1068
- throw new core_common_1.IModelError(outerErr.errorNumber, outerErr.message);
1105
+ catch (err) {
1106
+ if (SchemaSync_1.SchemaSync.requiresUpgrade(err))
1107
+ throw new core_common_1.IModelError(err.errorNumber, `${err.message} - this schema change needs the upgrade path. Use BriefcaseDb.upgradeSchemas, which takes the exclusive schema lock and pushes the result.`);
1108
+ throw new core_common_1.IModelError(err.errorNumber, err.message);
1069
1109
  }
1110
+ });
1111
+ }
1112
+ catch (err) {
1113
+ if (callerChangesSaved)
1114
+ this.abandonSchemaChanges();
1115
+ if (this.isBriefcaseDb() && undefined !== txnBeforeAdopt && this.txns.getCurrentTxnId() !== txnBeforeAdopt) {
1116
+ // Saving the adopt's txn started a new undo session, because schema changes are kept out of the
1117
+ // user's undo stack, so this reverses across that boundary. The changes themselves reverse like
1118
+ // any other - a rebase does it to every local txn on every pull. It does not reverse DDL: a table
1119
+ // or column the adopt created stays behind with no ec_ row describing it, which is the state a
1120
+ // briefcase already tolerates, and the next successful import finds the table up to date and
1121
+ // carries on. Cancel rather than reverse, so the rows cannot come back through undo either.
1122
+ const status = this[Symbols_1._nativeDb].cancelTo(txnBeforeAdopt, true);
1123
+ if (core_bentley_1.IModelStatus.Success !== status)
1124
+ core_bentley_1.Logger.logError(loggerCategory, `Failed to roll back the adopted schema rows after a failed import: ${core_bentley_1.IModelStatus[status] ?? status}`);
1070
1125
  }
1071
- });
1126
+ throw err;
1127
+ }
1072
1128
  }
1073
1129
  else {
1074
1130
  const nativeImportOptions = {
@@ -2178,7 +2234,7 @@ function processSchemaWriteStatus(status) {
2178
2234
  * @param props The data for the new model.
2179
2235
  * @returns The newly inserted model's Id.
2180
2236
  * @throws [[IModelError]] if insertion fails.
2181
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.insertModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2237
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.insertModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2182
2238
  */
2183
2239
  insertModel(props) {
2184
2240
  return this._iModel[Symbols_1._implicitTxn].insertModel(props);
@@ -2186,7 +2242,7 @@ function processSchemaWriteStatus(status) {
2186
2242
  /** Update an existing model.
2187
2243
  * @param props the properties of the model to change
2188
2244
  * @throws [[IModelError]] if update fails.
2189
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.updateModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2245
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.updateModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2190
2246
  */
2191
2247
  updateModel(props) {
2192
2248
  this._iModel[Symbols_1._implicitTxn].updateModel(props);
@@ -2198,7 +2254,7 @@ function processSchemaWriteStatus(status) {
2198
2254
  * Cached [Tile]($frontend)s are only invalidated after the geometry guid of the model changes.
2199
2255
  * @note This will throw IModelError with [IModelStatus.VersionTooOld]($core-bentley) if a version of the BisCore schema older than 1.0.11 is present in the iModel.
2200
2256
  * @throws [[IModelError]] if the update fails.
2201
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.updateGeometryGuid instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2257
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.updateGeometryGuid instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2202
2258
  * @see [[TxnManager.onModelGeometryChanged]] for the event emitted in response to such a change.
2203
2259
  */
2204
2260
  updateGeometryGuid(modelId) {
@@ -2207,7 +2263,7 @@ function processSchemaWriteStatus(status) {
2207
2263
  /** Delete one or more existing models.
2208
2264
  * @param ids The Ids of the models to be deleted
2209
2265
  * @throws [[IModelError]] if deletion fails.
2210
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.deleteModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2266
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.deleteModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2211
2267
  */
2212
2268
  deleteModel(ids) {
2213
2269
  this._iModel[Symbols_1._implicitTxn].deleteModel(ids);
@@ -2431,7 +2487,7 @@ function processSchemaWriteStatus(status) {
2431
2487
  * However when `elProps.federationGuid` is not present or undefined, a new Guid will be generated and stored on the resultant element. But
2432
2488
  * the value of `elProps.federationGuid` is *not* updated. Generally, it is best to re-read the element after inserting (e.g. via [[getElementProps]])
2433
2489
  * if you intend to continue working with it. That will ensure its values reflect the persistent state.
2434
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.insertElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2490
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.insertElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2435
2491
  */
2436
2492
  insertElement(elProps, options) {
2437
2493
  return this._iModel[Symbols_1._implicitTxn].insertElement(elProps, options);
@@ -2446,7 +2502,7 @@ function processSchemaWriteStatus(status) {
2446
2502
  * @note The values of `classFullName` and `model` *may not be changed* by this method. Further, it will permute the `elProps` object by adding or
2447
2503
  * overwriting their values to the correct values.
2448
2504
  * @throws [[ITwinError]] if update fails.
2449
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.updateElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2505
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.updateElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2450
2506
  */
2451
2507
  updateElement(elProps) {
2452
2508
  this._iModel[Symbols_1._implicitTxn].updateElement(elProps);
@@ -2455,7 +2511,7 @@ function processSchemaWriteStatus(status) {
2455
2511
  * @param ids The set of Ids of the element(s) to be deleted
2456
2512
  * @throws [[ITwinError]]
2457
2513
  * @see deleteDefinitionElements
2458
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.deleteElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2514
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.deleteElement instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2459
2515
  */
2460
2516
  deleteElement(ids) {
2461
2517
  this._iModel[Symbols_1._implicitTxn].deleteElement(ids);
@@ -2466,7 +2522,7 @@ function processSchemaWriteStatus(status) {
2466
2522
  * @param deleteOptions Options for the delete operation.
2467
2523
  * @returns A result object containing information about the deletion operation success and the element ids that failed to delete (if any).
2468
2524
  * @throws [[ITwinError]] if any of the supplied ids are not well-formed/valid [[Id64String]]s.
2469
- * @deprecated in 5.1.9 - will not be removed until after 2026-08-15. Use EditTxn.deleteElements instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2525
+ * @deprecated in 5.1.9 - might be removed in next major version. Use EditTxn.deleteElements instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2470
2526
  * @beta
2471
2527
  */
2472
2528
  deleteElements(ids, deleteOptions) {
@@ -2480,7 +2536,7 @@ function processSchemaWriteStatus(status) {
2480
2536
  * DefinitionElements rather than calling this method separately for each one. Ids that are not valid DefinitionElements will be ignored.
2481
2537
  * @returns An IdSet of the DefinitionElements that are used and were therefore not deleted.
2482
2538
  * @see deleteElement
2483
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.deleteDefinitionElements instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2539
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.deleteDefinitionElements instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2484
2540
  */
2485
2541
  deleteDefinitionElements(definitionElementIds) {
2486
2542
  return this._iModel[Symbols_1._implicitTxn].deleteDefinitionElements(definitionElementIds);
@@ -2723,7 +2779,7 @@ function processSchemaWriteStatus(status) {
2723
2779
  * @returns the id of the newly inserted aspect.
2724
2780
  * @note Aspect Ids may collide with element Ids, so don't put both in a container like Set or Map
2725
2781
  * use [EntityReference]($common) for that instead.
2726
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.insertAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2782
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.insertAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2727
2783
  */
2728
2784
  insertAspect(aspectProps) {
2729
2785
  return this._iModel[Symbols_1._implicitTxn].insertAspect(aspectProps);
@@ -2731,7 +2787,7 @@ function processSchemaWriteStatus(status) {
2731
2787
  /** Update an exist ElementAspect within the iModel.
2732
2788
  * @param aspectProps The properties to use to update the ElementAspect.
2733
2789
  * @throws [[IModelError]] if unable to update the ElementAspect.
2734
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.updateAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2790
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.updateAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2735
2791
  */
2736
2792
  updateAspect(aspectProps) {
2737
2793
  this._iModel[Symbols_1._implicitTxn].updateAspect(aspectProps);
@@ -2739,7 +2795,7 @@ function processSchemaWriteStatus(status) {
2739
2795
  /** Delete one or more ElementAspects from this iModel.
2740
2796
  * @param aspectInstanceIds The set of instance Ids of the ElementAspect(s) to be deleted
2741
2797
  * @throws [[IModelError]] if unable to delete the ElementAspect.
2742
- * @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.deleteAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2798
+ * @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.deleteAspect instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2743
2799
  */
2744
2800
  deleteAspect(aspectInstanceIds) {
2745
2801
  this._iModel[Symbols_1._implicitTxn].deleteAspect(aspectInstanceIds);
@@ -2748,7 +2804,7 @@ function processSchemaWriteStatus(status) {
2748
2804
  * @param props The properties specifying the element to reparent and its new parent.
2749
2805
  * @throws [[ITwinError]] if the operation fails.
2750
2806
  * @beta
2751
- * @deprecated in 5.11.0 - will not be removed until after 2026-08-04. Use EditTxn.changeElementParent instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2807
+ * @deprecated in 5.11.0 - might be removed in next major version. Use EditTxn.changeElementParent instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2752
2808
  */
2753
2809
  changeElementParent(props) {
2754
2810
  this._iModel[Symbols_1._implicitTxn].changeElementParent(props);
@@ -2757,7 +2813,7 @@ function processSchemaWriteStatus(status) {
2757
2813
  * @param props The properties specifying the element to move and its new model.
2758
2814
  * @throws [[ITwinError]] if the operation fails.
2759
2815
  * @beta
2760
- * @deprecated in 5.11.0 - will not be removed until after 2026-08-04. Use EditTxn.changeElementModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2816
+ * @deprecated in 5.11.0 - might be removed in next major version. Use EditTxn.changeElementModel instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2761
2817
  */
2762
2818
  changeElementModel(props) {
2763
2819
  this._iModel[Symbols_1._implicitTxn].changeElementModel(props);
@@ -2816,7 +2872,7 @@ function processSchemaWriteStatus(status) {
2816
2872
  return this._viewStore;
2817
2873
  }
2818
2874
  /**
2819
- * @beta @deprecated in 5.9.0 - will not be removed until after 2026-08-04. Use EditTxn.saveDefaultViewStore instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2875
+ * @beta @deprecated in 5.9.0 - might be removed in next major version. Use EditTxn.saveDefaultViewStore instead, within an explicit EditTxn scope (or via withEditTxn). See EditTxn documentation for migration help.
2820
2876
  */
2821
2877
  saveDefaultViewStore(arg) {
2822
2878
  this._iModel[Symbols_1._implicitTxn].saveDefaultViewStore(arg);
@@ -2834,7 +2890,9 @@ function processSchemaWriteStatus(status) {
2834
2890
  try {
2835
2891
  props.push(imodel.elements.getElementProps(id));
2836
2892
  }
2837
- catch { }
2893
+ catch {
2894
+ return;
2895
+ }
2838
2896
  });
2839
2897
  return props;
2840
2898
  }
@@ -2857,7 +2915,9 @@ function processSchemaWriteStatus(status) {
2857
2915
  break;
2858
2916
  }
2859
2917
  }
2860
- catch { }
2918
+ catch {
2919
+ continue;
2920
+ }
2861
2921
  }
2862
2922
  return finished;
2863
2923
  }
@@ -3067,9 +3127,6 @@ class BriefcaseDb extends IModelDb {
3067
3127
  get isBriefcase() { return true; }
3068
3128
  /* the BriefcaseId of the briefcase opened with this BriefcaseDb */
3069
3129
  briefcaseId;
3070
- _skipSyncSchemasOnPullAndPush;
3071
- /** @internal */
3072
- get skipSyncSchemasOnPullAndPush() { return this._skipSyncSchemasOnPullAndPush ?? false; }
3073
3130
  /**
3074
3131
  * Event raised just before a BriefcaseDb is opened. Supplies the arguments that will be used to open the BriefcaseDb.
3075
3132
  * Throw an exception to stop the open.
@@ -3152,6 +3209,8 @@ class BriefcaseDb extends IModelDb {
3152
3209
  }
3153
3210
  constructor(args) {
3154
3211
  super({ ...args, changeset: args.nativeDb.getCurrentChangeset() });
3212
+ // Native invokes this private callback dynamically through the object registered by IModelDb.
3213
+ void this.onChangesetConflict;
3155
3214
  this._openMode = args.openMode;
3156
3215
  this.briefcaseId = args.briefcaseId;
3157
3216
  this.makeLockControl();
@@ -3164,26 +3223,33 @@ class BriefcaseDb extends IModelDb {
3164
3223
  wasChanges = nativeDb.hasPendingTxns();
3165
3224
  nativeDb.closeFile();
3166
3225
  };
3167
- const isSchemaSyncEnabled = await withBriefcaseDb(briefcase, async (db) => {
3168
- await SchemaSync_1.SchemaSync.pull(db);
3169
- return db[Symbols_1._nativeDb].schemaSyncEnabled();
3170
- });
3171
- if (isSchemaSyncEnabled) {
3226
+ const push = async () => {
3227
+ if (wasChanges)
3228
+ await withBriefcaseDb(briefcase, async (db) => db.pushChanges({ ...briefcase, description, retainLocks: true }));
3229
+ };
3230
+ // Asked of the closed file, so an iModel without schema sync never gets opened for this.
3231
+ if (SchemaSync_1.SchemaSync.isEnabled(briefcase)) {
3232
+ await withBriefcaseDb(briefcase, async (db) => SchemaSync_1.SchemaSync.updateDbSchema(db));
3172
3233
  await SchemaSync_1.SchemaSync.withLockedAccess(briefcase, { openMode: core_bentley_1.OpenMode.Readonly, operationName: "schema sync" }, async (syncAccess) => {
3173
3234
  const schemaSyncDbUri = syncAccess.getUri();
3174
3235
  executeUpgrade();
3236
+ // Overwriting advances the SchemaSync data version, so a no-op upgrade must not call it.
3237
+ if (!wasChanges)
3238
+ return;
3175
3239
  await withBriefcaseDb(briefcase, async (db) => {
3176
- db[Symbols_1._nativeDb].schemaSyncPush(schemaSyncDbUri);
3240
+ db[Symbols_1._nativeDb].schemaSyncOverwrite(schemaSyncDbUri);
3177
3241
  db[Symbols_1._nativeDb].saveChanges();
3178
3242
  });
3179
- syncAccess.synchronizeWithCloud();
3243
+ // Publish the sync db before the changeset while retaining both locks.
3244
+ syncAccess.closeDb();
3245
+ await syncAccess.container.uploadChanges();
3246
+ await push();
3180
3247
  });
3181
3248
  }
3182
3249
  else {
3183
3250
  executeUpgrade();
3251
+ await push();
3184
3252
  }
3185
- if (wasChanges)
3186
- await withBriefcaseDb(briefcase, async (db) => db.pushChanges({ ...briefcase, description, retainLocks: true }));
3187
3253
  }
3188
3254
  /** Upgrades the schemas in the iModel based on the current version of the software. Follows a sequence of operations -
3189
3255
  * * Acquires a schema lock to prevent other users from making any other changes while upgrade is happening
@@ -3203,6 +3269,22 @@ class BriefcaseDb extends IModelDb {
3203
3269
  // - push changes
3204
3270
  // - release schema lock
3205
3271
  // good thing computers are fast. Fortunately upgrading should be rare (and the push time will dominate anyway.) Don't try to optimize any of this away.
3272
+ // schemaSyncOverwrite can discard unpushed imports, so hold the exclusive lock across both upgrades.
3273
+ if (SchemaSync_1.SchemaSync.isEnabled(briefcase)) {
3274
+ try {
3275
+ await withBriefcaseDb(briefcase, async (db) => {
3276
+ if (!db.locks.isServerBased)
3277
+ throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, "Cannot upgrade schemas with SchemaSync without server-based locking");
3278
+ await db.acquireSchemaLock();
3279
+ });
3280
+ await this.doUpgrade(briefcase, { profile: core_common_1.ProfileOptions.Upgrade, schemaLockHeld: true }, "Upgraded profile");
3281
+ await this.doUpgrade(briefcase, { domain: core_common_1.DomainOptions.Upgrade, schemaLockHeld: true }, "Upgraded domain schemas");
3282
+ }
3283
+ finally {
3284
+ await withBriefcaseDb(briefcase, async (db) => db.locks[Symbols_1._releaseAllLocks]());
3285
+ }
3286
+ return;
3287
+ }
3206
3288
  try {
3207
3289
  await this.doUpgrade(briefcase, { profile: core_common_1.ProfileOptions.Upgrade }, "Upgraded profile");
3208
3290
  }
@@ -3267,6 +3349,7 @@ class BriefcaseDb extends IModelDb {
3267
3349
  }
3268
3350
  // load all of the settings from workspaces
3269
3351
  await briefcaseDb.loadWorkspaceSettings();
3352
+ await briefcaseDb.initializeSharedElementReservations();
3270
3353
  if (openMode === core_bentley_1.OpenMode.ReadWrite && CodeService_1.CodeService.createForIModel) {
3271
3354
  try {
3272
3355
  briefcaseDb._codeService = await CodeService_1.CodeService.createForIModel(briefcaseDb);
@@ -3322,6 +3405,18 @@ class BriefcaseDb extends IModelDb {
3322
3405
  return "foreign key";
3323
3406
  }
3324
3407
  };
3408
+ // `dgn_Domain` holds one bookkeeping row per BIS domain present in the briefcase. The row is
3409
+ // created automatically as soon as the domain's schema is imported, so merging a changeset
3410
+ // that registers a domain inserts a row that was just created locally. Both rows describe the
3411
+ // same domain and the incoming one is authoritative, so this duplicate insert is never fatal.
3412
+ // Only a primary key collision on an insert is benign - an update or delete whose "before"
3413
+ // values do not match (`DbConflictCause.Data`) describes a real divergence and must not be
3414
+ // silently discarded here.
3415
+ if (args.tableName === "dgn_Domain" && args.cause === core_bentley_1.DbConflictCause.Conflict && args.opcode === core_bentley_1.DbOpcode.Insert) {
3416
+ core_bentley_1.Logger.logWarning(category, `${interpretConflictCause(args.cause)} conflict on dgn_Domain - resolved by replacing the existing row with the incoming row`);
3417
+ args.dump();
3418
+ return core_bentley_1.DbConflictResolution.Replace;
3419
+ }
3325
3420
  if (args.cause === core_bentley_1.DbConflictCause.Data && !args.indirect) {
3326
3421
  /*
3327
3422
  * From SQLite Docs CHANGESET_DATA as the second argument
@@ -3490,10 +3585,12 @@ class BriefcaseDb extends IModelDb {
3490
3585
  async pullChanges(arg) {
3491
3586
  await this.executeWritable(async () => {
3492
3587
  await BriefcaseManager_1.BriefcaseManager.pullAndApplyChangesets(this, arg ?? {});
3493
- if (!this.skipSyncSchemasOnPullAndPush)
3494
- await SchemaSync_1.SchemaSync.pull(this);
3588
+ SchemaSync_1.SchemaSync.updateDbSchema(this);
3495
3589
  this.initializeIModelDb("pullMerge");
3496
3590
  });
3591
+ // If this pull enabled or disabled SchemaSync for this briefcase, its reservations must now be re-initialized
3592
+ if (this.reservations.isServerBased !== SchemaSync_1.SchemaSync.isEnabled(this))
3593
+ await this.initializeSharedElementReservations();
3497
3594
  this.txns._onChangesPulled(this.changeset);
3498
3595
  }
3499
3596
  async enableChangesetStatTracking() {
@@ -3573,24 +3670,10 @@ class BriefcaseDb extends IModelDb {
3573
3670
  if (nativeDb.hasPendingTxns()) {
3574
3671
  throw new core_common_1.IModelError(core_bentley_1.ChangeSetStatus.HasLocalChanges, "Cannot revert with pending txns");
3575
3672
  }
3576
- const skipSchemaSyncPull = async (func) => {
3577
- if (nativeDb.schemaSyncEnabled()) {
3578
- this._skipSyncSchemasOnPullAndPush = true;
3579
- try {
3580
- return await func();
3581
- }
3582
- finally {
3583
- this._skipSyncSchemasOnPullAndPush = undefined;
3584
- }
3585
- }
3586
- else {
3587
- return func();
3588
- }
3589
- };
3590
3673
  this.clearCaches();
3591
- await skipSchemaSyncPull(async () => this.pullChanges({ ...arg, toIndex: undefined }));
3674
+ await this.pullChanges({ ...arg, toIndex: undefined });
3592
3675
  await this.acquireSchemaLock();
3593
- if (nativeDb.schemaSyncEnabled()) {
3676
+ if (SchemaSync_1.SchemaSync.isEnabled(this)) {
3594
3677
  arg.skipSchemaChanges = true;
3595
3678
  }
3596
3679
  // The native side enables file-based txns during revert. Restore the original setting afterward.
@@ -3611,7 +3694,7 @@ class BriefcaseDb extends IModelDb {
3611
3694
  pushRetryDelay: arg.pushRetryDelay,
3612
3695
  retainLocks: arg.retainLocks,
3613
3696
  };
3614
- await skipSchemaSyncPull(async () => this.pushChanges(pushArgs));
3697
+ await this.pushChanges(pushArgs);
3615
3698
  this.clearCaches();
3616
3699
  }
3617
3700
  catch (err) {
@@ -3682,9 +3765,62 @@ class BriefcaseDb extends IModelDb {
3682
3765
  await BriefcaseManager_1.BriefcaseManager.pullMergePush(this, arg);
3683
3766
  this.initializeIModelDb("pullMerge");
3684
3767
  });
3768
+ // If this pull enabled or disabled SchemaSync for this briefcase, its reservations must now be re-initialized
3769
+ if (this.reservations.isServerBased !== SchemaSync_1.SchemaSync.isEnabled(this))
3770
+ await this.initializeSharedElementReservations();
3685
3771
  this.txns._onChangesPushed(this.changeset);
3686
3772
  BriefcaseManager_1.BriefcaseManager.deleteRebaseFolders(this);
3687
3773
  }
3774
+ /** Import schemas while allowing changes that move or delete data.
3775
+ *
3776
+ * Takes the exclusive schema lock, requires the briefcase to be at the timeline tip, imports, updates the sync db, and pushes the result.
3777
+ * @note The briefcase must have no local changes.
3778
+ * @see [[BriefcaseDb.upgradeSchemas]] (static) for upgrading the software's profile and domain schemas.
3779
+ * @alpha
3780
+ */
3781
+ async upgradeSchemas(schemaFileNames, arg) {
3782
+ return this.upgradeSchemasInternal(schemaFileNames, arg, (schemas, importOptions) => this[Symbols_1._nativeDb].importSchemas(schemas, importOptions));
3783
+ }
3784
+ /** The [[importSchemaStrings]] counterpart of [[upgradeSchemas]].
3785
+ * @alpha
3786
+ */
3787
+ async upgradeSchemaStrings(serializedXmlSchemas, arg) {
3788
+ return this.upgradeSchemasInternal(serializedXmlSchemas, arg, (schemas, importOptions) => this[Symbols_1._nativeDb].importXmlSchemas(schemas, importOptions));
3789
+ }
3790
+ async upgradeSchemasInternal(schemas, arg, nativeImportOp) {
3791
+ if (schemas.length === 0)
3792
+ return;
3793
+ this.assertCanImportSchemas();
3794
+ if (this[Symbols_1._nativeDb].hasUnsavedChanges() || this.txns.hasLocalChanges)
3795
+ throw new core_common_1.IModelError(core_bentley_1.ChangeSetStatus.HasLocalChanges, "Cannot upgrade schemas while there are local changes");
3796
+ if (SchemaSync_1.SchemaSync.isEnabled(this) && !this.locks.isServerBased)
3797
+ throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, "Cannot upgrade schemas with SchemaSync without server-based locking");
3798
+ await this.acquireSchemaLock();
3799
+ await this.pullChanges({ accessToken: arg.accessToken });
3800
+ if (!SchemaSync_1.SchemaSync.isEnabled(this)) {
3801
+ await this.importSchemasInternal(schemas, { ecSchemaXmlContext: arg.ecSchemaXmlContext }, nativeImportOp);
3802
+ await this.pushChanges(arg);
3803
+ return;
3804
+ }
3805
+ await SchemaSync_1.SchemaSync.withLockedAccess(this, { openMode: core_bentley_1.OpenMode.Readonly, operationName: "schema upgrade" }, async (syncAccess) => {
3806
+ this.saveSchemaChanges();
3807
+ try {
3808
+ nativeImportOp(schemas, {
3809
+ schemaLockHeld: true,
3810
+ ecSchemaXmlContext: arg.ecSchemaXmlContext?.nativeContext,
3811
+ schemaSyncDbUri: syncAccess.getUri(),
3812
+ });
3813
+ }
3814
+ catch (err) {
3815
+ this.abandonSchemaChanges();
3816
+ throw new core_common_1.IModelError(err.errorNumber, err.message);
3817
+ }
3818
+ this.clearCaches();
3819
+ syncAccess.closeDb();
3820
+ await syncAccess.container.uploadChanges();
3821
+ await this.pushChanges(arg);
3822
+ });
3823
+ }
3688
3824
  close(options) {
3689
3825
  if (this.isBriefcase && this.isOpen && !this.isReadonly && this.txns.rebaser.inProgress()) {
3690
3826
  this[Symbols_1._nativeDb].abandonChanges();
@@ -3857,6 +3993,7 @@ class SnapshotDb extends IModelDb {
3857
3993
  const key = CheckpointManager_1.CheckpointManager.getKey(checkpoint);
3858
3994
  const db = SnapshotDb.openFile(dbName, { key, container });
3859
3995
  await db.loadWorkspaceSettings();
3996
+ await db.initializeSharedElementReservations();
3860
3997
  return db;
3861
3998
  }
3862
3999
  /** @internal */