@sqlite.org/sqlite-wasm
Version:
SQLite Wasm conveniently wrapped as an ES Module.
1,291 lines (1,201 loc) • 284 kB
TypeScript
/** Types of values that can be passed to/retrieved from SQLite. */
declare type SqlValue =
| string
| number
| null
| bigint
| Uint8Array
| Int8Array
| ArrayBuffer;
/** Types of values that can be passed to SQLite. */
declare type BindableValue =
| SqlValue
/** Converted to NULL */
| undefined
/** Converted to INTEGER */
| boolean;
/** Internal data types supported by SQLite3. */
declare type SQLiteDataType =
| CAPI['SQLITE_INTEGER']
| CAPI['SQLITE_FLOAT']
| CAPI['SQLITE_TEXT']
| CAPI['SQLITE_BLOB']
| CAPI['SQLITE_NULL'];
/** Specifies parameter bindings. */
declare type BindingSpec =
| readonly BindableValue[]
| { [paramName: string]: BindableValue }
/** Assumed to have binding index `1` */
| (SqlValue | boolean);
/**
* Certain WASM-bound APIs, where explicitly noted, have additional string-type
* argument conversions colloquially known as "flexible strings." This support
* is generally reserved for arguments which expect SQL strings, as such strings
* are often large and frequently come from external sources, e.g. byte arrays
* loaded from local files, over XHR requests, or using `fetch()`. Functions
* which take filename strings, and simlilar "small" strings, do not use this
* feature.
*/
declare type FlexibleString =
| string
/** WASM C-string pointer, passed on to WASM as-is. */
| WasmPointer
/** Assumed to hold UTF-8 encoded text, converted to `string` */
| Uint8Array
| Int8Array
| ArrayBuffer
/**
* Gets converted to a string using `theArray.join('')` (i.e. concatenated
* as-is, with no space between each entry). Though JS supports multi-line
* string literals with the backtick syntax, it is frequently convenient to
* write out longer SQL constructs as arrays.
*/
| readonly string[];
/**
* Prepared statements are created solely through the {@link Database#prepare}
* method. Calling the constructor directly will trigger an exception.
*
* It is important that statements be finalized in a timely manner, else clients
* risk introducing locking errors later on in their apps.
*
* By and large, clients can avoid statement lifetime issues by using the
* {@link Database#exec} method. For cases when more control or flexibility is
* needed, however, clients will need to {@link Database#prepare} statements and
* then ensure that their lifetimes are properly managed. The simplest way to do
* this is with a `try`/`finally` block, as in this example:
*
* @example
* const stmt = myDb.prepare("...");
* try {
* ... use the stmt object ...
* } finally {
* stmt.finalize();
* }
*/
declare class PreparedStatement {
/** Binds one more values to its bindable parameters. */
bind(binding: BindingSpec): this;
/**
* Binds a value to a bindable parameter.
*
* @param idx The index of the bindable parameter to bind to, **ACHTUNG**:
* 1-based!
*/
bind(idx: number, binding: SqlValue): this;
/**
* Special case of {@link PreparedStatement#bind} which binds the given value
* using the `BLOB` binding mechanism instead of the default selected one for
* the value. Index can be the index number (**ACHTUNG**: 1-based!) or the
* string corresponding to a named parameter.
*/
bindAsBlob(
value: string | null | undefined | Uint8Array | Int8Array | ArrayBuffer,
): this;
bindAsBlob(
idx: number | string,
value: string | null | undefined | Uint8Array | Int8Array | ArrayBuffer,
): this;
/** Clears all bound values. */
clearBindings(): this;
/**
* "Finalizes" this statement. This is a no-op if the statement has already
* been finalized. Returns the value of the underlying `sqlite3_finalize()`
* call (0 on success, non-0 on error) or `undefined` if the statement has
* already been finalized. It does not throw if `sqlite3_finalize()` returns
* non-0 because this function is effectively a destructor and "destructors do
* not throw." This function will throw if it is called while the statement is
* in active use via a {@link Database#exec} callback.
*/
finalize(): number | undefined;
/**
* Fetches the value from the given 0-based column index of the current data
* row, throwing if index is out of range.
*
* Requires that {@link PreparedStatement#step} has just returned a truthy
* value, else an exception is thrown.
*
* By default it will determine the data type of the result automatically. If
* passed a second arugment, it must be one of the enumeration values for
* sqlite3 types, which are defined as members of the sqlite3 namespace:
* `SQLITE_INTEGER`, `SQLITE_FLOAT`, `SQLITE_TEXT`, `SQLITE_BLOB`. Any other
* value, except for `undefined`, will trigger an exception. Passing
* `undefined` is the same as not passing a value. It is legal to, e.g., fetch
* an integer value as a string, in which case sqlite3 will convert the value
* to a string.
*
* If the index is an array, this function behaves a differently: it assigns
* the indexes of the array, from 0 to the number of result columns, to the
* values of the corresponding result column, and returns that array:
*
* const values = stmt.get([]);
*
* This will return an array which contains one entry for each result column
* of the statement's current row..
*
* If the index is a plain object, this function behaves even differentlier:
* it assigns the properties of the object to the values of their
* corresponding result columns:
*
* const values = stmt.get({});
*
* This returns an object with properties named after the columns of the
* result set. Be aware that the ordering of the properties is undefined. If
* their order is important, use the array form instead.
*
* Blobs are returned as `Uint8Array` instances.
*
* Special case handling of 64-bit integers: the `Number` type is used for
* both floating point numbers and integers which are small enough to fit into
* it without loss of precision. If a larger integer is fetched, it is
* returned as a `BigInt` if that support is enabled, else it will throw an
* exception. The range of integers supported by the Number class is defined
* as:
*
* - `Number.MIN_SAFE_INTEGER = -9007199254740991`
* - `Number.MAX_SAFE_INTEGER = 9007199254740991`
*/
get(ndx: number, asType?: SQLiteDataType): SqlValue;
get(ndx: SqlValue[]): SqlValue[];
get(ndx: { [columnName: string]: SqlValue }): {
[columnName: string]: SqlValue;
};
/**
* Equivalent to {@link PreparedStatement#get(ndx)} but coerces the result to a
* `Uint8Array`.
*/
getBlob(ndx: number): Uint8Array | null;
/**
* Returns the result column name of the given index, or throws if index is
* out of bounds or this statement has been finalized. This may be used
* without having run {@link PreparedStatement#step()} first.
*/
getColumnName(ndx: number): string;
/**
* If this statement potentially has result columns, this function returns an
* array of all such names. If passed an array, it is used as the target and
* all names are appended to it. Returns the target array. Throws if this
* statement cannot have result columns. `this.columnCount`, set with the
* statement is prepared, holds the number of columns.
*/
getColumnNames(target?: string[]): string[];
/**
* Equivalent to {@link PreparedStatement#get(ndx)} but coerces the result to a
* number.
*/
getFloat(ndx: number): number | null;
/**
* Equivalent to {@link PreparedStatement#get(ndx)} but coerces the result to
* an integral number.
*/
getInt(ndx: number): number | null;
/**
* Equivalent to {@link PreparedStatement#getString(ndx)} but returns passes
* the result of passing the fetched string string through `JSON.parse()`. If
* JSON parsing throws, that exception is propagated.
*/
getJSON(ndx: number): any;
/**
* If this statement has named bindable parameters and the given name matches
* one, its 1-based bind index is returned. If no match is found, 0 is
* returned. If it has no bindable parameters, the undefined value is
* returned.
*/
getParamIndex(name: string): number | undefined;
/**
* Equivalent to {@link PreparedStatement#get(ndx)} but coerces the result to a
* string.
*/
getString(ndx: number): string | null;
/**
* Resets this statement so that it may be `step()`ed again from the
* beginning. Returns `this`. Throws if this statement has been finalized, if
* it may not legally be reset because it is currently being used from a
* {@link Database#exec} callback, or (as of versions 3.42.1 and 3.43) if the
* underlying call to `sqlite3_reset()` returns non-0.
*
* If passed a truthy argument then {@link PreparedStatement#clearBindings} is
* also called, otherwise any existing bindings, along with any memory
* allocated for them, are retained.
*
* In versions 3.42.0 and earlier, this function did not throw if
* `sqlite3_reset()` returns non-0, but it was discovered that throwing (or
* significant extra client-side code) is necessary in order to avoid certain
* silent failure scenarios
*/
reset(alsoClearBinds?: boolean): this;
/**
* Steps the statement one time. If the result indicates that a row of data is
* available, a truthy value is returned. If no row of data is available, a
* falsy value is returned. Throws on error.
*/
step(): boolean;
/**
* Functions like {@link PreparedStatement#step} except that it calls
* {@link PreparedStatement#finalize} on this statement immediately after
* stepping unless the `step()` throws.
*
* On success, it returns true if the step indicated that a row of data was
* available, else it returns false.
*
* This is intended to simplify use cases such as:
*
* ADb.prepare('INSERT INTO foo(a) VALUES(?)').bind(123).stepFinalize();
*/
stepFinalize(): boolean;
/**
* Functions exactly like {@link PreparedStatement#step} except that...
*
* On success, it calls {@link PreparedStatement#reset} and returns this
* object. On error, it throws and does not call reset().
*
* This is intended to simplify constructs like:
*
* For(...) { stmt.bind(...).stepReset(); }
*
* Note that the {@link PreparedStatement#reset} call makes it illegal to call
* {@link PreparedStatement#get} after the step.
*/
stepReset(): this;
/**
* The number of result columns this statement has, or 0 for statements which
* do not have result columns.
*
* _Minor achtung:_ for all releases > 3.42.0 this is a property interceptor
* which invokes `sqlite3_column_count`, so its use should be avoided in loops
* because of the call overhead. In versions <= 3.42.0 this value is collected
* and cached when the statement is created, but that can lead to misbehavior
* if changes are made to the database schema while this statement is active.
*/
columnCount: number;
/** The number of bindable parameters this statement has. */
parameterCount: number;
/**
* WASM pointer rwhich resolves to the `sqlite3_stmt*` which this object
* wraps. This value may be passed to any WASM-bound functions which accept an
* `sqlite3_stmt*` argument. It resolves to `undefined` after this statement
* is {@link PreparedStatement#finalize}d.
*/
pointer: WasmPointer | undefined;
}
declare type ExecOptions = {
/**
* The SQL to run (unless it's provided as the first argument). The SQL may
* contain any number of statements.
*/
sql?: FlexibleString;
/**
* A single value valid as an argument for {@link PreparedStatement#bind}. This
* is only applied to the first non-empty statement in the SQL which has any
* bindable parameters. (Empty statements are skipped entirely.)
*/
bind?: BindingSpec;
/**
* If set, the SQL of each executed statement is appended to this array before
* the statement is executed (but after it is prepared - we don't have the
* string until after that). Empty SQL statements are elided.
*/
saveSql?: string[];
/**
* A string specifying what this function should return: The default value is
* (usually) `"this"`. The exceptions is if the caller passes neither of
* `callback` nor `returnValue` but does pass an explicit `rowMode` then the
* default returnValue is `"resultRows"`, described below. The options are:
*
* - `"this"` menas that the DB object itself should be returned.
* - `"resultRows"` means to return the value of the `resultRows` option. If
* `resultRows` is not set, this function behaves as if it were set to an
* empty array.
* - `"saveSql"` means to return the value of the `saveSql` option. If `saveSql`
* is not set, this function behaves as if it were set to an empty array.
*/
returnValue?: 'this' | 'resultRows' | 'saveSql';
/**
* A function which gets called for each row of the result set (see `rowMode`,
* below), but only if that statement has any result rows. The callback's
* `this` is the `options` object, noting that this function will synthesize
* one if the caller does not provide one. The second argument passed to the
* callback is always the current {@link PreparedStatement} object, as it's
* needed if the caller wants to fetch the column names or some such (noting
* that they could also be fetched via `this.columnNames`, if the client
* provides the `columnNames` option). If the callback returns a literal
* `false` (as opposed to any other falsy value, e.g. an implicit undefined
* return), any ongoing statement-`step()` iteration stops without an error.
* The return value of the callback is otherwise ignored.
*
* Applies only to the first statement which has a non-zero result column
* count, regardless of whether the statement actually produces any result
* rows.
*
* **ACHTUNG:** the callback **MUST NOT** modify the {@link PreparedStatement}
* object. Calling any of the {@link PreparedStatement#get} variants,
* {@link PreparedStatement#getColumnName}, or similar, is legal, but calling
* {@link PreparedStatement#step} or {@link PreparedStatement#finalize} is not.
* Member methods which are illegal in this context will trigger an exception,
* but clients must also refrain from using any lower-level (C-style) APIs
* which might modify the statement.
*/
callback?: (
row:
| SqlValue[]
| { [columnName: string]: SqlValue }
| PreparedStatement
| SqlValue,
stmt: PreparedStatement,
) => void | false;
/**
* If this is an array, the column names of the result set are stored in this
* array before the `callback` (if any) is triggered (regardless of whether
* the query produces any result rows). If no statement has result columns,
* this value is unchanged.
*
* Applies only to the first statement which has a non-zero result column
* count, regardless of whether the statement actually produces any result
* rows.
*
* **Achtung:** an SQL result may have multiple columns with identical names.
*/
columnNames?: string[];
/**
* If this is an array, it functions similarly to the `callback` option: each
* row of the result set (if any), with the exception that the `rowMode`
* `'stmt'` is not legal. It is legal to use both `resultRows` and callback,
* but `resultRows` is likely much simpler to use for small data sets and can
* be used over a WebWorker-style message interface. `exec()` throws if
* `resultRows` is set and rowMode is `'stmt'`.
*
* Applies only to the first statement which has a non-zero result column
* count, regardless of whether the statement actually produces any result
* rows.
*/
resultRows?: (SqlValue[] | { [columnName: string]: SqlValue } | SqlValue)[];
/**
* Specifies the type of he `callback`'s first argument and the type of the
* `resultRows` array entries.
*/
rowMode?: 'array' | 'object' | 'stmt' | number | string;
};
/**
* Derivate type of ExecOptions to be used as base mixin for method overloads on
* `exec`
*/
declare type ExecBaseOptions = Omit<
ExecOptions,
'callback' | 'resultRows' | 'rowMode' | 'returnValue' | 'sql'
>;
declare type ExecReturnThisOptions = {
returnValue?: 'this';
};
declare type ExecReturnResultRowsOptions = {
returnValue: 'resultRows';
};
declare type ExecReturnSaveSqlOptions = {
returnValue: 'saveSql';
};
declare type ExecRowModeArrayOptions = {
callback?: (row: SqlValue[]) => void | false;
resultRows?: SqlValue[][];
rowMode?: 'array';
};
declare type ExecRowModeObjectOptions = {
callback?: (row: { [columnName: string]: SqlValue }) => void | false;
resultRows?: { [columnName: string]: SqlValue }[];
rowMode: 'object';
};
declare type ExecRowModeStmtOptions = {
callback?: (row: PreparedStatement) => void | false;
resultRows?: undefined;
rowMode: 'stmt';
};
declare type ExecRowModeScalarOptions = {
callback?: (row: SqlValue) => void | false;
resultRows?: SqlValue[];
/**
* For number values: indicates a zero-based column in the result row. Only
* that one single value will be passed on. If string. For string values: A
* string with a minimum length of 2 and leading character of `$` will fetch
* the row as an object, extract that one field, and pass that field's value
* to the `callback`. Note that these keys are case-sensitive so must match
* the case used in the SQL. e.g. `"select a A from t"` with a `rowMode` of
* `'$A'` would work but `'$a'` would not. A reference to a column not in the
* result set will trigger an exception on the first row (as the check is not
* performed until rows are fetched).
*/
rowMode: number | Exclude<string, 'stmt' | 'array' | 'object'>;
};
/** Options for creating a user-defined function that can be called from SQL. */
declare type FunctionOptions = {
/**
* Number of arguments which SQL calls to this function expect or require. The
* default value is `X.length` MINUS 1, where X is either `xFunc` or `xStep`,
* depending on the type of function being created. As a special case, if
* `X.length` is 0, its arity is also 0 instead of -1. A negative arity value
* means that the function is variadic and may accept any number of arguments,
* up to sqlite3's compile-time limits. sqlite3 will enforce the argument
* count if is zero or greater. The callback always receives a pointer to an
* `sqlite3_context` object as its first argument. Any arguments after that
* are from SQL code. The leading context argument does not count towards the
* function's arity. See the docs for `sqlite3_create_function()` for why that
* argument is required in the interface.
*/
arity?: number;
/**
* Corresponds to the `SQLITE_DETERMINISTIC` flag. Setting it means that the
* new function always gives the same output when the input parameters are the
* same. The `abs()` function is deterministic, for example, but
* `randomblob()` is not. Functions must be deterministic in order to be used
* in certain contexts such as with the `WHERE` clause of partial indexes or
* in generated columns. SQLite might also optimize deterministic functions by
* factoring them out of inner loops.
*/
deterministic?: boolean;
/**
* Corresponds to the `SQLITE_DIRECTONLY` flag.
*
* Setting it means that the function may only be invoked from top-level SQL,
* and cannot be used in `VIEW`s or `TRIGGER`s nor in schema structures such
* as `CHECK` constraints, `DEFAULT` clauses, expression indexes, partial
* indexes, or generated columns.
*
* The flag is recommended for any application-defined SQL function that has
* side-effects or that could potentially leak sensitive information. This
* will prevent attacks in which an application is tricked into using a
* database file that has had its schema surreptiously modified to invoke the
* application-defined function in ways that are harmful.
*
* Some people say it is good practice to set the flag on all
* application-defined SQL functions, regardless of whether or not they are
* security sensitive, as doing so prevents those functions from being used
* inside of the database schema, and thus ensures that the database can be
* inspected and modified using generic tools (such as the CLI) that do not
* have access to the application-defined functions.
*/
directOnly?: boolean;
/**
* Corresponds to the `SQLITE_INNOCUOUS` flag.
*
* Setting it means that the function is unlikely to cause problems even if
* misused. An innocuous function should have no side effects and should not
* depend on any values other than its input parameters. The `abs()` function
* is an example of an innocuous function. The `load_extension()` SQL function
* is not innocuous because of its side effects. The flag is similar to
* {@link FunctionOptions#directOnly}, but is not exactly the same. The
* `random()` function is an example of a function that is innocuous but not
* deterministic.
*
* Some heightened security settings (`SQLITE_DBCONFIG_TRUSTED_SCHEMA` and
* `PRAGMA trusted_schema=OFF`) disable the use of SQL functions inside views
* and triggers and in schema structures such as `CHECK` constraints,
* `DEFAULT` clauses, expression indexes, partial indexes, and generated
* columns unless the function is tagged with `SQLITE_INNOCUOUS`. Most
* built-in functions are innocuous. Developers are advised to avoid using the
* `SQLITE_INNOCUOUS` flag for application-defined functions unless the
* function has been carefully audited and found to be free of potentially
* security-adverse side-effects and information-leaks.
*/
innocuous?: boolean;
/** Name of the user-defined function. */
name?: string;
/**
* The options object may optionally have an xDestroy function-type property,
* as per `sqlite3_create_function_v2()`. Its argument will be the
* WASM-pointer-type value of the pApp property, and this function will throw
* if pApp is defined but is not null, undefined, or a numeric (WASM pointer)
* value. i.e. pApp, if set, must be value suitable for use as a WASM pointer
* argument, noting that null or undefined will translate to 0 for that
* purpose.
*/
xDestroy?: (pAppPtr: WasmPointer) => void;
};
declare type ScalarFunctionOptions = FunctionOptions & {
/** Scalar function to be defined. */
xFunc: (ctxPtr: number, ...args: SqlValue[]) => SqlValue;
};
declare type AggregateFunctionOptions = FunctionOptions & {
/**
* 'Step' callback for an aggregate function.
*
* It is invoked to add a row to the current aggregate value. The function
* arguments, if any, corresponding to the row being added are passed to the
* implementation of {@link AggregateFunctionOptions#xStep}.
*/
xStep: (ctxPtr: number, ...rowValues: SqlValue[]) => void;
/**
* 'Final' callback for an aggregate function.
*
* It is invoked to return the current value of the aggregate, and to free any
* resources allocated by earlier calls to
* {@link AggregateFunctionOptions#xStep}.
*/
xFinal: (ctxPtr: number) => SqlValue;
};
declare type WindowFunctionOptions = FunctionOptions & {
/**
* 'Step' callback for a window function.
*
* It is invoked to add a row to the current window. The function arguments,
* if any, corresponding to the row being added are passed to the
* implementation of {@link WindowFunctionOptions#xStep}.
*/
xStep: (ctxPtr: number, ...args: any[]) => void;
/**
* 'Final' callback for a window function.
*
* It is invoked to return the current value of the aggregate (determined by
* the contents of the current window), and to free any resources allocated by
* earlier calls to {@link WindowFunctionOptions#xStep}.
*/
xFinal: (ctxPtr: number) => SqlValue;
/**
* 'Value' callback for a window function. This method is invoked to return
* the current value of the aggregate. Unlike
* {@link WindowFunctionOptions#xFinal}, the implementation should not delete
* any context.
*/
xValue: (ctxPtr: number) => SqlValue;
/**
* 'Inverse' callback for a window function.
*
* It is invoked to remove the oldest presently aggregated result of
* {@link WindowFunctionOptions#xStep} from the current window. The function
* arguments, if any, are those passed to {@link WindowFunctionOptions#xStep}
* for the row being removed.
*/
xInverse: (ctxPtr: number, ...args: any[]) => void;
};
/**
* An instance of an implementing class corresponds to one `sqlite3*` created
* using `sqlite3_open` or equivalent.
*
* @example
* ```typescript
* const db = new sqlite3.DB();
* try {
* db.exec([
* "create table t(a);",
* "insert into t(a) values(10),(20),(30)"
* ]);
* } finally {
* db.close();
* }
* ```;
*/
declare class Database {
/**
* Creates a connection to the given file, optionally creating it if needed.
*
* @param options The options to use when opening the database file.
* @param options.filename The filename to open. Must be resolvable using
* whatever filesystem layer (virtual or otherwise) is set up for the
* default sqlite3 VFS. Note that the special sqlite3 db names `":memory:"`
* and `""` (temporary db) have their normal special meanings here.
* @param options.flags The flags to use when opening the file. It must be a
* string containing a sequence of letters (in any order, but case
* sensitive) specifying the mode:
*
* - `c`: create if it does not exist, else fail if it does not exist. Implies
* the `w` flag.
* - `w`: write. Implies `r`: a db cannot be write-only.
* - `r`: read-only if neither `w` nor `c` are provided, else it is ignored.
* - `t`: enable tracing of SQL executed on this database handle, sending it to
* `console.log()`. To disable it later, call
* `sqlite3.capi.sqlite3_trace_v2(thisDb.pointer, 0, 0, 0)`. If `w` is
* not provided, the db is implicitly read-only, noting that `rc` is
* meaningless. Any other letters are currently ignored. The default is
* `c`. These modes are ignored for the special `":memory:"` and `""`
* names and may be ignored by specific VFSes.
*/
constructor(options?: { filename?: string; flags?: string; vfs?: string }); // ✓
/**
* Creates a connection to the given file, optionally creating it if needed.
*
* @param filename The filename to open. Must be resolvable using whatever
* filesystem layer (virtual or otherwise) is set up for the default sqlite3
* VFS. Note that the special sqlite3 db names `":memory:"` and `""`
* (temporary db) have their normal special meanings here.
* @param flags The flags to use when opening the file. It must be a string
* containing a sequence of letters (in any order, but case sensitive)
* specifying the mode:
*
* - `c`: create if it does not exist, else fail if it does not exist. Implies
* the `w` flag.
* - `w`: write. Implies `r`: a db cannot be write-only.
* - `r`: read-only if neither `w` nor `c` are provided, else it is ignored.
* - `t`: enable tracing of SQL executed on this database handle, sending it to
* `console.log()`. To disable it later, call
* `sqlite3.capi.sqlite3_trace_v2(thisDb.pointer, 0, 0, 0)`. If `w` is
* not provided, the db is implicitly read-only, noting that `rc` is
* meaningless. Any other letters are currently ignored. The default is
* `c`. These modes are ignored for the special `":memory:"` and `""`
* names and may be ignored by specific VFSes.
*/
constructor(filename?: string, flags?: string, vfs?: string); // ✓
/** Filename which was passed to the constructor. */
filename: string; // ✓
/**
* Resolves to the `sqlite3*` which this object wraps. This value may be
* passed to any WASM-bound functions which accept an `sqlite3*` argument. It
* resolves to `undefined` after this object is `close()`d.
*/
pointer?: WasmPointer; // ✓
/** Callbacks called immediately before/after database is closed. */
onclose?: {
before?: (db: Database) => void;
after?: (db: Database) => void;
}; // ✓
/**
* Executes SQL statements and optionally collects query results and/or calls
* a callback for each result row.
*
* _LOTS_ of overloads on this one one, depending on:
*
* - `sql` as parameter or as option
* - `returnValue`:
*
* - `"this"`: default, return database instance, use for fluent calls
* - `"resultRows"`: return values of `resultRows` array (set to empty array if
* not set by user)
* - `"saveSql"`: return values of `saveSql` option (set to empty array if not
* set by user)
* - `resultRows`:
*
* - `"array"`: Array of column values for every result row
* - `"object"`: Object mapping column names to values for every result row
* - `"stmt"`: Only for use with `callback` option, pass
* {@link PreparedStatement} object for every row.
* - `number`: Extract column with (zero-based) index from every result row
* - `string`: Extract column with name from every result row, must have format
* `$<column>`, with `column` having at least two characters.
*
* ⚠️**ACHTUNG**⚠️: The combination of `returnValue: "resultRows"` and
* `rowMode: "stmt"` type checks fine, but will lead to a runtime error. This
* is due to a limitation in TypeScript's type system which does not allow
* restrictions on `string` types.
*/
exec(
sql: FlexibleString,
opts?: (ExecBaseOptions &
ExecRowModeArrayOptions &
ExecReturnThisOptions) & {
sql?: undefined;
},
): this;
exec(
opts: (ExecBaseOptions &
ExecRowModeArrayOptions &
ExecReturnThisOptions) & { sql: FlexibleString },
): this;
exec(
sql: FlexibleString,
opts: ExecBaseOptions &
ExecRowModeObjectOptions &
ExecReturnThisOptions & {
sql?: undefined;
},
): this;
exec(
opts: ExecBaseOptions &
ExecRowModeObjectOptions &
ExecReturnThisOptions & {
sql: FlexibleString;
},
): this;
exec(
sql: FlexibleString,
opts: ExecBaseOptions &
ExecRowModeStmtOptions &
ExecReturnThisOptions & {
sql?: undefined;
},
): this;
exec(
opts: ExecBaseOptions &
ExecRowModeStmtOptions &
ExecReturnThisOptions & {
sql: FlexibleString;
},
): this;
exec(
sql: FlexibleString,
opts: ExecBaseOptions &
ExecRowModeScalarOptions &
ExecReturnThisOptions & {
sql?: undefined;
},
): this;
exec(
opts: ExecBaseOptions &
ExecRowModeScalarOptions &
ExecReturnThisOptions & {
sql: FlexibleString;
},
): this;
exec(
sql: FlexibleString,
opts: ExecBaseOptions &
ExecRowModeArrayOptions &
ExecReturnResultRowsOptions & {
sql?: undefined;
},
): SqlValue[][];
exec(
opts: ExecBaseOptions &
ExecRowModeArrayOptions &
ExecReturnResultRowsOptions & {
sql: FlexibleString;
},
): SqlValue[][];
exec(
sql: FlexibleString,
opts: ExecBaseOptions &
ExecRowModeObjectOptions &
ExecReturnResultRowsOptions & {
sql?: undefined;
},
): { [columnName: string]: SqlValue }[];
exec(
opts: ExecBaseOptions &
ExecRowModeObjectOptions &
ExecReturnResultRowsOptions & {
sql: FlexibleString;
},
): { [columnName: string]: SqlValue }[];
exec(
sql: FlexibleString,
opts: ExecBaseOptions &
ExecRowModeScalarOptions &
ExecReturnResultRowsOptions & {
sql?: undefined;
},
): SqlValue[];
exec(
opts: ExecBaseOptions &
ExecRowModeScalarOptions &
ExecReturnResultRowsOptions & {
sql: FlexibleString;
},
): SqlValue[];
exec(
sql: FlexibleString,
opts: ExecBaseOptions &
ExecRowModeArrayOptions &
ExecReturnSaveSqlOptions & {
sql?: undefined;
},
): string[];
exec(
opts: ExecBaseOptions &
ExecRowModeArrayOptions &
ExecReturnSaveSqlOptions & {
sql: FlexibleString;
},
): string[];
exec(
sql: FlexibleString,
opts: ExecBaseOptions &
ExecRowModeObjectOptions &
ExecReturnSaveSqlOptions & {
sql?: undefined;
},
): string[];
exec(
opts: ExecBaseOptions &
ExecRowModeObjectOptions &
ExecReturnSaveSqlOptions & {
sql: FlexibleString;
},
): string[];
exec(
sql: FlexibleString,
opts: ExecBaseOptions &
ExecRowModeStmtOptions &
ExecReturnSaveSqlOptions & {
sql?: undefined;
},
): string[];
exec(
opts: ExecBaseOptions &
ExecRowModeStmtOptions &
ExecReturnSaveSqlOptions & {
sql: FlexibleString;
},
): string[];
exec(
sql: FlexibleString,
opts: ExecBaseOptions &
ExecRowModeScalarOptions &
ExecReturnSaveSqlOptions & {
sql?: undefined;
},
): string[];
exec(
opts: ExecBaseOptions &
ExecRowModeScalarOptions &
ExecReturnSaveSqlOptions & {
sql: FlexibleString;
},
): string[];
/**
* Compiles the given SQL and returns a {@link PreparedStatement}. This is the
* only way to create new {@link PreparedStatement} objects. Throws on error.
*/
prepare(sql: FlexibleString): PreparedStatement;
/** Returns true if the database handle is open, else false. */
isOpen(): boolean;
/** Throws if the given DB has been closed. */
affirmOpen(): this;
/**
* Finalizes all still-open statements which were opened by this object and
* closes this database connection. This is a no-op if the db has already been
* closed. After calling `close()`, {@link pointer} will resolve to
* `undefined`, so that can be used to check whether the db instance is still
* opened.
*
* If {@link onclose.before} is a function then it is called before any
* close-related cleanup. If {@link onclose.after} is a function then it is
* called after the db is closed but before auxiliary state like this.filename
* is cleared.
*
* Both onclose handlers are passed this object as their only argument. If
* this db is not opened, neither of the handlers are called. Any exceptions
* the handlers throw are ignored because "destructors must not throw."
*
* Note that garbage collection of a db handle, if it happens at all, will
* never trigger `close()`, so {@link onclose} handlers are not a reliable way
* to implement close-time cleanup or maintenance of a db.
*/
close(): void; // ✓
/**
* Returns the number of changes, as per `sqlite3_changes()` (if the first
* argument is `false`) or `sqlite3_total_changes()` (if it's `true`). If the
* 2nd argument is `true`, it uses `sqlite3_changes64()` or
* `sqlite3_total_changes64()`, which will trigger an exception if this build
* does not have `BigInt` support enabled.
*/
changes(total?: boolean, sixtyFour?: boolean): number;
/**
* Returns the filename associated with the given database name. Defaults to
* `main`. Throws if this database is `close()`d.
*/
dbFilename(dbName?: string): string | null;
/**
* Returns the name of the given 0-based db number. Defaults to `0`. Throws if
* this database is `close()`d.
*/
dbName(dbIndex?: number): string | null;
/**
* Returns the name of the sqlite_vfs for the given database. Defaults to
* `main`. Throws if this database is `close()`d.
*/
dbVfsName(dbName?: string | number): string | undefined;
/**
* Creates a new scalar, aggregate, or window function which is accessible via
* SQL code.
*
* When called from SQL, arguments to the UDF, and its result, will be
* converted between JS and SQL with as much fidelity as is feasible,
* triggering an exception if a type conversion cannot be determined. Some
* freedom is afforded to numeric conversions due to friction between the JS
* and C worlds: integers which are larger than 32 bits will be treated as
* doubles or `BigInt` values.
*
* UDFs cannot currently be removed from a DB handle after they're added. More
* correctly, they can be removed as documented for
* `sqlite3_create_function_v2()`, but doing so will "leak" the JS-created
* WASM binding of those functions.
*
* The first two call forms can only be used for creating scalar functions.
* Creating an aggregate or window function requires the options-object form,
* as described below.
*/
createFunction(
name: string,
func: (ctxPtr: number, ...values: SqlValue[]) => SqlValue,
): this;
createFunction(
name: string,
func: (ctxPtr: number, ...values: SqlValue[]) => void,
options: FunctionOptions,
): this;
createFunction(
name: string,
options:
| ScalarFunctionOptions
| AggregateFunctionOptions
| WindowFunctionOptions,
): this;
createFunction(
options: (
| ScalarFunctionOptions
| AggregateFunctionOptions
| WindowFunctionOptions
) & { name: string },
): this;
/**
* Prepares the given SQL, `step()`s it one time, and returns an array
* containing the values of the first result row. If it has no results,
* `undefined` is returned. If passed a second argument other than
* `undefined`, it is treated like an argument to
* {@link PreparedStatement#bind}, so may be any type supported by that
* function. Throws on error.
*/
selectArray(sql: FlexibleString, bind?: BindingSpec): SqlValue[] | undefined;
/**
* Runs the given SQL and returns an array of all results, with each row
* represented as an array, as per the `'array'` `rowMode` option to
* {@link Database#exec}. An empty result set resolves to an empty array. The
* second argument, if any, is treated as the `bind` option to a call to
* `exec()`. Throws on error.
*/
selectArrays(sql: FlexibleString, bind?: BindingSpec): SqlValue[][];
/**
* Prepares the given SQL, `step()`s it one time, and returns an object
* containing the key/value pairs of the first result row. If it has no
* results, `undefined` is returned. Note that the order of returned object's
* keys is not guaranteed to be the same as the order of the fields in the
* query string. If passed a second argument other than undefined, it is
* treated like an argument to Stmt.bind(), so may be any type supported by
* that function. Throws on error.
*/
selectObject(
sql: FlexibleString,
bind?: BindingSpec,
): { [columnName: string]: SqlValue } | undefined;
/**
* Works identically to {@link Database#selectArrays} except that each value in
* the returned array is an object, as per the `"object"` rowMode option to
* {@link Database#exec}.
*/
selectObjects(
sql: FlexibleString,
bind?: BindingSpec,
): { [columnName: string]: SqlValue }[];
/**
* Prepares the given SQL, `step()`s the resulting {@link PreparedStatement}
* one time, and returns the value of the first result column. If it has no
* results, `undefined` is returned. If passed a second argument, it is
* treated like an argument to {@link PreparedStatement#bind}, so may be any
* type supported by that function. Passing the `undefined` value is the same
* as passing no value, which is useful when... If passed a 3rd argument, it
* is expected to be one of the `SQLITE_{typename}` constants. Passing the
* `undefined` value is the same as not passing a value. Throws on error (e.g.
* malformed SQL).
*/
selectValue(
sql: FlexibleString,
bind: BindingSpec | undefined,
asType: CAPI['SQLITE_INTEGER'] | CAPI['SQLITE_FLOAT'],
): number | undefined;
selectValue(
sql: FlexibleString,
bind: BindingSpec | undefined,
asType: CAPI['SQLITE_TEXT'],
): string | undefined;
selectValue(
sql: FlexibleString,
bind: BindingSpec | undefined,
asType: CAPI['SQLITE_BLOB'],
): Uint8Array | undefined;
selectValue(
sql: FlexibleString,
bind: BindingSpec | undefined,
asType: CAPI['SQLITE_NULL'],
): null | undefined;
selectValue(sql: FlexibleString, bind?: BindingSpec): SqlValue | undefined;
/**
* Runs the given query and returns an array of the values from the first
* result column of each row of the result set. The 2nd argument is an
* optional value for use in a single-argument call to
* {@link PreparedStatement#bind}. The 3rd argument may be any value suitable
* for use as the 2nd argument to {@link PreparedStatement#get}. If a 3rd
* argument is desired but no bind data are needed, pass `undefined` for the
* 2nd argument. If there are no result rows, an empty array is returned.
*/
selectValues(
sql: FlexibleString,
bind?: BindingSpec,
asType?: SQLiteDataType,
): SqlValue[];
/**
* Returns the number of currently-opened {@link PreparedStatement} handles for
* this db handle, or 0 if this object is `close()`d. Note that only handles
* prepared via {@link Database#prepare} are counted, and not handles prepared
* using `capi.sqlite3_prepare_v3()` (or equivalent).
*/
openStatementCount(): number;
/**
* Starts a transaction, calls the given `callback`, and then either rolls
* back or commits the transaction, depending on whether the `callback`
* throws. The `callback` is passed this object as its only argument. On
* success, returns the result of the callback. Throws on error.
*
* Note that transactions may not be nested, so this will throw if it is
* called recursively. For nested transactions, use the
* {@link Database#savepoint} method or manually manage `SAVEPOINT`s using
* {@link Database#exec}.
*
* If called with 2 arguments, the first must be a keyword which is legal
* immediately after a `BEGIN` statement, e.g. one of `"DEFERRED"`,
* `"IMMEDIATE"`, or `"EXCLUSIVE"`. Though the exact list of supported
* keywords is not hard-coded here, in order to be future-compatible, if the
* argument does not look like a single keyword then an exception is triggered
* with a description of the problem.
*/
transaction<T>(callback: (db: this) => T): T;
transaction<T>(
beginQualifier: 'DEFERRED' | 'IMMEDIATE' | 'EXCLUSIVE',
callback: (db: this) => T,
): T;
/**
* This works similarly to {@link Database#transaction} but uses sqlite3's
* `SAVEPOINT` feature. This function starts a savepoint (with an unspecified
* name) and calls the given callback function, passing it this db object. If
* the callback returns, the savepoint is released (committed). If the
* callback throws, the savepoint is rolled back. If it does not throw, it
* returns the result of the callback.
*/
savepoint<T>(callback: (db: this) => T): T;
/**
* Expects to be given a `DatabaseApi` instance or an `sqlite3*` pointer (may
* be `null`) and an sqlite3 API result code. If the result code is not falsy,
* this function throws an `SQLite3Error` with an error message from
* `sqlite3_errmsg()`, using the given db handle, or `sqlite3_errstr()` if the
* db handle is falsy or is a `close()`ed DB instance. Note that if it's
* passed a non-error code like `SQLITE_ROW` or `SQLITE_DONE`, it will still
* throw but the error string might be `"Not an error."` The various non-0
* non-error codes need to be checked for in client code where they are
* expected. If it does not throw, it returns its `db` argument (`this`, if
* called as a member function).
*/
static checkRc: (
db: Database | number | null,
resultCode: number,
) => Database;
/** Instance method version of {@link checkRc()}. */
checkRc: (resultCode: number) => this;
}
/**
* SQLite3 database backed by `localStorage` or `sessionStorage`.
*
* When the sqlite3 API is installed in the main thread, the this class is
* added, which simplifies usage of the kvvfs.
*/
declare class JsStorageDb extends Database {
/** Create a new kvvfs-backed database in local or session storage. */
constructor(options?: { filename?: 'local' | 'session'; flags?: string });
constructor(mode: 'local' | 'session');
/** Returns an _estimate_ of how many bytes of storage are used by the kvvfs. */
storageSize(): number;
/**
* Clears all kvvfs-owned state and returns the number of records it deleted
* (one record per database page).
*/
clearStorage(): number;
}
/**
* SQLite3 database backed by the Origin Private File System API.
*
* Installed in the namespace only if OPFS VFS support is active.
*
* This support is only available when sqlite3.js is loaded from a Worker
* thread, whether it's loaded in its own dedicated worker or in a worker
* together with client code. This OPFS wrapper implements an `sqlite3_vfs`
* wrapper entirely in JavaScript.
*
* This feature is activated automatically if the browser appears to have the
* necessary APIs to support it. It can be tested for in JS code using one of:
*
* If(sqlite3.capi.sqlite3_vfs_find("opfs")){ ... OPFS VFS is available ... }
* // Alternately: if(sqlite3.oo1.OpfsDb){ ... OPFS VFS is available ... }
*
* If it is available, the VFS named `"opfs"` can be used with any sqlite3 APIs
* which accept a VFS name, such as `sqlite3_vfs_find()`,
* `sqlite3_db_open_v2()`, and the `sqlite3.oo1.DB` constructor, noting that
* {@link OpfsDb} is a convenience subclass of {@link Database} which
* automatically uses this VFS. For URI-style names, use `file:my.db?vfs=opfs`.
*
* ## ⚠️Achtung: Safari versions < 17:
*
* Safari versions less than version 17 are incompatible with the current OPFS
* VFS implementation because of a bug in storage handling from sub-workers.
* There is no workaround for that - supporting it will require a separate VFS
* implementation and we do not, as of July 2023, have an expected time frame
* for its release. Both the `SharedAccessHandle` pool VFS and the WASMFS
* support offers alternatives which should work with Safari versions 16.4 or
* higher.
*
* ## ⚠️Achtung: COOP and COEP HTTP Headers
*
* In order to offer some level of transparent concurrent-db-access support,
* JavaScript's SharedArrayBuffer type is required for the OPFS VFS, and that
* class is only available if the web server includes the so-called COOP and
* COEP response headers when delivering scripts:
*
* Cross-Origin-Embedder-Policy: require-corp
* Cross-Origin-Opener-Policy: same-origin
*
* Without these headers, the `SharedArrayBuffer` will not be available, so the
* OPFS VFS will not load. That class is required in order to coordinate
* communication between the synchronous and asynchronous parts of the
* `sqlite3_vfs` OPFS proxy.
*
* The COEP header may also have a value of `credentialless`, but whether or not
* that will work in the context of any given application depends on how it uses
* other remote assets.
*
* How to emit those headers depends on the underlying web server.
*/
declare class OpfsDatabase extends Database {
/**
* Creates a connection to the given file, optionally creating it if needed.
*
* @param filename The filename to open. Must be resolvable using whatever
* filesystem layer (virtual or otherwise) is set up for the default sqlite3
* VFS. Note that the special sqlite3 db names `":memory:"` and `""`
* (temporary db) have their normal special meanings here.
* @param flags The flags to use when opening the file. It must be a string
* containing a sequence of letters (in any order, but case sensitive)
* specifying the mode:
*
* - `c`: create if it does not exist, else fail if it does not exist. Implies
* the `w` flag. Will create all directorries leading up to the file.
* - `w`: write. Implies `r`: a db cannot be write-only.
* - `r`: read-only if neither `w` nor `c` are provided, else it is ignored.
* - `t`: enable tracing of SQL executed on this database handle, sending it to
* `console.log()`. To disable it later, call
* `sqlite3.capi.sqlite3_trace_v2(thisDb.pointer, 0, 0, 0)`. If `w` is
* not provided, the db is implicitly read-only, noting that `rc` is
* meaningless. Any other letters are currently ignored. The default is
* `c`. These modes are ignored for the special `":memory:"` and `""`
* names and may be ignored by specific VFSes.
*/
constructor(filename: string, flags?: string);
/**
* Import a database into OPFS storage. It only works with database files and
* will throw if passed a different file type.
*/
static importDb(
filename: string,
data:
| Uint8Array
| ArrayBuffer
| (() => Uint8Array | ArrayBuffer | undefined)
| (() => Promise<Uint8Array | ArrayBuffer | undefined>),
): Promise<number>;
}
declare class OpfsSAHPoolDatabase extends OpfsDatabase {
constructor(filename: string);
}
type SAHPoolUtil = {
OpfsSAHPoolDb: typeof OpfsSAHPoolDatabase;
/**
* Adds `numEntries` entries to the current pool.
*
* This change is persistent across sessions so should not be called
* automatically at each app startup (but see `reserveMinimumCapacity()`). Its
* returned Promise resolves to the new capacity. Because this operation is
* necessarily asynchronous, the C-level VFS API cannot call this on its own
* as needed.
*/
addCapacity: (numEntries: number) => Promise<number>;
/**
* Synchronousl