/** @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