@itwin/core-backend 5.14.0-dev.10 → 5.14.0-dev.12
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.
- package/CHANGELOG.md +16 -1
- package/lib/cjs/ECDb.d.ts +52 -0
- package/lib/cjs/ECDb.d.ts.map +1 -1
- package/lib/cjs/ECDb.js +51 -0
- package/lib/cjs/ECDb.js.map +1 -1
- package/lib/cjs/SchemaSync.d.ts +2 -2
- package/lib/cjs/SchemaSync.d.ts.map +1 -1
- package/lib/cjs/SchemaSync.js +2 -2
- package/lib/cjs/SchemaSync.js.map +1 -1
- package/lib/cjs/SqliteChangesetReader.d.ts +16 -8
- package/lib/cjs/SqliteChangesetReader.d.ts.map +1 -1
- package/lib/cjs/SqliteChangesetReader.js +11 -1
- package/lib/cjs/SqliteChangesetReader.js.map +1 -1
- package/lib/esm/ECDb.d.ts +52 -0
- package/lib/esm/ECDb.d.ts.map +1 -1
- package/lib/esm/ECDb.js +51 -0
- package/lib/esm/ECDb.js.map +1 -1
- package/lib/esm/SchemaSync.d.ts +2 -2
- package/lib/esm/SchemaSync.d.ts.map +1 -1
- package/lib/esm/SchemaSync.js +2 -2
- package/lib/esm/SchemaSync.js.map +1 -1
- package/lib/esm/SqliteChangesetReader.d.ts +16 -8
- package/lib/esm/SqliteChangesetReader.d.ts.map +1 -1
- package/lib/esm/SqliteChangesetReader.js +11 -1
- package/lib/esm/SqliteChangesetReader.js.map +1 -1
- package/lib/esm/test/ecdb/CSVImport.test.d.ts +2 -0
- package/lib/esm/test/ecdb/CSVImport.test.d.ts.map +1 -0
- package/lib/esm/test/ecdb/CSVImport.test.js +186 -0
- package/lib/esm/test/ecdb/CSVImport.test.js.map +1 -0
- package/lib/esm/test/standalone/SQLiteDb.test.d.ts.map +1 -1
- package/lib/esm/test/standalone/SQLiteDb.test.js +116 -0
- package/lib/esm/test/standalone/SQLiteDb.test.js.map +1 -1
- package/package.json +13 -13
package/lib/esm/ECDb.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { assert, BeEvent, DbResult, Logger, OpenMode } from "@itwin/core-bentley";
|
|
9
9
|
import { ECSqlReader, IModelError } from "@itwin/core-common";
|
|
10
|
+
import { serialize } from "node:v8";
|
|
10
11
|
import { BackendLoggerCategory } from "./BackendLoggerCategory";
|
|
11
12
|
import { ConcurrentQuery } from "./ConcurrentQuery";
|
|
12
13
|
import { ECSqlStatement, ECSqlWriteStatement } from "./ECSqlStatement";
|
|
@@ -16,6 +17,22 @@ import { _nativeDb } from "./internal/Symbols";
|
|
|
16
17
|
import { ECSqlRowExecutor, releaseECSqlStatement } from "./ECSqlRowExecutor";
|
|
17
18
|
import { ECSqlSyncReader } from "./ECSqlSyncReader";
|
|
18
19
|
const loggerCategory = BackendLoggerCategory.ECDb;
|
|
20
|
+
function validateCSVMapping(mapping) {
|
|
21
|
+
if (0 === mapping.length)
|
|
22
|
+
throw new TypeError("mapping must not be empty");
|
|
23
|
+
const columnIndexes = new Set();
|
|
24
|
+
for (const entry of mapping) {
|
|
25
|
+
if (undefined === entry || null === entry || "object" !== typeof entry)
|
|
26
|
+
throw new TypeError("mapping must contain only objects");
|
|
27
|
+
if (!Number.isSafeInteger(entry.columnIndex) || entry.columnIndex < 0 || entry.columnIndex >= 0xffff_ffff)
|
|
28
|
+
throw new TypeError("mapping columnIndex values must be non-negative safe integers");
|
|
29
|
+
if ("string" !== typeof entry.propertyName || 0 === entry.propertyName.length)
|
|
30
|
+
throw new TypeError("mapping propertyName values must not be empty");
|
|
31
|
+
if (columnIndexes.has(entry.columnIndex))
|
|
32
|
+
throw new TypeError("mapping must not contain duplicate columnIndex values");
|
|
33
|
+
columnIndexes.add(entry.columnIndex);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
19
36
|
/** Modes for how to open [ECDb]($backend) files.
|
|
20
37
|
* @public
|
|
21
38
|
*/
|
|
@@ -197,6 +214,40 @@ export class ECDb {
|
|
|
197
214
|
getSchemaProps(name) {
|
|
198
215
|
return this[_nativeDb].getSchemaProps(name);
|
|
199
216
|
}
|
|
217
|
+
/** Import in-memory CSV rows into an ECClass.
|
|
218
|
+
*
|
|
219
|
+
* The rows are V8-serialized and processed in one native call. Values are converted from
|
|
220
|
+
* their CSV string representation according to the mapped EC property type. One ECSQL
|
|
221
|
+
* statement is reused for all rows. Every row must have the same number of columns.
|
|
222
|
+
* Boolean fields accept `true`, `false`, `1`, or `0`. Integer fields must contain a
|
|
223
|
+
* base-10 value in the signed 32-bit range. Boolean, double, integer, and string EC
|
|
224
|
+
* properties are supported. The import is all-or-nothing and callers must call
|
|
225
|
+
* [[saveChanges]] to commit it to disk.
|
|
226
|
+
* @returns The number of imported rows.
|
|
227
|
+
* @beta
|
|
228
|
+
*/
|
|
229
|
+
importCSVData(rows, options) {
|
|
230
|
+
validateCSVMapping(options.mapping);
|
|
231
|
+
return this[_nativeDb].importCSVData(options.className, serialize(rows), options.mapping, { nullValue: options.nullValue });
|
|
232
|
+
}
|
|
233
|
+
/** Stream a CSV file into an ECClass.
|
|
234
|
+
*
|
|
235
|
+
* The file must be UTF-8 encoded; an optional UTF-8 byte-order mark is accepted. It is read
|
|
236
|
+
* and parsed in native code, and one ECSQL statement is reused for all rows. Every record must
|
|
237
|
+
* have the same number of columns; blank records are not skipped. Boolean fields accept
|
|
238
|
+
* `true`, `false`, `1`, or `0`. Integer fields must contain a base-10 value in the signed
|
|
239
|
+
* 32-bit range. Boolean, double, integer, and string EC properties are supported. The import
|
|
240
|
+
* is all-or-nothing and callers must call [[saveChanges]] to commit it to disk.
|
|
241
|
+
* @returns The number of imported rows, excluding an optional header.
|
|
242
|
+
* @beta
|
|
243
|
+
*/
|
|
244
|
+
importCSVFile(csvFilePath, options) {
|
|
245
|
+
validateCSVMapping(options.mapping);
|
|
246
|
+
return this[_nativeDb].importCSVFile(options.className, csvFilePath, options.mapping, {
|
|
247
|
+
hasHeader: options.hasHeader,
|
|
248
|
+
nullValue: options.nullValue,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
200
251
|
/**
|
|
201
252
|
* Use a prepared ECSQL statement, potentially from the statement cache. If the requested statement doesn't exist
|
|
202
253
|
* in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved
|
package/lib/esm/ECDb.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ECDb.js","sourceRoot":"","sources":["../../src/ECDb.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 ECDb\r\n */\r\nimport { assert, BeEvent, DbResult, Logger, OpenMode } from \"@itwin/core-bentley\";\r\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\r\nimport { DbQueryRequest, ECSchemaProps, ECSqlReader, IModelError, QueryBinder, QueryOptions } from \"@itwin/core-common\";\r\nimport { BackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { ConcurrentQuery } from \"./ConcurrentQuery\";\r\nimport { ECSqlStatement, ECSqlWriteStatement } from \"./ECSqlStatement\";\r\nimport { IModelNative } from \"./internal/NativePlatform\";\r\nimport { SqliteStatement, StatementCache } from \"./SqliteStatement\";\r\nimport { _nativeDb } from \"./internal/Symbols\";\r\nimport { ECSqlRowExecutor, releaseECSqlStatement } from \"./ECSqlRowExecutor\";\r\nimport { ECSqlSyncReader, SynchronousQueryOptions } from \"./ECSqlSyncReader\";\r\n\r\nconst loggerCategory: string = BackendLoggerCategory.ECDb;\r\n\r\n/** Modes for how to open [ECDb]($backend) files.\r\n * @public\r\n */\r\nexport enum ECDbOpenMode {\r\n Readonly,\r\n ReadWrite,\r\n /** Opens the file read-write and upgrades the file if necessary to the latest file format version. */\r\n FileUpgrade,\r\n}\r\n\r\n/** An ECDb file\r\n * @public\r\n */\r\nexport class ECDb implements Disposable {\r\n private _nativeDb?: IModelJsNative.ECDb;\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n private readonly _statementCache = new StatementCache<ECSqlStatement>();\r\n private _sqliteStatementCache = new StatementCache<SqliteStatement>();\r\n\r\n /** Event called when the ECDb is about to be closed. */\r\n public readonly onBeforeClose = new BeEvent<() => void>();\r\n\r\n /** only for tests\r\n * @internal\r\n */\r\n public resetSqliteCache(size: number) {\r\n this._sqliteStatementCache.clear();\r\n this._sqliteStatementCache = new StatementCache<SqliteStatement>(size);\r\n }\r\n\r\n constructor() {\r\n this._nativeDb = new IModelNative.platform.ECDb();\r\n }\r\n /** Call this function when finished with this ECDb object. This releases the native resources held by the\r\n * ECDb object.\r\n */\r\n public [Symbol.dispose](): void {\r\n if (!this._nativeDb)\r\n return;\r\n\r\n this.closeDb();\r\n this._nativeDb.dispose();\r\n this._nativeDb = undefined;\r\n }\r\n /**\r\n * Attach an iModel file to this connection and load and register its schemas.\r\n * @note There are some reserve tablespace names that cannot be used. They are 'main', 'schema_sync_db', 'ecchange' & 'temp'\r\n * @param fileName IModel file name\r\n * @param alias identifier for the attached file. This identifer is used to access schema from the attached file. e.g. if alias is 'abc' then schema can be accessed using 'abc.MySchema.MyClass'\r\n */\r\n public attachDb(fileName: string, alias: string): void {\r\n if (alias.toLowerCase() === \"main\" || alias.toLowerCase() === \"schema_sync_db\" || alias.toLowerCase() === \"ecchange\" || alias.toLowerCase() === \"temp\") {\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Reserved tablespace name cannot be used\");\r\n }\r\n this[_nativeDb].attachDb(fileName, alias);\r\n }\r\n /**\r\n * Detach the attached file from this connection. The attached file is closed and its schemas are unregistered.\r\n * @note There are some reserve tablespace names that cannot be used. They are 'main', 'schema_sync_db', 'ecchange' & 'temp'\r\n * @param alias identifer that was used in the call to [[attachDb]]\r\n */\r\n public detachDb(alias: string): void {\r\n if (alias.toLowerCase() === \"main\" || alias.toLowerCase() === \"schema_sync_db\" || alias.toLowerCase() === \"ecchange\" || alias.toLowerCase() === \"temp\") {\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Reserved tablespace name cannot be used\");\r\n }\r\n this.clearCaches();\r\n this[_nativeDb].detachDb(alias);\r\n }\r\n\r\n /** @deprecated in 5.0 - might be removed in next major version. Use [Symbol.dispose] instead. */\r\n public dispose(): void {\r\n this[Symbol.dispose]();\r\n }\r\n\r\n /** Create an ECDb\r\n * @param pathName The path to the ECDb file to create.\r\n * @throws [IModelError]($common) if the operation failed.\r\n */\r\n public createDb(pathName: string): void {\r\n const status: DbResult = this[_nativeDb].createDb(pathName);\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to created ECDb\");\r\n }\r\n\r\n /** Open the ECDb.\r\n * @param pathName The path to the ECDb file to open\r\n * @param openMode Open mode\r\n * @throws [IModelError]($common) if the operation failed.\r\n */\r\n public openDb(pathName: string, openMode: ECDbOpenMode = ECDbOpenMode.Readonly): void {\r\n const nativeOpenMode: OpenMode = openMode === ECDbOpenMode.Readonly ? OpenMode.Readonly : OpenMode.ReadWrite;\r\n const tryUpgrade: boolean = openMode === ECDbOpenMode.FileUpgrade;\r\n const status: DbResult = this[_nativeDb].openDb(pathName, nativeOpenMode, tryUpgrade);\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to open ECDb\");\r\n }\r\n\r\n /** Returns true if the ECDb is open */\r\n public get isOpen(): boolean { return this[_nativeDb].isOpen(); }\r\n\r\n /** Close the Db after saving any uncommitted changes.\r\n * @throws [IModelError]($common) if the database is not open.\r\n */\r\n public closeDb(): void {\r\n this.onBeforeClose.raiseEvent();\r\n this.clearCaches();\r\n this[_nativeDb].closeDb();\r\n }\r\n\r\n /** Clear all in-memory caches held in this ECDb.\r\n * @beta\r\n */\r\n public clearCaches(): void {\r\n this._statementCache.clear();\r\n this._sqliteStatementCache.clear();\r\n this[_nativeDb].clearECDbCache();\r\n }\r\n\r\n /** @internal use to test statement caching */\r\n public clearStatementCache() {\r\n this._statementCache.clear();\r\n }\r\n\r\n /** @internal use to test statement caching */\r\n public getCachedStatementCount() {\r\n return this._statementCache.size;\r\n }\r\n\r\n /** Commit the outermost transaction, writing changes to the file. Then, restart the transaction.\r\n * @param changesetName The name of the operation that generated these changes.\r\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\r\n */\r\n public saveChanges(changesetName?: string): void {\r\n const status: DbResult = this[_nativeDb].saveChanges(changesetName);\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to save changes\");\r\n }\r\n\r\n /** Abandon (cancel) the outermost transaction, discarding all changes since last save. Then, restart the transaction.\r\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\r\n */\r\n public abandonChanges(): void {\r\n const status: DbResult = this[_nativeDb].abandonChanges();\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to abandon changes\");\r\n }\r\n\r\n /** Import a schema.\r\n *\r\n * If the import was successful, the database is automatically saved to disk.\r\n * @param pathName Path to ECSchema XML file to import.\r\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\r\n */\r\n public importSchema(pathName: string): void {\r\n const status: DbResult = this[_nativeDb].importSchema(pathName);\r\n if (status !== DbResult.BE_SQLITE_OK) {\r\n Logger.logError(loggerCategory, `Failed to import schema from '${pathName}'.`);\r\n throw new IModelError(status, `Failed to import schema from '${pathName}'.`);\r\n }\r\n this.clearCaches();\r\n }\r\n\r\n /** Removes unused schemas from the database.\r\n *\r\n * If the removal was successful, the database is automatically saved to disk.\r\n * @param schemaNames Array of schema names to drop\r\n * @throws [IModelError]($common) if the database if the operation failed.\r\n * @alpha\r\n */\r\n public dropSchemas(schemaNames: string[]): void {\r\n if (schemaNames.length === 0)\r\n return;\r\n // SchemaSync.isEnabled() should be used, but ECDb is not an iModelDb so it has no container props\r\n if (this[_nativeDb].schemaSyncEnabled())\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot drop schemas when schema sync is enabled\");\r\n\r\n try {\r\n this[_nativeDb].dropSchemas(schemaNames);\r\n this.saveChanges('dropped unused schemas');\r\n } catch (error: any) {\r\n Logger.logError(loggerCategory, `Failed to drop schemas: ${error}`);\r\n this.abandonChanges();\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, `Failed to drop schemas: ${error}`);\r\n } finally {\r\n this.clearCaches();\r\n }\r\n }\r\n\r\n /**\r\n * Returns the full schema for the input name.\r\n * @param name The name of the schema e.g. 'ECDbMeta'\r\n * @returns The SchemaProps for the requested schema\r\n * @throws if the schema can not be found or loaded.\r\n */\r\n public getSchemaProps(name: string): ECSchemaProps {\r\n return this[_nativeDb].getSchemaProps(name);\r\n }\r\n\r\n /**\r\n * Use a prepared ECSQL 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 ECSQL 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 [[withStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withWriteStatement]]\r\n * @beta\r\n */\r\n public withCachedWriteStatement<T>(ecsql: string, callback: (stmt: ECSqlWriteStatement) => T, logErrors = true): T {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const stmt = this._statementCache.findAndRemove(ecsql) ?? this.prepareStatement(ecsql, logErrors);\r\n const release = () => this._statementCache.addOrDispose(stmt);\r\n try {\r\n const val = callback(new ECSqlWriteStatement(stmt));\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\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 * Prepared and execute a callback on an ECSQL statement. After the callback completes the statement is disposed.\r\n * Use this method for ECSQL 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 [[withPreparedStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withCachedWriteStatement]]\r\n * @beta\r\n */\r\n public withWriteStatement<T>(ecsql: string, callback: (stmt: ECSqlWriteStatement) => T, logErrors = true): T {\r\n const stmt = this.prepareWriteStatement(ecsql, logErrors);\r\n const release = () => stmt[Symbol.dispose]();\r\n try {\r\n const val = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /** Prepare an ECSQL statement.\r\n * @param ecsql The ECSQL statement to prepare\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @throws [IModelError]($common) if there is a problem preparing the statement.\r\n * @beta\r\n */\r\n public prepareWriteStatement(ecsql: string, logErrors = true): ECSqlWriteStatement {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n return new ECSqlWriteStatement(this.prepareStatement(ecsql, logErrors));\r\n }\r\n\r\n /**\r\n * Use a prepared ECSQL 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 ECSQL 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 [[withStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withStatement]]\r\n * @public\r\n * @deprecated in 4.11 - might be removed in next major version. Use [[createQueryReader]] for SELECT statements and [[withCachedWriteStatement]] for INSERT/UPDATE/DELETE instead.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n public withPreparedStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors = true): T {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const stmt = this._statementCache.findAndRemove(ecsql) ?? this.prepareStatement(ecsql, logErrors);\r\n const release = () => this._statementCache.addOrDispose(stmt);\r\n try {\r\n const val = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\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 * Prepared and execute a callback on an ECSQL statement. After the callback completes the statement is disposed.\r\n * Use this method for ECSQL 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 [[withPreparedStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withPreparedStatement]]\r\n * @public\r\n * @deprecated in 4.11 - might be removed in next major version. Use [[createQueryReader]] for SELECT statements and [[withWriteStatement]] for INSERT/UPDATE/DELETE instead.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n public withStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors = true): T {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const stmt = this.prepareStatement(ecsql, logErrors);\r\n const release = () => stmt[Symbol.dispose]();\r\n try {\r\n const val = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /** Prepare an ECSQL statement.\r\n * @param ecsql The ECSQL statement to prepare\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @throws [IModelError]($common) if there is a problem preparing the statement.\r\n * @deprecated in 4.11 - might be removed in next major version. Use [[prepareWriteStatement]] when preparing an INSERT/UPDATE/DELETE statement or [[createQueryReader]] to execute a SELECT statement.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n public prepareStatement(ecsql: string, logErrors = true): ECSqlStatement {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const stmt = new ECSqlStatement();\r\n stmt.prepare(this[_nativeDb], ecsql, logErrors);\r\n return stmt;\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 * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withPreparedStatement]]\r\n * @public\r\n */\r\n public withPreparedSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors = true): T {\r\n const stmt = this._sqliteStatementCache.findAndRemove(sql) ?? this.prepareSqliteStatement(sql, logErrors);\r\n const release = () => this._sqliteStatementCache.addOrDispose(stmt);\r\n try {\r\n const val: T = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\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 * Prepared 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 * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @public\r\n */\r\n public withSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors = true): T {\r\n const stmt = this.prepareSqliteStatement(sql, logErrors);\r\n const release = () => stmt[Symbol.dispose]();\r\n try {\r\n const val: T = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\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 Determines if error will be logged if statement fail to prepare\r\n * @throws [IModelError]($common) if there is a problem preparing the statement.\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 /** @internal */\r\n public get [_nativeDb](): IModelJsNative.ECDb {\r\n assert(undefined !== this._nativeDb);\r\n return this._nativeDb;\r\n }\r\n\r\n /** Allow to execute query and read results along with meta data. The result are streamed.\r\n *\r\n * See also:\r\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\r\n * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)\r\n * - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)\r\n *\r\n * @param params The values to bind to the parameters (if the ECSQL has any).\r\n * @param config Allow to specify certain flags which control how query is executed.\r\n * @returns Returns an [ECSqlReader]($common) which helps iterate over the result set and also give access to metadata.\r\n * @public\r\n * */\r\n public createQueryReader(ecsql: string, params?: QueryBinder, config?: QueryOptions): ECSqlReader {\r\n if (!this._nativeDb || !this._nativeDb.isOpen()) {\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR_NOTOPEN, \"db not open\");\r\n }\r\n const executor = {\r\n execute: async (request: DbQueryRequest) => {\r\n return ConcurrentQuery.executeQueryRequest(this[_nativeDb], request);\r\n },\r\n };\r\n return new ECSqlReader(executor, ecsql, params, config);\r\n }\r\n\r\n /** Allow to execute query and read results along with meta data. The result are stepped one by one.\r\n *\r\n * See also:\r\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\r\n * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)\r\n * - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)\r\n * @param ecsql The ECSQL query to execute.\r\n * @param callback the callback to invoke on the prepared ECSqlSyncReader\r\n * @param params The values to bind to the parameters (if the ECSQL has any).\r\n * @param config Optional flags which control how query is executed.\r\n * @returns the value returned by `callback`.\r\n * @throws IModelError if db is not open or if error occurs during statement execution\r\n * @beta\r\n * */\r\n public withQueryReader<T>(ecsql: string, callback: (reader: ECSqlSyncReader) => T, params?: QueryBinder, config?: SynchronousQueryOptions): T {\r\n if (!this[_nativeDb].isOpen())\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR_NOTOPEN, \"db not open\");\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const stmt = this._statementCache.findAndRemove(ecsql) ?? new ECSqlStatement();\r\n const executor = new ECSqlRowExecutor(this, stmt, loggerCategory);\r\n const release = () => {\r\n executor[Symbol.dispose]();\r\n releaseECSqlStatement(stmt, this._statementCache, loggerCategory, executor.canCacheStatement);\r\n };\r\n try {\r\n const reader = new ECSqlSyncReader(executor, ecsql, params, config);\r\n const val = callback(reader);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err: any) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"ECDb.js","sourceRoot":"","sources":["../../src/ECDb.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AACH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAElF,OAAO,EAAiC,WAAW,EAAE,WAAW,EAA6B,MAAM,oBAAoB,CAAC;AACxH,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,eAAe,EAA2B,MAAM,mBAAmB,CAAC;AAE7E,MAAM,cAAc,GAAW,qBAAqB,CAAC,IAAI,CAAC;AAgC1D,SAAS,kBAAkB,CAAC,OAAoC;IAC9D,IAAI,CAAC,KAAK,OAAO,CAAC,MAAM;QACtB,MAAM,IAAI,SAAS,CAAC,2BAA2B,CAAC,CAAC;IAEnD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,SAAS,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,QAAQ,KAAK,OAAO,KAAK;YACpE,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,IAAI,KAAK,CAAC,WAAW,IAAI,WAAW;YACvG,MAAM,IAAI,SAAS,CAAC,+DAA+D,CAAC,CAAC;QACvF,IAAI,QAAQ,KAAK,OAAO,KAAK,CAAC,YAAY,IAAI,CAAC,KAAK,KAAK,CAAC,YAAY,CAAC,MAAM;YAC3E,MAAM,IAAI,SAAS,CAAC,+CAA+C,CAAC,CAAC;QACvE,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC;YACtC,MAAM,IAAI,SAAS,CAAC,uDAAuD,CAAC,CAAC;QAC/E,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAN,IAAY,YAKX;AALD,WAAY,YAAY;IACtB,uDAAQ,CAAA;IACR,yDAAS,CAAA;IACT,sGAAsG;IACtG,6DAAW,CAAA;AACb,CAAC,EALW,YAAY,KAAZ,YAAY,QAKvB;AAED;;GAEG;AACH,MAAM,OAAO,IAAI;IACP,SAAS,CAAuB;IACxC,4DAA4D;IAC3C,eAAe,GAAG,IAAI,cAAc,EAAkB,CAAC;IAChE,qBAAqB,GAAG,IAAI,cAAc,EAAmB,CAAC;IAEtE,wDAAwD;IACxC,aAAa,GAAG,IAAI,OAAO,EAAc,CAAC;IAE1D;;OAEG;IACI,gBAAgB,CAAC,IAAY;QAClC,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;QACnC,IAAI,CAAC,qBAAqB,GAAG,IAAI,cAAc,CAAkB,IAAI,CAAC,CAAC;IACzE,CAAC;IAED;QACE,IAAI,CAAC,SAAS,GAAG,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACpD,CAAC;IACD;;OAEG;IACI,CAAC,MAAM,CAAC,OAAO,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,SAAS;YACjB,OAAO;QAET,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IACD;;;;;OAKG;IACI,QAAQ,CAAC,QAAgB,EAAE,KAAa;QAC7C,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,gBAAgB,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,UAAU,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;YACvJ,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,yCAAyC,CAAC,CAAC;QAC7F,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC;IACD;;;;OAIG;IACI,QAAQ,CAAC,KAAa;QAC3B,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,gBAAgB,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,UAAU,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;YACvJ,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,yCAAyC,CAAC,CAAC;QAC7F,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,iGAAiG;IAC1F,OAAO;QACZ,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;IACzB,CAAC;IAED;;;OAGG;IACI,QAAQ,CAAC,QAAgB;QAC9B,MAAM,MAAM,GAAa,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5D,IAAI,MAAM,KAAK,QAAQ,CAAC,YAAY;YAClC,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IAC5D,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,QAAgB,EAAE,WAAyB,YAAY,CAAC,QAAQ;QAC5E,MAAM,cAAc,GAAa,QAAQ,KAAK,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC7G,MAAM,UAAU,GAAY,QAAQ,KAAK,YAAY,CAAC,WAAW,CAAC;QAClE,MAAM,MAAM,GAAa,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;QACtF,IAAI,MAAM,KAAK,QAAQ,CAAC,YAAY;YAClC,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IACzD,CAAC;IAED,uCAAuC;IACvC,IAAW,MAAM,KAAc,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAEjE;;OAEG;IACI,OAAO;QACZ,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;QAChC,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IAED;;MAEE;IACK,WAAW;QAChB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;QACnC,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAC;IACnC,CAAC;IAED,8CAA8C;IACvC,mBAAmB;QACxB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED,8CAA8C;IACvC,uBAAuB;QAC5B,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;IACnC,CAAC;IAED;;;OAGG;IACI,WAAW,CAAC,aAAsB;QACvC,MAAM,MAAM,GAAa,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QACpE,IAAI,MAAM,KAAK,QAAQ,CAAC,YAAY;YAClC,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACI,cAAc;QACnB,MAAM,MAAM,GAAa,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAC;QAC1D,IAAI,MAAM,KAAK,QAAQ,CAAC,YAAY;YAClC,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;OAKG;IACI,YAAY,CAAC,QAAgB;QAClC,MAAM,MAAM,GAAa,IAAI,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAChE,IAAI,MAAM,KAAK,QAAQ,CAAC,YAAY,EAAE,CAAC;YACrC,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,iCAAiC,QAAQ,IAAI,CAAC,CAAC;YAC/E,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,iCAAiC,QAAQ,IAAI,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED;;;;;;OAMG;IACI,WAAW,CAAC,WAAqB;QACtC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAC1B,OAAO;QACT,kGAAkG;QAClG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,iBAAiB,EAAE;YACrC,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,iDAAiD,CAAC,CAAC;QAErG,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;YACzC,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,2BAA2B,KAAK,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,2BAA2B,KAAK,EAAE,CAAC,CAAC;QACtF,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACI,cAAc,CAAC,IAAY;QAChC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;;;;;;OAWG;IACI,aAAa,CAAC,IAAoC,EAAE,OAAyB;QAClF,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9H,CAAC;IAED;;;;;;;;;;OAUG;IACI,aAAa,CAAC,WAAmB,EAAE,OAA6B;QACrE,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,EAAE;YACpF,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,wBAAwB,CAAI,KAAa,EAAE,QAA0C,EAAE,SAAS,GAAG,IAAI;QAC5G,4DAA4D;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAClG,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC9D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;YACpD,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACI,kBAAkB,CAAI,KAAa,EAAE,QAA0C,EAAE,SAAS,GAAG,IAAI;QACtG,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;MAKE;IACK,qBAAqB,CAAC,KAAa,EAAE,SAAS,GAAG,IAAI;QAC1D,4DAA4D;QAC5D,OAAO,IAAI,mBAAmB,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,4DAA4D;IACrD,qBAAqB,CAAI,KAAa,EAAE,QAAqC,EAAE,SAAS,GAAG,IAAI;QACpG,4DAA4D;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAClG,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC9D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;;;;;;;OAWG;IACH,4DAA4D;IACrD,aAAa,CAAI,KAAa,EAAE,QAAqC,EAAE,SAAS,GAAG,IAAI;QAC5F,4DAA4D;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,4DAA4D;IACrD,gBAAgB,CAAC,KAAa,EAAE,SAAS,GAAG,IAAI;QACrD,4DAA4D;QAC5D,MAAM,IAAI,GAAG,IAAI,cAAc,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,2BAA2B,CAAI,GAAW,EAAE,QAAsC,EAAE,SAAS,GAAG,IAAI;QACzG,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC1G,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACpE,IAAI,CAAC;YACH,MAAM,GAAG,GAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACI,mBAAmB,CAAI,GAAW,EAAE,QAAsC,EAAE,SAAS,GAAG,IAAI;QACjG,MAAM,IAAI,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,GAAG,GAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACI,sBAAsB,CAAC,GAAW,EAAE,SAAS,GAAG,IAAI;QACzD,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gBAAgB;IAChB,IAAW,CAAC,SAAS,CAAC;QACpB,MAAM,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;;;;;;;;SAWK;IACE,iBAAiB,CAAC,KAAa,EAAE,MAAoB,EAAE,MAAqB;QACjF,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YAChD,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,uBAAuB,EAAE,aAAa,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,QAAQ,GAAG;YACf,OAAO,EAAE,KAAK,EAAE,OAAuB,EAAE,EAAE;gBACzC,OAAO,eAAe,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;YACvE,CAAC;SACF,CAAC;QACF,OAAO,IAAI,WAAW,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;;;;;;;;;SAaK;IACE,eAAe,CAAI,KAAa,EAAE,QAAwC,EAAE,MAAoB,EAAE,MAAgC;QACvI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE;YAC3B,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,uBAAuB,EAAE,aAAa,CAAC,CAAC;QAEzE,4DAA4D;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;QAC/E,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,cAAc,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC;QAChG,CAAC,CAAC;QACF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YACpE,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC7B,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;CACF","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 ECDb\r\n */\r\nimport { assert, BeEvent, DbResult, Logger, OpenMode } from \"@itwin/core-bentley\";\r\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\r\nimport { DbQueryRequest, ECSchemaProps, ECSqlReader, IModelError, QueryBinder, QueryOptions } from \"@itwin/core-common\";\r\nimport { serialize } from \"node:v8\";\r\nimport { BackendLoggerCategory } from \"./BackendLoggerCategory\";\r\nimport { ConcurrentQuery } from \"./ConcurrentQuery\";\r\nimport { ECSqlStatement, ECSqlWriteStatement } from \"./ECSqlStatement\";\r\nimport { IModelNative } from \"./internal/NativePlatform\";\r\nimport { SqliteStatement, StatementCache } from \"./SqliteStatement\";\r\nimport { _nativeDb } from \"./internal/Symbols\";\r\nimport { ECSqlRowExecutor, releaseECSqlStatement } from \"./ECSqlRowExecutor\";\r\nimport { ECSqlSyncReader, SynchronousQueryOptions } from \"./ECSqlSyncReader\";\r\n\r\nconst loggerCategory: string = BackendLoggerCategory.ECDb;\r\n\r\n/** Maps a zero-based CSV column to an EC property.\r\n * @beta\r\n */\r\nexport interface CSVColumnMapping {\r\n /** Zero-based index of the source CSV column. */\r\n columnIndex: number;\r\n /** EC property access string to receive the column value. */\r\n propertyName: string;\r\n}\r\n\r\n/** Common options for importing CSV data into an ECClass.\r\n * @beta\r\n */\r\nexport interface CSVImportOptions {\r\n /** Full name or ECSQL name of the ECClass to insert. */\r\n className: string;\r\n /** Source-column to EC-property mappings. Unmapped source columns are ignored. */\r\n mapping: readonly CSVColumnMapping[];\r\n /** Exact CSV value to bind as null. By default, every field is treated as a value. */\r\n nullValue?: string;\r\n}\r\n\r\n/** Options for [[ECDb.importCSVFile]].\r\n * @beta\r\n */\r\nexport interface CSVFileImportOptions extends CSVImportOptions {\r\n /** Whether the first CSV row is a header to skip. Defaults to false. */\r\n hasHeader?: boolean;\r\n}\r\n\r\nfunction validateCSVMapping(mapping: readonly CSVColumnMapping[]): void {\r\n if (0 === mapping.length)\r\n throw new TypeError(\"mapping must not be empty\");\r\n\r\n const columnIndexes = new Set<number>();\r\n for (const entry of mapping) {\r\n if (undefined === entry || null === entry || \"object\" !== typeof entry)\r\n throw new TypeError(\"mapping must contain only objects\");\r\n if (!Number.isSafeInteger(entry.columnIndex) || entry.columnIndex < 0 || entry.columnIndex >= 0xffff_ffff)\r\n throw new TypeError(\"mapping columnIndex values must be non-negative safe integers\");\r\n if (\"string\" !== typeof entry.propertyName || 0 === entry.propertyName.length)\r\n throw new TypeError(\"mapping propertyName values must not be empty\");\r\n if (columnIndexes.has(entry.columnIndex))\r\n throw new TypeError(\"mapping must not contain duplicate columnIndex values\");\r\n columnIndexes.add(entry.columnIndex);\r\n }\r\n}\r\n\r\n/** Modes for how to open [ECDb]($backend) files.\r\n * @public\r\n */\r\nexport enum ECDbOpenMode {\r\n Readonly,\r\n ReadWrite,\r\n /** Opens the file read-write and upgrades the file if necessary to the latest file format version. */\r\n FileUpgrade,\r\n}\r\n\r\n/** An ECDb file\r\n * @public\r\n */\r\nexport class ECDb implements Disposable {\r\n private _nativeDb?: IModelJsNative.ECDb;\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n private readonly _statementCache = new StatementCache<ECSqlStatement>();\r\n private _sqliteStatementCache = new StatementCache<SqliteStatement>();\r\n\r\n /** Event called when the ECDb is about to be closed. */\r\n public readonly onBeforeClose = new BeEvent<() => void>();\r\n\r\n /** only for tests\r\n * @internal\r\n */\r\n public resetSqliteCache(size: number) {\r\n this._sqliteStatementCache.clear();\r\n this._sqliteStatementCache = new StatementCache<SqliteStatement>(size);\r\n }\r\n\r\n constructor() {\r\n this._nativeDb = new IModelNative.platform.ECDb();\r\n }\r\n /** Call this function when finished with this ECDb object. This releases the native resources held by the\r\n * ECDb object.\r\n */\r\n public [Symbol.dispose](): void {\r\n if (!this._nativeDb)\r\n return;\r\n\r\n this.closeDb();\r\n this._nativeDb.dispose();\r\n this._nativeDb = undefined;\r\n }\r\n /**\r\n * Attach an iModel file to this connection and load and register its schemas.\r\n * @note There are some reserve tablespace names that cannot be used. They are 'main', 'schema_sync_db', 'ecchange' & 'temp'\r\n * @param fileName IModel file name\r\n * @param alias identifier for the attached file. This identifer is used to access schema from the attached file. e.g. if alias is 'abc' then schema can be accessed using 'abc.MySchema.MyClass'\r\n */\r\n public attachDb(fileName: string, alias: string): void {\r\n if (alias.toLowerCase() === \"main\" || alias.toLowerCase() === \"schema_sync_db\" || alias.toLowerCase() === \"ecchange\" || alias.toLowerCase() === \"temp\") {\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Reserved tablespace name cannot be used\");\r\n }\r\n this[_nativeDb].attachDb(fileName, alias);\r\n }\r\n /**\r\n * Detach the attached file from this connection. The attached file is closed and its schemas are unregistered.\r\n * @note There are some reserve tablespace names that cannot be used. They are 'main', 'schema_sync_db', 'ecchange' & 'temp'\r\n * @param alias identifer that was used in the call to [[attachDb]]\r\n */\r\n public detachDb(alias: string): void {\r\n if (alias.toLowerCase() === \"main\" || alias.toLowerCase() === \"schema_sync_db\" || alias.toLowerCase() === \"ecchange\" || alias.toLowerCase() === \"temp\") {\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Reserved tablespace name cannot be used\");\r\n }\r\n this.clearCaches();\r\n this[_nativeDb].detachDb(alias);\r\n }\r\n\r\n /** @deprecated in 5.0 - might be removed in next major version. Use [Symbol.dispose] instead. */\r\n public dispose(): void {\r\n this[Symbol.dispose]();\r\n }\r\n\r\n /** Create an ECDb\r\n * @param pathName The path to the ECDb file to create.\r\n * @throws [IModelError]($common) if the operation failed.\r\n */\r\n public createDb(pathName: string): void {\r\n const status: DbResult = this[_nativeDb].createDb(pathName);\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to created ECDb\");\r\n }\r\n\r\n /** Open the ECDb.\r\n * @param pathName The path to the ECDb file to open\r\n * @param openMode Open mode\r\n * @throws [IModelError]($common) if the operation failed.\r\n */\r\n public openDb(pathName: string, openMode: ECDbOpenMode = ECDbOpenMode.Readonly): void {\r\n const nativeOpenMode: OpenMode = openMode === ECDbOpenMode.Readonly ? OpenMode.Readonly : OpenMode.ReadWrite;\r\n const tryUpgrade: boolean = openMode === ECDbOpenMode.FileUpgrade;\r\n const status: DbResult = this[_nativeDb].openDb(pathName, nativeOpenMode, tryUpgrade);\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to open ECDb\");\r\n }\r\n\r\n /** Returns true if the ECDb is open */\r\n public get isOpen(): boolean { return this[_nativeDb].isOpen(); }\r\n\r\n /** Close the Db after saving any uncommitted changes.\r\n * @throws [IModelError]($common) if the database is not open.\r\n */\r\n public closeDb(): void {\r\n this.onBeforeClose.raiseEvent();\r\n this.clearCaches();\r\n this[_nativeDb].closeDb();\r\n }\r\n\r\n /** Clear all in-memory caches held in this ECDb.\r\n * @beta\r\n */\r\n public clearCaches(): void {\r\n this._statementCache.clear();\r\n this._sqliteStatementCache.clear();\r\n this[_nativeDb].clearECDbCache();\r\n }\r\n\r\n /** @internal use to test statement caching */\r\n public clearStatementCache() {\r\n this._statementCache.clear();\r\n }\r\n\r\n /** @internal use to test statement caching */\r\n public getCachedStatementCount() {\r\n return this._statementCache.size;\r\n }\r\n\r\n /** Commit the outermost transaction, writing changes to the file. Then, restart the transaction.\r\n * @param changesetName The name of the operation that generated these changes.\r\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\r\n */\r\n public saveChanges(changesetName?: string): void {\r\n const status: DbResult = this[_nativeDb].saveChanges(changesetName);\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to save changes\");\r\n }\r\n\r\n /** Abandon (cancel) the outermost transaction, discarding all changes since last save. Then, restart the transaction.\r\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\r\n */\r\n public abandonChanges(): void {\r\n const status: DbResult = this[_nativeDb].abandonChanges();\r\n if (status !== DbResult.BE_SQLITE_OK)\r\n throw new IModelError(status, \"Failed to abandon changes\");\r\n }\r\n\r\n /** Import a schema.\r\n *\r\n * If the import was successful, the database is automatically saved to disk.\r\n * @param pathName Path to ECSchema XML file to import.\r\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\r\n */\r\n public importSchema(pathName: string): void {\r\n const status: DbResult = this[_nativeDb].importSchema(pathName);\r\n if (status !== DbResult.BE_SQLITE_OK) {\r\n Logger.logError(loggerCategory, `Failed to import schema from '${pathName}'.`);\r\n throw new IModelError(status, `Failed to import schema from '${pathName}'.`);\r\n }\r\n this.clearCaches();\r\n }\r\n\r\n /** Removes unused schemas from the database.\r\n *\r\n * If the removal was successful, the database is automatically saved to disk.\r\n * @param schemaNames Array of schema names to drop\r\n * @throws [IModelError]($common) if the database if the operation failed.\r\n * @alpha\r\n */\r\n public dropSchemas(schemaNames: string[]): void {\r\n if (schemaNames.length === 0)\r\n return;\r\n // SchemaSync.isEnabled() should be used, but ECDb is not an iModelDb so it has no container props\r\n if (this[_nativeDb].schemaSyncEnabled())\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot drop schemas when schema sync is enabled\");\r\n\r\n try {\r\n this[_nativeDb].dropSchemas(schemaNames);\r\n this.saveChanges('dropped unused schemas');\r\n } catch (error: any) {\r\n Logger.logError(loggerCategory, `Failed to drop schemas: ${error}`);\r\n this.abandonChanges();\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, `Failed to drop schemas: ${error}`);\r\n } finally {\r\n this.clearCaches();\r\n }\r\n }\r\n\r\n /**\r\n * Returns the full schema for the input name.\r\n * @param name The name of the schema e.g. 'ECDbMeta'\r\n * @returns The SchemaProps for the requested schema\r\n * @throws if the schema can not be found or loaded.\r\n */\r\n public getSchemaProps(name: string): ECSchemaProps {\r\n return this[_nativeDb].getSchemaProps(name);\r\n }\r\n\r\n /** Import in-memory CSV rows into an ECClass.\r\n *\r\n * The rows are V8-serialized and processed in one native call. Values are converted from\r\n * their CSV string representation according to the mapped EC property type. One ECSQL\r\n * statement is reused for all rows. Every row must have the same number of columns.\r\n * Boolean fields accept `true`, `false`, `1`, or `0`. Integer fields must contain a\r\n * base-10 value in the signed 32-bit range. Boolean, double, integer, and string EC\r\n * properties are supported. The import is all-or-nothing and callers must call\r\n * [[saveChanges]] to commit it to disk.\r\n * @returns The number of imported rows.\r\n * @beta\r\n */\r\n public importCSVData(rows: readonly (readonly string[])[], options: CSVImportOptions): number {\r\n validateCSVMapping(options.mapping);\r\n return this[_nativeDb].importCSVData(options.className, serialize(rows), options.mapping, { nullValue: options.nullValue });\r\n }\r\n\r\n /** Stream a CSV file into an ECClass.\r\n *\r\n * The file must be UTF-8 encoded; an optional UTF-8 byte-order mark is accepted. It is read\r\n * and parsed in native code, and one ECSQL statement is reused for all rows. Every record must\r\n * have the same number of columns; blank records are not skipped. Boolean fields accept\r\n * `true`, `false`, `1`, or `0`. Integer fields must contain a base-10 value in the signed\r\n * 32-bit range. Boolean, double, integer, and string EC properties are supported. The import\r\n * is all-or-nothing and callers must call [[saveChanges]] to commit it to disk.\r\n * @returns The number of imported rows, excluding an optional header.\r\n * @beta\r\n */\r\n public importCSVFile(csvFilePath: string, options: CSVFileImportOptions): number {\r\n validateCSVMapping(options.mapping);\r\n return this[_nativeDb].importCSVFile(options.className, csvFilePath, options.mapping, {\r\n hasHeader: options.hasHeader,\r\n nullValue: options.nullValue,\r\n });\r\n }\r\n\r\n /**\r\n * Use a prepared ECSQL 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 ECSQL 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 [[withStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withWriteStatement]]\r\n * @beta\r\n */\r\n public withCachedWriteStatement<T>(ecsql: string, callback: (stmt: ECSqlWriteStatement) => T, logErrors = true): T {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const stmt = this._statementCache.findAndRemove(ecsql) ?? this.prepareStatement(ecsql, logErrors);\r\n const release = () => this._statementCache.addOrDispose(stmt);\r\n try {\r\n const val = callback(new ECSqlWriteStatement(stmt));\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\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 * Prepared and execute a callback on an ECSQL statement. After the callback completes the statement is disposed.\r\n * Use this method for ECSQL 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 [[withPreparedStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withCachedWriteStatement]]\r\n * @beta\r\n */\r\n public withWriteStatement<T>(ecsql: string, callback: (stmt: ECSqlWriteStatement) => T, logErrors = true): T {\r\n const stmt = this.prepareWriteStatement(ecsql, logErrors);\r\n const release = () => stmt[Symbol.dispose]();\r\n try {\r\n const val = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /** Prepare an ECSQL statement.\r\n * @param ecsql The ECSQL statement to prepare\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @throws [IModelError]($common) if there is a problem preparing the statement.\r\n * @beta\r\n */\r\n public prepareWriteStatement(ecsql: string, logErrors = true): ECSqlWriteStatement {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n return new ECSqlWriteStatement(this.prepareStatement(ecsql, logErrors));\r\n }\r\n\r\n /**\r\n * Use a prepared ECSQL 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 ECSQL 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 [[withStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withStatement]]\r\n * @public\r\n * @deprecated in 4.11 - might be removed in next major version. Use [[createQueryReader]] for SELECT statements and [[withCachedWriteStatement]] for INSERT/UPDATE/DELETE instead.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n public withPreparedStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors = true): T {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const stmt = this._statementCache.findAndRemove(ecsql) ?? this.prepareStatement(ecsql, logErrors);\r\n const release = () => this._statementCache.addOrDispose(stmt);\r\n try {\r\n const val = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\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 * Prepared and execute a callback on an ECSQL statement. After the callback completes the statement is disposed.\r\n * Use this method for ECSQL 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 [[withPreparedStatement]].\r\n * @param sql The SQLite SQL statement to execute\r\n * @param callback the callback to invoke on the prepared statement\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withPreparedStatement]]\r\n * @public\r\n * @deprecated in 4.11 - might be removed in next major version. Use [[createQueryReader]] for SELECT statements and [[withWriteStatement]] for INSERT/UPDATE/DELETE instead.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n public withStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors = true): T {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const stmt = this.prepareStatement(ecsql, logErrors);\r\n const release = () => stmt[Symbol.dispose]();\r\n try {\r\n const val = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n\r\n /** Prepare an ECSQL statement.\r\n * @param ecsql The ECSQL statement to prepare\r\n * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @throws [IModelError]($common) if there is a problem preparing the statement.\r\n * @deprecated in 4.11 - might be removed in next major version. Use [[prepareWriteStatement]] when preparing an INSERT/UPDATE/DELETE statement or [[createQueryReader]] to execute a SELECT statement.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n public prepareStatement(ecsql: string, logErrors = true): ECSqlStatement {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const stmt = new ECSqlStatement();\r\n stmt.prepare(this[_nativeDb], ecsql, logErrors);\r\n return stmt;\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 * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @see [[withPreparedStatement]]\r\n * @public\r\n */\r\n public withPreparedSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors = true): T {\r\n const stmt = this._sqliteStatementCache.findAndRemove(sql) ?? this.prepareSqliteStatement(sql, logErrors);\r\n const release = () => this._sqliteStatementCache.addOrDispose(stmt);\r\n try {\r\n const val: T = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\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 * Prepared 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 * @param logErrors Determines if error will be logged if statement fail to prepare\r\n * @returns the value returned by `callback`.\r\n * @public\r\n */\r\n public withSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors = true): T {\r\n const stmt = this.prepareSqliteStatement(sql, logErrors);\r\n const release = () => stmt[Symbol.dispose]();\r\n try {\r\n const val: T = callback(stmt);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err) {\r\n release();\r\n throw err;\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 Determines if error will be logged if statement fail to prepare\r\n * @throws [IModelError]($common) if there is a problem preparing the statement.\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 /** @internal */\r\n public get [_nativeDb](): IModelJsNative.ECDb {\r\n assert(undefined !== this._nativeDb);\r\n return this._nativeDb;\r\n }\r\n\r\n /** Allow to execute query and read results along with meta data. The result are streamed.\r\n *\r\n * See also:\r\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\r\n * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)\r\n * - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)\r\n *\r\n * @param params The values to bind to the parameters (if the ECSQL has any).\r\n * @param config Allow to specify certain flags which control how query is executed.\r\n * @returns Returns an [ECSqlReader]($common) which helps iterate over the result set and also give access to metadata.\r\n * @public\r\n * */\r\n public createQueryReader(ecsql: string, params?: QueryBinder, config?: QueryOptions): ECSqlReader {\r\n if (!this._nativeDb || !this._nativeDb.isOpen()) {\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR_NOTOPEN, \"db not open\");\r\n }\r\n const executor = {\r\n execute: async (request: DbQueryRequest) => {\r\n return ConcurrentQuery.executeQueryRequest(this[_nativeDb], request);\r\n },\r\n };\r\n return new ECSqlReader(executor, ecsql, params, config);\r\n }\r\n\r\n /** Allow to execute query and read results along with meta data. The result are stepped one by one.\r\n *\r\n * See also:\r\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\r\n * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)\r\n * - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)\r\n * @param ecsql The ECSQL query to execute.\r\n * @param callback the callback to invoke on the prepared ECSqlSyncReader\r\n * @param params The values to bind to the parameters (if the ECSQL has any).\r\n * @param config Optional flags which control how query is executed.\r\n * @returns the value returned by `callback`.\r\n * @throws IModelError if db is not open or if error occurs during statement execution\r\n * @beta\r\n * */\r\n public withQueryReader<T>(ecsql: string, callback: (reader: ECSqlSyncReader) => T, params?: QueryBinder, config?: SynchronousQueryOptions): T {\r\n if (!this[_nativeDb].isOpen())\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR_NOTOPEN, \"db not open\");\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n const stmt = this._statementCache.findAndRemove(ecsql) ?? new ECSqlStatement();\r\n const executor = new ECSqlRowExecutor(this, stmt, loggerCategory);\r\n const release = () => {\r\n executor[Symbol.dispose]();\r\n releaseECSqlStatement(stmt, this._statementCache, loggerCategory, executor.canCacheStatement);\r\n };\r\n try {\r\n const reader = new ECSqlSyncReader(executor, ecsql, params, config);\r\n const val = callback(reader);\r\n if (val instanceof Promise) {\r\n val.then(release, release);\r\n } else {\r\n release();\r\n }\r\n return val;\r\n } catch (err: any) {\r\n release();\r\n throw err;\r\n }\r\n }\r\n}\r\n"]}
|
package/lib/esm/SchemaSync.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export declare namespace SchemaSync {
|
|
|
40
40
|
private setNextReservedElementLocalId;
|
|
41
41
|
}
|
|
42
42
|
/** The `containerType` recorded on a BlobContainer that holds an iModel's `SchemaSyncDb`. */
|
|
43
|
-
const containerType = "
|
|
43
|
+
const containerType = "schemasync";
|
|
44
44
|
function setTestCache(iModel: IModelDb, cacheName?: string): void;
|
|
45
45
|
/** Either an open iModel or the name of a closed briefcase file. Every local read below accepts both, so
|
|
46
46
|
* a caller that has only a file name does not have to open a `BriefcaseDb` to ask a question about it.
|
|
@@ -176,7 +176,7 @@ export declare namespace SchemaSync {
|
|
|
176
176
|
* @note this deletes any existing content in the container.
|
|
177
177
|
*/
|
|
178
178
|
static initializeDb(props: CloudSqlite.ContainerProps): Promise<void>;
|
|
179
|
-
/** Create and initialize a new `
|
|
179
|
+
/** Create and initialize a new `schemasync` BlobContainer to hold a `SchemaSyncDb`. */
|
|
180
180
|
static createNewContainer(args: CreateNewContainerProps): Promise<CloudSqlite.ContainerProps>;
|
|
181
181
|
}
|
|
182
182
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaSync.d.ts","sourceRoot":"","sources":["../../src/SchemaSync.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAiD,UAAU,EAAQ,UAAU,EAAwB,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAClJ,OAAO,EAAoB,IAAI,EAA2D,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEpI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAI5D,gBAAgB;AAChB,yBAAiB,UAAU,CAAC;IAmB1B,0EAA0E;IAC1E,UAAiB,0BAA0B;QACzC,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC;QACpC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;QAC/B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;QACpB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;KAC/B;IAED,oFAAoF;IACpF,UAAiB,eAAgB,SAAQ,0BAA0B;QACjE,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;KAChC;IAED,UAAiB,WAAW;QAC1B,iEAAiE;QACjE,mBAAmB,CAAC,cAAc,EAAE,UAAU,GAAG,eAAe,GAAG,SAAS,CAAC;KAC9E;IAED,UAAiB,YAAY;QAC3B,wIAAwI;QACxI,eAAe,CAAC,UAAU,EAAE,0BAA0B,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAC1E;IAED,kFAAkF;IAClF,MAAa,YAAa,SAAQ,iBAAkB,YAAW,WAAW,EAAE,YAAY;QACtF,OAAO,CAAC,qBAAqB,CAAC,CAAU;QACxC,SAAyB,SAAS,WAAW;kBAC1B,SAAS;QAIZ,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,WAAW,CAAC,cAAc;QAKvH,OAAO,CAAC,2BAA2B;QAmB5B,mBAAmB,CAAC,cAAc,EAAE,UAAU,GAAG,eAAe,GAAG,SAAS;QAyBnF,OAAO,CAAC,qBAAqB;QAkBhB,eAAe,CAAC,QAAQ,EAAE,0BAA0B,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;QAyCnF,OAAO,CAAC,eAAe;QAMvB,OAAO,CAAC,6BAA6B;QASrC,OAAO,CAAC,6BAA6B;KAGtC;IAID,6FAA6F;IACtF,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"SchemaSync.d.ts","sourceRoot":"","sources":["../../src/SchemaSync.ts"],"names":[],"mappings":"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"}
|
package/lib/esm/SchemaSync.js
CHANGED
|
@@ -149,7 +149,7 @@ export var SchemaSync;
|
|
|
149
149
|
const syncProperty = { namespace: "itwinjs", name: "SchemaSync" };
|
|
150
150
|
const defaultDbName = "SchemaSyncDb";
|
|
151
151
|
/** The `containerType` recorded on a BlobContainer that holds an iModel's `SchemaSyncDb`. */
|
|
152
|
-
SchemaSync.containerType = "
|
|
152
|
+
SchemaSync.containerType = "schemasync";
|
|
153
153
|
const testSyncCachePropKey = "test.schema_sync.cache_name";
|
|
154
154
|
// for tests only
|
|
155
155
|
function setTestCache(iModel, cacheName) {
|
|
@@ -477,7 +477,7 @@ export var SchemaSync;
|
|
|
477
477
|
static async initializeDb(props) {
|
|
478
478
|
return super._initializeDb({ props, dbType: SchemaSyncDb, dbName: defaultDbName });
|
|
479
479
|
}
|
|
480
|
-
/** Create and initialize a new `
|
|
480
|
+
/** Create and initialize a new `schemasync` BlobContainer to hold a `SchemaSyncDb`. */
|
|
481
481
|
static async createNewContainer(args) {
|
|
482
482
|
const props = await this.createBlobContainer({ scope: args.scope, metadata: { ...args.metadata, containerType: SchemaSync.containerType } });
|
|
483
483
|
await this.initializeDb(props);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaSync.js","sourceRoot":"","sources":["../../src/SchemaSync.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module SQLiteDb\r\n */\r\n\r\nimport * as semver from \"semver\";\r\nimport { CloudSqlite } from \"./CloudSqlite\";\r\nimport { SQLiteDb, VersionedSqliteDb } from \"./SQLiteDb\";\r\nimport { BriefcaseDb, IModelDb } from \"./IModelDb\";\r\nimport { BentleyError, ChangeSetStatus, DbResult, Guid, GuidString, Id64, Id64String, IModelStatus, Logger, OpenMode } from \"@itwin/core-bentley\";\r\nimport { BriefcaseIdValue, Code, ElementReservationError, FilePropertyProps, IModelError, LocalFileName } from \"@itwin/core-common\";\r\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\r\nimport type { BlobContainer } from \"./BlobContainerService\";\r\nimport { IModelNative } from \"./internal/NativePlatform\";\r\nimport { _implicitTxn, _nativeDb } from \"./internal/Symbols\";\r\n\r\n/** @internal */\r\nexport namespace SchemaSync {\r\n /** How long a briefcase waits for another briefcase's schema import to finish before giving up.\r\n *\r\n * `nRetries` alone does not bound the wait: when the count runs out `CloudSqlite.withLockedDb` asks\r\n * `onFailure` what to do, and anything other than \"stop\" restarts the whole cycle. Without an\r\n * `onFailure` the caller waits forever with no way to give up, so this supplies one.\r\n */\r\n const lockParams: CloudSqlite.ObtainLockParams = {\r\n retryDelayMs: 6000,\r\n nRetries: 10,\r\n onFailure: async (lockedBy: string, expires: string) => {\r\n Logger.logInfo(\"SchemaSync\", `schema sync container is held by ${lockedBy} until ${expires}; giving up`);\r\n return \"stop\";\r\n },\r\n };\r\n const reservedElementsTableName = \"reserved_elements\";\r\n const maxLocalIdExclusive = 0x10000000000; // 2^40\r\n const idSequenceProp: FilePropertyProps = { namespace: \"schemasync\", name: \"nextReservedElementLocalId\" };\r\n\r\n /** Identifies an element to be reserved in a `SchemaSyncDb`. @internal */\r\n export interface ProposedElementReservation {\r\n readonly federationGuid: GuidString;\r\n readonly ecClassId: Id64String;\r\n readonly code: Code;\r\n readonly isCategory?: boolean;\r\n }\r\n\r\n /** An element reservation that has been persisted in a `SchemaSyncDb`. @internal */\r\n export interface ReservedElement extends ProposedElementReservation {\r\n readonly elementId: Id64String;\r\n }\r\n\r\n export interface ReadMethods {\r\n /** Look up an existing element reservation by federationGuid. */\r\n findReservedElement(federationGuid: GuidString): ReservedElement | undefined;\r\n }\r\n\r\n export interface WriteMethods {\r\n /** Reserve the specified elements in the `SchemaSyncDb`. Throws if any requested reservation conflicts with an existing reservation. */\r\n reserveElements(identities: ProposedElementReservation[]): Promise<void>;\r\n }\r\n\r\n /** A CloudSqlite database for synchronizing schema changes across briefcases. */\r\n export class SchemaSyncDb extends VersionedSqliteDb implements ReadMethods, WriteMethods {\r\n private _supportsReservations?: boolean;\r\n public override readonly myVersion = \"5.0.0\";\r\n protected override createDDL() {\r\n this.ensureReservedElementsTable();\r\n }\r\n\r\n public override openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer) {\r\n super.openDb(dbName, openMode, container);\r\n this._supportsReservations = semver.lte(this.myVersion, semver.minVersion(this.getRequiredVersions().readVersion) ?? \"0.0.0\");\r\n }\r\n\r\n private ensureReservedElementsTable(): void {\r\n if (this._supportsReservations)\r\n return;\r\n\r\n this.executeSQL(`\r\n CREATE TABLE IF NOT EXISTS ${reservedElementsTableName} (\r\n federationGuid BLOB PRIMARY KEY,\r\n elementId INTEGER NOT NULL UNIQUE,\r\n ecClassId INTEGER NOT NULL,\r\n codeSpecId INTEGER NOT NULL,\r\n codeScope TEXT NOT NULL,\r\n codeValue TEXT COLLATE NOCASE\r\n )`);\r\n this.executeSQL(`CREATE UNIQUE INDEX IF NOT EXISTS idx_reserved_elem_code ON ${reservedElementsTableName}(codeSpecId, codeScope, codeValue)`);\r\n const minVersion = `^${this.myVersion}`;\r\n this.setRequiredVersions({ readVersion: minVersion, writeVersion: minVersion });\r\n this._supportsReservations = true;\r\n }\r\n\r\n public findReservedElement(federationGuid: GuidString): ReservedElement | undefined {\r\n if (!this._supportsReservations)\r\n return undefined;\r\n\r\n return this.withPreparedSqliteStatement(\r\n `SELECT elementId, ecClassId, codeSpecId, codeScope, codeValue FROM ${reservedElementsTableName} WHERE federationGuid=?`,\r\n (stmt) => {\r\n stmt.bindGuid(1, federationGuid);\r\n if (!stmt.nextRow())\r\n return undefined;\r\n\r\n return {\r\n federationGuid,\r\n elementId: stmt.getValueId(0),\r\n ecClassId: stmt.getValueId(1),\r\n code: new Code({\r\n spec: stmt.getValueId(2),\r\n scope: stmt.getValueString(3),\r\n value: stmt.getValueStringMaybe(4),\r\n }),\r\n };\r\n },\r\n );\r\n }\r\n\r\n private insertReservedElement(id: ProposedElementReservation, elementId: Id64String): void {\r\n this.withPreparedSqliteStatement(\r\n `INSERT INTO ${reservedElementsTableName} (federationGuid, elementId, ecClassId, codeSpecId, codeScope, codeValue) VALUES (?, ?, ?, ?, ?, ?)`,\r\n (stmt) => {\r\n stmt.bindGuid(1, id.federationGuid);\r\n stmt.bindId(2, elementId);\r\n stmt.bindId(3, id.ecClassId);\r\n stmt.bindId(4, id.code.spec);\r\n stmt.bindString(5, id.code.scope);\r\n if (id.code.value === \"\")\r\n stmt.bindNull(6);\r\n else\r\n stmt.bindString(6, id.code.value);\r\n stmt.stepForWrite();\r\n },\r\n );\r\n }\r\n\r\n public async reserveElements(elements: ProposedElementReservation[]): Promise<void> {\r\n this.ensureReservedElementsTable();\r\n\r\n // Insert new reservations as we go, so later entries in `elements` can dedupe against earlier ones\r\n // through the shared (still-uncommitted) transaction. The caller commits on success and abandons on error.\r\n let nextLocalId = this.getNextReservedElementLocalId();\r\n const firstLocalId = nextLocalId;\r\n\r\n for (const def of elements) {\r\n if (!def.federationGuid || !Guid.isGuid(def.federationGuid)) {\r\n ElementReservationError.throwError(\"invalid-reservation\", {\r\n message: \"Element reservation requires an explicit, valid federationGuid\",\r\n });\r\n }\r\n\r\n // Identity is always the federationGuid. If a reservation already exists for it, it must match exactly.\r\n const existing = this.findReservedElement(def.federationGuid);\r\n if (existing) {\r\n if (!this.existingMatches(existing, def)) {\r\n ElementReservationError.throwError(\"reservation-conflict\", {\r\n message: `Element reservation conflict for federationGuid ${existing.federationGuid}: existing row does not match requested class/code`,\r\n federationGuid: existing.federationGuid,\r\n });\r\n }\r\n continue;\r\n }\r\n\r\n const elementId = Id64.fromLocalAndBriefcaseIds(nextLocalId, BriefcaseIdValue.SchemaSyncElementReserved);\r\n this.insertReservedElement(def, elementId);\r\n // skip a local id for each reserved category because category inserts always trigger a second insert for default subcategory\r\n nextLocalId += def.isCategory ? 2 : 1;\r\n if (nextLocalId >= maxLocalIdExclusive) {\r\n this.abandonChanges();\r\n ElementReservationError.throwError(\"id-sequence-exhausted\", { message: `SchemaSync reserved-element local-id sequence exhausted` });\r\n }\r\n }\r\n\r\n if (nextLocalId !== firstLocalId)\r\n this.setNextReservedElementLocalId(nextLocalId);\r\n }\r\n\r\n private existingMatches(existing: ProposedElementReservation, id: ProposedElementReservation): boolean {\r\n return existing.federationGuid === id.federationGuid\r\n && existing.ecClassId === id.ecClassId\r\n && existing.code.equals(id.code);\r\n }\r\n\r\n private getNextReservedElementLocalId(): number {\r\n const stored = this[_nativeDb].queryFileProperty(idSequenceProp, true) as string | undefined;\r\n const current = stored ? Number(stored) : 1;\r\n if (!Number.isInteger(current) || current < 1)\r\n ElementReservationError.throwError(\"corrupt-reservation-data\", { message: `Corrupt SchemaSync reserved-element local-id counter: '${stored}'` });\r\n\r\n return current;\r\n }\r\n\r\n private setNextReservedElementLocalId(next: number): void {\r\n this[_nativeDb].saveFileProperty(idSequenceProp, String(next));\r\n }\r\n }\r\n\r\n const syncProperty = { namespace: \"itwinjs\", name: \"SchemaSync\" };\r\n const defaultDbName = \"SchemaSyncDb\";\r\n /** The `containerType` recorded on a BlobContainer that holds an iModel's `SchemaSyncDb`. */\r\n export const containerType = \"schema-sync\";\r\n const testSyncCachePropKey = \"test.schema_sync.cache_name\";\r\n // for tests only\r\n export function setTestCache(iModel: IModelDb, cacheName?: string): void {\r\n if (cacheName)\r\n iModel[_nativeDb].saveLocalValue(testSyncCachePropKey, cacheName);\r\n else\r\n iModel[_nativeDb].deleteLocalValue(testSyncCachePropKey);\r\n }\r\n\r\n /** Either an open iModel or the name of a closed briefcase file. Every local read below accepts both, so\r\n * a caller that has only a file name does not have to open a `BriefcaseDb` to ask a question about it.\r\n */\r\n export type IModelOrFileName = IModelDb | { readonly fileName: LocalFileName };\r\n\r\n /** Read from an open iModel, or from a closed file opened readonly for the duration of `operation`. */\r\n function readFromIModel<T>(arg: IModelOrFileName, operation: (nativeDb: IModelJsNative.DgnDb) => T): T {\r\n if (arg instanceof IModelDb)\r\n return operation(arg[_nativeDb]);\r\n\r\n const nativeDb = new IModelNative.platform.DgnDb();\r\n nativeDb.openIModel(arg.fileName, OpenMode.Readonly);\r\n try {\r\n return operation(nativeDb);\r\n } finally {\r\n nativeDb.closeFile();\r\n }\r\n }\r\n\r\n /** Whether this iModel's ECSchemas are governed by a `SchemaSyncDb`.\r\n *\r\n * This is the single question every schema operation branches on. It reads one `be_Prop` row written when\r\n * schema sync was enabled and carried to every other briefcase by that changeset - no cloud access, and it\r\n * works on a readonly briefcase, a checkpoint, or a closed file.\r\n * @note This says nothing about whether the container is reachable, or even named. Use\r\n * [[queryContainerProps]] for that. The two are separate on purpose: a file that says it is governed by a\r\n * sync db must never fall back to importing schemas on its own, whatever state the container is in.\r\n */\r\n export function isEnabled(arg: IModelOrFileName): boolean {\r\n return readFromIModel(arg, (nativeDb) => nativeDb.schemaSyncEnabled());\r\n }\r\n\r\n /** One pass over the values schema sync keeps in the file: which container holds the sync db, plus the\r\n * test-only cache override. Read together so a closed file is opened once.\r\n */\r\n function readLocalSyncProps(arg: IModelOrFileName) {\r\n return readFromIModel(arg, (nativeDb) => {\r\n const propsString = nativeDb.queryFileProperty(syncProperty, true) as string | undefined;\r\n let containerProps: CloudSqlite.ContainerProps | undefined;\r\n if (propsString !== undefined) {\r\n try {\r\n containerProps = JSON.parse(propsString) as CloudSqlite.ContainerProps;\r\n } catch (e) {\r\n // Deliberately not swallowed into `undefined`: that would read as \"schema sync was never\r\n // enabled\" and let this briefcase import schemas on its own.\r\n throw new IModelError(DbResult.BE_SQLITE_CORRUPT, `iModel names a SchemaSyncDb container but the property cannot be read: ${BentleyError.getErrorMessage(e)}`);\r\n }\r\n }\r\n return {\r\n containerProps,\r\n testCacheName: nativeDb.queryLocalValue(testSyncCachePropKey),\r\n };\r\n });\r\n }\r\n\r\n /** The container holding this iModel's `SchemaSyncDb`, or `undefined` if schema sync was never enabled.\r\n *\r\n * Local read of the same `be_Prop` file property that [[initializeForIModel]] wrote. Requesting an access\r\n * token for the container is a separate, asynchronous step.\r\n */\r\n export function queryContainerProps(arg: IModelOrFileName): CloudSqlite.ContainerProps | undefined {\r\n return readLocalSyncProps(arg).containerProps;\r\n }\r\n\r\n interface SharedCloudAccess {\r\n access: CloudAccess;\r\n key: string;\r\n referenceCount: number;\r\n }\r\n\r\n const sharedAccessByContainer = new Map<string, SharedCloudAccess | Promise<SharedCloudAccess>>();\r\n const sharedAccessByInstance = new WeakMap<CloudAccess, SharedCloudAccess>();\r\n\r\n export async function getCloudAccess(arg: IModelOrFileName): Promise<CloudAccess> {\r\n const { containerProps, testCacheName } = readLocalSyncProps(arg);\r\n if (undefined === containerProps)\r\n throw new IModelError(DbResult.BE_SQLITE_NOTFOUND, \"iModel does not have a SchemaSyncDb\");\r\n\r\n const sharedAccessKey = JSON.stringify(containerProps) + (testCacheName ?? \"\");\r\n let shared = sharedAccessByContainer.get(sharedAccessKey);\r\n if (undefined === shared) {\r\n const pending = (async () => {\r\n const accessToken = await CloudSqlite.requestToken(containerProps);\r\n const access = new CloudAccess({ ...containerProps, accessToken });\r\n Object.assign(access.lockParams, lockParams);\r\n if (testCacheName)\r\n access.setCache(CloudSqlite.CloudCaches.getCache({ cacheName: testCacheName }));\r\n\r\n const created = { access, key: sharedAccessKey, referenceCount: 0 };\r\n sharedAccessByInstance.set(access, created);\r\n return created;\r\n })();\r\n sharedAccessByContainer.set(sharedAccessKey, pending);\r\n try {\r\n shared = await pending;\r\n if (sharedAccessByContainer.get(sharedAccessKey) === pending)\r\n sharedAccessByContainer.set(sharedAccessKey, shared);\r\n } catch (error) {\r\n if (sharedAccessByContainer.get(sharedAccessKey) === pending)\r\n sharedAccessByContainer.delete(sharedAccessKey);\r\n throw error;\r\n }\r\n } else if (shared instanceof Promise) {\r\n shared = await shared;\r\n }\r\n\r\n ++shared.referenceCount;\r\n return shared.access;\r\n }\r\n\r\n /** Release an access obtained through [[getCloudAccess]]. */\r\n export function releaseCloudAccess(access: CloudAccess): void {\r\n const shared = sharedAccessByInstance.get(access);\r\n if (undefined === shared) {\r\n access.close();\r\n return;\r\n }\r\n\r\n if (--shared.referenceCount > 0)\r\n return;\r\n\r\n sharedAccessByInstance.delete(access);\r\n if (sharedAccessByContainer.get(shared.key) === shared)\r\n sharedAccessByContainer.delete(shared.key);\r\n access.close();\r\n }\r\n\r\n /** Arguments for [[withLockedAccess]]. */\r\n export interface WithLockedAccessArgs {\r\n operationName: string;\r\n openMode?: OpenMode;\r\n user?: string;\r\n }\r\n\r\n export async function withLockedAccess(iModel: IModelOrFileName, args: WithLockedAccessArgs, operation: (access: CloudAccess) => Promise<void>): Promise<void> {\r\n const access = await SchemaSync.getCloudAccess(iModel);\r\n try {\r\n await access.withLockedDb(args, async () => operation(access));\r\n } finally {\r\n releaseCloudAccess(access);\r\n }\r\n }\r\n\r\n /** Build the tables and indexes the briefcase's `ec_` rows describe. A merged schema changeset carries\r\n * those rows but no DDL, so the physical columns are missing until this runs. Needs no cloud access.\r\n */\r\n export function updateDbSchema(iModel: IModelDb): void {\r\n if (isEnabled(iModel) && !iModel.isReadonly) {\r\n iModel.clearCaches();\r\n iModel[_nativeDb].schemaSyncUpdateDbSchema();\r\n iModel[_implicitTxn].saveChanges(\"materialized db schema from ec_ tables\");\r\n }\r\n }\r\n\r\n /** Whether a failed [[IModelDb.importSchemas]] can be retried through the upgrade path.\r\n *\r\n * The update tier refuses two kinds of change: one that has to move data between columns, and one\r\n * that destroys instances or property values. They arrive as different statuses because they are\r\n * different changes, but they mean one thing to a caller - this needs\r\n * [[BriefcaseDb.upgradeSchemas]], which takes the exclusive schema lock.\r\n *\r\n * The retry is the app's decision, not the platform's: taking that lock disturbs everyone else, so\r\n * only the app knows whether to do it now, schedule it, or tell the user.\r\n * ```ts\r\n * try {\r\n * await db.importSchemas(files);\r\n * } catch (e) {\r\n * if (!SchemaSync.requiresUpgrade(e)) throw e;\r\n * await db.upgradeSchemas(files, { description: \"...\" });\r\n * }\r\n * ```\r\n * @internal\r\n */\r\n export function requiresUpgrade(error: unknown): boolean {\r\n const errorNumber = (error as { errorNumber?: number } | undefined)?.errorNumber;\r\n return errorNumber === DbResult.BE_SQLITE_ERROR_DataTransformRequired\r\n || errorNumber === DbResult.BE_SQLITE_ERROR_DataDeletionRequired;\r\n }\r\n\r\n /** Arguments for [[createContainerForIModel]]. */\r\n export interface CreateContainerForIModelArgs {\r\n iModel: IModelDb;\r\n label?: string;\r\n description?: string;\r\n }\r\n\r\n /** Create a cloud container to hold this iModel's `SchemaSyncDb`, and initialize it as empty.\r\n *\r\n * The container is scoped to the iModel, so the service deletes it when the iModel is deleted. Pass the\r\n * returned props to [[initializeForIModel]] - the two calls together are what enables schema sync on an\r\n * iModel that was created without it.\r\n * @note The current user must be authorized to create containers for the iTwin.\r\n */\r\n export async function createContainerForIModel(arg: CreateContainerForIModelArgs): Promise<CloudSqlite.ContainerProps> {\r\n const iModel = arg.iModel;\r\n const iTwinId = iModel.iTwinId;\r\n if (undefined === iTwinId)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot create a SchemaSync container for an iModel that has no iTwin\");\r\n\r\n return CloudAccess.createNewContainer({\r\n scope: { iTwinId, iModelId: iModel.iModelId },\r\n metadata: { label: arg.label ?? `SchemaSync for ${iModel.name}`, description: arg.description },\r\n });\r\n }\r\n\r\n /** Arguments for [[initializeForIModel]]. */\r\n export interface InitializeForIModelArgs {\r\n iModel: IModelDb;\r\n containerProps: CloudSqlite.ContainerProps;\r\n /** Replace the container already recorded on this iModel instead of failing. */\r\n overrideContainer?: boolean;\r\n }\r\n\r\n /** Refuse initialization before a caller provisions a container, then hold the exclusive schema lock and pull to the tip. */\r\n async function prepareToInitializeForIModel(iModel: IModelDb, overrideContainer: boolean): Promise<BriefcaseDb | undefined> {\r\n const briefcase = iModel instanceof BriefcaseDb ? iModel : undefined;\r\n if (briefcase && !briefcase.locks.isServerBased)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot enable SchemaSync without server-based locking\");\r\n\r\n if (briefcase && (iModel[_nativeDb].hasUnsavedChanges() || briefcase.txns.hasLocalChanges))\r\n throw new IModelError(ChangeSetStatus.HasLocalChanges, \"Cannot enable SchemaSync while there are local changes\");\r\n\r\n const assertContainerCanBeInitialized = () => {\r\n const localInfo = iModel[_nativeDb].schemaSyncGetLocalDbInfo();\r\n if (localInfo && !overrideContainer)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, `Local db already initialized to schema sync (container-id: ${localInfo.id})`);\r\n };\r\n\r\n assertContainerCanBeInitialized();\r\n await iModel.acquireSchemaLock();\r\n await briefcase?.pullChanges();\r\n assertContainerCanBeInitialized();\r\n return briefcase;\r\n }\r\n\r\n async function initializeAfterPreflight(arg: InitializeForIModelArgs, briefcase: BriefcaseDb | undefined): Promise<void> {\r\n const props = { baseUri: arg.containerProps.baseUri, containerId: arg.containerProps.containerId, storageType: arg.containerProps.storageType }; // sanitize to only known properties\r\n const iModel = arg.iModel;\r\n const description = arg.overrideContainer\r\n ? `Overriding SchemaSync for iModel with container-id: ${props.containerId}`\r\n : `Enable SchemaSync for iModel with container-id: ${props.containerId}`;\r\n const txnBeforeInit = briefcase?.txns.getCurrentTxnId();\r\n try {\r\n iModel[_implicitTxn].saveFileProperty(syncProperty, JSON.stringify(props));\r\n try {\r\n await withLockedAccess(iModel, { operationName: \"initialize schemaSync\", openMode: OpenMode.Readonly }, async (syncAccess) => {\r\n iModel[_nativeDb].schemaSyncInit(syncAccess.getUri(), props.containerId, arg.overrideContainer ?? false);\r\n iModel[_implicitTxn].saveChanges(description);\r\n });\r\n } catch (error) {\r\n iModel[_implicitTxn].abandonChanges();\r\n if (briefcase && txnBeforeInit !== undefined && briefcase.txns.getCurrentTxnId() !== txnBeforeInit) {\r\n const status = briefcase[_nativeDb].cancelTo(txnBeforeInit, true);\r\n if (status !== IModelStatus.Success)\r\n Logger.logError(\"SchemaSync\", `Failed to roll back schema sync initialization after the container upload failed: ${IModelStatus[status] ?? status}`);\r\n }\r\n throw error;\r\n }\r\n\r\n // Upload the initialized container before publishing the property that tells every briefcase to use it.\r\n // If the push fails, this briefcase keeps the local txn and exclusive schema lock so the push can be retried.\r\n await briefcase?.pushChanges({ description });\r\n } finally {\r\n iModel[_implicitTxn].abandonChanges();\r\n }\r\n\r\n await iModel.initializeSharedElementReservations();\r\n }\r\n\r\n /** Enable schema sync for an iModel, seeding the container from this briefcase.\r\n * @note Takes the exclusive schema lock, refuses local changes, and pulls the briefcase to the tip before writing the container.\r\n * If this operation fails after acquiring the schema lock, it leaves the lock held.\r\n */\r\n export async function initializeForIModel(arg: InitializeForIModelArgs): Promise<void> {\r\n const briefcase = await prepareToInitializeForIModel(arg.iModel, arg.overrideContainer ?? false);\r\n await initializeAfterPreflight(arg, briefcase);\r\n }\r\n\r\n /** The part of a SchemaSyncDb to restore from an authoritative briefcase. @alpha */\r\n export type RepairScope = \"schemaMetadata\" | \"schemaMetadataAndProfile\";\r\n\r\n const nativeRepairScope: Record<RepairScope, number> = {\r\n schemaMetadata: 0,\r\n schemaMetadataAndProfile: 1,\r\n };\r\n\r\n /** Arguments for [[repairForIModel]]. @alpha */\r\n export interface RepairForIModelArgs {\r\n /** A clean SchemaSync-enabled briefcase at the tip of the iModel timeline. */\r\n iModel: BriefcaseDb;\r\n /** Include the schema-owned EC and BeSQLite profile table definitions. */\r\n scope?: RepairScope;\r\n }\r\n\r\n /** Restore the schema-owned portion of the SchemaSyncDb from a briefcase at the tip of the timeline.\r\n *\r\n * This operation takes the exclusive schema lock and refuses to pull or modify the briefcase. Element\r\n * reservations and all other target-only state in the SchemaSyncDb are preserved.\r\n * @alpha\r\n */\r\n export async function repairForIModel(arg: RepairForIModelArgs): Promise<void> {\r\n const iModel = arg.iModel;\r\n if (!isEnabled(iModel))\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot repair SchemaSync because it is not enabled for this iModel\");\r\n\r\n if (iModel[_nativeDb].hasUnsavedChanges() || iModel.txns.hasLocalChanges)\r\n throw new IModelError(ChangeSetStatus.HasLocalChanges, \"Cannot repair SchemaSync while there are local changes\");\r\n\r\n if (!iModel.locks.isServerBased)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot repair SchemaSync without server-based locking\");\r\n\r\n if (arg.scope !== undefined && arg.scope !== \"schemaMetadata\" && arg.scope !== \"schemaMetadataAndProfile\")\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Unknown SchemaSync repair scope\");\r\n\r\n const briefcaseManagerModule = await import(\"./BriefcaseManager\");\r\n const assertBriefcaseIsAtTip = async () => {\r\n const latestChangeset = await briefcaseManagerModule.BriefcaseManager.getLatestChangeset({ iModelId: iModel.iModelId });\r\n if (latestChangeset.id !== iModel.changeset.id)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot repair SchemaSync from a briefcase that is not at the tip of the iModel timeline\");\r\n };\r\n\r\n // Avoid asking Hub for an exclusive lock it cannot grant to a briefcase that first needs to pull.\r\n await assertBriefcaseIsAtTip();\r\n const schemaLockWasHeld = iModel.holdsSchemaLock;\r\n if (!schemaLockWasHeld)\r\n await iModel.acquireSchemaLock();\r\n try {\r\n // Close the race between the preflight query and acquiring the exclusive lock.\r\n await assertBriefcaseIsAtTip();\r\n const repairScope = nativeRepairScope[arg.scope ?? \"schemaMetadata\"];\r\n await withLockedAccess(iModel, { openMode: OpenMode.Readonly, operationName: \"repair schema sync\" }, async (syncAccess) => {\r\n const nativeDb = iModel[_nativeDb] as IModelJsNative.DgnDb & { schemaSyncRepair(syncDbUri: string, scope: number): void };\r\n nativeDb.schemaSyncRepair(syncAccess.getUri(), repairScope);\r\n });\r\n Logger.logInfo(\"SchemaSync\", `Repaired SchemaSyncDb from changeset ${iModel.changeset.id || \"0\"}`);\r\n } finally {\r\n if (!schemaLockWasHeld)\r\n await iModel.locks.abandonAllLocks();\r\n }\r\n }\r\n\r\n /** Arguments for [[enableForIModel]]. */\r\n export interface EnableForIModelArgs {\r\n iModel: IModelDb;\r\n /** An existing container to use. When omitted one is created for this iModel. */\r\n containerProps?: CloudSqlite.ContainerProps;\r\n /** Replace the container already recorded on this iModel instead of failing. */\r\n overrideContainer?: boolean;\r\n label?: string;\r\n description?: string;\r\n }\r\n\r\n /** Turn schema sync on for an iModel: create the container if needed, record it, and seed it.\r\n *\r\n * The single call callers should use. [[createContainerForIModel]] and [[initializeForIModel]] have\r\n * to happen in this order, and an iModel left between the two is one that names a container nothing\r\n * has seeded.\r\n * @returns the container props recorded on the iModel.\r\n * @note Takes the exclusive schema lock and pushes, same protocol as [[BriefcaseDb.upgradeSchemas]] -\r\n * every operation that changes how a file is governed uses it. If this operation fails after acquiring the schema lock,\r\n * it leaves the lock held.\r\n */\r\n export async function enableForIModel(arg: EnableForIModelArgs): Promise<CloudSqlite.ContainerProps> {\r\n if (undefined === arg.containerProps && undefined === arg.iModel.iTwinId)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot create a SchemaSync container for an iModel that has no iTwin\");\r\n\r\n const briefcase = await prepareToInitializeForIModel(arg.iModel, arg.overrideContainer ?? false);\r\n const containerProps = arg.containerProps\r\n ?? await createContainerForIModel({ iModel: arg.iModel, label: arg.label, description: arg.description });\r\n await initializeAfterPreflight({ iModel: arg.iModel, containerProps, overrideContainer: arg.overrideContainer }, briefcase);\r\n return containerProps;\r\n }\r\n\r\n /** Arguments for [[CloudAccess.createNewContainer]]. */\r\n export interface CreateNewContainerProps {\r\n scope: BlobContainer.Scope;\r\n metadata: Omit<BlobContainer.Metadata, \"containerType\">;\r\n }\r\n\r\n /** Provides access to a cloud-based `SchemaSyncDb` to hold ECSchemas. */\r\n export class CloudAccess extends CloudSqlite.DbAccess<SchemaSyncDb, ReadMethods, WriteMethods> {\r\n public constructor(props: CloudSqlite.ContainerAccessProps) {\r\n super({ dbType: SchemaSyncDb, props, dbName: defaultDbName });\r\n }\r\n\r\n public getUri() {\r\n return `${this.getCloudDb()[_nativeDb].getFilePath()}?vfs=${this.container.cache?.name}&writable=${this.container.isWriteable ? 1 : 0}`;\r\n }\r\n /**\r\n * Initialize a cloud container for use as a SchemaSync. The container must first be created via its storage supplier api (e.g. Azure, or AWS).\r\n * A valid sasToken that grants write access must be supplied. This function creates and uploads an empty ChannelDb into the container.\r\n * @note this deletes any existing content in the container.\r\n */\r\n public static async initializeDb(props: CloudSqlite.ContainerProps) {\r\n return super._initializeDb({ props, dbType: SchemaSyncDb, dbName: defaultDbName });\r\n }\r\n\r\n /** Create and initialize a new `schema-sync` BlobContainer to hold a `SchemaSyncDb`. */\r\n public static async createNewContainer(args: CreateNewContainerProps): Promise<CloudSqlite.ContainerProps> {\r\n const props = await this.createBlobContainer({ scope: args.scope, metadata: { ...args.metadata, containerType } });\r\n await this.initializeDb(props);\r\n return props;\r\n }\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"SchemaSync.js","sourceRoot":"","sources":["../../src/SchemaSync.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAE/F;;GAEG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAY,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAc,IAAI,EAAc,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAClJ,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,uBAAuB,EAAqB,WAAW,EAAiB,MAAM,oBAAoB,CAAC;AAGpI,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE7D,gBAAgB;AAChB,MAAM,KAAW,UAAU,CAmlB1B;AAnlBD,WAAiB,UAAU;IACzB;;;;;OAKG;IACH,MAAM,UAAU,GAAiC;QAC/C,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,EAAE;QACZ,SAAS,EAAE,KAAK,EAAE,QAAgB,EAAE,OAAe,EAAE,EAAE;YACrD,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,oCAAoC,QAAQ,UAAU,OAAO,aAAa,CAAC,CAAC;YACzG,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;IACF,MAAM,yBAAyB,GAAG,mBAAmB,CAAC;IACtD,MAAM,mBAAmB,GAAG,aAAa,CAAC,CAAC,OAAO;IAClD,MAAM,cAAc,GAAsB,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC;IAyB1G,kFAAkF;IAClF,MAAa,YAAa,SAAQ,iBAAiB;QACzC,qBAAqB,CAAW;QACf,SAAS,GAAG,OAAO,CAAC;QAC1B,SAAS;YAC1B,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACrC,CAAC;QAEe,MAAM,CAAC,MAAc,EAAE,QAAwC,EAAE,SAAsC;YACrH,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YAC1C,IAAI,CAAC,qBAAqB,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,CAAC;QAChI,CAAC;QAEO,2BAA2B;YACjC,IAAI,IAAI,CAAC,qBAAqB;gBAC5B,OAAO;YAET,IAAI,CAAC,UAAU,CAAC;qCACe,yBAAyB;;;;;;;UAOpD,CAAC,CAAC;YACN,IAAI,CAAC,UAAU,CAAC,gEAAgE,yBAAyB,oCAAoC,CAAC,CAAC;YAC/I,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACxC,IAAI,CAAC,mBAAmB,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;YAChF,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QACpC,CAAC;QAEM,mBAAmB,CAAC,cAA0B;YACnD,IAAI,CAAC,IAAI,CAAC,qBAAqB;gBAC7B,OAAO,SAAS,CAAC;YAEnB,OAAO,IAAI,CAAC,2BAA2B,CACrC,sEAAsE,yBAAyB,yBAAyB,EACxH,CAAC,IAAI,EAAE,EAAE;gBACP,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;gBACjC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;oBACjB,OAAO,SAAS,CAAC;gBAEnB,OAAO;oBACL,cAAc;oBACd,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;oBAC7B,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;oBAC7B,IAAI,EAAE,IAAI,IAAI,CAAC;wBACb,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;wBACxB,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;wBAC7B,KAAK,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;qBACnC,CAAC;iBACH,CAAC;YACJ,CAAC,CACF,CAAC;QACJ,CAAC;QAEO,qBAAqB,CAAC,EAA8B,EAAE,SAAqB;YACjF,IAAI,CAAC,2BAA2B,CAC9B,eAAe,yBAAyB,qGAAqG,EAC7I,CAAC,IAAI,EAAE,EAAE;gBACP,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC;gBACpC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;gBAC1B,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC;gBAC7B,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC7B,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAClC,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE;oBACtB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;;oBAEjB,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpC,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,CAAC,CACF,CAAC;QACJ,CAAC;QAEM,KAAK,CAAC,eAAe,CAAC,QAAsC;YACjE,IAAI,CAAC,2BAA2B,EAAE,CAAC;YAEnC,mGAAmG;YACnG,2GAA2G;YAC3G,IAAI,WAAW,GAAG,IAAI,CAAC,6BAA6B,EAAE,CAAC;YACvD,MAAM,YAAY,GAAG,WAAW,CAAC;YAEjC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,IAAI,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;oBAC5D,uBAAuB,CAAC,UAAU,CAAC,qBAAqB,EAAE;wBACxD,OAAO,EAAE,gEAAgE;qBAC1E,CAAC,CAAC;gBACL,CAAC;gBAED,wGAAwG;gBACxG,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBAC9D,IAAI,QAAQ,EAAE,CAAC;oBACb,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC;wBACzC,uBAAuB,CAAC,UAAU,CAAC,sBAAsB,EAAE;4BACzD,OAAO,EAAE,mDAAmD,QAAQ,CAAC,cAAc,oDAAoD;4BACvI,cAAc,EAAE,QAAQ,CAAC,cAAc;yBACxC,CAAC,CAAC;oBACL,CAAC;oBACD,SAAS;gBACX,CAAC;gBAED,MAAM,SAAS,GAAG,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE,gBAAgB,CAAC,yBAAyB,CAAC,CAAC;gBACzG,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAC3C,6HAA6H;gBAC7H,WAAW,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtC,IAAI,WAAW,IAAI,mBAAmB,EAAE,CAAC;oBACvC,IAAI,CAAC,cAAc,EAAE,CAAC;oBACtB,uBAAuB,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,OAAO,EAAE,yDAAyD,EAAE,CAAC,CAAC;gBACtI,CAAC;YACH,CAAC;YAED,IAAI,WAAW,KAAK,YAAY;gBAC9B,IAAI,CAAC,6BAA6B,CAAC,WAAW,CAAC,CAAC;QACpD,CAAC;QAEO,eAAe,CAAC,QAAoC,EAAE,EAA8B;YAC1F,OAAO,QAAQ,CAAC,cAAc,KAAK,EAAE,CAAC,cAAc;mBAC/C,QAAQ,CAAC,SAAS,KAAK,EAAE,CAAC,SAAS;mBACnC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QAEO,6BAA6B;YACnC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,cAAc,EAAE,IAAI,CAAuB,CAAC;YAC7F,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC;gBAC3C,uBAAuB,CAAC,UAAU,CAAC,0BAA0B,EAAE,EAAE,OAAO,EAAE,0DAA0D,MAAM,GAAG,EAAE,CAAC,CAAC;YAEnJ,OAAO,OAAO,CAAC;QACjB,CAAC;QAEO,6BAA6B,CAAC,IAAY;YAChD,IAAI,CAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACjE,CAAC;KACF;IArIY,uBAAY,eAqIxB,CAAA;IAED,MAAM,YAAY,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAClE,MAAM,aAAa,GAAG,cAAc,CAAC;IACrC,6FAA6F;IAChF,wBAAa,GAAG,YAAY,CAAC;IAC1C,MAAM,oBAAoB,GAAG,6BAA6B,CAAC;IAC3D,iBAAiB;IACjB,SAAgB,YAAY,CAAC,MAAgB,EAAE,SAAkB;QAC/D,IAAI,SAAS;YACX,MAAM,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;;YAElE,MAAM,CAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAC;IAC7D,CAAC;IALe,uBAAY,eAK3B,CAAA;IAOD,uGAAuG;IACvG,SAAS,cAAc,CAAI,GAAqB,EAAE,SAAgD;QAChG,IAAI,GAAG,YAAY,QAAQ;YACzB,OAAO,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;QAEnC,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnD,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAI,CAAC;YACH,OAAO,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;gBAAS,CAAC;YACT,QAAQ,CAAC,SAAS,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,SAAgB,SAAS,CAAC,GAAqB;QAC7C,OAAO,cAAc,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACzE,CAAC;IAFe,oBAAS,YAExB,CAAA;IAED;;OAEG;IACH,SAAS,kBAAkB,CAAC,GAAqB;QAC/C,OAAO,cAAc,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE;YACtC,MAAM,WAAW,GAAG,QAAQ,CAAC,iBAAiB,CAAC,YAAY,EAAE,IAAI,CAAuB,CAAC;YACzF,IAAI,cAAsD,CAAC;YAC3D,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC9B,IAAI,CAAC;oBACH,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAA+B,CAAC;gBACzE,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,yFAAyF;oBACzF,6DAA6D;oBAC7D,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,iBAAiB,EAAE,0EAA0E,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACjK,CAAC;YACH,CAAC;YACD,OAAO;gBACL,cAAc;gBACd,aAAa,EAAE,QAAQ,CAAC,eAAe,CAAC,oBAAoB,CAAC;aAC9D,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,SAAgB,mBAAmB,CAAC,GAAqB;QACvD,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC;IAChD,CAAC;IAFe,8BAAmB,sBAElC,CAAA;IAQD,MAAM,uBAAuB,GAAG,IAAI,GAAG,EAA0D,CAAC;IAClG,MAAM,sBAAsB,GAAG,IAAI,OAAO,EAAkC,CAAC;IAEtE,KAAK,UAAU,cAAc,CAAC,GAAqB;QACxD,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAClE,IAAI,SAAS,KAAK,cAAc;YAC9B,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,kBAAkB,EAAE,qCAAqC,CAAC,CAAC;QAE5F,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QAC/E,IAAI,MAAM,GAAG,uBAAuB,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC1D,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;gBAC1B,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;gBACnE,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,EAAE,GAAG,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;gBACnE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;gBAC7C,IAAI,aAAa;oBACf,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;gBAElF,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;gBACpE,sBAAsB,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC5C,OAAO,OAAO,CAAC;YACjB,CAAC,CAAC,EAAE,CAAC;YACL,uBAAuB,CAAC,GAAG,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;YACtD,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,OAAO,CAAC;gBACvB,IAAI,uBAAuB,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,OAAO;oBAC1D,uBAAuB,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;YACzD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,uBAAuB,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,OAAO;oBAC1D,uBAAuB,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;gBAClD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;YACrC,MAAM,GAAG,MAAM,MAAM,CAAC;QACxB,CAAC;QAED,EAAE,MAAM,CAAC,cAAc,CAAC;QACxB,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;IAnCqB,yBAAc,iBAmCnC,CAAA;IAED,6DAA6D;IAC7D,SAAgB,kBAAkB,CAAC,MAAmB;QACpD,MAAM,MAAM,GAAG,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAClD,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YACzB,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,IAAI,EAAE,MAAM,CAAC,cAAc,GAAG,CAAC;YAC7B,OAAO;QAET,sBAAsB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,uBAAuB,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,MAAM;YACpD,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IAde,6BAAkB,qBAcjC,CAAA;IASM,KAAK,UAAU,gBAAgB,CAAC,MAAwB,EAAE,IAA0B,EAAE,SAAiD;QAC5I,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QACjE,CAAC;gBAAS,CAAC;YACT,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAPqB,2BAAgB,mBAOrC,CAAA;IAED;;OAEG;IACH,SAAgB,cAAc,CAAC,MAAgB;QAC7C,IAAI,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC5C,MAAM,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,CAAC,SAAS,CAAC,CAAC,wBAAwB,EAAE,CAAC;YAC7C,MAAM,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,wCAAwC,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IANe,yBAAc,iBAM7B,CAAA;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAgB,eAAe,CAAC,KAAc;QAC5C,MAAM,WAAW,GAAI,KAA8C,EAAE,WAAW,CAAC;QACjF,OAAO,WAAW,KAAK,QAAQ,CAAC,qCAAqC;eAChE,WAAW,KAAK,QAAQ,CAAC,oCAAoC,CAAC;IACrE,CAAC;IAJe,0BAAe,kBAI9B,CAAA;IASD;;;;;;OAMG;IACI,KAAK,UAAU,wBAAwB,CAAC,GAAiC;QAC9E,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAC1B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC/B,IAAI,SAAS,KAAK,OAAO;YACvB,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,sEAAsE,CAAC,CAAC;QAE1H,OAAO,WAAW,CAAC,kBAAkB,CAAC;YACpC,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE;YAC7C,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,kBAAkB,MAAM,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE;SAChG,CAAC,CAAC;IACL,CAAC;IAVqB,mCAAwB,2BAU7C,CAAA;IAUD,6HAA6H;IAC7H,KAAK,UAAU,4BAA4B,CAAC,MAAgB,EAAE,iBAA0B;QACtF,MAAM,SAAS,GAAG,MAAM,YAAY,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QACrE,IAAI,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa;YAC7C,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,uDAAuD,CAAC,CAAC;QAE3G,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,iBAAiB,EAAE,IAAI,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC;YACxF,MAAM,IAAI,WAAW,CAAC,eAAe,CAAC,eAAe,EAAE,wDAAwD,CAAC,CAAC;QAEnH,MAAM,+BAA+B,GAAG,GAAG,EAAE;YAC3C,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,wBAAwB,EAAE,CAAC;YAC/D,IAAI,SAAS,IAAI,CAAC,iBAAiB;gBACjC,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,8DAA8D,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC;QACnI,CAAC,CAAC;QAEF,+BAA+B,EAAE,CAAC;QAClC,MAAM,MAAM,CAAC,iBAAiB,EAAE,CAAC;QACjC,MAAM,SAAS,EAAE,WAAW,EAAE,CAAC;QAC/B,+BAA+B,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,UAAU,wBAAwB,CAAC,GAA4B,EAAE,SAAkC;QACtG,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,CAAC,cAAc,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC,oCAAoC;QACrL,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAC1B,MAAM,WAAW,GAAG,GAAG,CAAC,iBAAiB;YACvC,CAAC,CAAC,uDAAuD,KAAK,CAAC,WAAW,EAAE;YAC5E,CAAC,CAAC,mDAAmD,KAAK,CAAC,WAAW,EAAE,CAAC;QAC3E,MAAM,aAAa,GAAG,SAAS,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,CAAC,YAAY,CAAC,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3E,IAAI,CAAC;gBACH,MAAM,gBAAgB,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,uBAAuB,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;oBAC3H,MAAM,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC,iBAAiB,IAAI,KAAK,CAAC,CAAC;oBACzG,MAAM,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;gBAChD,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,YAAY,CAAC,CAAC,cAAc,EAAE,CAAC;gBACtC,IAAI,SAAS,IAAI,aAAa,KAAK,SAAS,IAAI,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,aAAa,EAAE,CAAC;oBACnG,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;oBAClE,IAAI,MAAM,KAAK,YAAY,CAAC,OAAO;wBACjC,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,qFAAqF,YAAY,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC;gBACzJ,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;YAED,wGAAwG;YACxG,8GAA8G;YAC9G,MAAM,SAAS,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;QAChD,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,YAAY,CAAC,CAAC,cAAc,EAAE,CAAC;QACxC,CAAC;QAED,MAAM,MAAM,CAAC,mCAAmC,EAAE,CAAC;IACrD,CAAC;IAED;;;OAGG;IACI,KAAK,UAAU,mBAAmB,CAAC,GAA4B;QACpE,MAAM,SAAS,GAAG,MAAM,4BAA4B,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,iBAAiB,IAAI,KAAK,CAAC,CAAC;QACjG,MAAM,wBAAwB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACjD,CAAC;IAHqB,8BAAmB,sBAGxC,CAAA;IAKD,MAAM,iBAAiB,GAAgC;QACrD,cAAc,EAAE,CAAC;QACjB,wBAAwB,EAAE,CAAC;KAC5B,CAAC;IAUF;;;;;OAKG;IACI,KAAK,UAAU,eAAe,CAAC,GAAwB;QAC5D,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;YACpB,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,oEAAoE,CAAC,CAAC;QAExH,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,iBAAiB,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe;YACtE,MAAM,IAAI,WAAW,CAAC,eAAe,CAAC,eAAe,EAAE,wDAAwD,CAAC,CAAC;QAEnH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa;YAC7B,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,uDAAuD,CAAC,CAAC;QAE3G,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,KAAK,KAAK,gBAAgB,IAAI,GAAG,CAAC,KAAK,KAAK,0BAA0B;YACvG,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,iCAAiC,CAAC,CAAC;QAErF,MAAM,sBAAsB,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAClE,MAAM,sBAAsB,GAAG,KAAK,IAAI,EAAE;YACxC,MAAM,eAAe,GAAG,MAAM,sBAAsB,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACxH,IAAI,eAAe,CAAC,EAAE,KAAK,MAAM,CAAC,SAAS,CAAC,EAAE;gBAC5C,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,yFAAyF,CAAC,CAAC;QAC/I,CAAC,CAAC;QAEF,kGAAkG;QAClG,MAAM,sBAAsB,EAAE,CAAC;QAC/B,MAAM,iBAAiB,GAAG,MAAM,CAAC,eAAe,CAAC;QACjD,IAAI,CAAC,iBAAiB;YACpB,MAAM,MAAM,CAAC,iBAAiB,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,+EAA+E;YAC/E,MAAM,sBAAsB,EAAE,CAAC;YAC/B,MAAM,WAAW,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,IAAI,gBAAgB,CAAC,CAAC;YACrE,MAAM,gBAAgB,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,aAAa,EAAE,oBAAoB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBACxH,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAwF,CAAC;gBAC1H,QAAQ,CAAC,gBAAgB,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC;YAC9D,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,wCAAwC,MAAM,CAAC,SAAS,CAAC,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACrG,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,iBAAiB;gBACpB,MAAM,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;QACzC,CAAC;IACH,CAAC;IAvCqB,0BAAe,kBAuCpC,CAAA;IAaD;;;;;;;;;OASG;IACI,KAAK,UAAU,eAAe,CAAC,GAAwB;QAC5D,IAAI,SAAS,KAAK,GAAG,CAAC,cAAc,IAAI,SAAS,KAAK,GAAG,CAAC,MAAM,CAAC,OAAO;YACtE,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,sEAAsE,CAAC,CAAC;QAE1H,MAAM,SAAS,GAAG,MAAM,4BAA4B,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,iBAAiB,IAAI,KAAK,CAAC,CAAC;QACjG,MAAM,cAAc,GAAG,GAAG,CAAC,cAAc;eACpC,MAAM,wBAAwB,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5G,MAAM,wBAAwB,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,EAAE,EAAE,SAAS,CAAC,CAAC;QAC5H,OAAO,cAAc,CAAC;IACxB,CAAC;IATqB,0BAAe,kBASpC,CAAA;IAQD,0EAA0E;IAC1E,MAAa,WAAY,SAAQ,WAAW,CAAC,QAAiD;QAC5F,YAAmB,KAAuC;YACxD,KAAK,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;QAChE,CAAC;QAEM,MAAM;YACX,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,QAAQ,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,aAAa,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1I,CAAC;QACD;;;;SAIC;QACM,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,KAAiC;YAChE,OAAO,KAAK,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;QACrF,CAAC;QAED,uFAAuF;QAChF,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAA6B;YAClE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAb,WAAA,aAAa,EAAE,EAAE,CAAC,CAAC;YACnH,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YAC/B,OAAO,KAAK,CAAC;QACf,CAAC;KACF;IAvBY,sBAAW,cAuBvB,CAAA;AACH,CAAC,EAnlBgB,UAAU,KAAV,UAAU,QAmlB1B","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module SQLiteDb\r\n */\r\n\r\nimport * as semver from \"semver\";\r\nimport { CloudSqlite } from \"./CloudSqlite\";\r\nimport { SQLiteDb, VersionedSqliteDb } from \"./SQLiteDb\";\r\nimport { BriefcaseDb, IModelDb } from \"./IModelDb\";\r\nimport { BentleyError, ChangeSetStatus, DbResult, Guid, GuidString, Id64, Id64String, IModelStatus, Logger, OpenMode } from \"@itwin/core-bentley\";\r\nimport { BriefcaseIdValue, Code, ElementReservationError, FilePropertyProps, IModelError, LocalFileName } from \"@itwin/core-common\";\r\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\r\nimport type { BlobContainer } from \"./BlobContainerService\";\r\nimport { IModelNative } from \"./internal/NativePlatform\";\r\nimport { _implicitTxn, _nativeDb } from \"./internal/Symbols\";\r\n\r\n/** @internal */\r\nexport namespace SchemaSync {\r\n /** How long a briefcase waits for another briefcase's schema import to finish before giving up.\r\n *\r\n * `nRetries` alone does not bound the wait: when the count runs out `CloudSqlite.withLockedDb` asks\r\n * `onFailure` what to do, and anything other than \"stop\" restarts the whole cycle. Without an\r\n * `onFailure` the caller waits forever with no way to give up, so this supplies one.\r\n */\r\n const lockParams: CloudSqlite.ObtainLockParams = {\r\n retryDelayMs: 6000,\r\n nRetries: 10,\r\n onFailure: async (lockedBy: string, expires: string) => {\r\n Logger.logInfo(\"SchemaSync\", `schema sync container is held by ${lockedBy} until ${expires}; giving up`);\r\n return \"stop\";\r\n },\r\n };\r\n const reservedElementsTableName = \"reserved_elements\";\r\n const maxLocalIdExclusive = 0x10000000000; // 2^40\r\n const idSequenceProp: FilePropertyProps = { namespace: \"schemasync\", name: \"nextReservedElementLocalId\" };\r\n\r\n /** Identifies an element to be reserved in a `SchemaSyncDb`. @internal */\r\n export interface ProposedElementReservation {\r\n readonly federationGuid: GuidString;\r\n readonly ecClassId: Id64String;\r\n readonly code: Code;\r\n readonly isCategory?: boolean;\r\n }\r\n\r\n /** An element reservation that has been persisted in a `SchemaSyncDb`. @internal */\r\n export interface ReservedElement extends ProposedElementReservation {\r\n readonly elementId: Id64String;\r\n }\r\n\r\n export interface ReadMethods {\r\n /** Look up an existing element reservation by federationGuid. */\r\n findReservedElement(federationGuid: GuidString): ReservedElement | undefined;\r\n }\r\n\r\n export interface WriteMethods {\r\n /** Reserve the specified elements in the `SchemaSyncDb`. Throws if any requested reservation conflicts with an existing reservation. */\r\n reserveElements(identities: ProposedElementReservation[]): Promise<void>;\r\n }\r\n\r\n /** A CloudSqlite database for synchronizing schema changes across briefcases. */\r\n export class SchemaSyncDb extends VersionedSqliteDb implements ReadMethods, WriteMethods {\r\n private _supportsReservations?: boolean;\r\n public override readonly myVersion = \"5.0.0\";\r\n protected override createDDL() {\r\n this.ensureReservedElementsTable();\r\n }\r\n\r\n public override openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer) {\r\n super.openDb(dbName, openMode, container);\r\n this._supportsReservations = semver.lte(this.myVersion, semver.minVersion(this.getRequiredVersions().readVersion) ?? \"0.0.0\");\r\n }\r\n\r\n private ensureReservedElementsTable(): void {\r\n if (this._supportsReservations)\r\n return;\r\n\r\n this.executeSQL(`\r\n CREATE TABLE IF NOT EXISTS ${reservedElementsTableName} (\r\n federationGuid BLOB PRIMARY KEY,\r\n elementId INTEGER NOT NULL UNIQUE,\r\n ecClassId INTEGER NOT NULL,\r\n codeSpecId INTEGER NOT NULL,\r\n codeScope TEXT NOT NULL,\r\n codeValue TEXT COLLATE NOCASE\r\n )`);\r\n this.executeSQL(`CREATE UNIQUE INDEX IF NOT EXISTS idx_reserved_elem_code ON ${reservedElementsTableName}(codeSpecId, codeScope, codeValue)`);\r\n const minVersion = `^${this.myVersion}`;\r\n this.setRequiredVersions({ readVersion: minVersion, writeVersion: minVersion });\r\n this._supportsReservations = true;\r\n }\r\n\r\n public findReservedElement(federationGuid: GuidString): ReservedElement | undefined {\r\n if (!this._supportsReservations)\r\n return undefined;\r\n\r\n return this.withPreparedSqliteStatement(\r\n `SELECT elementId, ecClassId, codeSpecId, codeScope, codeValue FROM ${reservedElementsTableName} WHERE federationGuid=?`,\r\n (stmt) => {\r\n stmt.bindGuid(1, federationGuid);\r\n if (!stmt.nextRow())\r\n return undefined;\r\n\r\n return {\r\n federationGuid,\r\n elementId: stmt.getValueId(0),\r\n ecClassId: stmt.getValueId(1),\r\n code: new Code({\r\n spec: stmt.getValueId(2),\r\n scope: stmt.getValueString(3),\r\n value: stmt.getValueStringMaybe(4),\r\n }),\r\n };\r\n },\r\n );\r\n }\r\n\r\n private insertReservedElement(id: ProposedElementReservation, elementId: Id64String): void {\r\n this.withPreparedSqliteStatement(\r\n `INSERT INTO ${reservedElementsTableName} (federationGuid, elementId, ecClassId, codeSpecId, codeScope, codeValue) VALUES (?, ?, ?, ?, ?, ?)`,\r\n (stmt) => {\r\n stmt.bindGuid(1, id.federationGuid);\r\n stmt.bindId(2, elementId);\r\n stmt.bindId(3, id.ecClassId);\r\n stmt.bindId(4, id.code.spec);\r\n stmt.bindString(5, id.code.scope);\r\n if (id.code.value === \"\")\r\n stmt.bindNull(6);\r\n else\r\n stmt.bindString(6, id.code.value);\r\n stmt.stepForWrite();\r\n },\r\n );\r\n }\r\n\r\n public async reserveElements(elements: ProposedElementReservation[]): Promise<void> {\r\n this.ensureReservedElementsTable();\r\n\r\n // Insert new reservations as we go, so later entries in `elements` can dedupe against earlier ones\r\n // through the shared (still-uncommitted) transaction. The caller commits on success and abandons on error.\r\n let nextLocalId = this.getNextReservedElementLocalId();\r\n const firstLocalId = nextLocalId;\r\n\r\n for (const def of elements) {\r\n if (!def.federationGuid || !Guid.isGuid(def.federationGuid)) {\r\n ElementReservationError.throwError(\"invalid-reservation\", {\r\n message: \"Element reservation requires an explicit, valid federationGuid\",\r\n });\r\n }\r\n\r\n // Identity is always the federationGuid. If a reservation already exists for it, it must match exactly.\r\n const existing = this.findReservedElement(def.federationGuid);\r\n if (existing) {\r\n if (!this.existingMatches(existing, def)) {\r\n ElementReservationError.throwError(\"reservation-conflict\", {\r\n message: `Element reservation conflict for federationGuid ${existing.federationGuid}: existing row does not match requested class/code`,\r\n federationGuid: existing.federationGuid,\r\n });\r\n }\r\n continue;\r\n }\r\n\r\n const elementId = Id64.fromLocalAndBriefcaseIds(nextLocalId, BriefcaseIdValue.SchemaSyncElementReserved);\r\n this.insertReservedElement(def, elementId);\r\n // skip a local id for each reserved category because category inserts always trigger a second insert for default subcategory\r\n nextLocalId += def.isCategory ? 2 : 1;\r\n if (nextLocalId >= maxLocalIdExclusive) {\r\n this.abandonChanges();\r\n ElementReservationError.throwError(\"id-sequence-exhausted\", { message: `SchemaSync reserved-element local-id sequence exhausted` });\r\n }\r\n }\r\n\r\n if (nextLocalId !== firstLocalId)\r\n this.setNextReservedElementLocalId(nextLocalId);\r\n }\r\n\r\n private existingMatches(existing: ProposedElementReservation, id: ProposedElementReservation): boolean {\r\n return existing.federationGuid === id.federationGuid\r\n && existing.ecClassId === id.ecClassId\r\n && existing.code.equals(id.code);\r\n }\r\n\r\n private getNextReservedElementLocalId(): number {\r\n const stored = this[_nativeDb].queryFileProperty(idSequenceProp, true) as string | undefined;\r\n const current = stored ? Number(stored) : 1;\r\n if (!Number.isInteger(current) || current < 1)\r\n ElementReservationError.throwError(\"corrupt-reservation-data\", { message: `Corrupt SchemaSync reserved-element local-id counter: '${stored}'` });\r\n\r\n return current;\r\n }\r\n\r\n private setNextReservedElementLocalId(next: number): void {\r\n this[_nativeDb].saveFileProperty(idSequenceProp, String(next));\r\n }\r\n }\r\n\r\n const syncProperty = { namespace: \"itwinjs\", name: \"SchemaSync\" };\r\n const defaultDbName = \"SchemaSyncDb\";\r\n /** The `containerType` recorded on a BlobContainer that holds an iModel's `SchemaSyncDb`. */\r\n export const containerType = \"schemasync\";\r\n const testSyncCachePropKey = \"test.schema_sync.cache_name\";\r\n // for tests only\r\n export function setTestCache(iModel: IModelDb, cacheName?: string): void {\r\n if (cacheName)\r\n iModel[_nativeDb].saveLocalValue(testSyncCachePropKey, cacheName);\r\n else\r\n iModel[_nativeDb].deleteLocalValue(testSyncCachePropKey);\r\n }\r\n\r\n /** Either an open iModel or the name of a closed briefcase file. Every local read below accepts both, so\r\n * a caller that has only a file name does not have to open a `BriefcaseDb` to ask a question about it.\r\n */\r\n export type IModelOrFileName = IModelDb | { readonly fileName: LocalFileName };\r\n\r\n /** Read from an open iModel, or from a closed file opened readonly for the duration of `operation`. */\r\n function readFromIModel<T>(arg: IModelOrFileName, operation: (nativeDb: IModelJsNative.DgnDb) => T): T {\r\n if (arg instanceof IModelDb)\r\n return operation(arg[_nativeDb]);\r\n\r\n const nativeDb = new IModelNative.platform.DgnDb();\r\n nativeDb.openIModel(arg.fileName, OpenMode.Readonly);\r\n try {\r\n return operation(nativeDb);\r\n } finally {\r\n nativeDb.closeFile();\r\n }\r\n }\r\n\r\n /** Whether this iModel's ECSchemas are governed by a `SchemaSyncDb`.\r\n *\r\n * This is the single question every schema operation branches on. It reads one `be_Prop` row written when\r\n * schema sync was enabled and carried to every other briefcase by that changeset - no cloud access, and it\r\n * works on a readonly briefcase, a checkpoint, or a closed file.\r\n * @note This says nothing about whether the container is reachable, or even named. Use\r\n * [[queryContainerProps]] for that. The two are separate on purpose: a file that says it is governed by a\r\n * sync db must never fall back to importing schemas on its own, whatever state the container is in.\r\n */\r\n export function isEnabled(arg: IModelOrFileName): boolean {\r\n return readFromIModel(arg, (nativeDb) => nativeDb.schemaSyncEnabled());\r\n }\r\n\r\n /** One pass over the values schema sync keeps in the file: which container holds the sync db, plus the\r\n * test-only cache override. Read together so a closed file is opened once.\r\n */\r\n function readLocalSyncProps(arg: IModelOrFileName) {\r\n return readFromIModel(arg, (nativeDb) => {\r\n const propsString = nativeDb.queryFileProperty(syncProperty, true) as string | undefined;\r\n let containerProps: CloudSqlite.ContainerProps | undefined;\r\n if (propsString !== undefined) {\r\n try {\r\n containerProps = JSON.parse(propsString) as CloudSqlite.ContainerProps;\r\n } catch (e) {\r\n // Deliberately not swallowed into `undefined`: that would read as \"schema sync was never\r\n // enabled\" and let this briefcase import schemas on its own.\r\n throw new IModelError(DbResult.BE_SQLITE_CORRUPT, `iModel names a SchemaSyncDb container but the property cannot be read: ${BentleyError.getErrorMessage(e)}`);\r\n }\r\n }\r\n return {\r\n containerProps,\r\n testCacheName: nativeDb.queryLocalValue(testSyncCachePropKey),\r\n };\r\n });\r\n }\r\n\r\n /** The container holding this iModel's `SchemaSyncDb`, or `undefined` if schema sync was never enabled.\r\n *\r\n * Local read of the same `be_Prop` file property that [[initializeForIModel]] wrote. Requesting an access\r\n * token for the container is a separate, asynchronous step.\r\n */\r\n export function queryContainerProps(arg: IModelOrFileName): CloudSqlite.ContainerProps | undefined {\r\n return readLocalSyncProps(arg).containerProps;\r\n }\r\n\r\n interface SharedCloudAccess {\r\n access: CloudAccess;\r\n key: string;\r\n referenceCount: number;\r\n }\r\n\r\n const sharedAccessByContainer = new Map<string, SharedCloudAccess | Promise<SharedCloudAccess>>();\r\n const sharedAccessByInstance = new WeakMap<CloudAccess, SharedCloudAccess>();\r\n\r\n export async function getCloudAccess(arg: IModelOrFileName): Promise<CloudAccess> {\r\n const { containerProps, testCacheName } = readLocalSyncProps(arg);\r\n if (undefined === containerProps)\r\n throw new IModelError(DbResult.BE_SQLITE_NOTFOUND, \"iModel does not have a SchemaSyncDb\");\r\n\r\n const sharedAccessKey = JSON.stringify(containerProps) + (testCacheName ?? \"\");\r\n let shared = sharedAccessByContainer.get(sharedAccessKey);\r\n if (undefined === shared) {\r\n const pending = (async () => {\r\n const accessToken = await CloudSqlite.requestToken(containerProps);\r\n const access = new CloudAccess({ ...containerProps, accessToken });\r\n Object.assign(access.lockParams, lockParams);\r\n if (testCacheName)\r\n access.setCache(CloudSqlite.CloudCaches.getCache({ cacheName: testCacheName }));\r\n\r\n const created = { access, key: sharedAccessKey, referenceCount: 0 };\r\n sharedAccessByInstance.set(access, created);\r\n return created;\r\n })();\r\n sharedAccessByContainer.set(sharedAccessKey, pending);\r\n try {\r\n shared = await pending;\r\n if (sharedAccessByContainer.get(sharedAccessKey) === pending)\r\n sharedAccessByContainer.set(sharedAccessKey, shared);\r\n } catch (error) {\r\n if (sharedAccessByContainer.get(sharedAccessKey) === pending)\r\n sharedAccessByContainer.delete(sharedAccessKey);\r\n throw error;\r\n }\r\n } else if (shared instanceof Promise) {\r\n shared = await shared;\r\n }\r\n\r\n ++shared.referenceCount;\r\n return shared.access;\r\n }\r\n\r\n /** Release an access obtained through [[getCloudAccess]]. */\r\n export function releaseCloudAccess(access: CloudAccess): void {\r\n const shared = sharedAccessByInstance.get(access);\r\n if (undefined === shared) {\r\n access.close();\r\n return;\r\n }\r\n\r\n if (--shared.referenceCount > 0)\r\n return;\r\n\r\n sharedAccessByInstance.delete(access);\r\n if (sharedAccessByContainer.get(shared.key) === shared)\r\n sharedAccessByContainer.delete(shared.key);\r\n access.close();\r\n }\r\n\r\n /** Arguments for [[withLockedAccess]]. */\r\n export interface WithLockedAccessArgs {\r\n operationName: string;\r\n openMode?: OpenMode;\r\n user?: string;\r\n }\r\n\r\n export async function withLockedAccess(iModel: IModelOrFileName, args: WithLockedAccessArgs, operation: (access: CloudAccess) => Promise<void>): Promise<void> {\r\n const access = await SchemaSync.getCloudAccess(iModel);\r\n try {\r\n await access.withLockedDb(args, async () => operation(access));\r\n } finally {\r\n releaseCloudAccess(access);\r\n }\r\n }\r\n\r\n /** Build the tables and indexes the briefcase's `ec_` rows describe. A merged schema changeset carries\r\n * those rows but no DDL, so the physical columns are missing until this runs. Needs no cloud access.\r\n */\r\n export function updateDbSchema(iModel: IModelDb): void {\r\n if (isEnabled(iModel) && !iModel.isReadonly) {\r\n iModel.clearCaches();\r\n iModel[_nativeDb].schemaSyncUpdateDbSchema();\r\n iModel[_implicitTxn].saveChanges(\"materialized db schema from ec_ tables\");\r\n }\r\n }\r\n\r\n /** Whether a failed [[IModelDb.importSchemas]] can be retried through the upgrade path.\r\n *\r\n * The update tier refuses two kinds of change: one that has to move data between columns, and one\r\n * that destroys instances or property values. They arrive as different statuses because they are\r\n * different changes, but they mean one thing to a caller - this needs\r\n * [[BriefcaseDb.upgradeSchemas]], which takes the exclusive schema lock.\r\n *\r\n * The retry is the app's decision, not the platform's: taking that lock disturbs everyone else, so\r\n * only the app knows whether to do it now, schedule it, or tell the user.\r\n * ```ts\r\n * try {\r\n * await db.importSchemas(files);\r\n * } catch (e) {\r\n * if (!SchemaSync.requiresUpgrade(e)) throw e;\r\n * await db.upgradeSchemas(files, { description: \"...\" });\r\n * }\r\n * ```\r\n * @internal\r\n */\r\n export function requiresUpgrade(error: unknown): boolean {\r\n const errorNumber = (error as { errorNumber?: number } | undefined)?.errorNumber;\r\n return errorNumber === DbResult.BE_SQLITE_ERROR_DataTransformRequired\r\n || errorNumber === DbResult.BE_SQLITE_ERROR_DataDeletionRequired;\r\n }\r\n\r\n /** Arguments for [[createContainerForIModel]]. */\r\n export interface CreateContainerForIModelArgs {\r\n iModel: IModelDb;\r\n label?: string;\r\n description?: string;\r\n }\r\n\r\n /** Create a cloud container to hold this iModel's `SchemaSyncDb`, and initialize it as empty.\r\n *\r\n * The container is scoped to the iModel, so the service deletes it when the iModel is deleted. Pass the\r\n * returned props to [[initializeForIModel]] - the two calls together are what enables schema sync on an\r\n * iModel that was created without it.\r\n * @note The current user must be authorized to create containers for the iTwin.\r\n */\r\n export async function createContainerForIModel(arg: CreateContainerForIModelArgs): Promise<CloudSqlite.ContainerProps> {\r\n const iModel = arg.iModel;\r\n const iTwinId = iModel.iTwinId;\r\n if (undefined === iTwinId)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot create a SchemaSync container for an iModel that has no iTwin\");\r\n\r\n return CloudAccess.createNewContainer({\r\n scope: { iTwinId, iModelId: iModel.iModelId },\r\n metadata: { label: arg.label ?? `SchemaSync for ${iModel.name}`, description: arg.description },\r\n });\r\n }\r\n\r\n /** Arguments for [[initializeForIModel]]. */\r\n export interface InitializeForIModelArgs {\r\n iModel: IModelDb;\r\n containerProps: CloudSqlite.ContainerProps;\r\n /** Replace the container already recorded on this iModel instead of failing. */\r\n overrideContainer?: boolean;\r\n }\r\n\r\n /** Refuse initialization before a caller provisions a container, then hold the exclusive schema lock and pull to the tip. */\r\n async function prepareToInitializeForIModel(iModel: IModelDb, overrideContainer: boolean): Promise<BriefcaseDb | undefined> {\r\n const briefcase = iModel instanceof BriefcaseDb ? iModel : undefined;\r\n if (briefcase && !briefcase.locks.isServerBased)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot enable SchemaSync without server-based locking\");\r\n\r\n if (briefcase && (iModel[_nativeDb].hasUnsavedChanges() || briefcase.txns.hasLocalChanges))\r\n throw new IModelError(ChangeSetStatus.HasLocalChanges, \"Cannot enable SchemaSync while there are local changes\");\r\n\r\n const assertContainerCanBeInitialized = () => {\r\n const localInfo = iModel[_nativeDb].schemaSyncGetLocalDbInfo();\r\n if (localInfo && !overrideContainer)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, `Local db already initialized to schema sync (container-id: ${localInfo.id})`);\r\n };\r\n\r\n assertContainerCanBeInitialized();\r\n await iModel.acquireSchemaLock();\r\n await briefcase?.pullChanges();\r\n assertContainerCanBeInitialized();\r\n return briefcase;\r\n }\r\n\r\n async function initializeAfterPreflight(arg: InitializeForIModelArgs, briefcase: BriefcaseDb | undefined): Promise<void> {\r\n const props = { baseUri: arg.containerProps.baseUri, containerId: arg.containerProps.containerId, storageType: arg.containerProps.storageType }; // sanitize to only known properties\r\n const iModel = arg.iModel;\r\n const description = arg.overrideContainer\r\n ? `Overriding SchemaSync for iModel with container-id: ${props.containerId}`\r\n : `Enable SchemaSync for iModel with container-id: ${props.containerId}`;\r\n const txnBeforeInit = briefcase?.txns.getCurrentTxnId();\r\n try {\r\n iModel[_implicitTxn].saveFileProperty(syncProperty, JSON.stringify(props));\r\n try {\r\n await withLockedAccess(iModel, { operationName: \"initialize schemaSync\", openMode: OpenMode.Readonly }, async (syncAccess) => {\r\n iModel[_nativeDb].schemaSyncInit(syncAccess.getUri(), props.containerId, arg.overrideContainer ?? false);\r\n iModel[_implicitTxn].saveChanges(description);\r\n });\r\n } catch (error) {\r\n iModel[_implicitTxn].abandonChanges();\r\n if (briefcase && txnBeforeInit !== undefined && briefcase.txns.getCurrentTxnId() !== txnBeforeInit) {\r\n const status = briefcase[_nativeDb].cancelTo(txnBeforeInit, true);\r\n if (status !== IModelStatus.Success)\r\n Logger.logError(\"SchemaSync\", `Failed to roll back schema sync initialization after the container upload failed: ${IModelStatus[status] ?? status}`);\r\n }\r\n throw error;\r\n }\r\n\r\n // Upload the initialized container before publishing the property that tells every briefcase to use it.\r\n // If the push fails, this briefcase keeps the local txn and exclusive schema lock so the push can be retried.\r\n await briefcase?.pushChanges({ description });\r\n } finally {\r\n iModel[_implicitTxn].abandonChanges();\r\n }\r\n\r\n await iModel.initializeSharedElementReservations();\r\n }\r\n\r\n /** Enable schema sync for an iModel, seeding the container from this briefcase.\r\n * @note Takes the exclusive schema lock, refuses local changes, and pulls the briefcase to the tip before writing the container.\r\n * If this operation fails after acquiring the schema lock, it leaves the lock held.\r\n */\r\n export async function initializeForIModel(arg: InitializeForIModelArgs): Promise<void> {\r\n const briefcase = await prepareToInitializeForIModel(arg.iModel, arg.overrideContainer ?? false);\r\n await initializeAfterPreflight(arg, briefcase);\r\n }\r\n\r\n /** The part of a SchemaSyncDb to restore from an authoritative briefcase. @alpha */\r\n export type RepairScope = \"schemaMetadata\" | \"schemaMetadataAndProfile\";\r\n\r\n const nativeRepairScope: Record<RepairScope, number> = {\r\n schemaMetadata: 0,\r\n schemaMetadataAndProfile: 1,\r\n };\r\n\r\n /** Arguments for [[repairForIModel]]. @alpha */\r\n export interface RepairForIModelArgs {\r\n /** A clean SchemaSync-enabled briefcase at the tip of the iModel timeline. */\r\n iModel: BriefcaseDb;\r\n /** Include the schema-owned EC and BeSQLite profile table definitions. */\r\n scope?: RepairScope;\r\n }\r\n\r\n /** Restore the schema-owned portion of the SchemaSyncDb from a briefcase at the tip of the timeline.\r\n *\r\n * This operation takes the exclusive schema lock and refuses to pull or modify the briefcase. Element\r\n * reservations and all other target-only state in the SchemaSyncDb are preserved.\r\n * @alpha\r\n */\r\n export async function repairForIModel(arg: RepairForIModelArgs): Promise<void> {\r\n const iModel = arg.iModel;\r\n if (!isEnabled(iModel))\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot repair SchemaSync because it is not enabled for this iModel\");\r\n\r\n if (iModel[_nativeDb].hasUnsavedChanges() || iModel.txns.hasLocalChanges)\r\n throw new IModelError(ChangeSetStatus.HasLocalChanges, \"Cannot repair SchemaSync while there are local changes\");\r\n\r\n if (!iModel.locks.isServerBased)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot repair SchemaSync without server-based locking\");\r\n\r\n if (arg.scope !== undefined && arg.scope !== \"schemaMetadata\" && arg.scope !== \"schemaMetadataAndProfile\")\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Unknown SchemaSync repair scope\");\r\n\r\n const briefcaseManagerModule = await import(\"./BriefcaseManager\");\r\n const assertBriefcaseIsAtTip = async () => {\r\n const latestChangeset = await briefcaseManagerModule.BriefcaseManager.getLatestChangeset({ iModelId: iModel.iModelId });\r\n if (latestChangeset.id !== iModel.changeset.id)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot repair SchemaSync from a briefcase that is not at the tip of the iModel timeline\");\r\n };\r\n\r\n // Avoid asking Hub for an exclusive lock it cannot grant to a briefcase that first needs to pull.\r\n await assertBriefcaseIsAtTip();\r\n const schemaLockWasHeld = iModel.holdsSchemaLock;\r\n if (!schemaLockWasHeld)\r\n await iModel.acquireSchemaLock();\r\n try {\r\n // Close the race between the preflight query and acquiring the exclusive lock.\r\n await assertBriefcaseIsAtTip();\r\n const repairScope = nativeRepairScope[arg.scope ?? \"schemaMetadata\"];\r\n await withLockedAccess(iModel, { openMode: OpenMode.Readonly, operationName: \"repair schema sync\" }, async (syncAccess) => {\r\n const nativeDb = iModel[_nativeDb] as IModelJsNative.DgnDb & { schemaSyncRepair(syncDbUri: string, scope: number): void };\r\n nativeDb.schemaSyncRepair(syncAccess.getUri(), repairScope);\r\n });\r\n Logger.logInfo(\"SchemaSync\", `Repaired SchemaSyncDb from changeset ${iModel.changeset.id || \"0\"}`);\r\n } finally {\r\n if (!schemaLockWasHeld)\r\n await iModel.locks.abandonAllLocks();\r\n }\r\n }\r\n\r\n /** Arguments for [[enableForIModel]]. */\r\n export interface EnableForIModelArgs {\r\n iModel: IModelDb;\r\n /** An existing container to use. When omitted one is created for this iModel. */\r\n containerProps?: CloudSqlite.ContainerProps;\r\n /** Replace the container already recorded on this iModel instead of failing. */\r\n overrideContainer?: boolean;\r\n label?: string;\r\n description?: string;\r\n }\r\n\r\n /** Turn schema sync on for an iModel: create the container if needed, record it, and seed it.\r\n *\r\n * The single call callers should use. [[createContainerForIModel]] and [[initializeForIModel]] have\r\n * to happen in this order, and an iModel left between the two is one that names a container nothing\r\n * has seeded.\r\n * @returns the container props recorded on the iModel.\r\n * @note Takes the exclusive schema lock and pushes, same protocol as [[BriefcaseDb.upgradeSchemas]] -\r\n * every operation that changes how a file is governed uses it. If this operation fails after acquiring the schema lock,\r\n * it leaves the lock held.\r\n */\r\n export async function enableForIModel(arg: EnableForIModelArgs): Promise<CloudSqlite.ContainerProps> {\r\n if (undefined === arg.containerProps && undefined === arg.iModel.iTwinId)\r\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot create a SchemaSync container for an iModel that has no iTwin\");\r\n\r\n const briefcase = await prepareToInitializeForIModel(arg.iModel, arg.overrideContainer ?? false);\r\n const containerProps = arg.containerProps\r\n ?? await createContainerForIModel({ iModel: arg.iModel, label: arg.label, description: arg.description });\r\n await initializeAfterPreflight({ iModel: arg.iModel, containerProps, overrideContainer: arg.overrideContainer }, briefcase);\r\n return containerProps;\r\n }\r\n\r\n /** Arguments for [[CloudAccess.createNewContainer]]. */\r\n export interface CreateNewContainerProps {\r\n scope: BlobContainer.Scope;\r\n metadata: Omit<BlobContainer.Metadata, \"containerType\">;\r\n }\r\n\r\n /** Provides access to a cloud-based `SchemaSyncDb` to hold ECSchemas. */\r\n export class CloudAccess extends CloudSqlite.DbAccess<SchemaSyncDb, ReadMethods, WriteMethods> {\r\n public constructor(props: CloudSqlite.ContainerAccessProps) {\r\n super({ dbType: SchemaSyncDb, props, dbName: defaultDbName });\r\n }\r\n\r\n public getUri() {\r\n return `${this.getCloudDb()[_nativeDb].getFilePath()}?vfs=${this.container.cache?.name}&writable=${this.container.isWriteable ? 1 : 0}`;\r\n }\r\n /**\r\n * Initialize a cloud container for use as a SchemaSync. The container must first be created via its storage supplier api (e.g. Azure, or AWS).\r\n * A valid sasToken that grants write access must be supplied. This function creates and uploads an empty ChannelDb into the container.\r\n * @note this deletes any existing content in the container.\r\n */\r\n public static async initializeDb(props: CloudSqlite.ContainerProps) {\r\n return super._initializeDb({ props, dbType: SchemaSyncDb, dbName: defaultDbName });\r\n }\r\n\r\n /** Create and initialize a new `schemasync` BlobContainer to hold a `SchemaSyncDb`. */\r\n public static async createNewContainer(args: CreateNewContainerProps): Promise<CloudSqlite.ContainerProps> {\r\n const props = await this.createBlobContainer({ scope: args.scope, metadata: { ...args.metadata, containerType } });\r\n await this.initializeDb(props);\r\n return props;\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { DbValueType, Id64String } from "@itwin/core-bentley";
|
|
5
5
|
import { ECDb } from "./ECDb";
|
|
6
6
|
import { IModelDb } from "./IModelDb";
|
|
7
|
+
import { SQLiteDb } from "./SQLiteDb";
|
|
7
8
|
/** Changed value type
|
|
8
9
|
* @beta
|
|
9
10
|
*/
|
|
@@ -40,12 +41,18 @@ export type SqliteValueStage = "Old" | "New";
|
|
|
40
41
|
* @beta
|
|
41
42
|
*/
|
|
42
43
|
export type AnyDb = IModelDb | ECDb;
|
|
44
|
+
/** A database that can supply SQLite table metadata to a changeset reader.
|
|
45
|
+
* The database must contain every table referenced by the changeset. When using a plain
|
|
46
|
+
* [[SQLiteDb]], [[SqliteChangesetReaderArgs.disableSchemaCheck]] may be used to tolerate additional columns in the changeset.
|
|
47
|
+
* @beta
|
|
48
|
+
*/
|
|
49
|
+
export type SqliteChangesetReaderDb = AnyDb | SQLiteDb;
|
|
43
50
|
/** Arg to open a changeset file from disk
|
|
44
51
|
* @beta
|
|
45
52
|
*/
|
|
46
|
-
export interface SqliteChangesetReaderArgs {
|
|
47
|
-
/**
|
|
48
|
-
readonly db:
|
|
53
|
+
export interface SqliteChangesetReaderArgs<TDb extends SqliteChangesetReaderDb = AnyDb> {
|
|
54
|
+
/** Database from which table and column metadata will be read. It must be open and contain every table in the changeset. */
|
|
55
|
+
readonly db: TDb;
|
|
49
56
|
/** invert the changeset operations */
|
|
50
57
|
readonly invert?: true;
|
|
51
58
|
/** do not check if column of change match db schema instead ignore addition columns */
|
|
@@ -71,24 +78,25 @@ export interface SqliteChange {
|
|
|
71
78
|
* a db provided.
|
|
72
79
|
* @beta
|
|
73
80
|
*/
|
|
74
|
-
export declare class SqliteChangesetReader implements Disposable {
|
|
81
|
+
export declare class SqliteChangesetReader<TDb extends SqliteChangesetReaderDb = AnyDb> implements Disposable {
|
|
75
82
|
/** db from where sql schema will be read */
|
|
76
|
-
readonly db:
|
|
83
|
+
readonly db: TDb;
|
|
77
84
|
private readonly _nativeReader;
|
|
78
85
|
private _schemaCache;
|
|
79
86
|
private _disableSchemaCheck;
|
|
80
87
|
private _changeIndex;
|
|
81
88
|
protected constructor(
|
|
82
89
|
/** db from where sql schema will be read */
|
|
83
|
-
db:
|
|
90
|
+
db: TDb);
|
|
91
|
+
private static requireOpenDb;
|
|
84
92
|
/**
|
|
85
93
|
* Open changeset file from disk
|
|
86
94
|
* @param args fileName of changeset reader and other options.
|
|
87
95
|
* @returns SqliteChangesetReader instance
|
|
88
96
|
*/
|
|
89
|
-
static openFile(args: {
|
|
97
|
+
static openFile<TDb extends SqliteChangesetReaderDb>(args: {
|
|
90
98
|
readonly fileName: string;
|
|
91
|
-
} & SqliteChangesetReaderArgs): SqliteChangesetReader
|
|
99
|
+
} & SqliteChangesetReaderArgs<TDb>): SqliteChangesetReader<TDb>;
|
|
92
100
|
/**
|
|
93
101
|
* Group changeset file into single changeset and open that changeset.
|
|
94
102
|
* @param args - The arguments for opening the changeset group. Requires an open db.
|