@itwin/core-backend 5.15.0-dev.9 → 5.15.1

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 (231) hide show
  1. package/CHANGELOG.md +46 -1
  2. package/lib/cjs/BlobContainerService.d.ts +2 -0
  3. package/lib/cjs/BlobContainerService.d.ts.map +1 -1
  4. package/lib/cjs/BlobContainerService.js.map +1 -1
  5. package/lib/cjs/BriefcaseManager.d.ts +2 -1
  6. package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
  7. package/lib/cjs/BriefcaseManager.js +39 -9
  8. package/lib/cjs/BriefcaseManager.js.map +1 -1
  9. package/lib/cjs/ChangeUnifier.d.ts +82 -0
  10. package/lib/cjs/ChangeUnifier.d.ts.map +1 -0
  11. package/lib/cjs/ChangeUnifier.js +163 -0
  12. package/lib/cjs/ChangeUnifier.js.map +1 -0
  13. package/lib/cjs/ChangesetReader.d.ts +21 -2
  14. package/lib/cjs/ChangesetReader.d.ts.map +1 -1
  15. package/lib/cjs/ChangesetReader.js +37 -1
  16. package/lib/cjs/ChangesetReader.js.map +1 -1
  17. package/lib/cjs/CloudSqlite.d.ts +15 -0
  18. package/lib/cjs/CloudSqlite.d.ts.map +1 -1
  19. package/lib/cjs/CloudSqlite.js.map +1 -1
  20. package/lib/cjs/ECDb.d.ts +1 -0
  21. package/lib/cjs/ECDb.d.ts.map +1 -1
  22. package/lib/cjs/ECDb.js +4 -1
  23. package/lib/cjs/ECDb.js.map +1 -1
  24. package/lib/cjs/EditTxn.d.ts +61 -19
  25. package/lib/cjs/EditTxn.d.ts.map +1 -1
  26. package/lib/cjs/EditTxn.js +84 -29
  27. package/lib/cjs/EditTxn.js.map +1 -1
  28. package/lib/cjs/GeoCoordConfig.d.ts +1 -0
  29. package/lib/cjs/GeoCoordConfig.d.ts.map +1 -1
  30. package/lib/cjs/GeoCoordConfig.js +12 -8
  31. package/lib/cjs/GeoCoordConfig.js.map +1 -1
  32. package/lib/cjs/IModelDb.d.ts +22 -9
  33. package/lib/cjs/IModelDb.d.ts.map +1 -1
  34. package/lib/cjs/IModelDb.js +54 -12
  35. package/lib/cjs/IModelDb.js.map +1 -1
  36. package/lib/cjs/NativeHost.d.ts.map +1 -1
  37. package/lib/cjs/NativeHost.js +5 -1
  38. package/lib/cjs/NativeHost.js.map +1 -1
  39. package/lib/cjs/Relationship.d.ts +28 -0
  40. package/lib/cjs/Relationship.d.ts.map +1 -1
  41. package/lib/cjs/Relationship.js +78 -0
  42. package/lib/cjs/Relationship.js.map +1 -1
  43. package/lib/cjs/SQLiteDb.d.ts +52 -5
  44. package/lib/cjs/SQLiteDb.d.ts.map +1 -1
  45. package/lib/cjs/SQLiteDb.js +40 -5
  46. package/lib/cjs/SQLiteDb.js.map +1 -1
  47. package/lib/cjs/SchemaSync.d.ts.map +1 -1
  48. package/lib/cjs/SchemaSync.js +1 -0
  49. package/lib/cjs/SchemaSync.js.map +1 -1
  50. package/lib/cjs/TxnManager.d.ts +126 -89
  51. package/lib/cjs/TxnManager.d.ts.map +1 -1
  52. package/lib/cjs/TxnManager.js +114 -76
  53. package/lib/cjs/TxnManager.js.map +1 -1
  54. package/lib/cjs/ViewStateHydrator.d.ts.map +1 -1
  55. package/lib/cjs/ViewStateHydrator.js.map +1 -1
  56. package/lib/cjs/ViewStore.d.ts.map +1 -1
  57. package/lib/cjs/ViewStore.js +62 -19
  58. package/lib/cjs/ViewStore.js.map +1 -1
  59. package/lib/cjs/annotations/LeaderGeometry.d.ts.map +1 -1
  60. package/lib/cjs/annotations/LeaderGeometry.js +3 -0
  61. package/lib/cjs/annotations/LeaderGeometry.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/BriefcaseUtils.d.ts +19 -0
  67. package/lib/cjs/internal/BriefcaseUtils.d.ts.map +1 -0
  68. package/lib/cjs/internal/BriefcaseUtils.js +65 -0
  69. package/lib/cjs/internal/BriefcaseUtils.js.map +1 -0
  70. package/lib/cjs/internal/QueryMetadataCache.d.ts +44 -0
  71. package/lib/cjs/internal/QueryMetadataCache.d.ts.map +1 -0
  72. package/lib/cjs/internal/QueryMetadataCache.js +107 -0
  73. package/lib/cjs/internal/QueryMetadataCache.js.map +1 -0
  74. package/lib/cjs/internal/Symbols.d.ts +9 -0
  75. package/lib/cjs/internal/Symbols.d.ts.map +1 -1
  76. package/lib/cjs/internal/Symbols.js +10 -1
  77. package/lib/cjs/internal/Symbols.js.map +1 -1
  78. package/lib/cjs/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
  79. package/lib/cjs/internal/workspace/WorkspaceImpl.js +20 -6
  80. package/lib/cjs/internal/workspace/WorkspaceImpl.js.map +1 -1
  81. package/lib/cjs/rpc-impl/IModelReadRpcImpl.d.ts +6 -6
  82. package/lib/cjs/rpc-impl/IModelReadRpcImpl.d.ts.map +1 -1
  83. package/lib/cjs/rpc-impl/IModelReadRpcImpl.js.map +1 -1
  84. package/lib/cjs/workspace/SettingsEditor.d.ts +4 -3
  85. package/lib/cjs/workspace/SettingsEditor.d.ts.map +1 -1
  86. package/lib/cjs/workspace/SettingsEditor.js +7 -5
  87. package/lib/cjs/workspace/SettingsEditor.js.map +1 -1
  88. package/lib/esm/BlobContainerService.d.ts +2 -0
  89. package/lib/esm/BlobContainerService.d.ts.map +1 -1
  90. package/lib/esm/BlobContainerService.js.map +1 -1
  91. package/lib/esm/BriefcaseManager.d.ts +2 -1
  92. package/lib/esm/BriefcaseManager.d.ts.map +1 -1
  93. package/lib/esm/BriefcaseManager.js +40 -10
  94. package/lib/esm/BriefcaseManager.js.map +1 -1
  95. package/lib/esm/ChangeUnifier.d.ts +82 -0
  96. package/lib/esm/ChangeUnifier.d.ts.map +1 -0
  97. package/lib/esm/ChangeUnifier.js +159 -0
  98. package/lib/esm/ChangeUnifier.js.map +1 -0
  99. package/lib/esm/ChangesetReader.d.ts +21 -2
  100. package/lib/esm/ChangesetReader.d.ts.map +1 -1
  101. package/lib/esm/ChangesetReader.js +38 -2
  102. package/lib/esm/ChangesetReader.js.map +1 -1
  103. package/lib/esm/CloudSqlite.d.ts +15 -0
  104. package/lib/esm/CloudSqlite.d.ts.map +1 -1
  105. package/lib/esm/CloudSqlite.js.map +1 -1
  106. package/lib/esm/ECDb.d.ts +1 -0
  107. package/lib/esm/ECDb.d.ts.map +1 -1
  108. package/lib/esm/ECDb.js +4 -1
  109. package/lib/esm/ECDb.js.map +1 -1
  110. package/lib/esm/EditTxn.d.ts +61 -19
  111. package/lib/esm/EditTxn.d.ts.map +1 -1
  112. package/lib/esm/EditTxn.js +85 -30
  113. package/lib/esm/EditTxn.js.map +1 -1
  114. package/lib/esm/GeoCoordConfig.d.ts +1 -0
  115. package/lib/esm/GeoCoordConfig.d.ts.map +1 -1
  116. package/lib/esm/GeoCoordConfig.js +12 -8
  117. package/lib/esm/GeoCoordConfig.js.map +1 -1
  118. package/lib/esm/IModelDb.d.ts +22 -9
  119. package/lib/esm/IModelDb.d.ts.map +1 -1
  120. package/lib/esm/IModelDb.js +56 -14
  121. package/lib/esm/IModelDb.js.map +1 -1
  122. package/lib/esm/NativeHost.d.ts.map +1 -1
  123. package/lib/esm/NativeHost.js +5 -1
  124. package/lib/esm/NativeHost.js.map +1 -1
  125. package/lib/esm/Relationship.d.ts +28 -0
  126. package/lib/esm/Relationship.d.ts.map +1 -1
  127. package/lib/esm/Relationship.js +78 -0
  128. package/lib/esm/Relationship.js.map +1 -1
  129. package/lib/esm/SQLiteDb.d.ts +52 -5
  130. package/lib/esm/SQLiteDb.d.ts.map +1 -1
  131. package/lib/esm/SQLiteDb.js +40 -5
  132. package/lib/esm/SQLiteDb.js.map +1 -1
  133. package/lib/esm/SchemaSync.d.ts.map +1 -1
  134. package/lib/esm/SchemaSync.js +1 -0
  135. package/lib/esm/SchemaSync.js.map +1 -1
  136. package/lib/esm/TxnManager.d.ts +126 -89
  137. package/lib/esm/TxnManager.d.ts.map +1 -1
  138. package/lib/esm/TxnManager.js +116 -78
  139. package/lib/esm/TxnManager.js.map +1 -1
  140. package/lib/esm/ViewStateHydrator.d.ts.map +1 -1
  141. package/lib/esm/ViewStateHydrator.js.map +1 -1
  142. package/lib/esm/ViewStore.d.ts.map +1 -1
  143. package/lib/esm/ViewStore.js +62 -19
  144. package/lib/esm/ViewStore.js.map +1 -1
  145. package/lib/esm/annotations/LeaderGeometry.d.ts.map +1 -1
  146. package/lib/esm/annotations/LeaderGeometry.js +3 -0
  147. package/lib/esm/annotations/LeaderGeometry.js.map +1 -1
  148. package/lib/esm/core-backend.d.ts +1 -0
  149. package/lib/esm/core-backend.d.ts.map +1 -1
  150. package/lib/esm/core-backend.js +1 -0
  151. package/lib/esm/core-backend.js.map +1 -1
  152. package/lib/esm/internal/BriefcaseUtils.d.ts +19 -0
  153. package/lib/esm/internal/BriefcaseUtils.d.ts.map +1 -0
  154. package/lib/esm/internal/BriefcaseUtils.js +61 -0
  155. package/lib/esm/internal/BriefcaseUtils.js.map +1 -0
  156. package/lib/esm/internal/QueryMetadataCache.d.ts +44 -0
  157. package/lib/esm/internal/QueryMetadataCache.d.ts.map +1 -0
  158. package/lib/esm/internal/QueryMetadataCache.js +103 -0
  159. package/lib/esm/internal/QueryMetadataCache.js.map +1 -0
  160. package/lib/esm/internal/Symbols.d.ts +9 -0
  161. package/lib/esm/internal/Symbols.d.ts.map +1 -1
  162. package/lib/esm/internal/Symbols.js +9 -0
  163. package/lib/esm/internal/Symbols.js.map +1 -1
  164. package/lib/esm/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
  165. package/lib/esm/internal/workspace/WorkspaceImpl.js +20 -6
  166. package/lib/esm/internal/workspace/WorkspaceImpl.js.map +1 -1
  167. package/lib/esm/rpc-impl/IModelReadRpcImpl.d.ts +6 -6
  168. package/lib/esm/rpc-impl/IModelReadRpcImpl.d.ts.map +1 -1
  169. package/lib/esm/rpc-impl/IModelReadRpcImpl.js.map +1 -1
  170. package/lib/esm/test/annotations/LeaderGeometry.test.js +15 -1
  171. package/lib/esm/test/annotations/LeaderGeometry.test.js.map +1 -1
  172. package/lib/esm/test/ecdb/ConcurrentQuery.test.js +144 -30
  173. package/lib/esm/test/ecdb/ConcurrentQuery.test.js.map +1 -1
  174. package/lib/esm/test/ecdb/QueryMetadataCache.test.d.ts +2 -0
  175. package/lib/esm/test/ecdb/QueryMetadataCache.test.d.ts.map +1 -0
  176. package/lib/esm/test/ecdb/QueryMetadataCache.test.js +630 -0
  177. package/lib/esm/test/ecdb/QueryMetadataCache.test.js.map +1 -0
  178. package/lib/esm/test/element/DeleteDefinitionElements.test.js +403 -249
  179. package/lib/esm/test/element/DeleteDefinitionElements.test.js.map +1 -1
  180. package/lib/esm/test/element/RelationshipBatchLookup.test.d.ts +2 -0
  181. package/lib/esm/test/element/RelationshipBatchLookup.test.d.ts.map +1 -0
  182. package/lib/esm/test/element/RelationshipBatchLookup.test.js +202 -0
  183. package/lib/esm/test/element/RelationshipBatchLookup.test.js.map +1 -0
  184. package/lib/esm/test/hubaccess/BriefcaseManager.test.js +187 -1
  185. package/lib/esm/test/hubaccess/BriefcaseManager.test.js.map +1 -1
  186. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.d.ts +2 -0
  187. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.d.ts.map +1 -0
  188. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.js +142 -0
  189. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.js.map +1 -0
  190. package/lib/esm/test/imodel/IModelGeolocation.test.js +8 -6
  191. package/lib/esm/test/imodel/IModelGeolocation.test.js.map +1 -1
  192. package/lib/esm/test/imodel/IModelProps.test.d.ts +2 -0
  193. package/lib/esm/test/imodel/IModelProps.test.d.ts.map +1 -0
  194. package/lib/esm/test/imodel/IModelProps.test.js +411 -0
  195. package/lib/esm/test/imodel/IModelProps.test.js.map +1 -0
  196. package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.d.ts +2 -0
  197. package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.d.ts.map +1 -0
  198. package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.js +240 -0
  199. package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.js.map +1 -0
  200. package/lib/esm/test/schema/SchemaViewValidation.test.js +2 -8
  201. package/lib/esm/test/schema/SchemaViewValidation.test.js.map +1 -1
  202. package/lib/esm/test/standalone/BriefcaseManagerDelete.test.d.ts +2 -0
  203. package/lib/esm/test/standalone/BriefcaseManagerDelete.test.d.ts.map +1 -0
  204. package/lib/esm/test/standalone/BriefcaseManagerDelete.test.js +159 -0
  205. package/lib/esm/test/standalone/BriefcaseManagerDelete.test.js.map +1 -0
  206. package/lib/esm/test/standalone/ChangeUnifier.test.d.ts +2 -0
  207. package/lib/esm/test/standalone/ChangeUnifier.test.d.ts.map +1 -0
  208. package/lib/esm/test/standalone/ChangeUnifier.test.js +732 -0
  209. package/lib/esm/test/standalone/ChangeUnifier.test.js.map +1 -0
  210. package/lib/esm/test/standalone/DeleteElements.test.js +962 -83
  211. package/lib/esm/test/standalone/DeleteElements.test.js.map +1 -1
  212. package/lib/esm/test/standalone/EditTxn.test.js +72 -1
  213. package/lib/esm/test/standalone/EditTxn.test.js.map +1 -1
  214. package/lib/esm/test/standalone/GeoCoordConfig.test.d.ts +2 -0
  215. package/lib/esm/test/standalone/GeoCoordConfig.test.d.ts.map +1 -0
  216. package/lib/esm/test/standalone/GeoCoordConfig.test.js +158 -0
  217. package/lib/esm/test/standalone/GeoCoordConfig.test.js.map +1 -0
  218. package/lib/esm/test/standalone/SQLiteDb.test.d.ts.map +1 -1
  219. package/lib/esm/test/standalone/SQLiteDb.test.js +422 -1
  220. package/lib/esm/test/standalone/SQLiteDb.test.js.map +1 -1
  221. package/lib/esm/test/standalone/ViewStoreDb.test.js +53 -0
  222. package/lib/esm/test/standalone/ViewStoreDb.test.js.map +1 -1
  223. package/lib/esm/test/workspace/SettingsContainers.test.d.ts +2 -0
  224. package/lib/esm/test/workspace/SettingsContainers.test.d.ts.map +1 -0
  225. package/lib/esm/test/workspace/SettingsContainers.test.js +95 -0
  226. package/lib/esm/test/workspace/SettingsContainers.test.js.map +1 -0
  227. package/lib/esm/workspace/SettingsEditor.d.ts +4 -3
  228. package/lib/esm/workspace/SettingsEditor.d.ts.map +1 -1
  229. package/lib/esm/workspace/SettingsEditor.js +7 -5
  230. package/lib/esm/workspace/SettingsEditor.js.map +1 -1
  231. package/package.json +18 -18
@@ -198,18 +198,22 @@ class SQLiteDb {
198
198
  * extension - to this SQLiteDb. This is *not* the same on-disk format used for iModel changesets.
199
199
  * Unlike `BriefcaseDb.pullChanges`, this does *not* perform any iModel-style changeset relationship validation (e.g. parentId/changesetId)
200
200
  * against the current state of the database (raw sqlite changesets have no header) - it simply applies the changes it contains. It also does *not*
201
- * support DDL/schema changes - raw sqlite changesets cannot represent them. If applying the changeset
202
- * encounters any conflict, or otherwise fails, this method throws (conflicts are never resolved
203
- * automatically).
201
+ * support DDL/schema changes - raw sqlite changesets cannot represent them. Conflicts abort by default.
202
+ * A built-in policy or custom handler can resolve conflicts; unresolved conflicts and other failures throw.
204
203
  * @note this method only throws on failure - it does *not* commit or abandon any changes itself. If it
205
204
  * throws, some (but not necessarily all) of the changeset's changes may have already been applied to the
206
205
  * current transaction. It is the caller's responsibility to call [[saveChanges]] or [[abandonChanges]]
207
206
  * as appropriate after catching an error from this method.
208
207
  * @param changesetFile the local file name of the changeset to apply.
208
+ * @param flags Independent apply options. Defaults to [[SQLiteDb.ApplyChangesetFlags.None]].
209
+ * @param conflictHandler Defaults to [[SQLiteDb.ChangesetConflictPolicy.AbortOnAnyConflict]].
210
+ * Use [[SQLiteDb.ChangesetConflictPolicy.NoLocalChanges]] for the generic iModel policy without
211
+ * table-specific rules, or supply a synchronous custom handler. This does not enable any apply flags:
212
+ * to suppress cascades, also pass [[SQLiteDb.ApplyChangesetFlags.FkNoAction]].
209
213
  * @internal
210
214
  */
211
- applyChangeset(changesetFile) {
212
- this[Symbols_1._nativeDb].applyChangeset(changesetFile);
215
+ applyChangeset(changesetFile, flags, conflictHandler) {
216
+ this[Symbols_1._nativeDb].applyChangeset(changesetFile, flags, conflictHandler);
213
217
  }
214
218
  /**
215
219
  * Begin capturing data changes made to this SQLiteDb, so they may later be saved via [[createChangeset]].
@@ -417,6 +421,37 @@ class VersionedSqliteDb extends SQLiteDb {
417
421
  exports.VersionedSqliteDb = VersionedSqliteDb;
418
422
  /** @public */
419
423
  (function (SQLiteDb) {
424
+ /** Independent flags for applying a raw SQLite changeset. Combine with bitwise OR.
425
+ * @internal
426
+ */
427
+ let ApplyChangesetFlags;
428
+ (function (ApplyChangesetFlags) {
429
+ /** Apply with no optional flags. */
430
+ ApplyChangesetFlags[ApplyChangesetFlags["None"] = 0] = "None";
431
+ /** Apply the inverse of the changeset. */
432
+ ApplyChangesetFlags[ApplyChangesetFlags["Invert"] = 1] = "Invert";
433
+ /** Skip changes that would leave the database unchanged without invoking the conflict handler. */
434
+ ApplyChangesetFlags[ApplyChangesetFlags["IgnoreNoop"] = 2] = "IgnoreNoop";
435
+ /** Treat all foreign-key actions as NO ACTION, including CASCADE, RESTRICT, SET NULL, and SET DEFAULT. */
436
+ ApplyChangesetFlags[ApplyChangesetFlags["FkNoAction"] = 4] = "FkNoAction";
437
+ /** Report cyclic UNIQUE updates as constraint conflicts instead of retrying them. */
438
+ ApplyChangesetFlags[ApplyChangesetFlags["NoUpdateLoop"] = 8] = "NoUpdateLoop";
439
+ })(ApplyChangesetFlags = SQLiteDb.ApplyChangesetFlags || (SQLiteDb.ApplyChangesetFlags = {}));
440
+ /** Built-in conflict policies, independent of apply flags.
441
+ * @internal
442
+ */
443
+ let ChangesetConflictPolicy;
444
+ (function (ChangesetConflictPolicy) {
445
+ /** Abort on any conflict. This is the default. */
446
+ ChangesetConflictPolicy[ChangesetConflictPolicy["AbortOnAnyConflict"] = 0] = "AbortOnAnyConflict";
447
+ /** Generic iModel policy with no local changes: skip missing rows and constraint conflicts,
448
+ * replace data and primary-key insert conflicts, and abort on foreign-key violations.
449
+ * Indirect data conflicts are replaced without warnings except for sqlite_stat1 conflicts.
450
+ * Primary-key insert conflicts are replaced with a warning even for indirect changes.
451
+ * Does not include iModel-specific table rules or disable foreign-key actions.
452
+ */
453
+ ChangesetConflictPolicy[ChangesetConflictPolicy["NoLocalChanges"] = 1] = "NoLocalChanges";
454
+ })(ChangesetConflictPolicy = SQLiteDb.ChangesetConflictPolicy || (SQLiteDb.ChangesetConflictPolicy = {}));
420
455
  /** Default transaction mode for SQLiteDbs.
421
456
  * @see https://www.sqlite.org/lang_transaction.html
422
457
  */
@@ -1 +1 @@
1
- {"version":3,"file":"SQLiteDb.js","sourceRoot":"","sources":["../../src/SQLiteDb.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module SQLiteDb\r\n */\r\n\r\nimport * as fs from \"fs\";\r\nimport { dirname } from \"path\";\r\nimport * as semver from \"semver\";\r\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\r\nimport { DbResult, OpenMode } from \"@itwin/core-bentley\";\r\nimport { LocalFileName, SqliteError } from \"@itwin/core-common\";\r\nimport { CloudSqlite } from \"./CloudSqlite\";\r\nimport { IModelNative } from \"./internal/NativePlatform\";\r\nimport { IModelJsFs } from \"./IModelJsFs\";\r\nimport { SqliteStatement, StatementCache } from \"./SqliteStatement\";\r\nimport { _nativeDb } from \"./internal/Symbols\";\r\n\r\n// cspell:ignore savepoint julianday rowid\r\n\r\n/**\r\n * A \"generic\" SQLiteDb. This class may be used to access local files or databases in a cloud container.\r\n * @public\r\n */\r\nexport class SQLiteDb {\r\n /** @internal */\r\n public readonly [_nativeDb] = new IModelNative.platform.SQLiteDb();\r\n private _sqliteStatementCache = new StatementCache<SqliteStatement>();\r\n\r\n /** @internal */\r\n public static createBlobIO(): SQLiteDb.BlobIO {\r\n return new IModelNative.platform.BlobIO();\r\n }\r\n\r\n /** alias for closeDb.\r\n * @deprecated in 4.0 - might be removed in next major version. Use [[closeDb]]\r\n */\r\n public dispose(): void {\r\n this.closeDb();\r\n }\r\n\r\n /** Create a SQLiteDb\r\n * @param dbName The path to the SQLiteDb file to create.\r\n */\r\n public createDb(dbName: string): void;\r\n /** @beta */\r\n public createDb(dbName: string, container?: CloudSqlite.CloudContainer, params?: SQLiteDb.CreateParams): void;\r\n public createDb(dbName: string, container?: CloudSqlite.CloudContainer, params?: SQLiteDb.CreateParams): void {\r\n this[_nativeDb].createDb(dbName, container, params);\r\n }\r\n\r\n /** Open a SQLiteDb.\r\n * @param dbName The path to the SQLiteDb file to open\r\n */\r\n public openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams): void;\r\n /**\r\n * @param container optional CloudContainer holding database\r\n * @beta\r\n */\r\n public openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer): void;\r\n public openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer): void {\r\n this[_nativeDb].openDb(dbName, openMode, container);\r\n }\r\n\r\n /** Close SQLiteDb.\r\n * @param saveChanges if true, call `saveChanges` before closing db. Otherwise unsaved changes are abandoned.\r\n */\r\n public closeDb(saveChanges?: boolean): void {\r\n if (saveChanges && this.isOpen)\r\n this.saveChanges();\r\n this._sqliteStatementCache.clear();\r\n this[_nativeDb].closeDb();\r\n }\r\n\r\n /** Returns true if this SQLiteDb is open */\r\n public get isOpen(): boolean { return this[_nativeDb].isOpen(); }\r\n\r\n /** Returns true if this SQLiteDb is open readonly */\r\n public get isReadonly(): boolean { return this[_nativeDb].isReadonly(); }\r\n\r\n /** Create a new table in this database. */\r\n protected createTable(args: {\r\n /** The name of the table to create. */\r\n tableName: string;\r\n /** all of the columns in the table. */\r\n columns: string;\r\n /** any unique or foreign key constraints */\r\n constraints?: string;\r\n /** if true, add a \"lastMod\" timestamp column and triggers to automatically update it. */\r\n addTimestamp?: boolean;\r\n }) {\r\n const timestampCol = args.addTimestamp ? \",lastMod TIMESTAMP NOT NULL DEFAULT(julianday('now'))\" : \"\";\r\n const constraints = args.constraints ? `,${args.constraints}` : \"\";\r\n this.executeSQL(`CREATE TABLE ${args.tableName}(${args.columns}${timestampCol}${constraints})`);\r\n if (args.addTimestamp)\r\n this.executeSQL(`CREATE TRIGGER ${args.tableName}_timestamp AFTER UPDATE ON ${args.tableName} WHEN old.lastMod=new.lastMod AND old.lastMod != julianday('now') BEGIN UPDATE ${args.tableName} SET lastMod=julianday('now') WHERE rowid=new.rowid; END`);\r\n }\r\n\r\n /**\r\n * Get the last modified date for a row in a table of this database.\r\n * @note the table must have been created with `addTimestamp: true`\r\n */\r\n public readLastModTime(tableName: string, rowId: number): Date {\r\n return this.withSqliteStatement(`SELECT lastMod from ${tableName} WHERE rowid=?`, (stmt) => {\r\n stmt.bindInteger(1, rowId);\r\n return stmt.getValueDate(0);\r\n });\r\n }\r\n\r\n /**\r\n * Open a database, perform an operation, then close the database.\r\n *\r\n * Details:\r\n * - if database is open, throw an error\r\n * - open a database\r\n * - call a function with the database opened. If it is async, await its return.\r\n * - if function throws, abandon all changes, close database, and rethrow\r\n * - save all changes\r\n * - close the database\r\n * @return value from operation\r\n */\r\n public withOpenDb<T>(args: SQLiteDb.WithOpenDbArgs, operation: () => T): T {\r\n if (this.isOpen)\r\n SqliteError.throwError(\"already-open\", \"database is already open\", args.dbName);\r\n\r\n const save = () => this.closeDb(true), abandon = () => this.closeDb(false);\r\n this.openDb(args.dbName, args.openMode ?? OpenMode.Readonly, args.container);\r\n try {\r\n const result = operation();\r\n result instanceof Promise ? result.then(save, abandon) : save();\r\n return result;\r\n } catch (e) {\r\n abandon();\r\n throw e;\r\n }\r\n }\r\n\r\n /** The cloud container backing this SQLite database, if any.\r\n * @beta\r\n */\r\n public get cloudContainer(): CloudSqlite.CloudContainer | undefined {\r\n return this[_nativeDb].cloudContainer;\r\n }\r\n\r\n /** Returns the Id of the most-recently-inserted row in this database, per [sqlite3_last_insert_rowid](https://www.sqlite.org/c3ref/last_insert_rowid.html). */\r\n public getLastInsertRowId(): number {\r\n return this[_nativeDb].getLastInsertRowId();\r\n }\r\n\r\n /**\r\n * Perform an operation on a database in a CloudContainer with the write lock held.\r\n *\r\n * Details:\r\n * - acquire the write lock on a CloudContainer\r\n * - call `withOpenDb` with openMode `ReadWrite`\r\n * - upload changes\r\n * - release the write lock\r\n * @param args arguments to lock the container and open the database\r\n * @param operation an operation performed on the database with the write lock held.\r\n * @return value from operation\r\n * @internal\r\n */\r\n public async withLockedContainer<T>(args: CloudSqlite.LockAndOpenArgs, operation: () => Promise<T>) {\r\n return CloudSqlite.withWriteLock(args, async () => this.withOpenDb({ ...args, openMode: args.openMode ?? OpenMode.ReadWrite }, operation));\r\n }\r\n\r\n /** vacuum this database\r\n * @see https://www.sqlite.org/lang_vacuum.html\r\n */\r\n public vacuum(args?: SQLiteDb.VacuumDbArgs) {\r\n this[_nativeDb].vacuum(args);\r\n }\r\n\r\n /** Commit the outermost transaction, writing changes to the file. Then, restart the default transaction. */\r\n public saveChanges(): void {\r\n this[_nativeDb].saveChanges();\r\n }\r\n\r\n /** Abandon (cancel) the outermost transaction, discarding all changes since last save. Then, restart the default transaction. */\r\n public abandonChanges(): void {\r\n this[_nativeDb].abandonChanges();\r\n }\r\n\r\n /**\r\n * Apply a raw sqlite changeset file - the plain, uncompressed byte stream produced by the sqlite session\r\n * extension - to this SQLiteDb. This is *not* the same on-disk format used for iModel changesets.\r\n * Unlike `BriefcaseDb.pullChanges`, this does *not* perform any iModel-style changeset relationship validation (e.g. parentId/changesetId)\r\n * against the current state of the database (raw sqlite changesets have no header) - it simply applies the changes it contains. It also does *not*\r\n * support DDL/schema changes - raw sqlite changesets cannot represent them. If applying the changeset\r\n * encounters any conflict, or otherwise fails, this method throws (conflicts are never resolved\r\n * automatically).\r\n * @note this method only throws on failure - it does *not* commit or abandon any changes itself. If it\r\n * throws, some (but not necessarily all) of the changeset's changes may have already been applied to the\r\n * current transaction. It is the caller's responsibility to call [[saveChanges]] or [[abandonChanges]]\r\n * as appropriate after catching an error from this method.\r\n * @param changesetFile the local file name of the changeset to apply.\r\n * @internal\r\n */\r\n public applyChangeset(changesetFile: LocalFileName): void {\r\n this[_nativeDb].applyChangeset(changesetFile);\r\n }\r\n\r\n /**\r\n * Begin capturing data changes made to this SQLiteDb, so they may later be saved via [[createChangeset]].\r\n * Intended only to produce changeset files for testing [[applyChangeset]] - not for any other purpose.\r\n * @note DDL/schema changes are *not* captured - the raw sqlite changeset format produced by [[createChangeset]]\r\n * cannot represent them. [[createChangeset]] throws if any DDL was executed via [[executeDdl]] since tracking began.\r\n * @internal\r\n */\r\n public startChangeTracking(): void {\r\n this[_nativeDb].startChangeTracking();\r\n }\r\n\r\n /**\r\n * Execute a DDL statement (e.g. `CREATE TABLE`). DDL cannot be represented in the raw sqlite changeset format\r\n * produced by [[createChangeset]], so it is never included in a changeset regardless of how it is executed.\r\n * However, unlike DDL executed via [[executeSQL]], DDL executed via this method *is* recorded by change\r\n * tracking (see [[startChangeTracking]]) for detection purposes: if any DDL is executed via this method while\r\n * tracking is active, [[createChangeset]] throws rather than silently producing a changeset that omits the\r\n * schema change.\r\n * @internal\r\n */\r\n public executeDdl(ddl: string): void {\r\n this[_nativeDb].executeDdl(ddl);\r\n }\r\n\r\n /**\r\n * Write out the changes captured since [[startChangeTracking]] was called to a changeset file, holding the\r\n * raw sqlite changeset (the plain, uncompressed byte stream produced by the sqlite session extension). This\r\n * is *not* the same on-disk format used for iModel changesets. Throws if any DDL/schema changes were captured,\r\n * since raw sqlite changesets cannot represent them.\r\n * @param changesetFile the local file name to write the changeset to.\r\n * @internal\r\n */\r\n public createChangeset(changesetFile: LocalFileName): void {\r\n this[_nativeDb].createChangeset(changesetFile);\r\n }\r\n\r\n /**\r\n * Use a prepared SQL statement, potentially from the statement cache. If the requested statement doesn't exist\r\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\r\n * in the statement cache so it can be reused in the future. Use this method for SQL statements that will be\r\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\r\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withSqliteStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @returns the value returned by `callback`.\r\n */\r\n public withPreparedSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T): T {\r\n const stmt = this._sqliteStatementCache.findAndRemove(sql) ?? this.prepareSqliteStatement(sql);\r\n const release = () => this._sqliteStatementCache.addOrDispose(stmt);\r\n try {\r\n const val = callback(stmt);\r\n val instanceof Promise ? val.then(release, release) : release();\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Prepare and execute a callback on a SQL statement. After the callback completes the statement is disposed.\r\n * Use this method for SQL statements are either not expected to be reused, or are not expensive to prepare.\r\n * For statements that will be reused often, instead use [[withPreparedSqliteStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @returns the value returned by `callback`.\r\n */\r\n public withSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T): T {\r\n const stmt = this.prepareSqliteStatement(sql);\r\n const release = () => stmt[Symbol.dispose]();\r\n try {\r\n const val = callback(stmt);\r\n val instanceof Promise ? val.then(release, release) : release();\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Perform an operation on this database within a [savepoint](https://www.sqlite.org/lang_savepoint.html). If the operation completes successfully, the\r\n * changes remain in the current transaction. If the operation throws an exception, the savepoint is rolled back\r\n * and all changes to the database from this method are reversed, leaving the transaction exactly as it was before this method.\r\n */\r\n public withSavePoint(savePointName: string, operation: () => void) {\r\n if (this.isReadonly)\r\n SqliteError.throwError(\"readonly\", \"database is readonly\", this[_nativeDb].getFilePath());\r\n\r\n this.executeSQL(`SAVEPOINT ${savePointName}`);\r\n try {\r\n operation();\r\n this.executeSQL(`RELEASE ${savePointName}`);\r\n } catch (e) {\r\n this.executeSQL(`ROLLBACK TO ${savePointName}`);\r\n throw e;\r\n }\r\n }\r\n\r\n /** Prepare an SQL statement.\r\n * @param sql The SQLite SQL statement to prepare\r\n * @param logErrors Determine if errors are logged or not\r\n * @internal\r\n */\r\n public prepareSqliteStatement(sql: string, logErrors = true): SqliteStatement {\r\n const stmt = new SqliteStatement(sql);\r\n stmt.prepare(this[_nativeDb], logErrors);\r\n return stmt;\r\n }\r\n\r\n /** execute an SQL statement */\r\n public executeSQL(sql: string): DbResult {\r\n using stmt = this.prepareSqliteStatement(sql);\r\n return stmt.step();\r\n }\r\n}\r\n\r\n/**\r\n * Abstract base class for a SQLite database that has [[SQLiteDb.RequiredVersionRanges]] stored in it.\r\n * This class provides version checking when the database is opened, to guarantee that a valid version of software is\r\n * always used for access.\r\n *\r\n * Notes:\r\n * - This class may be used either to access a local file, or one stored in a cloud container.\r\n * - Subclasses must provide a `myVersion` member indicating the version of its software, and implement the `createDDL` member to create its\r\n * tables.\r\n * @beta\r\n */\r\nexport abstract class VersionedSqliteDb extends SQLiteDb {\r\n protected static _versionProps = { namespace: \"SQLiteDb\", name: \"versions\" } as const;\r\n\r\n /** The current semver \"persistence version\" of this class.\r\n * @note This value should only be changed when logic in its code is modified in a way that affects the operation of extant copies.\r\n * If this value is outside of the range of accepted versions of a to-be-opened VersionedSqliteDb, the operation will fail. In this manner, if\r\n * changes are made to the format of a VersionedSqliteDb, or if bug fixes are necessary, the `requiredVersions` property in a VersionedSqliteDb may be updated\r\n * and immediately old versions of the package will refuse to open the VersionedSqliteDb, with a message to the user that they need to upgrade their\r\n * software. Likewise, if a new version of the package is asked to open an older VersionedSqliteDb that has not been upgraded to the lowest version\r\n * supported by it, the user will be informed that they need to upgrade their software.\r\n * @note this identifier is independent of versions in `package.json` files.\r\n */\r\n public abstract myVersion: string;\r\n\r\n /**\r\n * Change the \"versions required to open this database\" property stored in this database. After this call,\r\n * versions of software that don't meet the supplied ranges will fail.\r\n * @param versions the new versions required for reading and writing this database.\r\n * @note the database must be opened for write access.\r\n */\r\n public setRequiredVersions(versions: SQLiteDb.RequiredVersionRanges) {\r\n // NOTE: It might look tempting to just stringify the supplied `versions` object, but we only include required members - there may be others.\r\n this[_nativeDb].saveFileProperty(VersionedSqliteDb._versionProps, JSON.stringify({ readVersion: versions.readVersion, writeVersion: versions.writeVersion }));\r\n }\r\n\r\n /** Get the required version ranges necessary to open this VersionedSqliteDb. */\r\n public getRequiredVersions() {\r\n const checkIsString = (value: any) => {\r\n if (typeof value !== \"string\")\r\n SqliteError.throwError(\"invalid-versions-property\", `CloudDb has invalid \"versions\" property`, this[_nativeDb].getFilePath());\r\n return value;\r\n };\r\n const versionJson = checkIsString(this[_nativeDb].queryFileProperty(VersionedSqliteDb._versionProps, true));\r\n const versionRanges = JSON.parse(versionJson) as SQLiteDb.RequiredVersionRanges;\r\n checkIsString(versionRanges.readVersion);\r\n checkIsString(versionRanges.writeVersion);\r\n return versionRanges;\r\n }\r\n\r\n /**\r\n * Implement this method to create all tables for this subclass of `VersionedSqliteDb` when a new database file is created. Called from [[createNewDb]].\r\n */\r\n protected abstract createDDL(args: any): void;\r\n\r\n /**\r\n * Create a new database file for the subclass of VersionedSqliteDb.\r\n * @note The required versions are saved as [[myVersion]] or newer for both read and write.\r\n */\r\n public static createNewDb(fileName: LocalFileName, setupArgs?: any) {\r\n const db = new (this as any)() as VersionedSqliteDb; // \"as any\" necessary because VersionedSqliteDb is abstract\r\n IModelJsFs.recursiveMkDirSync(dirname(fileName));\r\n if (fs.existsSync(fileName))\r\n fs.unlinkSync(fileName);\r\n\r\n db.createDb(fileName);\r\n db.createDDL(setupArgs);\r\n const minVer = `^${db.myVersion}`;\r\n db.setRequiredVersions({ readVersion: minVer, writeVersion: minVer });\r\n db.closeDb(true);\r\n }\r\n\r\n /**\r\n * Verify that this version of the software meets the required version range (as appropriate, read or write) stored in the database.\r\n * Throws otherwise.\r\n */\r\n protected verifyVersions() {\r\n const versions = this.getRequiredVersions();\r\n const isReadonly = this.isReadonly; // so we can tell read/write after the file is closed.\r\n const range = isReadonly ? versions.readVersion : versions.writeVersion;\r\n if (semver.satisfies(this.myVersion, range))\r\n return;\r\n\r\n this.closeDb();\r\n const tooNew = semver.gtr(this.myVersion, range);\r\n SqliteError.throwError(\"incompatible-version\", `requires ${tooNew ? \"older\" : \"newer\"} version of ${this.constructor.name} for ${isReadonly ? \"read\" : \"write\"}`, this[_nativeDb].getFilePath());\r\n\r\n }\r\n\r\n /**\r\n * Open this database and verify that this version of the software meets the required version range (as appropriate, read or write) stored in the database.\r\n * Throws otherwise.\r\n * @see [[SqliteDb.openDb]] for argument types\r\n */\r\n public override openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer) {\r\n super.openDb(dbName, openMode, container);\r\n this.verifyVersions();\r\n }\r\n\r\n public async upgradeSchema(arg: { dbName: string, lockContainer?: { container: CloudSqlite.CloudContainer, user: string }, upgradeFn: () => void }) {\r\n // can't use \"this\" because it checks for version, which we don't want here\r\n return (arg.lockContainer) ?\r\n super.withLockedContainer({ dbName: arg.dbName, ...arg.lockContainer }, async () => arg.upgradeFn) :\r\n super.withOpenDb({ ...arg, openMode: OpenMode.ReadWrite }, arg.upgradeFn);\r\n }\r\n}\r\n\r\n/** @public */\r\nexport namespace SQLiteDb {\r\n /** A semver version range.\r\n * @see https://docs.npmjs.com/cli/v6/using-npm/semver\r\n */\r\n export type VersionRange = string;\r\n\r\n /**\r\n * A pair of semver [[SQLiteDb.VersionRange]]s, one for read and one for write, required to access a [[VersionedSqliteDb]].\r\n * If the version of the software attempting to read or write the database does not satisfy the range, access is denied.\r\n */\r\n export interface RequiredVersionRanges {\r\n /** a range of acceptable persistence versions for reading from a VersionedSqliteDb. */\r\n readonly readVersion: VersionRange;\r\n /** a range of acceptable persistence versions for writing to a VersionedSqliteDb. */\r\n readonly writeVersion: VersionRange;\r\n }\r\n\r\n /** interface for reading and writing to a blob in a SQLiteDb\r\n * @internal\r\n */\r\n export interface BlobIO {\r\n /** Close this BlobIO if it is opened.\r\n * @note this BlobIO *may* be reused after this call by calling `open` again.\r\n */\r\n close(): void;\r\n /** get the total number of bytes in the blob */\r\n getNumBytes(): number;\r\n /** @return true if this BlobIO was successfully opened and may be use to read or write the blob */\r\n isValid(): boolean;\r\n /** Open this BlobIO against a table/row/column in a Db */\r\n open(\r\n /** The database for the blob */\r\n db: IModelJsNative.AnyDb,\r\n args: {\r\n /** the name of the table for the blob*/\r\n tableName: string;\r\n /** the name of the column for the blob */\r\n columnName: string;\r\n /** The rowId of the blob */\r\n row: number;\r\n /** If true, open this BlobIO for write access */\r\n writeable?: boolean;\r\n }): void;\r\n /** Read from a blob\r\n * @returns the contents of the requested byte range\r\n */\r\n read(args: {\r\n /** The number of bytes to read */\r\n numBytes: number;\r\n /** starting offset within the blob to read */\r\n offset: number;\r\n /** If present and of sufficient size, use this ArrayBuffer for the value. */\r\n blob?: ArrayBuffer;\r\n }): Uint8Array;\r\n /** Reposition this BlobIO to a new rowId\r\n * @note this BlobIO must be valid when this methods is called.\r\n */\r\n changeRow(row: number): void;\r\n /** Write to a blob */\r\n write(args: {\r\n /** The number of bytes to write */\r\n numBytes: number;\r\n /** starting offset within the blob to write */\r\n offset: number;\r\n /** the value to write */\r\n blob: ArrayBuffer;\r\n }): void;\r\n }\r\n\r\n /** Default transaction mode for SQLiteDbs.\r\n * @see https://www.sqlite.org/lang_transaction.html\r\n */\r\n export enum DefaultTxnMode {\r\n /** no default transaction is started. You must use BEGIN/COMMIT or SQLite will use implicit transactions */\r\n None = 0,\r\n /** A deferred transaction is started when the file is first opened. This is the default. */\r\n Deferred = 1,\r\n /** An immediate transaction is started when the file is first opened. */\r\n Immediate = 2,\r\n /** An exclusive transaction is started when the file is first opened. */\r\n Exclusive = 3\r\n }\r\n\r\n /** parameters common to opening or creating a new SQLiteDb */\r\n export interface OpenOrCreateParams {\r\n /** If true, do not require that the `be_Prop` table exist */\r\n rawSQLite?: boolean;\r\n /** @see immutable option at https://www.sqlite.org/c3ref/open.html */\r\n immutable?: boolean;\r\n /** Do not attempt to verify that the file is a valid sQLite file before opening. */\r\n skipFileCheck?: boolean;\r\n /** the default transaction mode\r\n * @see [[SQLiteDb.DefaultTxnMode]]\r\n */\r\n defaultTxn?: 0 | 1 | 2 | 3;\r\n /** see query parameters from 'URI Filenames' in https://www.sqlite.org/c3ref/open.html */\r\n queryParam?: string;\r\n }\r\n\r\n /** Parameters for opening an existing SQLiteDb */\r\n export interface OpenParams extends OpenOrCreateParams {\r\n /** use OpenMode.ReadWrite to open the file with write access */\r\n openMode: OpenMode;\r\n }\r\n\r\n /** Size of a SQLiteDb page in bytes */\r\n export interface PageSize {\r\n /** see https://www.sqlite.org/pragma.html#pragma_page_size */\r\n pageSize?: number;\r\n }\r\n\r\n /** Parameters for creating a new SQLiteDb */\r\n export type CreateParams = OpenOrCreateParams & PageSize;\r\n\r\n /** Arguments for `SqliteDb.withOpenDb` */\r\n export interface WithOpenDbArgs {\r\n /** The name of the database to open */\r\n dbName: string;\r\n /** either an object with the open parameters or just OpenMode value. */\r\n openMode?: OpenMode | SQLiteDb.OpenParams;\r\n /** @internal */\r\n container?: CloudSqlite.CloudContainer;\r\n }\r\n\r\n /** Arguments for `SQLiteDb.vacuum` */\r\n export interface VacuumDbArgs extends PageSize {\r\n /** if present, name of new file to [vacuum into](https://www.sqlite.org/lang_vacuum.html) */\r\n into?: LocalFileName;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"SQLiteDb.js","sourceRoot":"","sources":["../../src/SQLiteDb.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module SQLiteDb\r\n */\r\n\r\nimport * as fs from \"fs\";\r\nimport { dirname } from \"path\";\r\nimport * as semver from \"semver\";\r\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\r\nimport { DbConflictResolution, DbResult, OpenMode } from \"@itwin/core-bentley\";\r\nimport { LocalFileName, SqliteError } from \"@itwin/core-common\";\r\nimport { CloudSqlite } from \"./CloudSqlite\";\r\nimport { IModelNative } from \"./internal/NativePlatform\";\r\nimport { IModelJsFs } from \"./IModelJsFs\";\r\nimport { SqliteStatement, StatementCache } from \"./SqliteStatement\";\r\nimport { _nativeDb } from \"./internal/Symbols\";\r\n\r\n// cspell:ignore savepoint julianday rowid\r\n\r\n/**\r\n * A \"generic\" SQLiteDb. This class may be used to access local files or databases in a cloud container.\r\n * @public\r\n */\r\nexport class SQLiteDb {\r\n /** @internal */\r\n public readonly [_nativeDb] = new IModelNative.platform.SQLiteDb();\r\n private _sqliteStatementCache = new StatementCache<SqliteStatement>();\r\n\r\n /** @internal */\r\n public static createBlobIO(): SQLiteDb.BlobIO {\r\n return new IModelNative.platform.BlobIO();\r\n }\r\n\r\n /** alias for closeDb.\r\n * @deprecated in 4.0 - might be removed in next major version. Use [[closeDb]]\r\n */\r\n public dispose(): void {\r\n this.closeDb();\r\n }\r\n\r\n /** Create a SQLiteDb\r\n * @param dbName The path to the SQLiteDb file to create.\r\n */\r\n public createDb(dbName: string): void;\r\n /** @beta */\r\n public createDb(dbName: string, container?: CloudSqlite.CloudContainer, params?: SQLiteDb.CreateParams): void;\r\n public createDb(dbName: string, container?: CloudSqlite.CloudContainer, params?: SQLiteDb.CreateParams): void {\r\n this[_nativeDb].createDb(dbName, container, params);\r\n }\r\n\r\n /** Open a SQLiteDb.\r\n * @param dbName The path to the SQLiteDb file to open\r\n */\r\n public openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams): void;\r\n /**\r\n * @param container optional CloudContainer holding database\r\n * @beta\r\n */\r\n public openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer): void;\r\n public openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer): void {\r\n this[_nativeDb].openDb(dbName, openMode, container);\r\n }\r\n\r\n /** Close SQLiteDb.\r\n * @param saveChanges if true, call `saveChanges` before closing db. Otherwise unsaved changes are abandoned.\r\n */\r\n public closeDb(saveChanges?: boolean): void {\r\n if (saveChanges && this.isOpen)\r\n this.saveChanges();\r\n this._sqliteStatementCache.clear();\r\n this[_nativeDb].closeDb();\r\n }\r\n\r\n /** Returns true if this SQLiteDb is open */\r\n public get isOpen(): boolean { return this[_nativeDb].isOpen(); }\r\n\r\n /** Returns true if this SQLiteDb is open readonly */\r\n public get isReadonly(): boolean { return this[_nativeDb].isReadonly(); }\r\n\r\n /** Create a new table in this database. */\r\n protected createTable(args: {\r\n /** The name of the table to create. */\r\n tableName: string;\r\n /** all of the columns in the table. */\r\n columns: string;\r\n /** any unique or foreign key constraints */\r\n constraints?: string;\r\n /** if true, add a \"lastMod\" timestamp column and triggers to automatically update it. */\r\n addTimestamp?: boolean;\r\n }) {\r\n const timestampCol = args.addTimestamp ? \",lastMod TIMESTAMP NOT NULL DEFAULT(julianday('now'))\" : \"\";\r\n const constraints = args.constraints ? `,${args.constraints}` : \"\";\r\n this.executeSQL(`CREATE TABLE ${args.tableName}(${args.columns}${timestampCol}${constraints})`);\r\n if (args.addTimestamp)\r\n this.executeSQL(`CREATE TRIGGER ${args.tableName}_timestamp AFTER UPDATE ON ${args.tableName} WHEN old.lastMod=new.lastMod AND old.lastMod != julianday('now') BEGIN UPDATE ${args.tableName} SET lastMod=julianday('now') WHERE rowid=new.rowid; END`);\r\n }\r\n\r\n /**\r\n * Get the last modified date for a row in a table of this database.\r\n * @note the table must have been created with `addTimestamp: true`\r\n */\r\n public readLastModTime(tableName: string, rowId: number): Date {\r\n return this.withSqliteStatement(`SELECT lastMod from ${tableName} WHERE rowid=?`, (stmt) => {\r\n stmt.bindInteger(1, rowId);\r\n return stmt.getValueDate(0);\r\n });\r\n }\r\n\r\n /**\r\n * Open a database, perform an operation, then close the database.\r\n *\r\n * Details:\r\n * - if database is open, throw an error\r\n * - open a database\r\n * - call a function with the database opened. If it is async, await its return.\r\n * - if function throws, abandon all changes, close database, and rethrow\r\n * - save all changes\r\n * - close the database\r\n * @return value from operation\r\n */\r\n public withOpenDb<T>(args: SQLiteDb.WithOpenDbArgs, operation: () => T): T {\r\n if (this.isOpen)\r\n SqliteError.throwError(\"already-open\", \"database is already open\", args.dbName);\r\n\r\n const save = () => this.closeDb(true), abandon = () => this.closeDb(false);\r\n this.openDb(args.dbName, args.openMode ?? OpenMode.Readonly, args.container);\r\n try {\r\n const result = operation();\r\n result instanceof Promise ? result.then(save, abandon) : save();\r\n return result;\r\n } catch (e) {\r\n abandon();\r\n throw e;\r\n }\r\n }\r\n\r\n /** The cloud container backing this SQLite database, if any.\r\n * @beta\r\n */\r\n public get cloudContainer(): CloudSqlite.CloudContainer | undefined {\r\n return this[_nativeDb].cloudContainer;\r\n }\r\n\r\n /** Returns the Id of the most-recently-inserted row in this database, per [sqlite3_last_insert_rowid](https://www.sqlite.org/c3ref/last_insert_rowid.html). */\r\n public getLastInsertRowId(): number {\r\n return this[_nativeDb].getLastInsertRowId();\r\n }\r\n\r\n /**\r\n * Perform an operation on a database in a CloudContainer with the write lock held.\r\n *\r\n * Details:\r\n * - acquire the write lock on a CloudContainer\r\n * - call `withOpenDb` with openMode `ReadWrite`\r\n * - upload changes\r\n * - release the write lock\r\n * @param args arguments to lock the container and open the database\r\n * @param operation an operation performed on the database with the write lock held.\r\n * @return value from operation\r\n * @internal\r\n */\r\n public async withLockedContainer<T>(args: CloudSqlite.LockAndOpenArgs, operation: () => Promise<T>) {\r\n return CloudSqlite.withWriteLock(args, async () => this.withOpenDb({ ...args, openMode: args.openMode ?? OpenMode.ReadWrite }, operation));\r\n }\r\n\r\n /** vacuum this database\r\n * @see https://www.sqlite.org/lang_vacuum.html\r\n */\r\n public vacuum(args?: SQLiteDb.VacuumDbArgs) {\r\n this[_nativeDb].vacuum(args);\r\n }\r\n\r\n /** Commit the outermost transaction, writing changes to the file. Then, restart the default transaction. */\r\n public saveChanges(): void {\r\n this[_nativeDb].saveChanges();\r\n }\r\n\r\n /** Abandon (cancel) the outermost transaction, discarding all changes since last save. Then, restart the default transaction. */\r\n public abandonChanges(): void {\r\n this[_nativeDb].abandonChanges();\r\n }\r\n\r\n /**\r\n * Apply a raw sqlite changeset file - the plain, uncompressed byte stream produced by the sqlite session\r\n * extension - to this SQLiteDb. This is *not* the same on-disk format used for iModel changesets.\r\n * Unlike `BriefcaseDb.pullChanges`, this does *not* perform any iModel-style changeset relationship validation (e.g. parentId/changesetId)\r\n * against the current state of the database (raw sqlite changesets have no header) - it simply applies the changes it contains. It also does *not*\r\n * support DDL/schema changes - raw sqlite changesets cannot represent them. Conflicts abort by default.\r\n * A built-in policy or custom handler can resolve conflicts; unresolved conflicts and other failures throw.\r\n * @note this method only throws on failure - it does *not* commit or abandon any changes itself. If it\r\n * throws, some (but not necessarily all) of the changeset's changes may have already been applied to the\r\n * current transaction. It is the caller's responsibility to call [[saveChanges]] or [[abandonChanges]]\r\n * as appropriate after catching an error from this method.\r\n * @param changesetFile the local file name of the changeset to apply.\r\n * @param flags Independent apply options. Defaults to [[SQLiteDb.ApplyChangesetFlags.None]].\r\n * @param conflictHandler Defaults to [[SQLiteDb.ChangesetConflictPolicy.AbortOnAnyConflict]].\r\n * Use [[SQLiteDb.ChangesetConflictPolicy.NoLocalChanges]] for the generic iModel policy without\r\n * table-specific rules, or supply a synchronous custom handler. This does not enable any apply flags:\r\n * to suppress cascades, also pass [[SQLiteDb.ApplyChangesetFlags.FkNoAction]].\r\n * @internal\r\n */\r\n public applyChangeset(changesetFile: LocalFileName, flags?: SQLiteDb.ApplyChangesetFlags, conflictHandler?: SQLiteDb.ChangesetConflictPolicy | SQLiteDb.ChangesetConflictHandler): void {\r\n this[_nativeDb].applyChangeset(changesetFile, flags, conflictHandler);\r\n }\r\n\r\n /**\r\n * Begin capturing data changes made to this SQLiteDb, so they may later be saved via [[createChangeset]].\r\n * Intended only to produce changeset files for testing [[applyChangeset]] - not for any other purpose.\r\n * @note DDL/schema changes are *not* captured - the raw sqlite changeset format produced by [[createChangeset]]\r\n * cannot represent them. [[createChangeset]] throws if any DDL was executed via [[executeDdl]] since tracking began.\r\n * @internal\r\n */\r\n public startChangeTracking(): void {\r\n this[_nativeDb].startChangeTracking();\r\n }\r\n\r\n /**\r\n * Execute a DDL statement (e.g. `CREATE TABLE`). DDL cannot be represented in the raw sqlite changeset format\r\n * produced by [[createChangeset]], so it is never included in a changeset regardless of how it is executed.\r\n * However, unlike DDL executed via [[executeSQL]], DDL executed via this method *is* recorded by change\r\n * tracking (see [[startChangeTracking]]) for detection purposes: if any DDL is executed via this method while\r\n * tracking is active, [[createChangeset]] throws rather than silently producing a changeset that omits the\r\n * schema change.\r\n * @internal\r\n */\r\n public executeDdl(ddl: string): void {\r\n this[_nativeDb].executeDdl(ddl);\r\n }\r\n\r\n /**\r\n * Write out the changes captured since [[startChangeTracking]] was called to a changeset file, holding the\r\n * raw sqlite changeset (the plain, uncompressed byte stream produced by the sqlite session extension). This\r\n * is *not* the same on-disk format used for iModel changesets. Throws if any DDL/schema changes were captured,\r\n * since raw sqlite changesets cannot represent them.\r\n * @param changesetFile the local file name to write the changeset to.\r\n * @internal\r\n */\r\n public createChangeset(changesetFile: LocalFileName): void {\r\n this[_nativeDb].createChangeset(changesetFile);\r\n }\r\n\r\n /**\r\n * Use a prepared SQL statement, potentially from the statement cache. If the requested statement doesn't exist\r\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\r\n * in the statement cache so it can be reused in the future. Use this method for SQL statements that will be\r\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\r\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withSqliteStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @returns the value returned by `callback`.\r\n */\r\n public withPreparedSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T): T {\r\n const stmt = this._sqliteStatementCache.findAndRemove(sql) ?? this.prepareSqliteStatement(sql);\r\n const release = () => this._sqliteStatementCache.addOrDispose(stmt);\r\n try {\r\n const val = callback(stmt);\r\n val instanceof Promise ? val.then(release, release) : release();\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Prepare and execute a callback on a SQL statement. After the callback completes the statement is disposed.\r\n * Use this method for SQL statements are either not expected to be reused, or are not expensive to prepare.\r\n * For statements that will be reused often, instead use [[withPreparedSqliteStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @returns the value returned by `callback`.\r\n */\r\n public withSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T): T {\r\n const stmt = this.prepareSqliteStatement(sql);\r\n const release = () => stmt[Symbol.dispose]();\r\n try {\r\n const val = callback(stmt);\r\n val instanceof Promise ? val.then(release, release) : release();\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Perform an operation on this database within a [savepoint](https://www.sqlite.org/lang_savepoint.html). If the operation completes successfully, the\r\n * changes remain in the current transaction. If the operation throws an exception, the savepoint is rolled back\r\n * and all changes to the database from this method are reversed, leaving the transaction exactly as it was before this method.\r\n */\r\n public withSavePoint(savePointName: string, operation: () => void) {\r\n if (this.isReadonly)\r\n SqliteError.throwError(\"readonly\", \"database is readonly\", this[_nativeDb].getFilePath());\r\n\r\n this.executeSQL(`SAVEPOINT ${savePointName}`);\r\n try {\r\n operation();\r\n this.executeSQL(`RELEASE ${savePointName}`);\r\n } catch (e) {\r\n this.executeSQL(`ROLLBACK TO ${savePointName}`);\r\n throw e;\r\n }\r\n }\r\n\r\n /** Prepare an SQL statement.\r\n * @param sql The SQLite SQL statement to prepare\r\n * @param logErrors Determine if errors are logged or not\r\n * @internal\r\n */\r\n public prepareSqliteStatement(sql: string, logErrors = true): SqliteStatement {\r\n const stmt = new SqliteStatement(sql);\r\n stmt.prepare(this[_nativeDb], logErrors);\r\n return stmt;\r\n }\r\n\r\n /** execute an SQL statement */\r\n public executeSQL(sql: string): DbResult {\r\n using stmt = this.prepareSqliteStatement(sql);\r\n return stmt.step();\r\n }\r\n}\r\n\r\n/**\r\n * Abstract base class for a SQLite database that has [[SQLiteDb.RequiredVersionRanges]] stored in it.\r\n * This class provides version checking when the database is opened, to guarantee that a valid version of software is\r\n * always used for access.\r\n *\r\n * Notes:\r\n * - This class may be used either to access a local file, or one stored in a cloud container.\r\n * - Subclasses must provide a `myVersion` member indicating the version of its software, and implement the `createDDL` member to create its\r\n * tables.\r\n * @beta\r\n */\r\nexport abstract class VersionedSqliteDb extends SQLiteDb {\r\n protected static _versionProps = { namespace: \"SQLiteDb\", name: \"versions\" } as const;\r\n\r\n /** The current semver \"persistence version\" of this class.\r\n * @note This value should only be changed when logic in its code is modified in a way that affects the operation of extant copies.\r\n * If this value is outside of the range of accepted versions of a to-be-opened VersionedSqliteDb, the operation will fail. In this manner, if\r\n * changes are made to the format of a VersionedSqliteDb, or if bug fixes are necessary, the `requiredVersions` property in a VersionedSqliteDb may be updated\r\n * and immediately old versions of the package will refuse to open the VersionedSqliteDb, with a message to the user that they need to upgrade their\r\n * software. Likewise, if a new version of the package is asked to open an older VersionedSqliteDb that has not been upgraded to the lowest version\r\n * supported by it, the user will be informed that they need to upgrade their software.\r\n * @note this identifier is independent of versions in `package.json` files.\r\n */\r\n public abstract myVersion: string;\r\n\r\n /**\r\n * Change the \"versions required to open this database\" property stored in this database. After this call,\r\n * versions of software that don't meet the supplied ranges will fail.\r\n * @param versions the new versions required for reading and writing this database.\r\n * @note the database must be opened for write access.\r\n */\r\n public setRequiredVersions(versions: SQLiteDb.RequiredVersionRanges) {\r\n // NOTE: It might look tempting to just stringify the supplied `versions` object, but we only include required members - there may be others.\r\n this[_nativeDb].saveFileProperty(VersionedSqliteDb._versionProps, JSON.stringify({ readVersion: versions.readVersion, writeVersion: versions.writeVersion }));\r\n }\r\n\r\n /** Get the required version ranges necessary to open this VersionedSqliteDb. */\r\n public getRequiredVersions() {\r\n const checkIsString = (value: any) => {\r\n if (typeof value !== \"string\")\r\n SqliteError.throwError(\"invalid-versions-property\", `CloudDb has invalid \"versions\" property`, this[_nativeDb].getFilePath());\r\n return value;\r\n };\r\n const versionJson = checkIsString(this[_nativeDb].queryFileProperty(VersionedSqliteDb._versionProps, true));\r\n const versionRanges = JSON.parse(versionJson) as SQLiteDb.RequiredVersionRanges;\r\n checkIsString(versionRanges.readVersion);\r\n checkIsString(versionRanges.writeVersion);\r\n return versionRanges;\r\n }\r\n\r\n /**\r\n * Implement this method to create all tables for this subclass of `VersionedSqliteDb` when a new database file is created. Called from [[createNewDb]].\r\n */\r\n protected abstract createDDL(args: any): void;\r\n\r\n /**\r\n * Create a new database file for the subclass of VersionedSqliteDb.\r\n * @note The required versions are saved as [[myVersion]] or newer for both read and write.\r\n */\r\n public static createNewDb(fileName: LocalFileName, setupArgs?: any) {\r\n const db = new (this as any)() as VersionedSqliteDb; // \"as any\" necessary because VersionedSqliteDb is abstract\r\n IModelJsFs.recursiveMkDirSync(dirname(fileName));\r\n if (fs.existsSync(fileName))\r\n fs.unlinkSync(fileName);\r\n\r\n db.createDb(fileName);\r\n db.createDDL(setupArgs);\r\n const minVer = `^${db.myVersion}`;\r\n db.setRequiredVersions({ readVersion: minVer, writeVersion: minVer });\r\n db.closeDb(true);\r\n }\r\n\r\n /**\r\n * Verify that this version of the software meets the required version range (as appropriate, read or write) stored in the database.\r\n * Throws otherwise.\r\n */\r\n protected verifyVersions() {\r\n const versions = this.getRequiredVersions();\r\n const isReadonly = this.isReadonly; // so we can tell read/write after the file is closed.\r\n const range = isReadonly ? versions.readVersion : versions.writeVersion;\r\n if (semver.satisfies(this.myVersion, range))\r\n return;\r\n\r\n this.closeDb();\r\n const tooNew = semver.gtr(this.myVersion, range);\r\n SqliteError.throwError(\"incompatible-version\", `requires ${tooNew ? \"older\" : \"newer\"} version of ${this.constructor.name} for ${isReadonly ? \"read\" : \"write\"}`, this[_nativeDb].getFilePath());\r\n\r\n }\r\n\r\n /**\r\n * Open this database and verify that this version of the software meets the required version range (as appropriate, read or write) stored in the database.\r\n * Throws otherwise.\r\n * @see [[SqliteDb.openDb]] for argument types\r\n */\r\n public override openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer) {\r\n super.openDb(dbName, openMode, container);\r\n this.verifyVersions();\r\n }\r\n\r\n public async upgradeSchema(arg: { dbName: string, lockContainer?: { container: CloudSqlite.CloudContainer, user: string }, upgradeFn: () => void }) {\r\n // can't use \"this\" because it checks for version, which we don't want here\r\n return (arg.lockContainer) ?\r\n super.withLockedContainer({ dbName: arg.dbName, ...arg.lockContainer }, async () => arg.upgradeFn) :\r\n super.withOpenDb({ ...arg, openMode: OpenMode.ReadWrite }, arg.upgradeFn);\r\n }\r\n}\r\n\r\n/** @public */\r\nexport namespace SQLiteDb {\r\n /** Independent flags for applying a raw SQLite changeset. Combine with bitwise OR.\r\n * @internal\r\n */\r\n export enum ApplyChangesetFlags {\r\n /** Apply with no optional flags. */\r\n None = 0,\r\n /** Apply the inverse of the changeset. */\r\n Invert = 1,\r\n /** Skip changes that would leave the database unchanged without invoking the conflict handler. */\r\n IgnoreNoop = 2,\r\n /** Treat all foreign-key actions as NO ACTION, including CASCADE, RESTRICT, SET NULL, and SET DEFAULT. */\r\n FkNoAction = 4,\r\n /** Report cyclic UNIQUE updates as constraint conflicts instead of retrying them. */\r\n NoUpdateLoop = 8,\r\n }\r\n\r\n /** Built-in conflict policies, independent of apply flags.\r\n * @internal\r\n */\r\n export enum ChangesetConflictPolicy {\r\n /** Abort on any conflict. This is the default. */\r\n AbortOnAnyConflict = 0,\r\n /** Generic iModel policy with no local changes: skip missing rows and constraint conflicts,\r\n * replace data and primary-key insert conflicts, and abort on foreign-key violations.\r\n * Indirect data conflicts are replaced without warnings except for sqlite_stat1 conflicts.\r\n * Primary-key insert conflicts are replaced with a warning even for indirect changes.\r\n * Does not include iModel-specific table rules or disable foreign-key actions.\r\n */\r\n NoLocalChanges = 1,\r\n }\r\n\r\n /** Copied conflict metadata, safe to retain after the callback returns.\r\n * Row conflicts include table, operation, column count, and primary-key indices.\r\n * Foreign-key conflicts only include their cause and violation count because SQLite provides no associated row.\r\n * @internal\r\n */\r\n export type ChangesetConflictArgs = IModelJsNative.SQLiteChangesetConflictArgs;\r\n\r\n /** A synchronous callback returning Skip, Replace, or Abort. Exceptions abort application and\r\n * propagate to the caller, who remains responsible for abandoning any partially applied changes.\r\n * Replace is valid only for data and primary-key insert conflicts.\r\n * The handler may query this database, but must not modify it (including through prepared\r\n * statements), close it, change its transaction, or recursively apply another changeset to it.\r\n * @internal\r\n */\r\n export type ChangesetConflictHandler = (args: ChangesetConflictArgs) => DbConflictResolution;\r\n\r\n /** A semver version range.\r\n * @see https://docs.npmjs.com/cli/v6/using-npm/semver\r\n */\r\n export type VersionRange = string;\r\n\r\n /**\r\n * A pair of semver [[SQLiteDb.VersionRange]]s, one for read and one for write, required to access a [[VersionedSqliteDb]].\r\n * If the version of the software attempting to read or write the database does not satisfy the range, access is denied.\r\n */\r\n export interface RequiredVersionRanges {\r\n /** a range of acceptable persistence versions for reading from a VersionedSqliteDb. */\r\n readonly readVersion: VersionRange;\r\n /** a range of acceptable persistence versions for writing to a VersionedSqliteDb. */\r\n readonly writeVersion: VersionRange;\r\n }\r\n\r\n /** interface for reading and writing to a blob in a SQLiteDb\r\n * @internal\r\n */\r\n export interface BlobIO {\r\n /** Close this BlobIO if it is opened.\r\n * @note this BlobIO *may* be reused after this call by calling `open` again.\r\n */\r\n close(): void;\r\n /** get the total number of bytes in the blob */\r\n getNumBytes(): number;\r\n /** @return true if this BlobIO was successfully opened and may be use to read or write the blob */\r\n isValid(): boolean;\r\n /** Open this BlobIO against a table/row/column in a Db */\r\n open(\r\n /** The database for the blob */\r\n db: IModelJsNative.AnyDb,\r\n args: {\r\n /** the name of the table for the blob*/\r\n tableName: string;\r\n /** the name of the column for the blob */\r\n columnName: string;\r\n /** The rowId of the blob */\r\n row: number;\r\n /** If true, open this BlobIO for write access */\r\n writeable?: boolean;\r\n }): void;\r\n /** Read from a blob\r\n * @returns the contents of the requested byte range\r\n */\r\n read(args: {\r\n /** The number of bytes to read */\r\n numBytes: number;\r\n /** starting offset within the blob to read */\r\n offset: number;\r\n /** If present and of sufficient size, use this ArrayBuffer for the value. */\r\n blob?: ArrayBuffer;\r\n }): Uint8Array;\r\n /** Reposition this BlobIO to a new rowId\r\n * @note this BlobIO must be valid when this methods is called.\r\n */\r\n changeRow(row: number): void;\r\n /** Write to a blob */\r\n write(args: {\r\n /** The number of bytes to write */\r\n numBytes: number;\r\n /** starting offset within the blob to write */\r\n offset: number;\r\n /** the value to write */\r\n blob: ArrayBuffer;\r\n }): void;\r\n }\r\n\r\n /** Default transaction mode for SQLiteDbs.\r\n * @see https://www.sqlite.org/lang_transaction.html\r\n */\r\n export enum DefaultTxnMode {\r\n /** no default transaction is started. You must use BEGIN/COMMIT or SQLite will use implicit transactions */\r\n None = 0,\r\n /** A deferred transaction is started when the file is first opened. This is the default. */\r\n Deferred = 1,\r\n /** An immediate transaction is started when the file is first opened. */\r\n Immediate = 2,\r\n /** An exclusive transaction is started when the file is first opened. */\r\n Exclusive = 3\r\n }\r\n\r\n /** parameters common to opening or creating a new SQLiteDb */\r\n export interface OpenOrCreateParams {\r\n /** If true, do not require that the `be_Prop` table exist */\r\n rawSQLite?: boolean;\r\n /** @see immutable option at https://www.sqlite.org/c3ref/open.html */\r\n immutable?: boolean;\r\n /** Do not attempt to verify that the file is a valid sQLite file before opening. */\r\n skipFileCheck?: boolean;\r\n /** the default transaction mode\r\n * @see [[SQLiteDb.DefaultTxnMode]]\r\n */\r\n defaultTxn?: 0 | 1 | 2 | 3;\r\n /** see query parameters from 'URI Filenames' in https://www.sqlite.org/c3ref/open.html */\r\n queryParam?: string;\r\n }\r\n\r\n /** Parameters for opening an existing SQLiteDb */\r\n export interface OpenParams extends OpenOrCreateParams {\r\n /** use OpenMode.ReadWrite to open the file with write access */\r\n openMode: OpenMode;\r\n }\r\n\r\n /** Size of a SQLiteDb page in bytes */\r\n export interface PageSize {\r\n /** see https://www.sqlite.org/pragma.html#pragma_page_size */\r\n pageSize?: number;\r\n }\r\n\r\n /** Parameters for creating a new SQLiteDb */\r\n export type CreateParams = OpenOrCreateParams & PageSize;\r\n\r\n /** Arguments for `SqliteDb.withOpenDb` */\r\n export interface WithOpenDbArgs {\r\n /** The name of the database to open */\r\n dbName: string;\r\n /** either an object with the open parameters or just OpenMode value. */\r\n openMode?: OpenMode | SQLiteDb.OpenParams;\r\n /** @internal */\r\n container?: CloudSqlite.CloudContainer;\r\n }\r\n\r\n /** Arguments for `SQLiteDb.vacuum` */\r\n export interface VacuumDbArgs extends PageSize {\r\n /** if present, name of new file to [vacuum into](https://www.sqlite.org/lang_vacuum.html) */\r\n into?: LocalFileName;\r\n }\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaSync.d.ts","sourceRoot":"","sources":["../../src/SchemaSync.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAiD,UAAU,EAAQ,UAAU,EAAwB,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAClJ,OAAO,EAAoB,IAAI,EAA2D,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEpI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAI5D,gBAAgB;AAChB,yBAAiB,UAAU,CAAC;IAmB1B,0EAA0E;IAC1E,UAAiB,0BAA0B;QACzC,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC;QACpC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;QAC/B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;QACpB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;KAC/B;IAED,oFAAoF;IACpF,UAAiB,eAAgB,SAAQ,0BAA0B;QACjE,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;KAChC;IAED,UAAiB,WAAW;QAC1B,iEAAiE;QACjE,mBAAmB,CAAC,cAAc,EAAE,UAAU,GAAG,eAAe,GAAG,SAAS,CAAC;KAC9E;IAED,UAAiB,YAAY;QAC3B,wIAAwI;QACxI,eAAe,CAAC,UAAU,EAAE,0BAA0B,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAC1E;IAED,kFAAkF;IAClF,MAAa,YAAa,SAAQ,iBAAkB,YAAW,WAAW,EAAE,YAAY;QACtF,OAAO,CAAC,qBAAqB,CAAC,CAAU;QACxC,SAAyB,SAAS,WAAW;kBAC1B,SAAS;QAIZ,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,WAAW,CAAC,cAAc;QAKvH,OAAO,CAAC,2BAA2B;QAmB5B,mBAAmB,CAAC,cAAc,EAAE,UAAU,GAAG,eAAe,GAAG,SAAS;QAyBnF,OAAO,CAAC,qBAAqB;QAkBhB,eAAe,CAAC,QAAQ,EAAE,0BAA0B,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;QAyCnF,OAAO,CAAC,eAAe;QAMvB,OAAO,CAAC,6BAA6B;QASrC,OAAO,CAAC,6BAA6B;KAGtC;IAID,6FAA6F;IACtF,MAAM,aAAa,eAAe,CAAC;IAG1C,SAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAKvE;IAED;;OAEG;IACH,KAAY,gBAAgB,GAAG,QAAQ,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAA;KAAE,CAAC;IAgB/E;;;;;;;;OAQG;IACH,SAAgB,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAExD;IAyBD;;;;OAIG;IACH,SAAgB,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,GAAG,WAAW,CAAC,cAAc,GAAG,SAAS,CAEjG;IAWD,SAAsB,cAAc,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAmChF;IAED,6DAA6D;IAC7D,SAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAc5D;IAED,0CAA0C;IAC1C,UAAiB,oBAAoB;QACnC,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;IAED,SAAsB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,oBAAoB,EAAE,SAAS,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAO7J;IAED;;OAEG;IACH,SAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAMrD;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIvD;IAED,kDAAkD;IAClD,UAAiB,4BAA4B;QAC3C,MAAM,EAAE,QAAQ,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB;IAED;;;;;;OAMG;IACH,SAAsB,wBAAwB,CAAC,GAAG,EAAE,4BAA4B,GAAG,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC,CAUrH;IAED,6CAA6C;IAC7C,UAAiB,uBAAuB;QACtC,MAAM,EAAE,QAAQ,CAAC;QACjB,cAAc,EAAE,WAAW,CAAC,cAAc,CAAC;QAC3C,gFAAgF;QAChF,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC7B;IA0DD;;;OAGG;IACH,SAAsB,mBAAmB,CAAC,GAAG,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGrF;IAED,oFAAoF;IACpF,KAAY,WAAW,GAAG,gBAAgB,GAAG,0BAA0B,CAAC;IAOxE,gDAAgD;IAChD,UAAiB,mBAAmB;QAClC,8EAA8E;QAC9E,MAAM,EAAE,WAAW,CAAC;QACpB,0EAA0E;QAC1E,KAAK,CAAC,EAAE,WAAW,CAAC;KACrB;IAED;;;;;OAKG;IACH,SAAsB,eAAe,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuC7E;IAED,yCAAyC;IACzC,UAAiB,mBAAmB;QAClC,MAAM,EAAE,QAAQ,CAAC;QACjB,iFAAiF;QACjF,cAAc,CAAC,EAAE,WAAW,CAAC,cAAc,CAAC;QAC5C,gFAAgF;QAChF,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB;IAED;;;;;;;;;OASG;IACH,SAAsB,eAAe,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC,CASnG;IAED,wDAAwD;IACxD,UAAiB,uBAAuB;QACtC,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC;QAC3B,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;KACzD;IAED,0EAA0E;IAC1E,MAAa,WAAY,SAAQ,WAAW,CAAC,QAAQ,CAAC,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC;oBACzE,KAAK,EAAE,WAAW,CAAC,oBAAoB;QAInD,MAAM;QAGb;;;;SAIC;eACmB,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,cAAc;QAIlE,uFAAuF;eACnE,kBAAkB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC;KAK3G;CACF"}
1
+ {"version":3,"file":"SchemaSync.d.ts","sourceRoot":"","sources":["../../src/SchemaSync.ts"],"names":[],"mappings":"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"}
@@ -376,6 +376,7 @@ var SchemaSync;
376
376
  const status = briefcase[Symbols_1._nativeDb].cancelTo(txnBeforeInit, true);
377
377
  if (status !== core_bentley_1.IModelStatus.Success)
378
378
  core_bentley_1.Logger.logError("SchemaSync", `Failed to roll back schema sync initialization after the container upload failed: ${core_bentley_1.IModelStatus[status] ?? status}`);
379
+ briefcase.clearCaches();
379
380
  }
380
381
  throw error;
381
382
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaSync.js","sourceRoot":"","sources":["../../src/SchemaSync.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module SQLiteDb\r\n */\r\n\r\nimport * as semver from \"semver\";\r\nimport { CloudSqlite } from \"./CloudSqlite\";\r\nimport { SQLiteDb, VersionedSqliteDb } from \"./SQLiteDb\";\r\nimport { BriefcaseDb, IModelDb } from \"./IModelDb\";\r\nimport { BentleyError, ChangeSetStatus, DbResult, Guid, GuidString, Id64, Id64String, IModelStatus, Logger, OpenMode } from \"@itwin/core-bentley\";\r\nimport { BriefcaseIdValue, Code, ElementReservationError, FilePropertyProps, IModelError, LocalFileName } from \"@itwin/core-common\";\r\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\r\nimport type { BlobContainer } from \"./BlobContainerService\";\r\nimport { IModelNative } from \"./internal/NativePlatform\";\r\nimport { _implicitTxn, _nativeDb } from \"./internal/Symbols\";\r\n\r\n/** @internal */\r\nexport namespace SchemaSync {\r\n /** How long a briefcase waits for another briefcase's schema import to finish before giving up.\r\n *\r\n * `nRetries` alone does not bound the wait: when the count runs out `CloudSqlite.withLockedDb` asks\r\n * `onFailure` what to do, and anything other than \"stop\" restarts the whole cycle. Without an\r\n * `onFailure` the caller waits forever with no way to give up, so this supplies one.\r\n */\r\n const lockParams: CloudSqlite.ObtainLockParams = {\r\n retryDelayMs: 6000,\r\n nRetries: 10,\r\n onFailure: async (lockedBy: string, expires: string) => {\r\n Logger.logInfo(\"SchemaSync\", `schema sync container is held by ${lockedBy} until ${expires}; giving up`);\r\n return \"stop\";\r\n },\r\n };\r\n const reservedElementsTableName = \"reserved_elements\";\r\n const maxLocalIdExclusive = 0x10000000000; // 2^40\r\n const idSequenceProp: FilePropertyProps = { namespace: \"schemasync\", name: \"nextReservedElementLocalId\" };\r\n\r\n /** Identifies an element to be reserved in a `SchemaSyncDb`. @internal */\r\n export interface ProposedElementReservation {\r\n readonly federationGuid: GuidString;\r\n readonly ecClassId: Id64String;\r\n readonly code: Code;\r\n readonly isCategory?: boolean;\r\n }\r\n\r\n /** An element reservation that has been persisted in a `SchemaSyncDb`. @internal */\r\n export interface ReservedElement extends ProposedElementReservation {\r\n readonly elementId: Id64String;\r\n }\r\n\r\n export interface ReadMethods {\r\n /** Look up an existing element reservation by federationGuid. */\r\n findReservedElement(federationGuid: GuidString): ReservedElement | undefined;\r\n }\r\n\r\n export interface WriteMethods {\r\n /** Reserve the specified elements in the `SchemaSyncDb`. Throws if any requested reservation conflicts with an existing reservation. */\r\n reserveElements(identities: ProposedElementReservation[]): Promise<void>;\r\n }\r\n\r\n /** A CloudSqlite database for synchronizing schema changes across briefcases. */\r\n export class SchemaSyncDb extends VersionedSqliteDb implements ReadMethods, WriteMethods {\r\n private _supportsReservations?: boolean;\r\n public override readonly myVersion = \"5.0.0\";\r\n protected override createDDL() {\r\n this.ensureReservedElementsTable();\r\n }\r\n\r\n public override openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer) {\r\n super.openDb(dbName, openMode, container);\r\n this._supportsReservations = semver.lte(this.myVersion, semver.minVersion(this.getRequiredVersions().readVersion) ?? \"0.0.0\");\r\n }\r\n\r\n private ensureReservedElementsTable(): void {\r\n if (this._supportsReservations)\r\n return;\r\n\r\n this.executeSQL(`\r\n CREATE TABLE IF NOT EXISTS ${reservedElementsTableName} (\r\n federationGuid BLOB PRIMARY KEY,\r\n elementId INTEGER NOT NULL UNIQUE,\r\n ecClassId INTEGER NOT NULL,\r\n codeSpecId INTEGER NOT NULL,\r\n codeScope TEXT NOT NULL,\r\n codeValue TEXT COLLATE NOCASE\r\n )`);\r\n this.executeSQL(`CREATE UNIQUE INDEX IF NOT EXISTS idx_reserved_elem_code ON ${reservedElementsTableName}(codeSpecId, codeScope, codeValue)`);\r\n const minVersion = `^${this.myVersion}`;\r\n this.setRequiredVersions({ readVersion: minVersion, writeVersion: minVersion });\r\n this._supportsReservations = true;\r\n }\r\n\r\n public findReservedElement(federationGuid: GuidString): ReservedElement | undefined {\r\n if (!this._supportsReservations)\r\n return undefined;\r\n\r\n return this.withPreparedSqliteStatement(\r\n `SELECT elementId, ecClassId, codeSpecId, codeScope, codeValue FROM ${reservedElementsTableName} WHERE federationGuid=?`,\r\n (stmt) => {\r\n stmt.bindGuid(1, federationGuid);\r\n if (!stmt.nextRow())\r\n return undefined;\r\n\r\n return {\r\n federationGuid,\r\n elementId: stmt.getValueId(0),\r\n ecClassId: stmt.getValueId(1),\r\n code: new Code({\r\n spec: stmt.getValueId(2),\r\n scope: stmt.getValueString(3),\r\n value: stmt.getValueStringMaybe(4),\r\n }),\r\n };\r\n },\r\n );\r\n }\r\n\r\n private insertReservedElement(id: ProposedElementReservation, elementId: Id64String): void {\r\n this.withPreparedSqliteStatement(\r\n `INSERT INTO ${reservedElementsTableName} (federationGuid, elementId, ecClassId, codeSpecId, codeScope, codeValue) VALUES (?, ?, ?, ?, ?, ?)`,\r\n (stmt) => {\r\n stmt.bindGuid(1, id.federationGuid);\r\n stmt.bindId(2, elementId);\r\n stmt.bindId(3, id.ecClassId);\r\n stmt.bindId(4, id.code.spec);\r\n stmt.bindString(5, id.code.scope);\r\n if (id.code.value === \"\")\r\n stmt.bindNull(6);\r\n else\r\n stmt.bindString(6, id.code.value);\r\n stmt.stepForWrite();\r\n },\r\n );\r\n }\r\n\r\n public async reserveElements(elements: ProposedElementReservation[]): Promise<void> {\r\n this.ensureReservedElementsTable();\r\n\r\n // Insert new reservations as we go, so later entries in `elements` can dedupe against earlier ones\r\n // through the shared (still-uncommitted) transaction. The caller commits on success and abandons on error.\r\n let nextLocalId = this.getNextReservedElementLocalId();\r\n const firstLocalId = nextLocalId;\r\n\r\n for (const def of elements) {\r\n if (!def.federationGuid || !Guid.isGuid(def.federationGuid)) {\r\n ElementReservationError.throwError(\"invalid-reservation\", {\r\n message: \"Element reservation requires an explicit, valid federationGuid\",\r\n });\r\n }\r\n\r\n // Identity is always the federationGuid. If a reservation already exists for it, it must match exactly.\r\n const existing = this.findReservedElement(def.federationGuid);\r\n if (existing) {\r\n if (!this.existingMatches(existing, def)) {\r\n ElementReservationError.throwError(\"reservation-conflict\", {\r\n message: `Element reservation conflict for federationGuid ${existing.federationGuid}: existing row does not match requested class/code`,\r\n federationGuid: existing.federationGuid,\r\n });\r\n }\r\n continue;\r\n }\r\n\r\n const elementId = Id64.fromLocalAndBriefcaseIds(nextLocalId, BriefcaseIdValue.SchemaSyncElementReserved);\r\n this.insertReservedElement(def, elementId);\r\n // skip a local id for each reserved category because category inserts always trigger a second insert for default subcategory\r\n nextLocalId += def.isCategory ? 2 : 1;\r\n if (nextLocalId >= maxLocalIdExclusive) {\r\n this.abandonChanges();\r\n ElementReservationError.throwError(\"id-sequence-exhausted\", { message: `SchemaSync reserved-element local-id sequence exhausted` });\r\n }\r\n }\r\n\r\n if (nextLocalId !== firstLocalId)\r\n this.setNextReservedElementLocalId(nextLocalId);\r\n }\r\n\r\n private existingMatches(existing: ProposedElementReservation, id: ProposedElementReservation): boolean {\r\n return existing.federationGuid === id.federationGuid\r\n && existing.ecClassId === id.ecClassId\r\n && existing.code.equals(id.code);\r\n }\r\n\r\n private getNextReservedElementLocalId(): number {\r\n const stored = this[_nativeDb].queryFileProperty(idSequenceProp, true) as string | undefined;\r\n const current = stored ? Number(stored) : 1;\r\n if (!Number.isInteger(current) || current < 1)\r\n ElementReservationError.throwError(\"corrupt-reservation-data\", { message: `Corrupt SchemaSync reserved-element local-id counter: '${stored}'` });\r\n\r\n return current;\r\n }\r\n\r\n private setNextReservedElementLocalId(next: number): void {\r\n this[_nativeDb].saveFileProperty(idSequenceProp, String(next));\r\n }\r\n }\r\n\r\n const syncProperty = { namespace: \"itwinjs\", name: \"SchemaSync\" };\r\n const defaultDbName = \"SchemaSyncDb\";\r\n /** The `containerType` recorded on a BlobContainer that holds an iModel's `SchemaSyncDb`. */\r\n export const containerType = \"schemasync\";\r\n const testSyncCachePropKey = \"test.schema_sync.cache_name\";\r\n // for tests only\r\n export function setTestCache(iModel: IModelDb, cacheName?: string): void {\r\n if (cacheName)\r\n iModel[_nativeDb].saveLocalValue(testSyncCachePropKey, cacheName);\r\n else\r\n iModel[_nativeDb].deleteLocalValue(testSyncCachePropKey);\r\n }\r\n\r\n /** Either an open iModel or the name of a closed briefcase file. Every local read below accepts both, so\r\n * a caller that has only a file name does not have to open a `BriefcaseDb` to ask a question about it.\r\n */\r\n export type IModelOrFileName = IModelDb | { readonly fileName: LocalFileName };\r\n\r\n /** Read from an open iModel, or from a closed file opened readonly for the duration of `operation`. */\r\n function readFromIModel<T>(arg: IModelOrFileName, operation: (nativeDb: IModelJsNative.DgnDb) => T): T {\r\n if (arg instanceof IModelDb)\r\n return operation(arg[_nativeDb]);\r\n\r\n const nativeDb = new IModelNative.platform.DgnDb();\r\n nativeDb.openIModel(arg.fileName, OpenMode.Readonly);\r\n try {\r\n return operation(nativeDb);\r\n } finally {\r\n nativeDb.closeFile();\r\n }\r\n }\r\n\r\n /** Whether this iModel's ECSchemas are governed by a `SchemaSyncDb`.\r\n *\r\n * This is the single question every schema operation branches on. It reads one `be_Prop` row written when\r\n * schema sync was enabled and carried to every other briefcase by that changeset - no cloud access, and it\r\n * works on a readonly briefcase, a checkpoint, or a closed file.\r\n * @note This says nothing about whether the container is reachable, or even named. Use\r\n * [[queryContainerProps]] for that. The two are separate on purpose: a file that says it is governed by a\r\n * sync db must never fall back to importing schemas on its own, whatever state the container is in.\r\n */\r\n export function isEnabled(arg: IModelOrFileName): boolean {\r\n return readFromIModel(arg, (nativeDb) => nativeDb.schemaSyncEnabled());\r\n }\r\n\r\n /** One pass over the values schema sync keeps in the file: which container holds the sync db, plus the\r\n * test-only cache override. Read together so a closed file is opened once.\r\n */\r\n function readLocalSyncProps(arg: IModelOrFileName) {\r\n return readFromIModel(arg, (nativeDb) => {\r\n const propsString = nativeDb.queryFileProperty(syncProperty, true) as string | undefined;\r\n let containerProps: CloudSqlite.ContainerProps | undefined;\r\n if (propsString !== undefined) {\r\n try {\r\n containerProps = JSON.parse(propsString) as CloudSqlite.ContainerProps;\r\n } catch (e) {\r\n // Deliberately not swallowed into `undefined`: that would read as \"schema sync was never\r\n // enabled\" and let this briefcase import schemas on its own.\r\n throw new IModelError(DbResult.BE_SQLITE_CORRUPT, `iModel names a SchemaSyncDb container but the property cannot be read: ${BentleyError.getErrorMessage(e)}`);\r\n }\r\n }\r\n return {\r\n containerProps,\r\n testCacheName: nativeDb.queryLocalValue(testSyncCachePropKey),\r\n };\r\n });\r\n }\r\n\r\n /** The container holding this iModel's `SchemaSyncDb`, or `undefined` if schema sync was never enabled.\r\n *\r\n * Local read of the same `be_Prop` file property that [[initializeForIModel]] wrote. Requesting an access\r\n * token for the container is a separate, asynchronous step.\r\n */\r\n export function queryContainerProps(arg: IModelOrFileName): CloudSqlite.ContainerProps | undefined {\r\n return readLocalSyncProps(arg).containerProps;\r\n }\r\n\r\n interface SharedCloudAccess {\r\n access: CloudAccess;\r\n key: string;\r\n referenceCount: number;\r\n }\r\n\r\n const sharedAccessByContainer = new Map<string, SharedCloudAccess | Promise<SharedCloudAccess>>();\r\n const sharedAccessByInstance = new WeakMap<CloudAccess, SharedCloudAccess>();\r\n\r\n export async function getCloudAccess(arg: IModelOrFileName): Promise<CloudAccess> {\r\n const { containerProps, testCacheName } = readLocalSyncProps(arg);\r\n if (undefined === containerProps)\r\n throw new IModelError(DbResult.BE_SQLITE_NOTFOUND, \"iModel does not have a SchemaSyncDb\");\r\n\r\n const sharedAccessKey = JSON.stringify(containerProps) + (testCacheName ?? \"\");\r\n let shared = sharedAccessByContainer.get(sharedAccessKey);\r\n if (undefined === shared) {\r\n const pending = (async () => {\r\n const accessToken = await CloudSqlite.requestToken(containerProps);\r\n const access = new CloudAccess({ ...containerProps, accessToken });\r\n Object.assign(access.lockParams, lockParams);\r\n if (testCacheName)\r\n access.setCache(CloudSqlite.CloudCaches.getCache({ cacheName: testCacheName }));\r\n\r\n const created = { access, key: sharedAccessKey, referenceCount: 0 };\r\n sharedAccessByInstance.set(access, created);\r\n return created;\r\n })();\r\n sharedAccessByContainer.set(sharedAccessKey, pending);\r\n try {\r\n shared = await pending;\r\n if (sharedAccessByContainer.get(sharedAccessKey) === pending)\r\n sharedAccessByContainer.set(sharedAccessKey, shared);\r\n } catch (error) {\r\n if (sharedAccessByContainer.get(sharedAccessKey) === pending)\r\n sharedAccessByContainer.delete(sharedAccessKey);\r\n throw error;\r\n }\r\n } else if (shared instanceof Promise) {\r\n shared = await shared;\r\n }\r\n\r\n ++shared.referenceCount;\r\n return shared.access;\r\n }\r\n\r\n /** Release an access obtained through [[getCloudAccess]]. */\r\n export function releaseCloudAccess(access: CloudAccess): void {\r\n const shared = sharedAccessByInstance.get(access);\r\n if (undefined === shared) {\r\n access.close();\r\n return;\r\n }\r\n\r\n if (--shared.referenceCount > 0)\r\n return;\r\n\r\n sharedAccessByInstance.delete(access);\r\n if (sharedAccessByContainer.get(shared.key) === shared)\r\n sharedAccessByContainer.delete(shared.key);\r\n access.close();\r\n }\r\n\r\n /** Arguments for [[withLockedAccess]]. */\r\n export interface WithLockedAccessArgs {\r\n operationName: string;\r\n openMode?: OpenMode;\r\n user?: string;\r\n }\r\n\r\n export async function withLockedAccess(iModel: IModelOrFileName, args: WithLockedAccessArgs, operation: (access: CloudAccess) => Promise<void>): Promise<void> {\r\n const access = await SchemaSync.getCloudAccess(iModel);\r\n try {\r\n await access.withLockedDb(args, async () => operation(access));\r\n } finally {\r\n releaseCloudAccess(access);\r\n }\r\n }\r\n\r\n /** Build the tables and indexes the briefcase's `ec_` rows describe. A merged schema changeset carries\r\n * those rows but no DDL, so the physical columns are missing until this runs. Needs no cloud access.\r\n */\r\n export function updateDbSchema(iModel: IModelDb): void {\r\n if (isEnabled(iModel) && !iModel.isReadonly) {\r\n iModel.clearCaches();\r\n iModel[_nativeDb].schemaSyncUpdateDbSchema();\r\n iModel[_implicitTxn].saveChanges(\"materialized db schema from ec_ tables\");\r\n }\r\n }\r\n\r\n /** Whether a failed [[IModelDb.importSchemas]] can be retried through the upgrade path.\r\n *\r\n * The update tier refuses two kinds of change: one that has to move data between columns, and one\r\n * that destroys instances or property values. They arrive as different statuses because they are\r\n * different changes, but they mean one thing to a caller - this needs\r\n * [[BriefcaseDb.upgradeSchemas]], which takes the exclusive schema lock.\r\n *\r\n * The retry is the app's decision, not the platform's: taking that lock disturbs everyone else, so\r\n * only the app knows whether to do it now, schedule it, or tell the user.\r\n * ```ts\r\n * try {\r\n * await db.importSchemas(files);\r\n * } catch (e) {\r\n * if (!SchemaSync.requiresUpgrade(e)) throw e;\r\n * await db.upgradeSchemas(files, { description: \"...\" });\r\n * }\r\n * ```\r\n * @internal\r\n */\r\n export function requiresUpgrade(error: unknown): boolean {\r\n const errorNumber = (error as { errorNumber?: number } | undefined)?.errorNumber;\r\n return errorNumber === DbResult.BE_SQLITE_ERROR_DataTransformRequired\r\n || errorNumber === DbResult.BE_SQLITE_ERROR_DataDeletionRequired;\r\n }\r\n\r\n /** Arguments for [[createContainerForIModel]]. */\r\n export interface CreateContainerForIModelArgs {\r\n iModel: IModelDb;\r\n label?: string;\r\n description?: string;\r\n }\r\n\r\n /** Create a cloud container to hold this iModel's `SchemaSyncDb`, and initialize it as empty.\r\n *\r\n * The container is scoped to the iModel, so the service deletes it when the iModel is deleted. Pass the\r\n * returned props to [[initializeForIModel]] - the two calls together are what enables schema sync on an\r\n * iModel that was created without it.\r\n * @note The current user must be authorized to create containers for the iTwin.\r\n */\r\n export async function createContainerForIModel(arg: CreateContainerForIModelArgs): Promise<CloudSqlite.ContainerProps> {\r\n const iModel = arg.iModel;\r\n const iTwinId = iModel.iTwinId;\r\n if (undefined === iTwinId)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot create a SchemaSync container for an iModel that has no iTwin\");\r\n\r\n return CloudAccess.createNewContainer({\r\n scope: { iTwinId, iModelId: iModel.iModelId },\r\n metadata: { label: arg.label ?? `SchemaSync for ${iModel.name}`, description: arg.description },\r\n });\r\n }\r\n\r\n /** Arguments for [[initializeForIModel]]. */\r\n export interface InitializeForIModelArgs {\r\n iModel: IModelDb;\r\n containerProps: CloudSqlite.ContainerProps;\r\n /** Replace the container already recorded on this iModel instead of failing. */\r\n overrideContainer?: boolean;\r\n }\r\n\r\n /** Refuse initialization before a caller provisions a container, then hold the exclusive schema lock and pull to the tip. */\r\n async function prepareToInitializeForIModel(iModel: IModelDb, overrideContainer: boolean): Promise<BriefcaseDb | undefined> {\r\n const briefcase = iModel instanceof BriefcaseDb ? iModel : undefined;\r\n if (briefcase && !briefcase.locks.isServerBased)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot enable SchemaSync without server-based locking\");\r\n\r\n if (briefcase && (iModel[_nativeDb].hasUnsavedChanges() || briefcase.txns.hasLocalChanges))\r\n throw new IModelError(ChangeSetStatus.HasLocalChanges, \"Cannot enable SchemaSync while there are local changes\");\r\n\r\n const assertContainerCanBeInitialized = () => {\r\n const localInfo = iModel[_nativeDb].schemaSyncGetLocalDbInfo();\r\n if (localInfo && !overrideContainer)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, `Local db already initialized to schema sync (container-id: ${localInfo.id})`);\r\n };\r\n\r\n assertContainerCanBeInitialized();\r\n await iModel.acquireSchemaLock();\r\n await briefcase?.pullChanges();\r\n assertContainerCanBeInitialized();\r\n return briefcase;\r\n }\r\n\r\n async function initializeAfterPreflight(arg: InitializeForIModelArgs, briefcase: BriefcaseDb | undefined): Promise<void> {\r\n const props = { baseUri: arg.containerProps.baseUri, containerId: arg.containerProps.containerId, storageType: arg.containerProps.storageType }; // sanitize to only known properties\r\n const iModel = arg.iModel;\r\n const description = arg.overrideContainer\r\n ? `Overriding SchemaSync for iModel with container-id: ${props.containerId}`\r\n : `Enable SchemaSync for iModel with container-id: ${props.containerId}`;\r\n const txnBeforeInit = briefcase?.txns.getCurrentTxnId();\r\n try {\r\n iModel[_implicitTxn].saveFileProperty(syncProperty, JSON.stringify(props));\r\n try {\r\n await withLockedAccess(iModel, { operationName: \"initialize schemaSync\", openMode: OpenMode.Readonly }, async (syncAccess) => {\r\n iModel[_nativeDb].schemaSyncInit(syncAccess.getUri(), props.containerId, arg.overrideContainer ?? false);\r\n iModel[_implicitTxn].saveChanges(description);\r\n });\r\n } catch (error) {\r\n iModel[_implicitTxn].abandonChanges();\r\n if (briefcase && txnBeforeInit !== undefined && briefcase.txns.getCurrentTxnId() !== txnBeforeInit) {\r\n const status = briefcase[_nativeDb].cancelTo(txnBeforeInit, true);\r\n if (status !== IModelStatus.Success)\r\n Logger.logError(\"SchemaSync\", `Failed to roll back schema sync initialization after the container upload failed: ${IModelStatus[status] ?? status}`);\r\n }\r\n throw error;\r\n }\r\n\r\n // Upload the initialized container before publishing the property that tells every briefcase to use it.\r\n // If the push fails, this briefcase keeps the local txn and exclusive schema lock so the push can be retried.\r\n await briefcase?.pushChanges({ description });\r\n } finally {\r\n iModel[_implicitTxn].abandonChanges();\r\n }\r\n\r\n await iModel.initializeSharedElementReservations();\r\n }\r\n\r\n /** Enable schema sync for an iModel, seeding the container from this briefcase.\r\n * @note Takes the exclusive schema lock, refuses local changes, and pulls the briefcase to the tip before writing the container.\r\n * If this operation fails after acquiring the schema lock, it leaves the lock held.\r\n */\r\n export async function initializeForIModel(arg: InitializeForIModelArgs): Promise<void> {\r\n const briefcase = await prepareToInitializeForIModel(arg.iModel, arg.overrideContainer ?? false);\r\n await initializeAfterPreflight(arg, briefcase);\r\n }\r\n\r\n /** The part of a SchemaSyncDb to restore from an authoritative briefcase. @alpha */\r\n export type RepairScope = \"schemaMetadata\" | \"schemaMetadataAndProfile\";\r\n\r\n const nativeRepairScope: Record<RepairScope, number> = {\r\n schemaMetadata: 0,\r\n schemaMetadataAndProfile: 1,\r\n };\r\n\r\n /** Arguments for [[repairForIModel]]. @alpha */\r\n export interface RepairForIModelArgs {\r\n /** A clean SchemaSync-enabled briefcase at the tip of the iModel timeline. */\r\n iModel: BriefcaseDb;\r\n /** Include the schema-owned EC and BeSQLite profile table definitions. */\r\n scope?: RepairScope;\r\n }\r\n\r\n /** Restore the schema-owned portion of the SchemaSyncDb from a briefcase at the tip of the timeline.\r\n *\r\n * This operation takes the exclusive schema lock and refuses to pull or modify the briefcase. Element\r\n * reservations and all other target-only state in the SchemaSyncDb are preserved.\r\n * @alpha\r\n */\r\n export async function repairForIModel(arg: RepairForIModelArgs): Promise<void> {\r\n const iModel = arg.iModel;\r\n if (!isEnabled(iModel))\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot repair SchemaSync because it is not enabled for this iModel\");\r\n\r\n if (iModel[_nativeDb].hasUnsavedChanges() || iModel.txns.hasLocalChanges)\r\n throw new IModelError(ChangeSetStatus.HasLocalChanges, \"Cannot repair SchemaSync while there are local changes\");\r\n\r\n if (!iModel.locks.isServerBased)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot repair SchemaSync without server-based locking\");\r\n\r\n if (arg.scope !== undefined && arg.scope !== \"schemaMetadata\" && arg.scope !== \"schemaMetadataAndProfile\")\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Unknown SchemaSync repair scope\");\r\n\r\n const briefcaseManagerModule = await import(\"./BriefcaseManager\");\r\n const assertBriefcaseIsAtTip = async () => {\r\n const latestChangeset = await briefcaseManagerModule.BriefcaseManager.getLatestChangeset({ iModelId: iModel.iModelId });\r\n if (latestChangeset.id !== iModel.changeset.id)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot repair SchemaSync from a briefcase that is not at the tip of the iModel timeline\");\r\n };\r\n\r\n // Avoid asking Hub for an exclusive lock it cannot grant to a briefcase that first needs to pull.\r\n await assertBriefcaseIsAtTip();\r\n const schemaLockWasHeld = iModel.holdsSchemaLock;\r\n if (!schemaLockWasHeld)\r\n await iModel.acquireSchemaLock();\r\n try {\r\n // Close the race between the preflight query and acquiring the exclusive lock.\r\n await assertBriefcaseIsAtTip();\r\n const repairScope = nativeRepairScope[arg.scope ?? \"schemaMetadata\"];\r\n await withLockedAccess(iModel, { openMode: OpenMode.Readonly, operationName: \"repair schema sync\" }, async (syncAccess) => {\r\n const nativeDb = iModel[_nativeDb] as IModelJsNative.DgnDb & { schemaSyncRepair(syncDbUri: string, scope: number): void };\r\n nativeDb.schemaSyncRepair(syncAccess.getUri(), repairScope);\r\n });\r\n Logger.logInfo(\"SchemaSync\", `Repaired SchemaSyncDb from changeset ${iModel.changeset.id || \"0\"}`);\r\n } finally {\r\n if (!schemaLockWasHeld)\r\n await iModel.locks.abandonAllLocks();\r\n }\r\n }\r\n\r\n /** Arguments for [[enableForIModel]]. */\r\n export interface EnableForIModelArgs {\r\n iModel: IModelDb;\r\n /** An existing container to use. When omitted one is created for this iModel. */\r\n containerProps?: CloudSqlite.ContainerProps;\r\n /** Replace the container already recorded on this iModel instead of failing. */\r\n overrideContainer?: boolean;\r\n label?: string;\r\n description?: string;\r\n }\r\n\r\n /** Turn schema sync on for an iModel: create the container if needed, record it, and seed it.\r\n *\r\n * The single call callers should use. [[createContainerForIModel]] and [[initializeForIModel]] have\r\n * to happen in this order, and an iModel left between the two is one that names a container nothing\r\n * has seeded.\r\n * @returns the container props recorded on the iModel.\r\n * @note Takes the exclusive schema lock and pushes, same protocol as [[BriefcaseDb.upgradeSchemas]] -\r\n * every operation that changes how a file is governed uses it. If this operation fails after acquiring the schema lock,\r\n * it leaves the lock held.\r\n */\r\n export async function enableForIModel(arg: EnableForIModelArgs): Promise<CloudSqlite.ContainerProps> {\r\n if (undefined === arg.containerProps && undefined === arg.iModel.iTwinId)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot create a SchemaSync container for an iModel that has no iTwin\");\r\n\r\n const briefcase = await prepareToInitializeForIModel(arg.iModel, arg.overrideContainer ?? false);\r\n const containerProps = arg.containerProps\r\n ?? await createContainerForIModel({ iModel: arg.iModel, label: arg.label, description: arg.description });\r\n await initializeAfterPreflight({ iModel: arg.iModel, containerProps, overrideContainer: arg.overrideContainer }, briefcase);\r\n return containerProps;\r\n }\r\n\r\n /** Arguments for [[CloudAccess.createNewContainer]]. */\r\n export interface CreateNewContainerProps {\r\n scope: BlobContainer.Scope;\r\n metadata: Omit<BlobContainer.Metadata, \"containerType\">;\r\n }\r\n\r\n /** Provides access to a cloud-based `SchemaSyncDb` to hold ECSchemas. */\r\n export class CloudAccess extends CloudSqlite.DbAccess<SchemaSyncDb, ReadMethods, WriteMethods> {\r\n public constructor(props: CloudSqlite.ContainerAccessProps) {\r\n super({ dbType: SchemaSyncDb, props, dbName: defaultDbName });\r\n }\r\n\r\n public getUri() {\r\n return `${this.getCloudDb()[_nativeDb].getFilePath()}?vfs=${this.container.cache?.name}&writable=${this.container.isWriteable ? 1 : 0}`;\r\n }\r\n /**\r\n * Initialize a cloud container for use as a SchemaSync. The container must first be created via its storage supplier api (e.g. Azure, or AWS).\r\n * A valid sasToken that grants write access must be supplied. This function creates and uploads an empty ChannelDb into the container.\r\n * @note this deletes any existing content in the container.\r\n */\r\n public static async initializeDb(props: CloudSqlite.ContainerProps) {\r\n return super._initializeDb({ props, dbType: SchemaSyncDb, dbName: defaultDbName });\r\n }\r\n\r\n /** Create and initialize a new `schemasync` BlobContainer to hold a `SchemaSyncDb`. */\r\n public static async createNewContainer(args: CreateNewContainerProps): Promise<CloudSqlite.ContainerProps> {\r\n const props = await this.createBlobContainer({ scope: args.scope, metadata: { ...args.metadata, containerType } });\r\n await this.initializeDb(props);\r\n return props;\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"SchemaSync.js","sourceRoot":"","sources":["../../src/SchemaSync.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module SQLiteDb\r\n */\r\n\r\nimport * as semver from \"semver\";\r\nimport { CloudSqlite } from \"./CloudSqlite\";\r\nimport { SQLiteDb, VersionedSqliteDb } from \"./SQLiteDb\";\r\nimport { BriefcaseDb, IModelDb } from \"./IModelDb\";\r\nimport { BentleyError, ChangeSetStatus, DbResult, Guid, GuidString, Id64, Id64String, IModelStatus, Logger, OpenMode } from \"@itwin/core-bentley\";\r\nimport { BriefcaseIdValue, Code, ElementReservationError, FilePropertyProps, IModelError, LocalFileName } from \"@itwin/core-common\";\r\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\r\nimport type { BlobContainer } from \"./BlobContainerService\";\r\nimport { IModelNative } from \"./internal/NativePlatform\";\r\nimport { _implicitTxn, _nativeDb } from \"./internal/Symbols\";\r\n\r\n/** @internal */\r\nexport namespace SchemaSync {\r\n /** How long a briefcase waits for another briefcase's schema import to finish before giving up.\r\n *\r\n * `nRetries` alone does not bound the wait: when the count runs out `CloudSqlite.withLockedDb` asks\r\n * `onFailure` what to do, and anything other than \"stop\" restarts the whole cycle. Without an\r\n * `onFailure` the caller waits forever with no way to give up, so this supplies one.\r\n */\r\n const lockParams: CloudSqlite.ObtainLockParams = {\r\n retryDelayMs: 6000,\r\n nRetries: 10,\r\n onFailure: async (lockedBy: string, expires: string) => {\r\n Logger.logInfo(\"SchemaSync\", `schema sync container is held by ${lockedBy} until ${expires}; giving up`);\r\n return \"stop\";\r\n },\r\n };\r\n const reservedElementsTableName = \"reserved_elements\";\r\n const maxLocalIdExclusive = 0x10000000000; // 2^40\r\n const idSequenceProp: FilePropertyProps = { namespace: \"schemasync\", name: \"nextReservedElementLocalId\" };\r\n\r\n /** Identifies an element to be reserved in a `SchemaSyncDb`. @internal */\r\n export interface ProposedElementReservation {\r\n readonly federationGuid: GuidString;\r\n readonly ecClassId: Id64String;\r\n readonly code: Code;\r\n readonly isCategory?: boolean;\r\n }\r\n\r\n /** An element reservation that has been persisted in a `SchemaSyncDb`. @internal */\r\n export interface ReservedElement extends ProposedElementReservation {\r\n readonly elementId: Id64String;\r\n }\r\n\r\n export interface ReadMethods {\r\n /** Look up an existing element reservation by federationGuid. */\r\n findReservedElement(federationGuid: GuidString): ReservedElement | undefined;\r\n }\r\n\r\n export interface WriteMethods {\r\n /** Reserve the specified elements in the `SchemaSyncDb`. Throws if any requested reservation conflicts with an existing reservation. */\r\n reserveElements(identities: ProposedElementReservation[]): Promise<void>;\r\n }\r\n\r\n /** A CloudSqlite database for synchronizing schema changes across briefcases. */\r\n export class SchemaSyncDb extends VersionedSqliteDb implements ReadMethods, WriteMethods {\r\n private _supportsReservations?: boolean;\r\n public override readonly myVersion = \"5.0.0\";\r\n protected override createDDL() {\r\n this.ensureReservedElementsTable();\r\n }\r\n\r\n public override openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer) {\r\n super.openDb(dbName, openMode, container);\r\n this._supportsReservations = semver.lte(this.myVersion, semver.minVersion(this.getRequiredVersions().readVersion) ?? \"0.0.0\");\r\n }\r\n\r\n private ensureReservedElementsTable(): void {\r\n if (this._supportsReservations)\r\n return;\r\n\r\n this.executeSQL(`\r\n CREATE TABLE IF NOT EXISTS ${reservedElementsTableName} (\r\n federationGuid BLOB PRIMARY KEY,\r\n elementId INTEGER NOT NULL UNIQUE,\r\n ecClassId INTEGER NOT NULL,\r\n codeSpecId INTEGER NOT NULL,\r\n codeScope TEXT NOT NULL,\r\n codeValue TEXT COLLATE NOCASE\r\n )`);\r\n this.executeSQL(`CREATE UNIQUE INDEX IF NOT EXISTS idx_reserved_elem_code ON ${reservedElementsTableName}(codeSpecId, codeScope, codeValue)`);\r\n const minVersion = `^${this.myVersion}`;\r\n this.setRequiredVersions({ readVersion: minVersion, writeVersion: minVersion });\r\n this._supportsReservations = true;\r\n }\r\n\r\n public findReservedElement(federationGuid: GuidString): ReservedElement | undefined {\r\n if (!this._supportsReservations)\r\n return undefined;\r\n\r\n return this.withPreparedSqliteStatement(\r\n `SELECT elementId, ecClassId, codeSpecId, codeScope, codeValue FROM ${reservedElementsTableName} WHERE federationGuid=?`,\r\n (stmt) => {\r\n stmt.bindGuid(1, federationGuid);\r\n if (!stmt.nextRow())\r\n return undefined;\r\n\r\n return {\r\n federationGuid,\r\n elementId: stmt.getValueId(0),\r\n ecClassId: stmt.getValueId(1),\r\n code: new Code({\r\n spec: stmt.getValueId(2),\r\n scope: stmt.getValueString(3),\r\n value: stmt.getValueStringMaybe(4),\r\n }),\r\n };\r\n },\r\n );\r\n }\r\n\r\n private insertReservedElement(id: ProposedElementReservation, elementId: Id64String): void {\r\n this.withPreparedSqliteStatement(\r\n `INSERT INTO ${reservedElementsTableName} (federationGuid, elementId, ecClassId, codeSpecId, codeScope, codeValue) VALUES (?, ?, ?, ?, ?, ?)`,\r\n (stmt) => {\r\n stmt.bindGuid(1, id.federationGuid);\r\n stmt.bindId(2, elementId);\r\n stmt.bindId(3, id.ecClassId);\r\n stmt.bindId(4, id.code.spec);\r\n stmt.bindString(5, id.code.scope);\r\n if (id.code.value === \"\")\r\n stmt.bindNull(6);\r\n else\r\n stmt.bindString(6, id.code.value);\r\n stmt.stepForWrite();\r\n },\r\n );\r\n }\r\n\r\n public async reserveElements(elements: ProposedElementReservation[]): Promise<void> {\r\n this.ensureReservedElementsTable();\r\n\r\n // Insert new reservations as we go, so later entries in `elements` can dedupe against earlier ones\r\n // through the shared (still-uncommitted) transaction. The caller commits on success and abandons on error.\r\n let nextLocalId = this.getNextReservedElementLocalId();\r\n const firstLocalId = nextLocalId;\r\n\r\n for (const def of elements) {\r\n if (!def.federationGuid || !Guid.isGuid(def.federationGuid)) {\r\n ElementReservationError.throwError(\"invalid-reservation\", {\r\n message: \"Element reservation requires an explicit, valid federationGuid\",\r\n });\r\n }\r\n\r\n // Identity is always the federationGuid. If a reservation already exists for it, it must match exactly.\r\n const existing = this.findReservedElement(def.federationGuid);\r\n if (existing) {\r\n if (!this.existingMatches(existing, def)) {\r\n ElementReservationError.throwError(\"reservation-conflict\", {\r\n message: `Element reservation conflict for federationGuid ${existing.federationGuid}: existing row does not match requested class/code`,\r\n federationGuid: existing.federationGuid,\r\n });\r\n }\r\n continue;\r\n }\r\n\r\n const elementId = Id64.fromLocalAndBriefcaseIds(nextLocalId, BriefcaseIdValue.SchemaSyncElementReserved);\r\n this.insertReservedElement(def, elementId);\r\n // skip a local id for each reserved category because category inserts always trigger a second insert for default subcategory\r\n nextLocalId += def.isCategory ? 2 : 1;\r\n if (nextLocalId >= maxLocalIdExclusive) {\r\n this.abandonChanges();\r\n ElementReservationError.throwError(\"id-sequence-exhausted\", { message: `SchemaSync reserved-element local-id sequence exhausted` });\r\n }\r\n }\r\n\r\n if (nextLocalId !== firstLocalId)\r\n this.setNextReservedElementLocalId(nextLocalId);\r\n }\r\n\r\n private existingMatches(existing: ProposedElementReservation, id: ProposedElementReservation): boolean {\r\n return existing.federationGuid === id.federationGuid\r\n && existing.ecClassId === id.ecClassId\r\n && existing.code.equals(id.code);\r\n }\r\n\r\n private getNextReservedElementLocalId(): number {\r\n const stored = this[_nativeDb].queryFileProperty(idSequenceProp, true) as string | undefined;\r\n const current = stored ? Number(stored) : 1;\r\n if (!Number.isInteger(current) || current < 1)\r\n ElementReservationError.throwError(\"corrupt-reservation-data\", { message: `Corrupt SchemaSync reserved-element local-id counter: '${stored}'` });\r\n\r\n return current;\r\n }\r\n\r\n private setNextReservedElementLocalId(next: number): void {\r\n this[_nativeDb].saveFileProperty(idSequenceProp, String(next));\r\n }\r\n }\r\n\r\n const syncProperty = { namespace: \"itwinjs\", name: \"SchemaSync\" };\r\n const defaultDbName = \"SchemaSyncDb\";\r\n /** The `containerType` recorded on a BlobContainer that holds an iModel's `SchemaSyncDb`. */\r\n export const containerType = \"schemasync\";\r\n const testSyncCachePropKey = \"test.schema_sync.cache_name\";\r\n // for tests only\r\n export function setTestCache(iModel: IModelDb, cacheName?: string): void {\r\n if (cacheName)\r\n iModel[_nativeDb].saveLocalValue(testSyncCachePropKey, cacheName);\r\n else\r\n iModel[_nativeDb].deleteLocalValue(testSyncCachePropKey);\r\n }\r\n\r\n /** Either an open iModel or the name of a closed briefcase file. Every local read below accepts both, so\r\n * a caller that has only a file name does not have to open a `BriefcaseDb` to ask a question about it.\r\n */\r\n export type IModelOrFileName = IModelDb | { readonly fileName: LocalFileName };\r\n\r\n /** Read from an open iModel, or from a closed file opened readonly for the duration of `operation`. */\r\n function readFromIModel<T>(arg: IModelOrFileName, operation: (nativeDb: IModelJsNative.DgnDb) => T): T {\r\n if (arg instanceof IModelDb)\r\n return operation(arg[_nativeDb]);\r\n\r\n const nativeDb = new IModelNative.platform.DgnDb();\r\n nativeDb.openIModel(arg.fileName, OpenMode.Readonly);\r\n try {\r\n return operation(nativeDb);\r\n } finally {\r\n nativeDb.closeFile();\r\n }\r\n }\r\n\r\n /** Whether this iModel's ECSchemas are governed by a `SchemaSyncDb`.\r\n *\r\n * This is the single question every schema operation branches on. It reads one `be_Prop` row written when\r\n * schema sync was enabled and carried to every other briefcase by that changeset - no cloud access, and it\r\n * works on a readonly briefcase, a checkpoint, or a closed file.\r\n * @note This says nothing about whether the container is reachable, or even named. Use\r\n * [[queryContainerProps]] for that. The two are separate on purpose: a file that says it is governed by a\r\n * sync db must never fall back to importing schemas on its own, whatever state the container is in.\r\n */\r\n export function isEnabled(arg: IModelOrFileName): boolean {\r\n return readFromIModel(arg, (nativeDb) => nativeDb.schemaSyncEnabled());\r\n }\r\n\r\n /** One pass over the values schema sync keeps in the file: which container holds the sync db, plus the\r\n * test-only cache override. Read together so a closed file is opened once.\r\n */\r\n function readLocalSyncProps(arg: IModelOrFileName) {\r\n return readFromIModel(arg, (nativeDb) => {\r\n const propsString = nativeDb.queryFileProperty(syncProperty, true) as string | undefined;\r\n let containerProps: CloudSqlite.ContainerProps | undefined;\r\n if (propsString !== undefined) {\r\n try {\r\n containerProps = JSON.parse(propsString) as CloudSqlite.ContainerProps;\r\n } catch (e) {\r\n // Deliberately not swallowed into `undefined`: that would read as \"schema sync was never\r\n // enabled\" and let this briefcase import schemas on its own.\r\n throw new IModelError(DbResult.BE_SQLITE_CORRUPT, `iModel names a SchemaSyncDb container but the property cannot be read: ${BentleyError.getErrorMessage(e)}`);\r\n }\r\n }\r\n return {\r\n containerProps,\r\n testCacheName: nativeDb.queryLocalValue(testSyncCachePropKey),\r\n };\r\n });\r\n }\r\n\r\n /** The container holding this iModel's `SchemaSyncDb`, or `undefined` if schema sync was never enabled.\r\n *\r\n * Local read of the same `be_Prop` file property that [[initializeForIModel]] wrote. Requesting an access\r\n * token for the container is a separate, asynchronous step.\r\n */\r\n export function queryContainerProps(arg: IModelOrFileName): CloudSqlite.ContainerProps | undefined {\r\n return readLocalSyncProps(arg).containerProps;\r\n }\r\n\r\n interface SharedCloudAccess {\r\n access: CloudAccess;\r\n key: string;\r\n referenceCount: number;\r\n }\r\n\r\n const sharedAccessByContainer = new Map<string, SharedCloudAccess | Promise<SharedCloudAccess>>();\r\n const sharedAccessByInstance = new WeakMap<CloudAccess, SharedCloudAccess>();\r\n\r\n export async function getCloudAccess(arg: IModelOrFileName): Promise<CloudAccess> {\r\n const { containerProps, testCacheName } = readLocalSyncProps(arg);\r\n if (undefined === containerProps)\r\n throw new IModelError(DbResult.BE_SQLITE_NOTFOUND, \"iModel does not have a SchemaSyncDb\");\r\n\r\n const sharedAccessKey = JSON.stringify(containerProps) + (testCacheName ?? \"\");\r\n let shared = sharedAccessByContainer.get(sharedAccessKey);\r\n if (undefined === shared) {\r\n const pending = (async () => {\r\n const accessToken = await CloudSqlite.requestToken(containerProps);\r\n const access = new CloudAccess({ ...containerProps, accessToken });\r\n Object.assign(access.lockParams, lockParams);\r\n if (testCacheName)\r\n access.setCache(CloudSqlite.CloudCaches.getCache({ cacheName: testCacheName }));\r\n\r\n const created = { access, key: sharedAccessKey, referenceCount: 0 };\r\n sharedAccessByInstance.set(access, created);\r\n return created;\r\n })();\r\n sharedAccessByContainer.set(sharedAccessKey, pending);\r\n try {\r\n shared = await pending;\r\n if (sharedAccessByContainer.get(sharedAccessKey) === pending)\r\n sharedAccessByContainer.set(sharedAccessKey, shared);\r\n } catch (error) {\r\n if (sharedAccessByContainer.get(sharedAccessKey) === pending)\r\n sharedAccessByContainer.delete(sharedAccessKey);\r\n throw error;\r\n }\r\n } else if (shared instanceof Promise) {\r\n shared = await shared;\r\n }\r\n\r\n ++shared.referenceCount;\r\n return shared.access;\r\n }\r\n\r\n /** Release an access obtained through [[getCloudAccess]]. */\r\n export function releaseCloudAccess(access: CloudAccess): void {\r\n const shared = sharedAccessByInstance.get(access);\r\n if (undefined === shared) {\r\n access.close();\r\n return;\r\n }\r\n\r\n if (--shared.referenceCount > 0)\r\n return;\r\n\r\n sharedAccessByInstance.delete(access);\r\n if (sharedAccessByContainer.get(shared.key) === shared)\r\n sharedAccessByContainer.delete(shared.key);\r\n access.close();\r\n }\r\n\r\n /** Arguments for [[withLockedAccess]]. */\r\n export interface WithLockedAccessArgs {\r\n operationName: string;\r\n openMode?: OpenMode;\r\n user?: string;\r\n }\r\n\r\n export async function withLockedAccess(iModel: IModelOrFileName, args: WithLockedAccessArgs, operation: (access: CloudAccess) => Promise<void>): Promise<void> {\r\n const access = await SchemaSync.getCloudAccess(iModel);\r\n try {\r\n await access.withLockedDb(args, async () => operation(access));\r\n } finally {\r\n releaseCloudAccess(access);\r\n }\r\n }\r\n\r\n /** Build the tables and indexes the briefcase's `ec_` rows describe. A merged schema changeset carries\r\n * those rows but no DDL, so the physical columns are missing until this runs. Needs no cloud access.\r\n */\r\n export function updateDbSchema(iModel: IModelDb): void {\r\n if (isEnabled(iModel) && !iModel.isReadonly) {\r\n iModel.clearCaches();\r\n iModel[_nativeDb].schemaSyncUpdateDbSchema();\r\n iModel[_implicitTxn].saveChanges(\"materialized db schema from ec_ tables\");\r\n }\r\n }\r\n\r\n /** Whether a failed [[IModelDb.importSchemas]] can be retried through the upgrade path.\r\n *\r\n * The update tier refuses two kinds of change: one that has to move data between columns, and one\r\n * that destroys instances or property values. They arrive as different statuses because they are\r\n * different changes, but they mean one thing to a caller - this needs\r\n * [[BriefcaseDb.upgradeSchemas]], which takes the exclusive schema lock.\r\n *\r\n * The retry is the app's decision, not the platform's: taking that lock disturbs everyone else, so\r\n * only the app knows whether to do it now, schedule it, or tell the user.\r\n * ```ts\r\n * try {\r\n * await db.importSchemas(files);\r\n * } catch (e) {\r\n * if (!SchemaSync.requiresUpgrade(e)) throw e;\r\n * await db.upgradeSchemas(files, { description: \"...\" });\r\n * }\r\n * ```\r\n * @internal\r\n */\r\n export function requiresUpgrade(error: unknown): boolean {\r\n const errorNumber = (error as { errorNumber?: number } | undefined)?.errorNumber;\r\n return errorNumber === DbResult.BE_SQLITE_ERROR_DataTransformRequired\r\n || errorNumber === DbResult.BE_SQLITE_ERROR_DataDeletionRequired;\r\n }\r\n\r\n /** Arguments for [[createContainerForIModel]]. */\r\n export interface CreateContainerForIModelArgs {\r\n iModel: IModelDb;\r\n label?: string;\r\n description?: string;\r\n }\r\n\r\n /** Create a cloud container to hold this iModel's `SchemaSyncDb`, and initialize it as empty.\r\n *\r\n * The container is scoped to the iModel, so the service deletes it when the iModel is deleted. Pass the\r\n * returned props to [[initializeForIModel]] - the two calls together are what enables schema sync on an\r\n * iModel that was created without it.\r\n * @note The current user must be authorized to create containers for the iTwin.\r\n */\r\n export async function createContainerForIModel(arg: CreateContainerForIModelArgs): Promise<CloudSqlite.ContainerProps> {\r\n const iModel = arg.iModel;\r\n const iTwinId = iModel.iTwinId;\r\n if (undefined === iTwinId)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot create a SchemaSync container for an iModel that has no iTwin\");\r\n\r\n return CloudAccess.createNewContainer({\r\n scope: { iTwinId, iModelId: iModel.iModelId },\r\n metadata: { label: arg.label ?? `SchemaSync for ${iModel.name}`, description: arg.description },\r\n });\r\n }\r\n\r\n /** Arguments for [[initializeForIModel]]. */\r\n export interface InitializeForIModelArgs {\r\n iModel: IModelDb;\r\n containerProps: CloudSqlite.ContainerProps;\r\n /** Replace the container already recorded on this iModel instead of failing. */\r\n overrideContainer?: boolean;\r\n }\r\n\r\n /** Refuse initialization before a caller provisions a container, then hold the exclusive schema lock and pull to the tip. */\r\n async function prepareToInitializeForIModel(iModel: IModelDb, overrideContainer: boolean): Promise<BriefcaseDb | undefined> {\r\n const briefcase = iModel instanceof BriefcaseDb ? iModel : undefined;\r\n if (briefcase && !briefcase.locks.isServerBased)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot enable SchemaSync without server-based locking\");\r\n\r\n if (briefcase && (iModel[_nativeDb].hasUnsavedChanges() || briefcase.txns.hasLocalChanges))\r\n throw new IModelError(ChangeSetStatus.HasLocalChanges, \"Cannot enable SchemaSync while there are local changes\");\r\n\r\n const assertContainerCanBeInitialized = () => {\r\n const localInfo = iModel[_nativeDb].schemaSyncGetLocalDbInfo();\r\n if (localInfo && !overrideContainer)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, `Local db already initialized to schema sync (container-id: ${localInfo.id})`);\r\n };\r\n\r\n assertContainerCanBeInitialized();\r\n await iModel.acquireSchemaLock();\r\n await briefcase?.pullChanges();\r\n assertContainerCanBeInitialized();\r\n return briefcase;\r\n }\r\n\r\n async function initializeAfterPreflight(arg: InitializeForIModelArgs, briefcase: BriefcaseDb | undefined): Promise<void> {\r\n const props = { baseUri: arg.containerProps.baseUri, containerId: arg.containerProps.containerId, storageType: arg.containerProps.storageType }; // sanitize to only known properties\r\n const iModel = arg.iModel;\r\n const description = arg.overrideContainer\r\n ? `Overriding SchemaSync for iModel with container-id: ${props.containerId}`\r\n : `Enable SchemaSync for iModel with container-id: ${props.containerId}`;\r\n const txnBeforeInit = briefcase?.txns.getCurrentTxnId();\r\n try {\r\n iModel[_implicitTxn].saveFileProperty(syncProperty, JSON.stringify(props));\r\n try {\r\n await withLockedAccess(iModel, { operationName: \"initialize schemaSync\", openMode: OpenMode.Readonly }, async (syncAccess) => {\r\n iModel[_nativeDb].schemaSyncInit(syncAccess.getUri(), props.containerId, arg.overrideContainer ?? false);\r\n iModel[_implicitTxn].saveChanges(description);\r\n });\r\n } catch (error) {\r\n iModel[_implicitTxn].abandonChanges();\r\n if (briefcase && txnBeforeInit !== undefined && briefcase.txns.getCurrentTxnId() !== txnBeforeInit) {\r\n const status = briefcase[_nativeDb].cancelTo(txnBeforeInit, true);\r\n if (status !== IModelStatus.Success)\r\n Logger.logError(\"SchemaSync\", `Failed to roll back schema sync initialization after the container upload failed: ${IModelStatus[status] ?? status}`);\r\n briefcase.clearCaches();\r\n }\r\n throw error;\r\n }\r\n\r\n // Upload the initialized container before publishing the property that tells every briefcase to use it.\r\n // If the push fails, this briefcase keeps the local txn and exclusive schema lock so the push can be retried.\r\n await briefcase?.pushChanges({ description });\r\n } finally {\r\n iModel[_implicitTxn].abandonChanges();\r\n }\r\n\r\n await iModel.initializeSharedElementReservations();\r\n }\r\n\r\n /** Enable schema sync for an iModel, seeding the container from this briefcase.\r\n * @note Takes the exclusive schema lock, refuses local changes, and pulls the briefcase to the tip before writing the container.\r\n * If this operation fails after acquiring the schema lock, it leaves the lock held.\r\n */\r\n export async function initializeForIModel(arg: InitializeForIModelArgs): Promise<void> {\r\n const briefcase = await prepareToInitializeForIModel(arg.iModel, arg.overrideContainer ?? false);\r\n await initializeAfterPreflight(arg, briefcase);\r\n }\r\n\r\n /** The part of a SchemaSyncDb to restore from an authoritative briefcase. @alpha */\r\n export type RepairScope = \"schemaMetadata\" | \"schemaMetadataAndProfile\";\r\n\r\n const nativeRepairScope: Record<RepairScope, number> = {\r\n schemaMetadata: 0,\r\n schemaMetadataAndProfile: 1,\r\n };\r\n\r\n /** Arguments for [[repairForIModel]]. @alpha */\r\n export interface RepairForIModelArgs {\r\n /** A clean SchemaSync-enabled briefcase at the tip of the iModel timeline. */\r\n iModel: BriefcaseDb;\r\n /** Include the schema-owned EC and BeSQLite profile table definitions. */\r\n scope?: RepairScope;\r\n }\r\n\r\n /** Restore the schema-owned portion of the SchemaSyncDb from a briefcase at the tip of the timeline.\r\n *\r\n * This operation takes the exclusive schema lock and refuses to pull or modify the briefcase. Element\r\n * reservations and all other target-only state in the SchemaSyncDb are preserved.\r\n * @alpha\r\n */\r\n export async function repairForIModel(arg: RepairForIModelArgs): Promise<void> {\r\n const iModel = arg.iModel;\r\n if (!isEnabled(iModel))\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot repair SchemaSync because it is not enabled for this iModel\");\r\n\r\n if (iModel[_nativeDb].hasUnsavedChanges() || iModel.txns.hasLocalChanges)\r\n throw new IModelError(ChangeSetStatus.HasLocalChanges, \"Cannot repair SchemaSync while there are local changes\");\r\n\r\n if (!iModel.locks.isServerBased)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot repair SchemaSync without server-based locking\");\r\n\r\n if (arg.scope !== undefined && arg.scope !== \"schemaMetadata\" && arg.scope !== \"schemaMetadataAndProfile\")\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Unknown SchemaSync repair scope\");\r\n\r\n const briefcaseManagerModule = await import(\"./BriefcaseManager\");\r\n const assertBriefcaseIsAtTip = async () => {\r\n const latestChangeset = await briefcaseManagerModule.BriefcaseManager.getLatestChangeset({ iModelId: iModel.iModelId });\r\n if (latestChangeset.id !== iModel.changeset.id)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot repair SchemaSync from a briefcase that is not at the tip of the iModel timeline\");\r\n };\r\n\r\n // Avoid asking Hub for an exclusive lock it cannot grant to a briefcase that first needs to pull.\r\n await assertBriefcaseIsAtTip();\r\n const schemaLockWasHeld = iModel.holdsSchemaLock;\r\n if (!schemaLockWasHeld)\r\n await iModel.acquireSchemaLock();\r\n try {\r\n // Close the race between the preflight query and acquiring the exclusive lock.\r\n await assertBriefcaseIsAtTip();\r\n const repairScope = nativeRepairScope[arg.scope ?? \"schemaMetadata\"];\r\n await withLockedAccess(iModel, { openMode: OpenMode.Readonly, operationName: \"repair schema sync\" }, async (syncAccess) => {\r\n const nativeDb = iModel[_nativeDb] as IModelJsNative.DgnDb & { schemaSyncRepair(syncDbUri: string, scope: number): void };\r\n nativeDb.schemaSyncRepair(syncAccess.getUri(), repairScope);\r\n });\r\n Logger.logInfo(\"SchemaSync\", `Repaired SchemaSyncDb from changeset ${iModel.changeset.id || \"0\"}`);\r\n } finally {\r\n if (!schemaLockWasHeld)\r\n await iModel.locks.abandonAllLocks();\r\n }\r\n }\r\n\r\n /** Arguments for [[enableForIModel]]. */\r\n export interface EnableForIModelArgs {\r\n iModel: IModelDb;\r\n /** An existing container to use. When omitted one is created for this iModel. */\r\n containerProps?: CloudSqlite.ContainerProps;\r\n /** Replace the container already recorded on this iModel instead of failing. */\r\n overrideContainer?: boolean;\r\n label?: string;\r\n description?: string;\r\n }\r\n\r\n /** Turn schema sync on for an iModel: create the container if needed, record it, and seed it.\r\n *\r\n * The single call callers should use. [[createContainerForIModel]] and [[initializeForIModel]] have\r\n * to happen in this order, and an iModel left between the two is one that names a container nothing\r\n * has seeded.\r\n * @returns the container props recorded on the iModel.\r\n * @note Takes the exclusive schema lock and pushes, same protocol as [[BriefcaseDb.upgradeSchemas]] -\r\n * every operation that changes how a file is governed uses it. If this operation fails after acquiring the schema lock,\r\n * it leaves the lock held.\r\n */\r\n export async function enableForIModel(arg: EnableForIModelArgs): Promise<CloudSqlite.ContainerProps> {\r\n if (undefined === arg.containerProps && undefined === arg.iModel.iTwinId)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot create a SchemaSync container for an iModel that has no iTwin\");\r\n\r\n const briefcase = await prepareToInitializeForIModel(arg.iModel, arg.overrideContainer ?? false);\r\n const containerProps = arg.containerProps\r\n ?? await createContainerForIModel({ iModel: arg.iModel, label: arg.label, description: arg.description });\r\n await initializeAfterPreflight({ iModel: arg.iModel, containerProps, overrideContainer: arg.overrideContainer }, briefcase);\r\n return containerProps;\r\n }\r\n\r\n /** Arguments for [[CloudAccess.createNewContainer]]. */\r\n export interface CreateNewContainerProps {\r\n scope: BlobContainer.Scope;\r\n metadata: Omit<BlobContainer.Metadata, \"containerType\">;\r\n }\r\n\r\n /** Provides access to a cloud-based `SchemaSyncDb` to hold ECSchemas. */\r\n export class CloudAccess extends CloudSqlite.DbAccess<SchemaSyncDb, ReadMethods, WriteMethods> {\r\n public constructor(props: CloudSqlite.ContainerAccessProps) {\r\n super({ dbType: SchemaSyncDb, props, dbName: defaultDbName });\r\n }\r\n\r\n public getUri() {\r\n return `${this.getCloudDb()[_nativeDb].getFilePath()}?vfs=${this.container.cache?.name}&writable=${this.container.isWriteable ? 1 : 0}`;\r\n }\r\n /**\r\n * Initialize a cloud container for use as a SchemaSync. The container must first be created via its storage supplier api (e.g. Azure, or AWS).\r\n * A valid sasToken that grants write access must be supplied. This function creates and uploads an empty ChannelDb into the container.\r\n * @note this deletes any existing content in the container.\r\n */\r\n public static async initializeDb(props: CloudSqlite.ContainerProps) {\r\n return super._initializeDb({ props, dbType: SchemaSyncDb, dbName: defaultDbName });\r\n }\r\n\r\n /** Create and initialize a new `schemasync` BlobContainer to hold a `SchemaSyncDb`. */\r\n public static async createNewContainer(args: CreateNewContainerProps): Promise<CloudSqlite.ContainerProps> {\r\n const props = await this.createBlobContainer({ scope: args.scope, metadata: { ...args.metadata, containerType } });\r\n await this.initializeDb(props);\r\n return props;\r\n }\r\n }\r\n}\r\n"]}