UNPKG

@itwin/core-backend

Version:
324 lines • 15.5 kB
/** @packageDocumentation * @module SQLiteDb */ import { IModelJsNative } from "@bentley/imodeljs-native"; import { DbResult, OpenMode } from "@itwin/core-bentley"; import { LocalFileName } from "@itwin/core-common"; import { CloudSqlite } from "./CloudSqlite"; import { SqliteStatement } from "./SqliteStatement"; import { _nativeDb } from "./internal/Symbols"; /** * A "generic" SQLiteDb. This class may be used to access local files or databases in a cloud container. * @public */ export declare class SQLiteDb { /** @internal */ readonly [_nativeDb]: IModelJsNative.SQLiteDb; private _sqliteStatementCache; /** @internal */ static createBlobIO(): SQLiteDb.BlobIO; /** alias for closeDb. * @deprecated in 4.0 - will not be removed until after 2026-06-13. Use [[closeDb]] */ dispose(): void; /** Create a SQLiteDb * @param dbName The path to the SQLiteDb file to create. */ createDb(dbName: string): void; /** @beta */ createDb(dbName: string, container?: CloudSqlite.CloudContainer, params?: SQLiteDb.CreateParams): void; /** Open a SQLiteDb. * @param dbName The path to the SQLiteDb file to open */ openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams): void; /** * @param container optional CloudContainer holding database * @beta */ openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer): void; /** Close SQLiteDb. * @param saveChanges if true, call `saveChanges` before closing db. Otherwise unsaved changes are abandoned. */ closeDb(saveChanges?: boolean): void; /** Returns true if this SQLiteDb is open */ get isOpen(): boolean; /** Returns true if this SQLiteDb is open readonly */ get isReadonly(): boolean; /** Create a new table in this database. */ protected createTable(args: { /** The name of the table to create. */ tableName: string; /** all of the columns in the table. */ columns: string; /** any unique or foreign key constraints */ constraints?: string; /** if true, add a "lastMod" timestamp column and triggers to automatically update it. */ addTimestamp?: boolean; }): void; /** * Get the last modified date for a row in a table of this database. * @note the table must have been created with `addTimestamp: true` */ readLastModTime(tableName: string, rowId: number): Date; /** * Open a database, perform an operation, then close the database. * * Details: * - if database is open, throw an error * - open a database * - call a function with the database opened. If it is async, await its return. * - if function throws, abandon all changes, close database, and rethrow * - save all changes * - close the database * @return value from operation */ withOpenDb<T>(args: SQLiteDb.WithOpenDbArgs, operation: () => T): T; /** The cloud container backing this SQLite database, if any. * @beta */ get cloudContainer(): CloudSqlite.CloudContainer | undefined; /** Returns the Id of the most-recently-inserted row in this database, per [sqlite3_last_insert_rowid](https://www.sqlite.org/c3ref/last_insert_rowid.html). */ getLastInsertRowId(): number; /** * Perform an operation on a database in a CloudContainer with the write lock held. * * Details: * - acquire the write lock on a CloudContainer * - call `withOpenDb` with openMode `ReadWrite` * - upload changes * - release the write lock * @param args arguments to lock the container and open the database * @param operation an operation performed on the database with the write lock held. * @return value from operation * @internal */ withLockedContainer<T>(args: CloudSqlite.LockAndOpenArgs, operation: () => Promise<T>): Promise<T>; /** vacuum this database * @see https://www.sqlite.org/lang_vacuum.html */ vacuum(args?: SQLiteDb.VacuumDbArgs): void; /** Commit the outermost transaction, writing changes to the file. Then, restart the default transaction. */ saveChanges(): void; /** Abandon (cancel) the outermost transaction, discarding all changes since last save. Then, restart the default transaction. */ abandonChanges(): void; /** * Use a prepared SQL statement, potentially from the statement cache. If the requested statement doesn't exist * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved * in the statement cache so it can be reused in the future. Use this method for SQL statements that will be * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withSqliteStatement]]. * @param sql The SQLite SQL statement to execute * @param callback the callback to invoke on the prepared statement * @returns the value returned by `callback`. */ withPreparedSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T): T; /** * Prepare and execute a callback on a SQL statement. After the callback completes the statement is disposed. * Use this method for SQL statements are either not expected to be reused, or are not expensive to prepare. * For statements that will be reused often, instead use [[withPreparedSqliteStatement]]. * @param sql The SQLite SQL statement to execute * @param callback the callback to invoke on the prepared statement * @returns the value returned by `callback`. */ withSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T): T; /** * Perform an operation on this database within a [savepoint](https://www.sqlite.org/lang_savepoint.html). If the operation completes successfully, the * changes remain in the current transaction. If the operation throws an exception, the savepoint is rolled back * and all changes to the database from this method are reversed, leaving the transaction exactly as it was before this method. */ withSavePoint(savePointName: string, operation: () => void): void; /** Prepare an SQL statement. * @param sql The SQLite SQL statement to prepare * @param logErrors Determine if errors are logged or not * @internal */ prepareSqliteStatement(sql: string, logErrors?: boolean): SqliteStatement; /** execute an SQL statement */ executeSQL(sql: string): DbResult; } /** * Abstract base class for a SQLite database that has [[SQLiteDb.RequiredVersionRanges]] stored in it. * This class provides version checking when the database is opened, to guarantee that a valid version of software is * always used for access. * * Notes: * - This class may be used either to access a local file, or one stored in a cloud container. * - Subclasses must provide a `myVersion` member indicating the version of its software, and implement the `createDDL` member to create its * tables. * @beta */ export declare abstract class VersionedSqliteDb extends SQLiteDb { protected static _versionProps: { readonly namespace: "SQLiteDb"; readonly name: "versions"; }; /** The current semver "persistence version" of this class. * @note This value should only be changed when logic in its code is modified in a way that affects the operation of extant copies. * If this value is outside of the range of accepted versions of a to-be-opened VersionedSqliteDb, the operation will fail. In this manner, if * changes are made to the format of a VersionedSqliteDb, or if bug fixes are necessary, the `requiredVersions` property in a VersionedSqliteDb may be updated * and immediately old versions of the package will refuse to open the VersionedSqliteDb, with a message to the user that they need to upgrade their * software. Likewise, if a new version of the package is asked to open an older VersionedSqliteDb that has not been upgraded to the lowest version * supported by it, the user will be informed that they need to upgrade their software. * @note this identifier is independent of versions in `package.json` files. */ abstract myVersion: string; /** * Change the "versions required to open this database" property stored in this database. After this call, * versions of software that don't meet the supplied ranges will fail. * @param versions the new versions required for reading and writing this database. * @note the database must be opened for write access. */ setRequiredVersions(versions: SQLiteDb.RequiredVersionRanges): void; /** Get the required version ranges necessary to open this VersionedSqliteDb. */ getRequiredVersions(): SQLiteDb.RequiredVersionRanges; /** * Implement this method to create all tables for this subclass of `VersionedSqliteDb` when a new database file is created. Called from [[createNewDb]]. */ protected abstract createDDL(args: any): void; /** * Create a new database file for the subclass of VersionedSqliteDb. * @note The required versions are saved as [[myVersion]] or newer for both read and write. */ static createNewDb(fileName: LocalFileName, setupArgs?: any): void; /** * Verify that this version of the software meets the required version range (as appropriate, read or write) stored in the database. * Throws otherwise. */ protected verifyVersions(): void; /** * Open this database and verify that this version of the software meets the required version range (as appropriate, read or write) stored in the database. * Throws otherwise. * @see [[SqliteDb.openDb]] for argument types */ openDb(dbName: string, openMode: OpenMode | SQLiteDb.OpenParams, container?: CloudSqlite.CloudContainer): void; upgradeSchema(arg: { dbName: string; lockContainer?: { container: CloudSqlite.CloudContainer; user: string; }; upgradeFn: () => void; }): Promise<void | (() => void)>; } /** @public */ export declare namespace SQLiteDb { /** A semver version range. * @see https://docs.npmjs.com/cli/v6/using-npm/semver */ type VersionRange = string; /** * A pair of semver [[SQLiteDb.VersionRange]]s, one for read and one for write, required to access a [[VersionedSqliteDb]]. * If the version of the software attempting to read or write the database does not satisfy the range, access is denied. */ interface RequiredVersionRanges { /** a range of acceptable persistence versions for reading from a VersionedSqliteDb. */ readonly readVersion: VersionRange; /** a range of acceptable persistence versions for writing to a VersionedSqliteDb. */ readonly writeVersion: VersionRange; } /** interface for reading and writing to a blob in a SQLiteDb * @internal */ interface BlobIO { /** Close this BlobIO if it is opened. * @note this BlobIO *may* be reused after this call by calling `open` again. */ close(): void; /** get the total number of bytes in the blob */ getNumBytes(): number; /** @return true if this BlobIO was successfully opened and may be use to read or write the blob */ isValid(): boolean; /** Open this BlobIO against a table/row/column in a Db */ open( /** The database for the blob */ db: IModelJsNative.AnyDb, args: { /** the name of the table for the blob*/ tableName: string; /** the name of the column for the blob */ columnName: string; /** The rowId of the blob */ row: number; /** If true, open this BlobIO for write access */ writeable?: boolean; }): void; /** Read from a blob * @returns the contents of the requested byte range */ read(args: { /** The number of bytes to read */ numBytes: number; /** starting offset within the blob to read */ offset: number; /** If present and of sufficient size, use this ArrayBuffer for the value. */ blob?: ArrayBuffer; }): Uint8Array; /** Reposition this BlobIO to a new rowId * @note this BlobIO must be valid when this methods is called. */ changeRow(row: number): void; /** Write to a blob */ write(args: { /** The number of bytes to write */ numBytes: number; /** starting offset within the blob to write */ offset: number; /** the value to write */ blob: ArrayBuffer; }): void; } /** Default transaction mode for SQLiteDbs. * @see https://www.sqlite.org/lang_transaction.html */ enum DefaultTxnMode { /** no default transaction is started. You must use BEGIN/COMMIT or SQLite will use implicit transactions */ None = 0, /** A deferred transaction is started when the file is first opened. This is the default. */ Deferred = 1, /** An immediate transaction is started when the file is first opened. */ Immediate = 2, /** An exclusive transaction is started when the file is first opened. */ Exclusive = 3 } /** parameters common to opening or creating a new SQLiteDb */ interface OpenOrCreateParams { /** If true, do not require that the `be_Prop` table exist */ rawSQLite?: boolean; /** @see immutable option at https://www.sqlite.org/c3ref/open.html */ immutable?: boolean; /** Do not attempt to verify that the file is a valid sQLite file before opening. */ skipFileCheck?: boolean; /** the default transaction mode * @see [[SQLiteDb.DefaultTxnMode]] */ defaultTxn?: 0 | 1 | 2 | 3; /** see query parameters from 'URI Filenames' in https://www.sqlite.org/c3ref/open.html */ queryParam?: string; } /** Parameters for opening an existing SQLiteDb */ interface OpenParams extends OpenOrCreateParams { /** use OpenMode.ReadWrite to open the file with write access */ openMode: OpenMode; } /** Size of a SQLiteDb page in bytes */ interface PageSize { /** see https://www.sqlite.org/pragma.html#pragma_page_size */ pageSize?: number; } /** Parameters for creating a new SQLiteDb */ type CreateParams = OpenOrCreateParams & PageSize; /** Arguments for `SqliteDb.withOpenDb` */ interface WithOpenDbArgs { /** The name of the database to open */ dbName: string; /** either an object with the open parameters or just OpenMode value. */ openMode?: OpenMode | SQLiteDb.OpenParams; /** @internal */ container?: CloudSqlite.CloudContainer; } /** Arguments for `SQLiteDb.vacuum` */ interface VacuumDbArgs extends PageSize { /** if present, name of new file to [vacuum into](https://www.sqlite.org/lang_vacuum.html) */ into?: LocalFileName; } } //# sourceMappingURL=SQLiteDb.d.ts.map