@itwin/core-backend 4.2.0-dev.8 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +100 -1
  2. package/lib/cjs/BlobContainerService.d.ts +6 -2
  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.map +1 -1
  6. package/lib/cjs/BriefcaseManager.js +5 -1
  7. package/lib/cjs/BriefcaseManager.js.map +1 -1
  8. package/lib/cjs/CheckpointManager.d.ts.map +1 -1
  9. package/lib/cjs/CheckpointManager.js +6 -3
  10. package/lib/cjs/CheckpointManager.js.map +1 -1
  11. package/lib/cjs/CloudSqlite.d.ts +79 -34
  12. package/lib/cjs/CloudSqlite.d.ts.map +1 -1
  13. package/lib/cjs/CloudSqlite.js +7 -9
  14. package/lib/cjs/CloudSqlite.js.map +1 -1
  15. package/lib/cjs/IModelDb.d.ts +23 -4
  16. package/lib/cjs/IModelDb.d.ts.map +1 -1
  17. package/lib/cjs/IModelDb.js +171 -42
  18. package/lib/cjs/IModelDb.js.map +1 -1
  19. package/lib/cjs/SQLiteDb.js +1 -1
  20. package/lib/cjs/SQLiteDb.js.map +1 -1
  21. package/lib/cjs/SchemaSync.d.ts +41 -0
  22. package/lib/cjs/SchemaSync.d.ts.map +1 -0
  23. package/lib/cjs/SchemaSync.js +77 -0
  24. package/lib/cjs/SchemaSync.js.map +1 -0
  25. package/lib/cjs/SchemaUtils.d.ts.map +1 -1
  26. package/lib/cjs/SchemaUtils.js +3 -3
  27. package/lib/cjs/SchemaUtils.js.map +1 -1
  28. package/lib/cjs/TileStorage.d.ts +16 -5
  29. package/lib/cjs/TileStorage.d.ts.map +1 -1
  30. package/lib/cjs/TileStorage.js +34 -3
  31. package/lib/cjs/TileStorage.js.map +1 -1
  32. package/lib/cjs/TxnManager.d.ts +41 -0
  33. package/lib/cjs/TxnManager.d.ts.map +1 -1
  34. package/lib/cjs/TxnManager.js +38 -0
  35. package/lib/cjs/TxnManager.js.map +1 -1
  36. package/lib/cjs/core-backend.d.ts +1 -0
  37. package/lib/cjs/core-backend.d.ts.map +1 -1
  38. package/lib/cjs/core-backend.js +1 -0
  39. package/lib/cjs/core-backend.js.map +1 -1
  40. package/package.json +19 -16
@@ -116,7 +116,7 @@ class SQLiteDb {
116
116
  * @internal
117
117
  */
118
118
  async withLockedContainer(args, operation) {
119
- return CloudSqlite_1.CloudSqlite.withWriteLock(args, async () => this.withOpenDb({ openMode: core_bentley_1.OpenMode.ReadWrite, ...args }, operation));
119
+ return CloudSqlite_1.CloudSqlite.withWriteLock(args, async () => this.withOpenDb({ ...args, openMode: args.openMode ?? core_bentley_1.OpenMode.ReadWrite }, operation));
120
120
  }
121
121
  /** vacuum this database
122
122
  * @see https://www.sqlite.org/lang_vacuum.html
@@ -1 +1 @@
1
- {"version":3,"file":"SQLiteDb.js","sourceRoot":"","sources":["../../src/SQLiteDb.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,yBAAyB;AACzB,+BAA+B;AAC/B,iCAAiC;AAEjC,sDAAyD;AAEzD,+CAA4C;AAC5C,6CAA0C;AAC1C,6CAA0C;AAC1C,uDAAoE;AAEpE,0CAA0C;AAE1C,0DAA0D;AAE1D;;;GAGG;AACH,MAAa,QAAQ;IAArB;QACE,gBAAgB;QACA,aAAQ,GAAG,IAAI,uBAAU,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACtD,0BAAqB,GAAG,IAAI,gCAAc,EAAmB,CAAC;IAmOxE,CAAC;IAjOC,gBAAgB;IACT,MAAM,CAAC,YAAY;QACxB,OAAO,IAAI,uBAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAC1C,CAAC;IAED;;OAEG;IACI,OAAO;QACZ,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAQM,QAAQ,CAAC,MAAc,EAAE,SAAsC,EAAE,MAA8B;QACpG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACpD,CAAC;IAWM,MAAM,CAAC,MAAc,EAAE,QAAwC,EAAE,SAAsC;QAC5G,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACI,OAAO,CAAC,WAAqB;QAClC,IAAI,WAAW,IAAI,IAAI,CAAC,MAAM;YAC5B,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;IAED,4CAA4C;IAC5C,IAAW,MAAM,KAAc,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAE/D,qDAAqD;IACrD,IAAW,UAAU,KAAc,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAEvE,2CAA2C;IACjC,WAAW,CAAC,IASrB;QACC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,uDAAuD,CAAC,CAAC,CAAC,EAAE,CAAC;QACtG,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,IAAI,CAAC,UAAU,CAAC,gBAAgB,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,GAAG,YAAY,GAAG,WAAW,GAAG,CAAC,CAAC;QAChG,IAAI,IAAI,CAAC,YAAY;YACnB,IAAI,CAAC,UAAU,CAAC,kBAAkB,IAAI,CAAC,SAAS,8BAA8B,IAAI,CAAC,SAAS,kFAAkF,IAAI,CAAC,SAAS,0DAA0D,CAAC,CAAC;IAC5P,CAAC;IAED;;;MAGE;IACK,eAAe,CAAC,SAAiB,EAAE,KAAa;QACrD,OAAO,IAAI,CAAC,mBAAmB,CAAC,uBAAuB,SAAS,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE;YACzF,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAC3B,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;OAWG;IACI,UAAU,CAAI,IAA6B,EAAE,SAAkB;QACpE,IAAI,IAAI,CAAC,MAAM;YACb,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAE9C,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC3E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,IAAI,uBAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7E,IAAI;YACF,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,YAAY,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAChE,OAAO,MAAM,CAAC;SACf;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,EAAE,CAAC;YACV,MAAM,CAAC,CAAC;SACT;IACH,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,KAAK,CAAC,mBAAmB,CAAI,IAAiC,EAAE,SAA2B;QAChG,OAAO,yBAAW,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,uBAAQ,CAAC,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;IAC5H,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,IAA4B;QACxC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,4GAA4G;IACrG,WAAW;QAChB,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC9B,CAAC;IAED,iIAAiI;IAC1H,cAAc;QACnB,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;IACjC,CAAC;IAED;;;;;;;;;OASG;IACI,2BAA2B,CAAI,GAAW,EAAE,QAAsC;QACvF,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC/F,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACpE,IAAI;YACF,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3B,GAAG,YAAY,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YAChE,OAAO,GAAG,CAAC;SACZ;QAAC,OAAO,GAAG,EAAE;YACZ,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;SACX;IACH,CAAC;IAED;;;;;;;OAOG;IACI,mBAAmB,CAAI,GAAW,EAAE,QAAsC;QAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACrC,IAAI;YACF,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3B,GAAG,YAAY,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YAChE,OAAO,GAAG,CAAC;SACZ;QAAC,OAAO,GAAG,EAAE;YACZ,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;SACX;IACH,CAAC;IAED;;;;OAIG;IACI,aAAa,CAAC,aAAqB,EAAE,SAAqB;QAC/D,IAAI,IAAI,CAAC,UAAU;YACjB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAE1C,IAAI,CAAC,UAAU,CAAC,aAAa,aAAa,EAAE,CAAC,CAAC;QAC9C,IAAI;YACF,SAAS,EAAE,CAAC;YACZ,IAAI,CAAC,UAAU,CAAC,WAAW,aAAa,EAAE,CAAC,CAAC;SAC7C;QAAC,OAAO,CAAC,EAAE;YACV,IAAI,CAAC,UAAU,CAAC,eAAe,aAAa,EAAE,CAAC,CAAC;YAChD,MAAM,CAAC,CAAC;SACT;IACH,CAAC;IAED;;;;SAIK;IACE,sBAAsB,CAAC,GAAW,EAAE,SAAS,GAAG,IAAI;QACzD,MAAM,IAAI,GAAG,IAAI,iCAAe,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+BAA+B;IACxB,UAAU,CAAC,GAAW;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI;YACF,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;SACpB;gBAAS;YACR,IAAI,CAAC,OAAO,EAAE,CAAC;SAChB;IACH,CAAC;CACF;AAtOD,4BAsOC;AAED;;;;;;;;;;GAUG;AACH,MAAsB,iBAAkB,SAAQ,QAAQ;IActD;;;;;OAKG;IACI,mBAAmB,CAAC,QAAwC;QACjE,6IAA6I;QAC7I,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAC9J,CAAC;IAED,gFAAgF;IACzE,mBAAmB;QACxB,MAAM,aAAa,GAAG,CAAC,KAAU,EAAE,EAAE;YACnC,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAC3B,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,kCAAkC,CAAC,CAAC;YAC5F,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QACF,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1G,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAmC,CAAC;QAChF,aAAa,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QACzC,aAAa,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAC1C,OAAO,aAAa,CAAC;IACvB,CAAC;IAOD;;;;OAIG;IACI,MAAM,CAAC,WAAW,CAAC,QAAuB;QAC/C,MAAM,EAAE,GAAG,IAAK,IAAY,EAAuB,CAAC,CAAC,2DAA2D;QAChH,uBAAU,CAAC,kBAAkB,CAAC,IAAA,cAAO,EAAC,QAAQ,CAAC,CAAC,CAAC;QACjD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YACzB,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAE1B,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACtB,EAAE,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC,SAAS,EAAE,CAAC;QAClC,EAAE,CAAC,mBAAmB,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;QACtE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IAED;;;OAGG;IACO,cAAc;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,sDAAsD;QAC1F,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;QACxE,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC;YACzC,OAAO;QAET,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,aAAa,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,eAAe,IAAI,CAAC,WAAW,CAAC,IAAI,QAAQ,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAEpK,CAAC;IAED;;;;OAIG;IACa,MAAM,CAAC,MAAc,EAAE,QAAwC,EAAE,SAAsC;QACrH,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC1C,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,GAAuH;QAChJ,2EAA2E;QAC3E,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;YAC1B,KAAK,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,aAAa,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;YACpG,KAAK,CAAC,UAAU,CAAC,EAAE,GAAG,GAAG,EAAE,QAAQ,EAAE,uBAAQ,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;IAC9E,CAAC;;AA7FgB,+BAAa,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAW,CAAC;AADlE,8CAAiB;AAiGvC,cAAc;AACd,WAAiB,QAAQ;IAqEvB;;OAEG;IACH,IAAY,cASX;IATD,WAAY,cAAc;QACxB,4GAA4G;QAC5G,mDAAQ,CAAA;QACR,4FAA4F;QAC5F,2DAAY,CAAA;QACZ,yEAAyE;QACzE,6DAAa,CAAA;QACb,yEAAyE;QACzE,6DAAa,CAAA;IACf,CAAC,EATW,cAAc,GAAd,uBAAc,KAAd,uBAAc,QASzB;AAgDH,CAAC,EAjIgB,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAiIxB","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 } from \"@itwin/core-common\";\r\nimport { CloudSqlite } from \"./CloudSqlite\";\r\nimport { IModelHost } from \"./IModelHost\";\r\nimport { IModelJsFs } from \"./IModelJsFs\";\r\nimport { SqliteStatement, StatementCache } from \"./SqliteStatement\";\r\n\r\n// cspell:ignore savepoint julianday rowid\r\n\r\n/* eslint-disable @typescript-eslint/unified-signatures */\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 IModelHost.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 IModelHost.platform.BlobIO();\r\n }\r\n\r\n /** alias for closeDb.\r\n * @deprecated in 4.0, 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 throw new Error(\"database is already open\");\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 /**\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({ openMode: OpenMode.ReadWrite, ...args }, 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 * 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.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 throw new Error(\"database is readonly\");\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 const stmt = this.prepareSqliteStatement(sql);\r\n try {\r\n return stmt.step();\r\n } finally {\r\n stmt.dispose();\r\n }\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 throw new Error(`CloudDb ${this.nativeDb.getFilePath()} has invalid \"versions\" property`);\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(): void;\r\n\r\n /**\r\n * Create a new database file for the subclass of VersionedSqliteDb.\r\n * @param fileName the name of a local\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) {\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();\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 throw new Error(`${this.nativeDb.getFilePath()} requires ${tooNew ? \"older\" : \"newer\"} version of ${this.constructor.name} for ${isReadonly ? \"read\" : \"write\"}`);\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 { DbResult, OpenMode } from \"@itwin/core-bentley\";\r\nimport { LocalFileName } from \"@itwin/core-common\";\r\nimport { CloudSqlite } from \"./CloudSqlite\";\r\nimport { IModelHost } from \"./IModelHost\";\r\nimport { IModelJsFs } from \"./IModelJsFs\";\r\nimport { SqliteStatement, StatementCache } from \"./SqliteStatement\";\r\n\r\n// cspell:ignore savepoint julianday rowid\r\n\r\n/* eslint-disable @typescript-eslint/unified-signatures */\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 IModelHost.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 IModelHost.platform.BlobIO();\r\n }\r\n\r\n /** alias for closeDb.\r\n * @deprecated in 4.0, 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 throw new Error(\"database is already open\");\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 /**\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 * 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.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 throw new Error(\"database is readonly\");\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 const stmt = this.prepareSqliteStatement(sql);\r\n try {\r\n return stmt.step();\r\n } finally {\r\n stmt.dispose();\r\n }\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 throw new Error(`CloudDb ${this.nativeDb.getFilePath()} has invalid \"versions\" property`);\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(): void;\r\n\r\n /**\r\n * Create a new database file for the subclass of VersionedSqliteDb.\r\n * @param fileName the name of a local\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) {\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();\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 throw new Error(`${this.nativeDb.getFilePath()} requires ${tooNew ? \"older\" : \"newer\"} version of ${this.constructor.name} for ${isReadonly ? \"read\" : \"write\"}`);\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"]}
@@ -0,0 +1,41 @@
1
+ /** @packageDocumentation
2
+ * @module SQLiteDb
3
+ */
4
+ import { CloudSqlite } from "./CloudSqlite";
5
+ import { VersionedSqliteDb } from "./SQLiteDb";
6
+ import { IModelDb } from "./IModelDb";
7
+ import { OpenMode } from "@itwin/core-bentley";
8
+ type TestCacheIModel = IModelDb & {
9
+ testSyncCache?: string;
10
+ };
11
+ /** @internal */
12
+ export declare namespace SchemaSync {
13
+ /** A CloudSqlite database for synchronizing schema changes across briefcases. */
14
+ class SchemaSyncDb extends VersionedSqliteDb {
15
+ readonly myVersion = "4.0.0";
16
+ protected createDDL(): void;
17
+ }
18
+ const setTestCache: (iModel: IModelDb, cacheName: string) => void;
19
+ const withLockedAccess: (iModel: TestCacheIModel, args: {
20
+ operationName: string;
21
+ openMode?: OpenMode;
22
+ user?: string;
23
+ }, operation: (access: CloudAccess) => Promise<void>) => Promise<void>;
24
+ const initializeForIModel: (arg: {
25
+ iModel: IModelDb;
26
+ containerProps: CloudSqlite.ContainerProps;
27
+ }) => Promise<void>;
28
+ /** Provides access to a cloud-based `SchemaSyncDb` to hold ECSchemas. */
29
+ class CloudAccess extends CloudSqlite.DbAccess<SchemaSyncDb> {
30
+ constructor(props: CloudSqlite.ContainerAccessProps);
31
+ getUri(): string;
32
+ /**
33
+ * 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).
34
+ * A valid sasToken that grants write access must be supplied. This function creates and uploads an empty ChannelDb into the container.
35
+ * @note this deletes any existing content in the container.
36
+ */
37
+ static initializeDb(props: CloudSqlite.ContainerAccessProps): Promise<void>;
38
+ }
39
+ }
40
+ export {};
41
+ //# sourceMappingURL=SchemaSync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaSync.d.ts","sourceRoot":"","sources":["../../src/SchemaSync.ts"],"names":[],"mappings":"AAKA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,KAAK,eAAe,GAAG,QAAQ,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,gBAAgB;AAChB,yBAAiB,UAAU,CAAC;IAE1B,kFAAkF;IAClF,MAAa,YAAa,SAAQ,iBAAiB;QACjD,SAAyB,SAAS,WAAW;kBAC1B,SAAS;KAC7B;IAKM,MAAM,YAAY,WAAY,QAAQ,aAAa,MAAM,SAE/D,CAAC;IAEK,MAAM,gBAAgB,WAAkB,eAAe,QAAQ;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,sBAAsB,WAAW,KAAK,QAAQ,IAAI,CAAC,KAAG,QAAQ,IAAI,CAepM,CAAC;IAEK,MAAM,mBAAmB,QAAe;QAAE,MAAM,EAAE,QAAQ,CAAC;QAAC,cAAc,EAAE,YAAY,cAAc,CAAA;KAAE,kBAU9G,CAAC;IAEF,0EAA0E;IAC1E,MAAa,WAAY,SAAQ,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC;oBAC9C,KAAK,EAAE,WAAW,CAAC,oBAAoB;QAInD,MAAM;QAGb;;;;SAIC;eACmB,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,oBAAoB;KAGzE;CACF"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.SchemaSync = void 0;
8
+ /** @packageDocumentation
9
+ * @module SQLiteDb
10
+ */
11
+ const CloudSqlite_1 = require("./CloudSqlite");
12
+ const SQLiteDb_1 = require("./SQLiteDb");
13
+ const core_bentley_1 = require("@itwin/core-bentley");
14
+ /** @internal */
15
+ var SchemaSync;
16
+ (function (SchemaSync) {
17
+ /** A CloudSqlite database for synchronizing schema changes across briefcases. */
18
+ class SchemaSyncDb extends SQLiteDb_1.VersionedSqliteDb {
19
+ constructor() {
20
+ super(...arguments);
21
+ this.myVersion = "4.0.0";
22
+ }
23
+ createDDL() { }
24
+ }
25
+ SchemaSync.SchemaSyncDb = SchemaSyncDb;
26
+ const syncProperty = { namespace: "itwinjs", name: "SchemaSync" };
27
+ const defaultDbName = "SchemaSyncDb";
28
+ // for tests only
29
+ SchemaSync.setTestCache = (iModel, cacheName) => {
30
+ iModel.testSyncCache = cacheName;
31
+ };
32
+ SchemaSync.withLockedAccess = async (iModel, args, operation) => {
33
+ const propsString = iModel.queryFilePropertyString(syncProperty);
34
+ if (!propsString)
35
+ throw new Error("iModel does not have a SchemaSyncDb");
36
+ const props = JSON.parse(propsString);
37
+ const accessToken = await CloudSqlite_1.CloudSqlite.requestToken(props);
38
+ const access = new CloudAccess({ ...props, accessToken });
39
+ if (iModel.testSyncCache)
40
+ access.setCache(CloudSqlite_1.CloudSqlite.CloudCaches.getCache({ cacheName: iModel.testSyncCache }));
41
+ try {
42
+ await access.withLockedDb(args, async () => operation(access));
43
+ }
44
+ finally {
45
+ access.close();
46
+ }
47
+ };
48
+ SchemaSync.initializeForIModel = async (arg) => {
49
+ const props = { baseUri: arg.containerProps.baseUri, containerId: arg.containerProps.containerId, storageType: arg.containerProps.storageType }; // sanitize to only known properties
50
+ const iModel = arg.iModel;
51
+ iModel.saveFileProperty(syncProperty, JSON.stringify(props));
52
+ iModel.saveChanges();
53
+ await SchemaSync.withLockedAccess(arg.iModel, { operationName: "initialize schemaSync", openMode: core_bentley_1.OpenMode.Readonly }, async (syncAccess) => {
54
+ iModel.nativeDb.schemaSyncInit(syncAccess.getUri());
55
+ iModel.saveChanges();
56
+ });
57
+ };
58
+ /** Provides access to a cloud-based `SchemaSyncDb` to hold ECSchemas. */
59
+ class CloudAccess extends CloudSqlite_1.CloudSqlite.DbAccess {
60
+ constructor(props) {
61
+ super({ dbType: SchemaSyncDb, props, dbName: defaultDbName });
62
+ }
63
+ getUri() {
64
+ return `${this.getCloudDb().nativeDb.getFilePath()}?vfs=${this.container.cache?.name}&writable=${this.container.isWriteable ? 1 : 0}`;
65
+ }
66
+ /**
67
+ * 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).
68
+ * A valid sasToken that grants write access must be supplied. This function creates and uploads an empty ChannelDb into the container.
69
+ * @note this deletes any existing content in the container.
70
+ */
71
+ static async initializeDb(props) {
72
+ return super._initializeDb({ props, dbType: SchemaSyncDb, dbName: defaultDbName });
73
+ }
74
+ }
75
+ SchemaSync.CloudAccess = CloudAccess;
76
+ })(SchemaSync = exports.SchemaSync || (exports.SchemaSync = {}));
77
+ //# sourceMappingURL=SchemaSync.js.map
@@ -0,0 +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 { CloudSqlite } from \"./CloudSqlite\";\r\nimport { VersionedSqliteDb } from \"./SQLiteDb\";\r\nimport { IModelDb } from \"./IModelDb\";\r\nimport { OpenMode } from \"@itwin/core-bentley\";\r\n\r\ntype TestCacheIModel = IModelDb & { testSyncCache?: string };\r\n\r\n/** @internal */\r\nexport namespace SchemaSync {\r\n\r\n /** A CloudSqlite database for synchronizing schema changes across briefcases. */\r\n export class SchemaSyncDb extends VersionedSqliteDb {\r\n public override readonly myVersion = \"4.0.0\";\r\n protected override createDDL() { }\r\n }\r\n\r\n const syncProperty = { namespace: \"itwinjs\", name: \"SchemaSync\" };\r\n const defaultDbName = \"SchemaSyncDb\" as const;\r\n // for tests only\r\n export const setTestCache = (iModel: IModelDb, cacheName: string) => {\r\n (iModel as TestCacheIModel).testSyncCache = cacheName;\r\n };\r\n\r\n export const withLockedAccess = async (iModel: TestCacheIModel, args: { operationName: string, openMode?: OpenMode, user?: string }, operation: (access: CloudAccess) => Promise<void>): Promise<void> => {\r\n const propsString = iModel.queryFilePropertyString(syncProperty);\r\n if (!propsString)\r\n throw new Error(\"iModel does not have a SchemaSyncDb\");\r\n\r\n const props = JSON.parse(propsString) as CloudSqlite.ContainerProps;\r\n const accessToken = await CloudSqlite.requestToken(props);\r\n const access = new CloudAccess({ ...props, accessToken });\r\n if (iModel.testSyncCache)\r\n access.setCache(CloudSqlite.CloudCaches.getCache({ cacheName: iModel.testSyncCache }));\r\n try {\r\n await access.withLockedDb(args, async () => operation(access));\r\n } finally {\r\n access.close();\r\n }\r\n };\r\n\r\n export const initializeForIModel = async (arg: { iModel: IModelDb, containerProps: CloudSqlite.ContainerProps }) => {\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 iModel.saveFileProperty(syncProperty, JSON.stringify(props));\r\n iModel.saveChanges();\r\n\r\n await withLockedAccess(arg.iModel, { operationName: \"initialize schemaSync\", openMode: OpenMode.Readonly }, async (syncAccess) => {\r\n iModel.nativeDb.schemaSyncInit(syncAccess.getUri());\r\n iModel.saveChanges();\r\n });\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> {\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.ContainerAccessProps) {\r\n return super._initializeDb({ props, dbType: SchemaSyncDb, dbName: defaultDbName });\r\n }\r\n }\r\n}\r\n\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaUtils.d.ts","sourceRoot":"","sources":["../../src/SchemaUtils.ts"],"names":[],"mappings":"AAIA;;GAEG;AAKH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,aAAa,CAAC,EAAE,kBAAkB,GAAG,MAAM,EAAE,CAOnH;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,aAAa,CAAC,EAAE,kBAAkB,GAAG,MAAM,EAAE,CAO/G"}
1
+ {"version":3,"file":"SchemaUtils.d.ts","sourceRoot":"","sources":["../../src/SchemaUtils.ts"],"names":[],"mappings":"AAIA;;GAEG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,aAAa,CAAC,EAAE,kBAAkB,GAAG,MAAM,EAAE,CAOnH;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,aAAa,CAAC,EAAE,kBAAkB,GAAG,MAAM,EAAE,CAO/G"}
@@ -8,9 +8,9 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.upgradeCustomAttributesToEC3 = exports.convertEC2SchemasToEC3Schemas = void 0;
11
- const imodeljs_native_1 = require("@bentley/imodeljs-native");
12
11
  const core_bentley_1 = require("@itwin/core-bentley");
13
12
  const core_common_1 = require("@itwin/core-common");
13
+ const IModelHost_1 = require("./IModelHost");
14
14
  /** Converts EC2 Xml ECSchema(s). On success, the `EC2 Xml schemas` are converted into `EC3.2 Xml schemas`.
15
15
  * @param ec2XmlSchemas The EC2 Xml string(s) created from a serialized ECSchema.
16
16
  * @returns EC3.2 Xml ECSchema(s).
@@ -19,7 +19,7 @@ const core_common_1 = require("@itwin/core-common");
19
19
  */
20
20
  function convertEC2SchemasToEC3Schemas(ec2XmlSchemas, schemaContext) {
21
21
  const maybeNativeContext = schemaContext?.nativeContext;
22
- const ec3XmlSchemas = imodeljs_native_1.IModelJsNative.SchemaUtility.convertEC2XmlSchemas(ec2XmlSchemas, maybeNativeContext);
22
+ const ec3XmlSchemas = IModelHost_1.IModelHost.platform.SchemaUtility.convertEC2XmlSchemas(ec2XmlSchemas, maybeNativeContext);
23
23
  if (ec2XmlSchemas.length === 0)
24
24
  throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Error converting EC2 Xml schemas");
25
25
  return ec3XmlSchemas;
@@ -33,7 +33,7 @@ exports.convertEC2SchemasToEC3Schemas = convertEC2SchemasToEC3Schemas;
33
33
  */
34
34
  function upgradeCustomAttributesToEC3(xmlSchemas, schemaContext) {
35
35
  const maybeNativeContext = schemaContext?.nativeContext;
36
- const schemasWithConvertedCA = imodeljs_native_1.IModelJsNative.SchemaUtility.convertCustomAttributes(xmlSchemas, maybeNativeContext);
36
+ const schemasWithConvertedCA = IModelHost_1.IModelHost.platform.SchemaUtility.convertCustomAttributes(xmlSchemas, maybeNativeContext);
37
37
  if (schemasWithConvertedCA.length === 0)
38
38
  throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Error converting custom attributes of Xml schemas");
39
39
  return schemasWithConvertedCA;
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaUtils.js","sourceRoot":"","sources":["../../src/SchemaUtils.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,8DAA0D;AAC1D,sDAAoD;AACpD,oDAAiD;AAGjD;;;;;GAKG;AACH,SAAgB,6BAA6B,CAAC,aAAuB,EAAE,aAAkC;IACvG,MAAM,kBAAkB,GAAG,aAAa,EAAE,aAAa,CAAC;IACxD,MAAM,aAAa,GAAa,gCAAc,CAAC,aAAa,CAAC,oBAAoB,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;IACrH,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAC5B,MAAM,IAAI,yBAAW,CAAC,4BAAa,CAAC,KAAK,EAAE,kCAAkC,CAAC,CAAC;IAEjF,OAAO,aAAa,CAAC;AACvB,CAAC;AAPD,sEAOC;AAED;;;;;GAKG;AACH,SAAgB,4BAA4B,CAAC,UAAoB,EAAE,aAAkC;IACnG,MAAM,kBAAkB,GAAG,aAAa,EAAE,aAAa,CAAC;IACxD,MAAM,sBAAsB,GAAa,gCAAc,CAAC,aAAa,CAAC,uBAAuB,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;IAC9H,IAAI,sBAAsB,CAAC,MAAM,KAAK,CAAC;QACrC,MAAM,IAAI,yBAAW,CAAC,4BAAa,CAAC,KAAK,EAAE,mDAAmD,CAAC,CAAC;IAElG,OAAO,sBAAsB,CAAC;AAChC,CAAC;AAPD,oEAOC","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 Schema\r\n */\r\n\r\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\r\nimport { BentleyStatus } from \"@itwin/core-bentley\";\r\nimport { IModelError } from \"@itwin/core-common\";\r\nimport { ECSchemaXmlContext } from \"./ECSchemaXmlContext\";\r\n\r\n/** Converts EC2 Xml ECSchema(s). On success, the `EC2 Xml schemas` are converted into `EC3.2 Xml schemas`.\r\n * @param ec2XmlSchemas The EC2 Xml string(s) created from a serialized ECSchema.\r\n * @returns EC3.2 Xml ECSchema(s).\r\n * @throws [[IModelError]] if there is a problem converting the EC2 schemas.\r\n * @beta\r\n */\r\nexport function convertEC2SchemasToEC3Schemas(ec2XmlSchemas: string[], schemaContext?: ECSchemaXmlContext): string[] {\r\n const maybeNativeContext = schemaContext?.nativeContext;\r\n const ec3XmlSchemas: string[] = IModelJsNative.SchemaUtility.convertEC2XmlSchemas(ec2XmlSchemas, maybeNativeContext);\r\n if (ec2XmlSchemas.length === 0)\r\n throw new IModelError(BentleyStatus.ERROR, \"Error converting EC2 Xml schemas\");\r\n\r\n return ec3XmlSchemas;\r\n}\r\n\r\n/** Converts schema metadata to EC3 concepts by traversing custom attributes of the supplied schema and calling converters based on schemaName:customAttributeName\r\n * @param xmlSchemas The ECSchema Xml string(s).\r\n * @returns EC3.2 Xml ECSchema(s) with converted custom attributes.\r\n * @throws [[IModelError]] if there is a problem converting the custom attributes of a schema.\r\n * @beta\r\n */\r\nexport function upgradeCustomAttributesToEC3(xmlSchemas: string[], schemaContext?: ECSchemaXmlContext): string[] {\r\n const maybeNativeContext = schemaContext?.nativeContext;\r\n const schemasWithConvertedCA: string[] = IModelJsNative.SchemaUtility.convertCustomAttributes(xmlSchemas, maybeNativeContext);\r\n if (schemasWithConvertedCA.length === 0)\r\n throw new IModelError(BentleyStatus.ERROR, \"Error converting custom attributes of Xml schemas\");\r\n\r\n return schemasWithConvertedCA;\r\n}\r\n"]}
1
+ {"version":3,"file":"SchemaUtils.js","sourceRoot":"","sources":["../../src/SchemaUtils.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,sDAAoD;AACpD,oDAAiD;AAEjD,6CAA0C;AAE1C;;;;;GAKG;AACH,SAAgB,6BAA6B,CAAC,aAAuB,EAAE,aAAkC;IACvG,MAAM,kBAAkB,GAAG,aAAa,EAAE,aAAa,CAAC;IACxD,MAAM,aAAa,GAAa,uBAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,oBAAoB,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;IAC1H,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAC5B,MAAM,IAAI,yBAAW,CAAC,4BAAa,CAAC,KAAK,EAAE,kCAAkC,CAAC,CAAC;IAEjF,OAAO,aAAa,CAAC;AACvB,CAAC;AAPD,sEAOC;AAED;;;;;GAKG;AACH,SAAgB,4BAA4B,CAAC,UAAoB,EAAE,aAAkC;IACnG,MAAM,kBAAkB,GAAG,aAAa,EAAE,aAAa,CAAC;IACxD,MAAM,sBAAsB,GAAa,uBAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,uBAAuB,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;IACnI,IAAI,sBAAsB,CAAC,MAAM,KAAK,CAAC;QACrC,MAAM,IAAI,yBAAW,CAAC,4BAAa,CAAC,KAAK,EAAE,mDAAmD,CAAC,CAAC;IAElG,OAAO,sBAAsB,CAAC;AAChC,CAAC;AAPD,oEAOC","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 Schema\r\n */\r\n\r\nimport { BentleyStatus } from \"@itwin/core-bentley\";\r\nimport { IModelError } from \"@itwin/core-common\";\r\nimport { ECSchemaXmlContext } from \"./ECSchemaXmlContext\";\r\nimport { IModelHost } from \"./IModelHost\";\r\n\r\n/** Converts EC2 Xml ECSchema(s). On success, the `EC2 Xml schemas` are converted into `EC3.2 Xml schemas`.\r\n * @param ec2XmlSchemas The EC2 Xml string(s) created from a serialized ECSchema.\r\n * @returns EC3.2 Xml ECSchema(s).\r\n * @throws [[IModelError]] if there is a problem converting the EC2 schemas.\r\n * @beta\r\n */\r\nexport function convertEC2SchemasToEC3Schemas(ec2XmlSchemas: string[], schemaContext?: ECSchemaXmlContext): string[] {\r\n const maybeNativeContext = schemaContext?.nativeContext;\r\n const ec3XmlSchemas: string[] = IModelHost.platform.SchemaUtility.convertEC2XmlSchemas(ec2XmlSchemas, maybeNativeContext);\r\n if (ec2XmlSchemas.length === 0)\r\n throw new IModelError(BentleyStatus.ERROR, \"Error converting EC2 Xml schemas\");\r\n\r\n return ec3XmlSchemas;\r\n}\r\n\r\n/** Converts schema metadata to EC3 concepts by traversing custom attributes of the supplied schema and calling converters based on schemaName:customAttributeName\r\n * @param xmlSchemas The ECSchema Xml string(s).\r\n * @returns EC3.2 Xml ECSchema(s) with converted custom attributes.\r\n * @throws [[IModelError]] if there is a problem converting the custom attributes of a schema.\r\n * @beta\r\n */\r\nexport function upgradeCustomAttributesToEC3(xmlSchemas: string[], schemaContext?: ECSchemaXmlContext): string[] {\r\n const maybeNativeContext = schemaContext?.nativeContext;\r\n const schemasWithConvertedCA: string[] = IModelHost.platform.SchemaUtility.convertCustomAttributes(xmlSchemas, maybeNativeContext);\r\n if (schemasWithConvertedCA.length === 0)\r\n throw new IModelError(BentleyStatus.ERROR, \"Error converting custom attributes of Xml schemas\");\r\n\r\n return schemasWithConvertedCA;\r\n}\r\n"]}
@@ -1,4 +1,13 @@
1
1
  import { Metadata, ServerStorage, TransferConfig } from "@itwin/object-storage-core";
2
+ /**
3
+ * Identifies a tile in cloud tile cache.
4
+ * @beta
5
+ */
6
+ export interface TileId {
7
+ treeId: string;
8
+ contentId: string;
9
+ guid: string;
10
+ }
2
11
  /**
3
12
  * Facilitates interaction with cloud tile cache.
4
13
  * @beta
@@ -31,14 +40,16 @@ export declare class TileStorage {
31
40
  * Downloads a tile from the cloud cache.
32
41
  */
33
42
  downloadTile(iModelId: string, changesetId: string, treeId: string, contentId: string, guid?: string): Promise<Uint8Array>;
43
+ /**
44
+ * Returns an async iterator of all tiles that are found in the cloud cache.
45
+ */
46
+ getCachedTilesGenerator(iModelId: string): AsyncGenerator<TileId>;
47
+ private getCachedTilePages;
48
+ private convertPage;
34
49
  /**
35
50
  * Returns a list of all tiles that are found in the cloud cache.
36
51
  */
37
- getCachedTiles(iModelId: string): Promise<{
38
- treeId: string;
39
- contentId: string;
40
- guid: string;
41
- }[]>;
52
+ getCachedTiles(iModelId: string): Promise<TileId[]>;
42
53
  /**
43
54
  * Returns a boolean indicating whether a tile exists in the cloud cache
44
55
  */
@@ -1 +1 @@
1
- {"version":3,"file":"TileStorage.d.ts","sourceRoot":"","sources":["../../src/TileStorage.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAMrF;;;GAGG;AACH,qBAAa,WAAW;IACtB;;;OAGG;IACH,SAAgB,OAAO,EAAE,aAAa,CAAC;gBAEpB,OAAO,EAAE,aAAa;IAIzC,OAAO,CAAC,mBAAmB,CAA0B;IAErD;;OAEG;IACU,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxD;;;;;;OAMG;IACU,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAcpG;;OAEG;IACU,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAczK;;OAEG;IACU,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAavI;;OAEG;IACU,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAyB7G;;OAEG;IACU,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIpI,OAAO,CAAC,YAAY;CAOrB"}
1
+ {"version":3,"file":"TileStorage.d.ts","sourceRoot":"","sources":["../../src/TileStorage.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,QAAQ,EAAmB,aAAa,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAMtG;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,qBAAa,WAAW;IACtB;;;OAGG;IACH,SAAgB,OAAO,EAAE,aAAa,CAAC;gBAEpB,OAAO,EAAE,aAAa;IAIzC,OAAO,CAAC,mBAAmB,CAA0B;IAErD;;OAEG;IACU,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxD;;;;;;OAMG;IACU,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAcpG;;OAEG;IACU,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAczK;;OAEG;IACU,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAavI;;OAEG;IACW,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC;YAShE,kBAAkB;IAcjC,OAAO,CAAC,WAAW;IAyBnB;;OAEG;IACU,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAQhE;;OAEG;IACU,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIpI,OAAO,CAAC,YAAY;CAOrB"}
@@ -78,10 +78,31 @@ class TileStorage {
78
78
  }
79
79
  }
80
80
  /**
81
- * Returns a list of all tiles that are found in the cloud cache.
81
+ * Returns an async iterator of all tiles that are found in the cloud cache.
82
82
  */
83
- async getCachedTiles(iModelId) {
84
- return (await this.storage.listObjects({ baseDirectory: iModelId }))
83
+ async *getCachedTilesGenerator(iModelId) {
84
+ const iterator = this.getCachedTilePages(iModelId);
85
+ for await (const page of iterator) {
86
+ for (const tile of page) {
87
+ yield tile;
88
+ }
89
+ }
90
+ }
91
+ async *getCachedTilePages(iModelId) {
92
+ const iterator = this.storage.getListObjectsPagedIterator({ baseDirectory: iModelId }, 500);
93
+ let prevPage;
94
+ do {
95
+ // initiate loading the next page
96
+ const page = iterator.next();
97
+ // process results from the previous page
98
+ if (prevPage)
99
+ yield this.convertPage(prevPage.value);
100
+ // finish loading the next page
101
+ prevPage = await page;
102
+ } while (!prevPage.done);
103
+ }
104
+ convertPage(page) {
105
+ return page
85
106
  .map((objectReference) => ({
86
107
  parts: objectReference.relativeDirectory?.split("/") ?? [""],
87
108
  objectName: objectReference.objectName,
@@ -104,6 +125,16 @@ class TileStorage {
104
125
  };
105
126
  });
106
127
  }
128
+ /**
129
+ * Returns a list of all tiles that are found in the cloud cache.
130
+ */
131
+ async getCachedTiles(iModelId) {
132
+ const results = [];
133
+ for await (const page of this.getCachedTilePages(iModelId)) {
134
+ results.push(...page);
135
+ }
136
+ return results;
137
+ }
107
138
  /**
108
139
  * Returns a boolean indicating whether a tile exists in the cloud cache
109
140
  */
@@ -1 +1 @@
1
- {"version":3,"file":"TileStorage.js","sourceRoot":"","sources":["../../src/TileStorage.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\nimport { gunzip, gzip } from \"zlib\";\r\nimport { promisify } from \"util\";\r\nimport { Metadata, ServerStorage, TransferConfig } from \"@itwin/object-storage-core\";\r\nimport { getTileObjectReference } from \"@itwin/core-common\";\r\nimport { Logger } from \"@itwin/core-bentley\";\r\nimport { BackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { IModelHost } from \"./IModelHost\";\r\n\r\n/**\r\n * Facilitates interaction with cloud tile cache.\r\n * @beta\r\n */\r\nexport class TileStorage {\r\n /**\r\n * Allows using the underlying `ServerStorage` API directly.\r\n * @see https://github.com/iTwin/object-storage/\r\n */\r\n public readonly storage: ServerStorage;\r\n\r\n public constructor(storage: ServerStorage) {\r\n this.storage = storage;\r\n }\r\n\r\n private _initializedIModels: Set<string> = new Set();\r\n\r\n /**\r\n * Ensures any required cloud storage resources for a specific iModel are ready to use.\r\n */\r\n public async initialize(iModelId: string): Promise<void> {\r\n if (this._initializedIModels.has(iModelId))\r\n return;\r\n if (!(await this.storage.baseDirectoryExists({ baseDirectory: iModelId }))) {\r\n await this.storage.createBaseDirectory({ baseDirectory: iModelId });\r\n }\r\n this._initializedIModels.add(iModelId);\r\n }\r\n\r\n /**\r\n * Returns config that can be used by frontends to download tiles\r\n * @param iModelId Id of the iModel\r\n * @param expiresInSeconds Optional number of seconds until the download URL expires. Defaults to expiring exactly at midnight of next Sunday to enable persistent client-side caching.\r\n * It is recommended to set this to a shorter period when using S3-compatible storage - an exact expiry date cannot be ensured due to limitations in their API.\r\n * @see [TileStorage]($frontend)\r\n */\r\n public async getDownloadConfig(iModelId: string, expiresInSeconds?: number): Promise<TransferConfig> {\r\n try {\r\n if (expiresInSeconds !== undefined)\r\n return await this.storage.getDownloadConfig({ baseDirectory: iModelId }, { expiresInSeconds });\r\n const expiresOn = new Date();\r\n expiresOn.setDate(expiresOn.getDate() + (7 - expiresOn.getDay())); // next Sunday\r\n expiresOn.setHours(0, 0, 0, 0); // exactly at midnight\r\n return await this.storage.getDownloadConfig({ baseDirectory: iModelId }, { expiresOn });\r\n } catch (err) {\r\n this.logException(\"Failed to get download config\", err);\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Uploads a tile to the cloud cache.\r\n */\r\n public async uploadTile(iModelId: string, changesetId: string, treeId: string, contentId: string, content: Uint8Array, guid?: string, metadata?: Metadata): Promise<void> {\r\n try {\r\n await this.storage.upload(\r\n getTileObjectReference(iModelId, changesetId, treeId, contentId, guid),\r\n Buffer.from(IModelHost.compressCachedTiles ? await promisify(gzip)(content.buffer) : content.buffer),\r\n metadata,\r\n IModelHost.compressCachedTiles ? { contentEncoding: \"gzip\" } : undefined,\r\n );\r\n } catch (err) {\r\n this.logException(\"Failed to upload tile\", err);\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Downloads a tile from the cloud cache.\r\n */\r\n public async downloadTile(iModelId: string, changesetId: string, treeId: string, contentId: string, guid?: string): Promise<Uint8Array> {\r\n try {\r\n const buffer = await this.storage.download(\r\n getTileObjectReference(iModelId, changesetId, treeId, contentId, guid),\r\n \"buffer\",\r\n );\r\n return IModelHost.compressCachedTiles ? await promisify(gunzip)(buffer) : buffer;\r\n } catch (err) {\r\n this.logException(\"Failed to download tile\", err);\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Returns a list of all tiles that are found in the cloud cache.\r\n */\r\n public async getCachedTiles(iModelId: string): Promise<{ treeId: string, contentId: string, guid: string }[]> {\r\n return (await this.storage.listObjects({ baseDirectory: iModelId }))\r\n .map((objectReference) => ({\r\n parts: objectReference.relativeDirectory?.split(\"/\") ?? [\"\"],\r\n objectName: objectReference.objectName,\r\n }))\r\n .filter(({ parts, objectName }) => {\r\n if (parts[0] !== \"tiles\")\r\n return false;\r\n if (parts.length !== 3) {\r\n Logger.logWarning(BackendLoggerCategory.IModelTileStorage, \"Malformed tile id found in tile cache: {tileId}\", { tileId: [...parts, objectName].join(\"/\") });\r\n return false;\r\n }\r\n return true;\r\n }).map(({ parts, objectName }) => {\r\n // relativeDirectory = tiles/<treeId>/<guid>\r\n // objectName = <contentId>\r\n return {\r\n treeId: parts[1],\r\n contentId: objectName,\r\n guid: parts[2],\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Returns a boolean indicating whether a tile exists in the cloud cache\r\n */\r\n public async isTileCached(iModelId: string, changesetId: string, treeId: string, contentId: string, guid?: string): Promise<boolean> {\r\n return this.storage.objectExists(getTileObjectReference(iModelId, changesetId, treeId, contentId, guid));\r\n }\r\n\r\n private logException(message: string, err: unknown): void {\r\n Logger.logException(\r\n BackendLoggerCategory.IModelTileStorage,\r\n err,\r\n (category, msg, errorMetadata) => Logger.logError(category, `${message}: {errorMessage}`, { ...errorMetadata, errorMessage: msg }),\r\n );\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"TileStorage.js","sourceRoot":"","sources":["../../src/TileStorage.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\nimport { gunzip, gzip } from \"zlib\";\r\nimport { promisify } from \"util\";\r\nimport { Metadata, ObjectReference, ServerStorage, TransferConfig } from \"@itwin/object-storage-core\";\r\nimport { getTileObjectReference } from \"@itwin/core-common\";\r\nimport { Logger } from \"@itwin/core-bentley\";\r\nimport { BackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { IModelHost } from \"./IModelHost\";\r\n\r\n/**\r\n * Identifies a tile in cloud tile cache.\r\n * @beta\r\n */\r\nexport interface TileId {\r\n treeId: string;\r\n contentId: string;\r\n guid: string;\r\n}\r\n\r\n/**\r\n * Facilitates interaction with cloud tile cache.\r\n * @beta\r\n */\r\nexport class TileStorage {\r\n /**\r\n * Allows using the underlying `ServerStorage` API directly.\r\n * @see https://github.com/iTwin/object-storage/\r\n */\r\n public readonly storage: ServerStorage;\r\n\r\n public constructor(storage: ServerStorage) {\r\n this.storage = storage;\r\n }\r\n\r\n private _initializedIModels: Set<string> = new Set();\r\n\r\n /**\r\n * Ensures any required cloud storage resources for a specific iModel are ready to use.\r\n */\r\n public async initialize(iModelId: string): Promise<void> {\r\n if (this._initializedIModels.has(iModelId))\r\n return;\r\n if (!(await this.storage.baseDirectoryExists({ baseDirectory: iModelId }))) {\r\n await this.storage.createBaseDirectory({ baseDirectory: iModelId });\r\n }\r\n this._initializedIModels.add(iModelId);\r\n }\r\n\r\n /**\r\n * Returns config that can be used by frontends to download tiles\r\n * @param iModelId Id of the iModel\r\n * @param expiresInSeconds Optional number of seconds until the download URL expires. Defaults to expiring exactly at midnight of next Sunday to enable persistent client-side caching.\r\n * It is recommended to set this to a shorter period when using S3-compatible storage - an exact expiry date cannot be ensured due to limitations in their API.\r\n * @see [TileStorage]($frontend)\r\n */\r\n public async getDownloadConfig(iModelId: string, expiresInSeconds?: number): Promise<TransferConfig> {\r\n try {\r\n if (expiresInSeconds !== undefined)\r\n return await this.storage.getDownloadConfig({ baseDirectory: iModelId }, { expiresInSeconds });\r\n const expiresOn = new Date();\r\n expiresOn.setDate(expiresOn.getDate() + (7 - expiresOn.getDay())); // next Sunday\r\n expiresOn.setHours(0, 0, 0, 0); // exactly at midnight\r\n return await this.storage.getDownloadConfig({ baseDirectory: iModelId }, { expiresOn });\r\n } catch (err) {\r\n this.logException(\"Failed to get download config\", err);\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Uploads a tile to the cloud cache.\r\n */\r\n public async uploadTile(iModelId: string, changesetId: string, treeId: string, contentId: string, content: Uint8Array, guid?: string, metadata?: Metadata): Promise<void> {\r\n try {\r\n await this.storage.upload(\r\n getTileObjectReference(iModelId, changesetId, treeId, contentId, guid),\r\n Buffer.from(IModelHost.compressCachedTiles ? await promisify(gzip)(content.buffer) : content.buffer),\r\n metadata,\r\n IModelHost.compressCachedTiles ? { contentEncoding: \"gzip\" } : undefined,\r\n );\r\n } catch (err) {\r\n this.logException(\"Failed to upload tile\", err);\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Downloads a tile from the cloud cache.\r\n */\r\n public async downloadTile(iModelId: string, changesetId: string, treeId: string, contentId: string, guid?: string): Promise<Uint8Array> {\r\n try {\r\n const buffer = await this.storage.download(\r\n getTileObjectReference(iModelId, changesetId, treeId, contentId, guid),\r\n \"buffer\",\r\n );\r\n return IModelHost.compressCachedTiles ? await promisify(gunzip)(buffer) : buffer;\r\n } catch (err) {\r\n this.logException(\"Failed to download tile\", err);\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Returns an async iterator of all tiles that are found in the cloud cache.\r\n */\r\n public async *getCachedTilesGenerator(iModelId: string): AsyncGenerator<TileId> {\r\n const iterator = this.getCachedTilePages(iModelId);\r\n for await (const page of iterator) {\r\n for (const tile of page) {\r\n yield tile;\r\n }\r\n }\r\n }\r\n\r\n private async *getCachedTilePages(iModelId: string): AsyncGenerator<TileId[]> {\r\n const iterator = this.storage.getListObjectsPagedIterator({ baseDirectory: iModelId }, 500);\r\n let prevPage: IteratorResult<ObjectReference[], any> | undefined;\r\n do {\r\n // initiate loading the next page\r\n const page = iterator.next();\r\n // process results from the previous page\r\n if (prevPage)\r\n yield this.convertPage(prevPage.value);\r\n // finish loading the next page\r\n prevPage = await page;\r\n } while (!prevPage.done);\r\n }\r\n\r\n private convertPage(page: ObjectReference[]): TileId[] {\r\n return page\r\n .map((objectReference) => ({\r\n parts: objectReference.relativeDirectory?.split(\"/\") ?? [\"\"],\r\n objectName: objectReference.objectName,\r\n }))\r\n .filter(({ parts, objectName }) => {\r\n if (parts[0] !== \"tiles\")\r\n return false;\r\n if (parts.length !== 3) {\r\n Logger.logWarning(BackendLoggerCategory.IModelTileStorage, \"Malformed tile id found in tile cache: {tileId}\", { tileId: [...parts, objectName].join(\"/\") });\r\n return false;\r\n }\r\n return true;\r\n }).map(({ parts, objectName }) => {\r\n // relativeDirectory = tiles/<treeId>/<guid>\r\n // objectName = <contentId>\r\n return {\r\n treeId: parts[1],\r\n contentId: objectName,\r\n guid: parts[2],\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Returns a list of all tiles that are found in the cloud cache.\r\n */\r\n public async getCachedTiles(iModelId: string): Promise<TileId[]> {\r\n const results: TileId[] = [];\r\n for await (const page of this.getCachedTilePages(iModelId)) {\r\n results.push(...page);\r\n }\r\n return results;\r\n }\r\n\r\n /**\r\n * Returns a boolean indicating whether a tile exists in the cloud cache\r\n */\r\n public async isTileCached(iModelId: string, changesetId: string, treeId: string, contentId: string, guid?: string): Promise<boolean> {\r\n return this.storage.objectExists(getTileObjectReference(iModelId, changesetId, treeId, contentId, guid));\r\n }\r\n\r\n private logException(message: string, err: unknown): void {\r\n Logger.logException(\r\n BackendLoggerCategory.IModelTileStorage,\r\n err,\r\n (category, msg, errorMetadata) => Logger.logError(category, `${message}: {errorMessage}`, { ...errorMetadata, errorMessage: msg }),\r\n );\r\n }\r\n}\r\n"]}
@@ -33,6 +33,27 @@ export interface TxnChangedEntities {
33
33
  /** The entities that were modified by the transaction, including any [[Element]]s for which one of their [[ElementAspect]]s was changed. */
34
34
  readonly updates: EntityIdAndClassIdIterable;
35
35
  }
36
+ /** Arguments supplied to [[TxnManager.queryLocalChanges]].
37
+ * @beta
38
+ */
39
+ export interface QueryLocalChangesArgs {
40
+ /** If supplied and non-empty, restricts the results to include only EC instances belonging to the specified classes or subclasses thereof. */
41
+ readonly includedClasses?: string[];
42
+ /** If `true`, include changes that have not yet been saved. */
43
+ readonly includeUnsavedChanges?: boolean;
44
+ }
45
+ /** Represents a change (insertion, deletion, or modification) to a single EC instance made in a local [[BriefcaseDb]].
46
+ * @see [[TxnManager.queryLocalChanges]] to iterate all of the changed instances.
47
+ * @beta
48
+ */
49
+ export interface ChangeInstanceKey {
50
+ /** ECInstanceId of the instance. */
51
+ id: Id64String;
52
+ /** Fully-qualified class name of the instance. */
53
+ classFullName: string;
54
+ /** The type of change. */
55
+ changeType: "inserted" | "updated" | "deleted";
56
+ }
36
57
  /** Strictly for tests. @internal */
37
58
  export declare function setMaxEntitiesPerEvent(max: number): number;
38
59
  /** Manages local changes to a [[BriefcaseDb]] or [[StandaloneDb]] via [Txns]($docs/learning/InteractiveEditing.md)
@@ -51,6 +72,10 @@ export declare class TxnManager {
51
72
  private get _nativeDb();
52
73
  private _getElementClass;
53
74
  private _getRelationshipClass;
75
+ /** If a -watch file exists for this iModel, update its timestamp so watching processes can be
76
+ * notified that we've modified the briefcase.
77
+ */
78
+ private touchWatchFile;
54
79
  /** @internal */
55
80
  protected _onBeforeOutputsHandled(elClassName: string, elId: Id64String): void;
56
81
  /** @internal */
@@ -74,6 +99,10 @@ export declare class TxnManager {
74
99
  /** @internal */
75
100
  protected _onCommitted(): void;
76
101
  /** @internal */
102
+ protected _onReplayExternalTxns(): void;
103
+ /** @internal */
104
+ protected _onReplayedExternalTxns(): void;
105
+ /** @internal */
77
106
  protected _onChangesApplied(): void;
78
107
  /** @internal */
79
108
  protected _onBeforeUndoRedo(isUndo: boolean): void;
@@ -117,6 +146,14 @@ export declare class TxnManager {
117
146
  * @param _action The action that was performed.
118
147
  */
119
148
  readonly onAfterUndoRedo: BeEvent<(isUndo: boolean) => void>;
149
+ /** Event raised for a read-only briefcase that was opened with the `watchForChanges` flag enabled when changes made by another connection are applied to the briefcase.
150
+ * @see [[onReplayedExternalTxns]] for the event raised after all such changes have been applied.
151
+ */
152
+ readonly onReplayExternalTxns: BeEvent<() => void>;
153
+ /** Event raised for a read-only briefcase that was opened with the `watchForChanges` flag enabled when changes made by another connection are applied to the briefcase.
154
+ * @see [[onReplayExternalTxns]] for the event raised before the changes are applied.
155
+ */
156
+ readonly onReplayedExternalTxns: BeEvent<() => void>;
120
157
  /**
121
158
  * Restart the current TxnManager session. This causes all Txns in the current session to no longer be undoable (as if the file was closed
122
159
  * and reopened.)
@@ -199,5 +236,9 @@ export declare class TxnManager {
199
236
  get hasUnsavedChanges(): boolean;
200
237
  /** Query if there are un-saved or un-pushed local changes. */
201
238
  get hasLocalChanges(): boolean;
239
+ /** Obtain a list of the EC instances that have been changed locally by the [[BriefcaseDb]] associated with this `TxnManager` and have not yet been pushed to the iModel.
240
+ * @beta
241
+ */
242
+ queryLocalChanges(args?: QueryLocalChangesArgs): Iterable<ChangeInstanceKey>;
202
243
  }
203
244
  //# sourceMappingURL=TxnManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TxnManager.d.ts","sourceRoot":"","sources":["../../src/TxnManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TxnManager.d.ts","sourceRoot":"","sources":["../../src/TxnManager.ts"],"names":[],"mappings":"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"}