@itwin/core-backend
Version:
iTwin.js backend components
324 lines • 15.5 kB
TypeScript
/** @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