/** * Configuration options for creating SQLite aggregate functions. * Used with `DatabaseSync.aggregate()` to define custom aggregate operations. */ interface AggregateOptions { /** The initial value for the aggregation. */ readonly start?: any; /** Function called for each row to update the aggregate state. */ readonly step: (accumulator: any, ...args: any[]) => any; /** Optional function for window function support to reverse a step. */ readonly inverse?: (accumulator: any, ...args: any[]) => any; /** Optional function to compute the final result from the accumulator. */ readonly result?: (accumulator: any) => any; /** If `true`, sets the `SQLITE_DETERMINISTIC` flag. @default false */ readonly deterministic?: boolean; /** If `true`, sets the `SQLITE_DIRECTONLY` flag. @default false */ readonly directOnly?: boolean; /** If `true`, converts integer arguments to `BigInt`s. @default false */ readonly useBigIntArguments?: boolean; /** If `true`, allows function to be invoked with variable arguments. @default false */ readonly varargs?: boolean; } /** * Configuration options for applying changesets to a database. * Used with `DatabaseSync.applyChangeset()` to handle conflicts and filter tables. */ interface ChangesetApplyOptions { /** * Function called when a conflict is detected during changeset application. * @param conflictType The type of conflict (SQLITE_CHANGESET_CONFLICT, etc.) * @returns One of SQLITE_CHANGESET_OMIT, SQLITE_CHANGESET_REPLACE, or SQLITE_CHANGESET_ABORT */ readonly onConflict?: (conflictType: number) => number; /** * Function called to filter which tables to apply changes to. * @param tableName The name of the table * @returns true to include the table, false to skip it */ readonly filter?: (tableName: string) => boolean; } /** * Configuration options for creating SQLite sessions. * Used with `DatabaseSync.createSession()` to track database changes. */ interface SessionOptions { /** The table to track changes for. If omitted, all tables are tracked. */ readonly table?: string; /** The database name. @default "main" */ readonly db?: string; } /** * SQLTagStore provides cached prepared statements via tagged template syntax. * Statements are cached by their SQL string and reused across invocations. */ interface SQLTagStoreInstance { /** Returns the associated database instance. */ readonly db: DatabaseSyncInstance; /** Returns the maximum capacity of the statement cache. */ readonly capacity: number; /** * Returns the current number of cached statements. */ readonly size: number; /** * Clears all cached statements. */ clear(): void; /** * Execute an INSERT, UPDATE, DELETE or other statement that doesn't return rows. * @param strings Template literal strings array. * @param values Values to bind to the placeholders. * @returns An object with `changes` and `lastInsertRowid`. */ run(strings: TemplateStringsArray, ...values: unknown[]): { changes: number; lastInsertRowid: number | bigint; }; /** * Execute a query and return the first row, or undefined if no rows. * @param strings Template literal strings array. * @param values Values to bind to the placeholders. */ get(strings: TemplateStringsArray, ...values: unknown[]): unknown; /** * Execute a query and return all rows as an array. * @param strings Template literal strings array. * @param values Values to bind to the placeholders. */ all(strings: TemplateStringsArray, ...values: unknown[]): unknown[]; /** * Execute a query and return an iterator over the rows. * @param strings Template literal strings array. * @param values Values to bind to the placeholders. */ iterate(strings: TemplateStringsArray, ...values: unknown[]): IterableIterator; } /** * Metadata about a column in a prepared statement's result set. * Matches Node.js sqlite module's StatementColumnMetadata. */ interface StatementColumnMetadata { /** * The unaliased name of the column in the origin table, or `null` if the * column is the result of an expression or subquery. * This property is the result of `sqlite3_column_origin_name()`. */ column: string | null; /** * The unaliased name of the origin database, or `null` if the column is * the result of an expression or subquery. * This property is the result of `sqlite3_column_database_name()`. */ database: string | null; /** * The name assigned to the column in the result set of a SELECT statement. * This property is the result of `sqlite3_column_name()`. */ name: string; /** * The unaliased name of the origin table, or `null` if the column is * the result of an expression or subquery. * This property is the result of `sqlite3_column_table_name()`. */ table: string | null; /** * The declared data type of the column, or `null` if the column is * the result of an expression or subquery. * This property is the result of `sqlite3_column_decltype()`. */ type: string | null; } /** * A prepared SQL statement that can be executed multiple times with different parameters. * This interface represents an instance of the StatementSync class. */ interface StatementSyncInstance { /** The original SQL source string. */ readonly sourceSQL: string; /** The expanded SQL string with bound parameters, if expandedSQL option was set. */ readonly expandedSQL: string | undefined; /** * This method executes a prepared statement and returns an object. * @param parameters Optional named and anonymous parameters to bind to the statement. * @returns An object with the number of changes and the last insert rowid. */ run(...parameters: any[]): { changes: number; lastInsertRowid: number | bigint; }; /** * This method executes a prepared statement and returns the first result row. * @param parameters Optional named and anonymous parameters to bind to the statement. * @returns The first row from the query results, or undefined if no rows. */ get(...parameters: any[]): any; /** * This method executes a prepared statement and returns all results as an array. * @param parameters Optional named and anonymous parameters to bind to the statement. * @returns An array of row objects from the query results. */ all(...parameters: any[]): any[]; /** * This method executes a prepared statement and returns an iterable iterator of objects. * Each object represents a row from the query results. * @param parameters Optional named and anonymous parameters to bind to the statement. * @returns An iterable iterator of row objects. */ iterate(...parameters: any[]): IterableIterator; /** * Set whether to read integer values as JavaScript BigInt. * @param readBigInts If true, read integers as BigInts. @default false */ setReadBigInts(readBigInts: boolean): void; /** * Set whether to allow bare named parameters in SQL. * @param allowBareNamedParameters If true, allows bare named parameters. @default false */ setAllowBareNamedParameters(allowBareNamedParameters: boolean): void; /** * Set whether to allow unknown named parameters in SQL. * @param enabled If true, unknown named parameters are ignored. If false, they throw an error. @default false */ setAllowUnknownNamedParameters(enabled: boolean): void; /** * Set whether to return results as arrays rather than objects. * @param returnArrays If true, return results as arrays. @default false */ setReturnArrays(returnArrays: boolean): void; /** * Returns an array of objects, each representing a column in the statement's result set. * @returns Array of column metadata objects with name, column, database, table, and type. */ columns(): StatementColumnMetadata[]; } /** * Configuration options for creating SQLite user-defined functions. * Used with `DatabaseSync.function()` to customize function behavior. */ interface UserFunctionOptions { /** If `true`, sets the `SQLITE_DETERMINISTIC` flag. @default false */ readonly deterministic?: boolean; /** If `true`, sets the `SQLITE_DIRECTONLY` flag. @default false */ readonly directOnly?: boolean; /** If `true`, converts integer arguments to `BigInt`s. @default false */ readonly useBigIntArguments?: boolean; /** If `true`, allows function to be invoked with variable arguments. @default false */ readonly varargs?: boolean; } /** * Represents a SQLite database connection. * This interface represents an instance of the DatabaseSync class. */ interface DatabaseSyncInstance { /** Indicates whether the database connection is open. */ readonly isOpen: boolean; /** Indicates whether a transaction is currently active. */ readonly isTransaction: boolean; /** * Opens a database connection. This method should only be used when the database * was created with { open: false }. An exception is thrown if the database is already open. */ open(): void; /** * Closes the database connection. This method should be called to ensure that * the database connection is properly cleaned up. Once a database is closed, * it cannot be used again. */ close(): void; /** * Returns the location of the database file. For attached databases, you can specify * the database name. Returns null for in-memory databases. * @param dbName The name of the database. Defaults to 'main' (the primary database). * @returns The file path of the database, or null for in-memory databases. */ location(dbName?: string): string | null; /** * Compiles an SQL statement and returns a StatementSyncInstance object. * @param sql The SQL statement to prepare. * @param options Optional configuration for the statement. * @returns A StatementSyncInstance object that can be executed multiple times. */ prepare(sql: string, options?: StatementOptions): StatementSyncInstance; /** * This method allows one or more SQL statements to be executed without * returning any results. This is useful for commands like CREATE TABLE, * INSERT, UPDATE, or DELETE. * @param sql The SQL statement(s) to execute. */ exec(sql: string): void; /** * This method creates SQLite user-defined functions, wrapping sqlite3_create_function_v2(). * @param name The name of the SQLite function to create. * @param func The JavaScript function to call when the SQLite function is invoked. */ function(name: string, func: Function): void; /** * This method creates SQLite user-defined functions, wrapping sqlite3_create_function_v2(). * @param name The name of the SQLite function to create. * @param options Optional configuration settings. * @param func The JavaScript function to call when the SQLite function is invoked. */ function(name: string, options: UserFunctionOptions, func: Function): void; /** * This method creates SQLite aggregate functions, wrapping sqlite3_create_window_function(). * @param name The name of the SQLite aggregate function to create. * @param options Configuration object containing step function and other settings. */ aggregate(name: string, options: AggregateOptions): void; /** * Create a new session to record database changes. * @param options Optional configuration for the session. * @returns A Session object for recording changes. */ createSession(options?: SessionOptions): Session; /** * Create a new SQLTagStore for cached prepared statements via tagged template syntax. * @param capacity Optional maximum number of statements to cache. @default 1000 * @returns A SQLTagStore instance. * @example * ```typescript * const sql = db.createTagStore(); * sql.run`INSERT INTO users VALUES (${id}, ${name})`; * const user = sql.get`SELECT * FROM users WHERE id = ${id}`; * ``` */ createTagStore(capacity?: number): SQLTagStoreInstance; /** * Apply a changeset to the database. * @param changeset The changeset data to apply. * @param options Optional configuration for applying the changeset. * @returns true if successful, false if aborted. */ applyChangeset(changeset: Uint8Array, options?: ChangesetApplyOptions): boolean; /** * Enables or disables the loading of SQLite extensions. * @param enable If true, enables extension loading. If false, disables it. */ enableLoadExtension(enable: boolean): void; /** * Loads an SQLite extension from the specified file path. * @param path The path to the extension library. * @param entryPoint Optional entry point function name. If not provided, uses the default entry point. */ loadExtension(path: string, entryPoint?: string): void; /** * Enables or disables the defensive flag. When the defensive flag is active, * language features that allow ordinary SQL to deliberately corrupt the * database file are disabled. * @param active Whether to enable or disable the defensive flag. * @see https://sqlite.org/c3ref/c_dbconfig_defensive.html */ enableDefensive(active: boolean): void; /** * Sets an authorization callback that is invoked before each SQL operation. * The authorizer can allow, deny, or ignore each operation. * * @param callback The authorization callback function, or null to remove the authorizer. * - actionCode: The action being requested (e.g., SQLITE_SELECT, SQLITE_INSERT) * - param1: First parameter (varies by action, often table name) * - param2: Second parameter (varies by action, often column name) * - param3: Third parameter (usually database name like "main") * - param4: Fourth parameter (trigger or view name if applicable) * * The callback must return one of: * - constants.SQLITE_OK: Allow the operation * - constants.SQLITE_DENY: Deny the operation and abort the SQL statement * - constants.SQLITE_IGNORE: Silently ignore/skip the operation * * @example * ```typescript * // Block all DELETE operations * db.setAuthorizer((actionCode, table, column, dbName, trigger) => { * if (actionCode === constants.SQLITE_DELETE) { * return constants.SQLITE_DENY; * } * return constants.SQLITE_OK; * }); * * // Remove the authorizer * db.setAuthorizer(null); * ``` * * @see https://sqlite.org/c3ref/set_authorizer.html */ setAuthorizer(callback: ((actionCode: number, param1: string | null, param2: string | null, param3: string | null, param4: string | null) => number) | null): void; /** * An object with getters and setters for each SQLite limit. * Setting a property changes the limit immediately. * Setting a property to `Infinity` resets the limit to its compile-time maximum. * @see https://sqlite.org/c3ref/limit.html */ readonly limits: DatabaseSyncLimits; /** @internal Native method to get a SQLite limit by ID. */ getLimit(limitId: number): number; /** @internal Native method to set a SQLite limit by ID. Returns old value. */ setLimit(limitId: number, value: number): number; /** Dispose of the database resources using the explicit resource management protocol. */ [Symbol.dispose](): void; } /** * Represents the configurable SQLite limits for a database connection. * Each property corresponds to a SQLite limit constant. * @see https://sqlite.org/c3ref/limit.html */ interface DatabaseSyncLimits { /** Maximum length of any string or BLOB or table row, in bytes. */ length: number; /** Maximum length of an SQL statement, in bytes. */ sqlLength: number; /** Maximum number of columns in a table, result set, or index. */ column: number; /** Maximum depth of the parse tree on any expression. */ exprDepth: number; /** Maximum number of terms in a compound SELECT statement. */ compoundSelect: number; /** Maximum number of instructions in a virtual machine program. */ vdbeOp: number; /** Maximum number of arguments on a function. */ functionArg: number; /** Maximum number of attached databases. */ attach: number; /** Maximum length of the pattern argument to the LIKE or GLOB operators. */ likePatternLength: number; /** Maximum index number of any parameter in an SQL statement. */ variableNumber: number; /** Maximum depth of recursion for triggers. */ triggerDepth: number; } /** * SQLTagStore provides cached prepared statements via tagged template syntax. * * @example * ```js * const sql = db.createTagStore(); * sql.run`INSERT INTO users VALUES (${id}, ${name})`; * const user = sql.get`SELECT * FROM users WHERE id = ${id}`; * ``` */ declare class SQLTagStore { private readonly database; private readonly cache; private readonly maxCapacity; constructor(db: DatabaseSyncInstance, capacity?: number); /** * Returns the associated database instance. */ get db(): DatabaseSyncInstance; /** * Returns the maximum capacity of the statement cache. */ get capacity(): number; /** * Returns the current number of cached statements. */ get size(): number; /** * Clears all cached statements. */ clear(): void; /** * Execute an INSERT, UPDATE, DELETE or other statement that doesn't return rows. * Returns an object with `changes` and `lastInsertRowid`. */ run(strings: TemplateStringsArray, ...values: unknown[]): { changes: number; lastInsertRowid: number | bigint; }; /** * Execute a query and return the first row, or undefined if no rows. */ get(strings: TemplateStringsArray, ...values: unknown[]): unknown; /** * Execute a query and return all rows as an array. */ all(strings: TemplateStringsArray, ...values: unknown[]): unknown[]; /** * Execute a query and return an iterator over the rows. */ iterate(strings: TemplateStringsArray, ...values: unknown[]): IterableIterator; /** * Get a cached statement or prepare a new one. */ private getOrPrepare; /** * Build the SQL string by joining template parts with `?` placeholders. */ private buildSQL; } /** * Configuration options for opening a database. * This interface matches Node.js sqlite module's DatabaseSyncOptions. */ interface DatabaseSyncOptions { /** Path to the database file. Use ':memory:' for an in-memory database. */ readonly location?: string; /** If true, the database is opened in read-only mode. @default false */ readonly readOnly?: boolean; /** If true, foreign key constraints are enforced. @default true */ readonly enableForeignKeyConstraints?: boolean; /** * If true, double-quoted string literals are allowed. * * If enabled, double quotes can be misinterpreted as identifiers instead of * string literals, leading to confusing errors. * * **The SQLite documentation strongly recommends avoiding double-quoted * strings entirely.** * @see https://sqlite.org/quirks.html#dblquote * @default false */ readonly enableDoubleQuotedStringLiterals?: boolean; /** * Sets the busy timeout in milliseconds. * @default 0 */ readonly timeout?: number; /** If true, enables loading of SQLite extensions. @default false */ readonly allowExtension?: boolean; /** * If true, SQLite integers are returned as JavaScript BigInt values. * If false, integers are returned as JavaScript numbers. * @default false */ readonly readBigInts?: boolean; /** * If true, query results are returned as arrays instead of objects. * @default false */ readonly returnArrays?: boolean; /** * If true, allows binding named parameters without the prefix character. * For example, allows using 'foo' instead of ':foo' or '$foo'. * @default true */ readonly allowBareNamedParameters?: boolean; /** * If true, unknown named parameters are ignored during binding. * If false, an exception is thrown for unknown named parameters. * @default false */ readonly allowUnknownNamedParameters?: boolean; /** * If true, enables the defensive flag. When the defensive flag is enabled, * language features that allow ordinary SQL to deliberately corrupt the * database file are disabled. The defensive flag can also be set using * `enableDefensive()`. * @see https://sqlite.org/c3ref/c_dbconfig_defensive.html * @default false */ readonly defensive?: boolean; /** * If true, the database is opened immediately. If false, the database is not opened until the first operation. * @default true */ readonly open?: boolean; /** * An object specifying initial SQLite limits to set when opening the database. * Each property corresponds to a SQLite limit constant. Only integer values are * accepted (no Infinity). Omitted properties retain their default values. * @see https://sqlite.org/c3ref/limit.html */ readonly limits?: { readonly length?: number; readonly sqlLength?: number; readonly column?: number; readonly exprDepth?: number; readonly compoundSelect?: number; readonly vdbeOp?: number; readonly functionArg?: number; readonly attach?: number; readonly likePatternLength?: number; readonly variableNumber?: number; readonly triggerDepth?: number; }; } /** * Authorization action codes passed to `setAuthorizer()` callbacks. * * These constants are compatible with `node:sqlite`. * * @see https://sqlite.org/c3ref/c_alter_table.html */ interface SqliteAuthorizationActions { /** Create a new index. */ SQLITE_CREATE_INDEX: number; /** Create a new table. */ SQLITE_CREATE_TABLE: number; /** Create a new temporary index. */ SQLITE_CREATE_TEMP_INDEX: number; /** Create a new temporary table. */ SQLITE_CREATE_TEMP_TABLE: number; /** Create a new temporary trigger. */ SQLITE_CREATE_TEMP_TRIGGER: number; /** Create a new temporary view. */ SQLITE_CREATE_TEMP_VIEW: number; /** Create a new trigger. */ SQLITE_CREATE_TRIGGER: number; /** Create a new view. */ SQLITE_CREATE_VIEW: number; /** Delete rows from a table. */ SQLITE_DELETE: number; /** Drop an index. */ SQLITE_DROP_INDEX: number; /** Drop a table. */ SQLITE_DROP_TABLE: number; /** Drop a temporary index. */ SQLITE_DROP_TEMP_INDEX: number; /** Drop a temporary table. */ SQLITE_DROP_TEMP_TABLE: number; /** Drop a temporary trigger. */ SQLITE_DROP_TEMP_TRIGGER: number; /** Drop a temporary view. */ SQLITE_DROP_TEMP_VIEW: number; /** Drop a trigger. */ SQLITE_DROP_TRIGGER: number; /** Drop a view. */ SQLITE_DROP_VIEW: number; /** Insert rows into a table. */ SQLITE_INSERT: number; /** Execute a PRAGMA statement. */ SQLITE_PRAGMA: number; /** Read a column from a table. */ SQLITE_READ: number; /** Execute a SELECT statement. */ SQLITE_SELECT: number; /** Begin/commit/rollback a transaction. */ SQLITE_TRANSACTION: number; /** Update rows in a table. */ SQLITE_UPDATE: number; /** Attach a database. */ SQLITE_ATTACH: number; /** Detach a database. */ SQLITE_DETACH: number; /** Alter a table. */ SQLITE_ALTER_TABLE: number; /** Reindex. */ SQLITE_REINDEX: number; /** Analyze a table or index. */ SQLITE_ANALYZE: number; /** Create a virtual table. */ SQLITE_CREATE_VTABLE: number; /** Drop a virtual table. */ SQLITE_DROP_VTABLE: number; /** Call a function. */ SQLITE_FUNCTION: number; /** Create/release/rollback a savepoint. */ SQLITE_SAVEPOINT: number; /** No longer used (historical). */ SQLITE_COPY: number; /** Recursive query. */ SQLITE_RECURSIVE: number; } /** * Authorization callback return values for `setAuthorizer()`. * * These constants are compatible with `node:sqlite`. * * @see https://sqlite.org/c3ref/c_deny.html */ interface SqliteAuthorizationResults { /** Allow the operation. */ SQLITE_OK: number; /** Deny the operation and abort the SQL statement with an error. */ SQLITE_DENY: number; /** Silently ignore/skip the operation (e.g., return NULL for column reads). */ SQLITE_IGNORE: number; } /** * Changeset conflict type codes passed to `applyChangeset()` callbacks. * * These constants are compatible with `node:sqlite`. * * @see https://sqlite.org/session/c_changeset_conflict.html */ interface SqliteChangesetConflictTypes { /** Data conflict - row exists but values differ. */ SQLITE_CHANGESET_DATA: number; /** Row not found in target database. */ SQLITE_CHANGESET_NOTFOUND: number; /** Primary key conflict. */ SQLITE_CHANGESET_CONFLICT: number; /** Constraint violation (NOT NULL, CHECK, etc.). */ SQLITE_CHANGESET_CONSTRAINT: number; /** Foreign key constraint violation. */ SQLITE_CHANGESET_FOREIGN_KEY: number; } /** * Changeset conflict resolution return values for `applyChangeset()` callbacks. * * These constants are compatible with `node:sqlite`. * * @see https://sqlite.org/session/sqlite3changeset_apply.html */ interface SqliteChangesetResolution { /** Skip conflicting changes. */ SQLITE_CHANGESET_OMIT: number; /** Replace conflicting changes. */ SQLITE_CHANGESET_REPLACE: number; /** Abort on conflict. */ SQLITE_CHANGESET_ABORT: number; } /** * SQLite database open flags. * * **Note:** These constants are an extension beyond `node:sqlite`. * The `node:sqlite` module does not export `SQLITE_OPEN_*` constants. * * @see https://sqlite.org/c3ref/open.html */ interface SqliteOpenFlags { /** Open database for reading only. */ SQLITE_OPEN_READONLY: number; /** Open database for reading and writing. */ SQLITE_OPEN_READWRITE: number; /** Create database if it doesn't exist. */ SQLITE_OPEN_CREATE: number; /** Delete database file on close. */ SQLITE_OPEN_DELETEONCLOSE: number; /** Open with exclusive access. */ SQLITE_OPEN_EXCLUSIVE: number; /** Use automatic proxy for locking. */ SQLITE_OPEN_AUTOPROXY: number; /** Interpret filename as URI. */ SQLITE_OPEN_URI: number; /** Open in-memory database. */ SQLITE_OPEN_MEMORY: number; /** Open main database file. */ SQLITE_OPEN_MAIN_DB: number; /** Open temporary database file. */ SQLITE_OPEN_TEMP_DB: number; /** Open transient in-memory database. */ SQLITE_OPEN_TRANSIENT_DB: number; /** Open main journal file. */ SQLITE_OPEN_MAIN_JOURNAL: number; /** Open temporary journal file. */ SQLITE_OPEN_TEMP_JOURNAL: number; /** Open subjournal file. */ SQLITE_OPEN_SUBJOURNAL: number; /** Open super-journal file. */ SQLITE_OPEN_SUPER_JOURNAL: number; /** Open without mutex. */ SQLITE_OPEN_NOMUTEX: number; /** Open with full mutex. */ SQLITE_OPEN_FULLMUTEX: number; /** Enable shared cache mode. */ SQLITE_OPEN_SHAREDCACHE: number; /** Enable private cache mode. */ SQLITE_OPEN_PRIVATECACHE: number; /** Open WAL file. */ SQLITE_OPEN_WAL: number; } /** * Options for the pragma() method. * * @see https://sqlite.org/pragma.html */ interface PragmaOptions { /** * When true, returns only the first column of the first row. * This is useful for pragmas that return a single value. * * @default false * * @example * ```typescript * // Without simple: returns [{ cache_size: -16000 }] * db.pragma('cache_size'); * * // With simple: returns -16000 * db.pragma('cache_size', { simple: true }); * ``` */ readonly simple?: boolean; } /** * Transaction isolation modes supported by SQLite. * * @see https://sqlite.org/lang_transaction.html */ type TransactionMode = "deferred" | "immediate" | "exclusive"; /** * A function wrapped in a transaction. When called, it automatically: * - Begins a transaction (or savepoint if nested) * - Executes the wrapped function * - Commits on success, rolls back on error * * The function also has variants for different transaction modes accessible as * properties (`.deferred`, `.immediate`, `.exclusive`). * * **Note:** Each variant is itself a `TransactionFunction` with circular * references to all other variants. This matches better-sqlite3's behavior * where you can chain variants like `txn.deferred.immediate()` - the last * variant in the chain determines the actual transaction mode used. * * @example * ```typescript * const insertMany = db.transaction((items: Item[]) => { * for (const item of items) insert.run(item); * return items.length; * }); * * // Use default mode (DEFERRED) * insertMany([{ id: 1 }, { id: 2 }]); * * // Use IMMEDIATE mode for write transactions * insertMany.immediate([{ id: 3 }, { id: 4 }]); * * // Use EXCLUSIVE mode for exclusive access * insertMany.exclusive([{ id: 5 }, { id: 6 }]); * ``` */ interface TransactionFunction any> { /** * Execute the wrapped function within a transaction using the default mode (DEFERRED). */ (...args: Parameters): ReturnType; /** * Execute with DEFERRED transaction mode. * The database lock is not acquired until the first read or write operation. * This is the default SQLite behavior. */ readonly deferred: TransactionFunction; /** * Execute with IMMEDIATE transaction mode. * Acquires a write lock immediately, blocking other writers. * Recommended for transactions that will write to prevent SQLITE_BUSY errors. */ readonly immediate: TransactionFunction; /** * Execute with EXCLUSIVE transaction mode. * Acquires an exclusive lock immediately, blocking all other connections. * Use sparingly as it prevents all concurrent access. */ readonly exclusive: TransactionFunction; /** * The database connection this transaction function is bound to. */ readonly database: DatabaseSyncInstance; } /** * Enhancement utilities for adding better-sqlite3-style methods to any * compatible database, including `node:sqlite` DatabaseSync and this package's * DatabaseSync. * * This module provides the `enhance()` function which adds `.pragma()`, * `.transaction()`, and statement modes (`.pluck()`, `.raw()`, `.expand()`) * to database instances that don't have them (e.g., node:sqlite DatabaseSync). */ /** * Minimal interface for a database that can be enhanced. This matches the * subset of functionality needed by pragma() and transaction(). */ interface EnhanceableDatabaseSync { /** Execute SQL without returning results */ exec(sql: string): void; /** Prepare a statement that can return results */ prepare(sql: string): { all(): unknown[]; }; /** Whether the database connection is open */ readonly isOpen?: boolean; /** Whether a transaction is currently active */ readonly isTransaction: boolean; } /** * A statement enhanced with better-sqlite3-style `.pluck()`, `.raw()`, and * `.expand()` methods. These are mutually exclusive — enabling one disables * the others. */ interface EnhancedStatementMethods { /** * Causes the statement to return only the first column value of each row. * * When plucking is turned on, raw and expand modes are turned off. * * @param toggle Enable (true) or disable (false) pluck mode. Defaults to true. * @returns The same statement for chaining. * * @example * ```typescript * const count = db.prepare("SELECT COUNT(*) FROM users").pluck().get(); * // Returns: 42 (not { "COUNT(*)": 42 }) * * const names = db.prepare("SELECT name FROM users").pluck().all(); * // Returns: ["Alice", "Bob"] (not [{ name: "Alice" }, { name: "Bob" }]) * ``` */ pluck(toggle?: boolean): this; /** * Causes the statement to return rows as arrays of values instead of objects. * * When raw mode is turned on, pluck and expand modes are turned off. * * @param toggle Enable (true) or disable (false) raw mode. Defaults to true. * @returns The same statement for chaining. * * @example * ```typescript * const rows = db.prepare("SELECT id, name FROM users").raw().all(); * // Returns: [[1, "Alice"], [2, "Bob"]] (not [{ id: 1, name: "Alice" }, ...]) * ``` */ raw(toggle?: boolean): this; /** * Causes the statement to return data namespaced by table. Each key in a row * object will be a table name, and each corresponding value will be a nested * object containing that table's columns. Columns from expressions or * subqueries are placed under the special `$` namespace. * * When expand mode is turned on, pluck and raw modes are turned off. * * Requires the statement to have a `.columns()` method (available on real * statements but not minimal mocks). * * @param toggle Enable (true) or disable (false) expand mode. Defaults to true. * @returns The same statement for chaining. * * @example * ```typescript * const rows = db.prepare("SELECT u.id, u.name, p.title FROM users u JOIN posts p ON ...").expand().all(); * // Returns: [{ users: { id: 1, name: "Alice" }, posts: { title: "Hello" } }] * ``` */ expand(toggle?: boolean): this; /** The database instance this statement was prepared from. */ readonly database: EnhanceableDatabaseSync; } /** * Interface for an enhanced database with pragma() and transaction() methods. */ interface EnhancedMethods { /** * Executes a PRAGMA statement and returns its result. * * @param source The PRAGMA command (without "PRAGMA" prefix) * @param options Optional configuration * @returns Array of rows, or single value if `simple: true` * * @example * ```typescript * db.pragma('cache_size', { simple: true }); // -16000 * db.pragma('journal_mode = wal'); * ``` */ pragma(source: string, options?: PragmaOptions): unknown; /** * Creates a function that always runs inside a transaction. * * @param fn The function to wrap in a transaction * @returns A transaction function with `.deferred`, `.immediate`, * `.exclusive` variants * * @example * ```typescript * const insertMany = db.transaction((items) => { * for (const item of items) insert.run(item); * }); * insertMany(['a', 'b', 'c']); // All in one transaction * ``` */ transaction any>(fn: F): TransactionFunction; } /** * A database instance that has been enhanced with pragma(), transaction(), * and statement modes (pluck/raw/expand) on statements returned by prepare(). */ type EnhancedDatabaseSync = Omit & EnhancedMethods & { prepare(...args: Parameters): ReturnType & EnhancedStatementMethods; }; /** * Ensures that `.pragma()`, `.transaction()`, and statement modes * (`.pluck()`, `.raw()`, `.expand()`) are available on the given database. * * This function can enhance: * - `node:sqlite` DatabaseSync instances (adds the methods) * - `@photostructure/sqlite` DatabaseSync instances (adds the methods) * - Any object with compatible `exec()`, `prepare()`, and `isTransaction` * * The enhancement is done by adding methods directly to the instance, not the * prototype, so it won't affect other instances or the original class. * * @param db The database instance to enhance * @returns The same instance with `.pragma()`, `.transaction()`, and * `.pluck()` / `.raw()` / `.expand()` (on prepared statements) guaranteed * * @example * ```typescript * import { DatabaseSync, enhance } from '@photostructure/sqlite'; * * const db = enhance(new DatabaseSync(':memory:')); * * // better-sqlite3-style pragma * db.pragma('journal_mode = wal'); * * // better-sqlite3-style transactions * const insertMany = db.transaction((items) => { * for (const item of items) insert.run(item); * }); * * // better-sqlite3-style pluck * const count = db.prepare("SELECT COUNT(*) FROM users").pluck().get(); * const names = db.prepare("SELECT name FROM users").pluck().all(); * ``` */ declare function enhance(db: T): EnhancedDatabaseSync; /** * Type guard to check if a database has enhanced methods. * * @param db The database to check * @returns True if the database has `.pragma()` and `.transaction()` methods * * @example * ```typescript * import { isEnhanced } from '@photostructure/sqlite'; * * if (isEnhanced(db)) { * db.pragma('cache_size', { simple: true }); * } * ``` */ declare function isEnhanced(db: EnhanceableDatabaseSync): db is EnhanceableDatabaseSync & EnhancedMethods; /** * All SQLite constants exported by this module. * * This is a union of all constant category interfaces: * - {@link SqliteOpenFlags} - Database open flags (extension beyond `node:sqlite`) * - {@link SqliteChangesetResolution} - Changeset conflict resolution values * - {@link SqliteChangesetConflictTypes} - Changeset conflict type codes * - {@link SqliteAuthorizationResults} - Authorization return values * - {@link SqliteAuthorizationActions} - Authorization action codes * * **Note:** The categorized interfaces (`SqliteOpenFlags`, etc.) are extensions * provided by `@photostructure/sqlite`. The `node:sqlite` module exports only * a flat `constants` object without these type categories. */ type SqliteConstants = SqliteOpenFlags & SqliteChangesetResolution & SqliteChangesetConflictTypes & SqliteAuthorizationResults & SqliteAuthorizationActions; /** * Options for creating a prepared statement. * * **Note:** The per-statement override options (`readBigInts`, `returnArrays`, * `allowBareNamedParameters`, `allowUnknownNamedParameters`) are a **Node.js v25+** * feature. On Node.js v24 and earlier, `node:sqlite` silently ignores these options. * This library implements them for forward compatibility with Node.js v25+. */ interface StatementOptions { /** If true, the prepared statement's expandedSQL property will contain the expanded SQL. @default false */ readonly expandedSQL?: boolean; /** If true, anonymous parameters are enabled for the statement. @default false */ readonly anonymousParameters?: boolean; /** * If true, read integer values as JavaScript BigInt. Overrides database-level setting. * **Node.js v25+ feature** - silently ignored by `node:sqlite` on v24 and earlier. * @default database default */ readonly readBigInts?: boolean; /** * If true, return results as arrays rather than objects. Overrides database-level setting. * **Node.js v25+ feature** - silently ignored by `node:sqlite` on v24 and earlier. * @default database default */ readonly returnArrays?: boolean; /** * If true, allows bare named parameters (without prefix). Overrides database-level setting. * **Node.js v25+ feature** - silently ignored by `node:sqlite` on v24 and earlier. * @default database default */ readonly allowBareNamedParameters?: boolean; /** * If true, unknown named parameters are ignored. Overrides database-level setting. * **Node.js v25+ feature** - silently ignored by `node:sqlite` on v24 and earlier. * @default database default */ readonly allowUnknownNamedParameters?: boolean; } /** * The main SQLite module interface. */ interface SqliteModule { /** * The DatabaseSync class represents a synchronous connection to a SQLite database. * All operations are performed synchronously, blocking until completion. */ DatabaseSync: new (location?: string | Buffer | URL, options?: DatabaseSyncOptions) => DatabaseSyncInstance; /** * The StatementSync class represents a synchronous prepared statement. * This class should not be instantiated directly; use Database.prepare() instead. */ StatementSync: new (database: DatabaseSyncInstance, sql: string, options?: StatementOptions) => StatementSyncInstance; /** * The Session class for recording database changes. * This class should not be instantiated directly; use Database.createSession() instead. */ Session: new () => Session; /** * SQLite constants for various operations and flags. * @see {@link SqliteConstants} for the type definition * @see {@link SqliteOpenFlags} for database open flags (extension beyond `node:sqlite`) * @see {@link SqliteChangesetResolution} for changeset conflict resolution values * @see {@link SqliteChangesetConflictTypes} for changeset conflict type codes * @see {@link SqliteAuthorizationResults} for authorization return values * @see {@link SqliteAuthorizationActions} for authorization action codes */ constants: SqliteConstants; } declare const DatabaseSync: SqliteModule["DatabaseSync"]; declare const StatementSync: SqliteModule["StatementSync"]; interface Session { /** * Generate a changeset containing all changes recorded by the session. * @returns A Uint8Array containing the changeset data. */ changeset(): Uint8Array; /** * Generate a patchset containing all changes recorded by the session. * @returns A Uint8Array containing the patchset data. */ patchset(): Uint8Array; /** * Close the session and release its resources. */ close(): void; } /** * The Session class for recording database changes. * This class should not be instantiated directly; use DatabaseSync.createSession() instead. * * @example * ```typescript * const session = db.createSession({ table: 'users' }); * // Make some changes to the users table * const changeset = session.changeset(); * session.close(); * ``` */ declare const Session: SqliteModule["Session"]; /** * SQLite constants for various operations and flags. * * @example * ```typescript * import { constants } from '@photostructure/sqlite'; * * const db = new DatabaseSync('./data.db', { * readOnly: true, * // Uses SQLITE_OPEN_READONLY internally * }); * ``` */ declare const constants: SqliteConstants; /** * Options for the backup() function. */ interface BackupOptions { /** Number of pages to be transmitted in each batch of the backup. @default 100 */ rate?: number; /** Name of the source database. Can be 'main' or any attached database. @default 'main' */ source?: string; /** Name of the target database. Can be 'main' or any attached database. @default 'main' */ target?: string; /** Callback function that will be called with progress information. */ progress?: (info: { totalPages: number; remainingPages: number; }) => void; } /** * Standalone function to make a backup of a database. * * This function matches the Node.js `node:sqlite` module API which exports * `backup()` as a standalone function in addition to the `db.backup()` method. * * @param sourceDb The database to backup from. * @param destination The path where the backup will be created. * @param options Optional configuration for the backup operation. * @returns A promise that resolves when the backup is completed. * * @example * ```typescript * import { DatabaseSync, backup } from '@photostructure/sqlite'; * * const db = new DatabaseSync('./source.db'); * await backup(db, './backup.db'); * * // With options * await backup(db, './backup.db', { * rate: 10, * progress: ({ totalPages, remainingPages }) => { * console.log(`Progress: ${totalPages - remainingPages}/${totalPages}`); * } * }); * ``` */ declare const backup: (sourceDb: DatabaseSyncInstance, destination: string | Buffer | URL, options?: BackupOptions) => Promise; declare const _default: SqliteModule; export { type AggregateOptions, type BackupOptions, type ChangesetApplyOptions, DatabaseSync, type DatabaseSyncInstance, type DatabaseSyncLimits, type DatabaseSyncOptions, type EnhanceableDatabaseSync, type EnhancedDatabaseSync, type EnhancedMethods, type EnhancedStatementMethods, type PragmaOptions, SQLTagStore, type SQLTagStoreInstance, Session, type SessionOptions, type SqliteAuthorizationActions, type SqliteAuthorizationResults, type SqliteChangesetConflictTypes, type SqliteChangesetResolution, type SqliteConstants, type SqliteModule, type SqliteOpenFlags, type StatementColumnMetadata, type StatementOptions, StatementSync, type StatementSyncInstance, type TransactionFunction, type TransactionMode, type UserFunctionOptions, backup, constants, _default as default, enhance, isEnhanced };