constructor
sqlite.Database.constructor
Open or create a SQLite3 database
The filename of the database to open. Pass an empty string ("") or ":memory:" or undefined for an in-memory database.
defaults to {readwrite: true, create: true}. If a number, then it's treated as SQLITE_OPEN_* constant flags.
Referenced types
interface DatabaseOptions
Options for Database
- readonly?: boolean
Open the database as read-only (no write operations, no create).
Equivalent to constants.SQLITE_OPEN_READONLY
- safeIntegers?: boolean
When
true, integers are returned asbigint.When
false, integers are returned asnumberand truncated to 52 bits. - strict?: boolean
When set to
falseorundefined:- Queries missing bound parameters do NOT throw an error
- Bound named parameters in JavaScript need to exactly match the SQL query.
const db = new Database(":memory:", { strict: false }); db.run("INSERT INTO foo (name) VALUES ($name)", { $name: "foo" });When set to
true:- Queries missing bound parameters throw an error
- Bound named parameters in JavaScript no longer need the
$,:, or@prefix. The SQL query keeps its prefix.
class Database
A SQLite3 database
const db = new Database("mydb.sqlite");
db.run("CREATE TABLE foo (bar TEXT)");
db.run("INSERT INTO foo VALUES (?)", ["baz"]);
console.log(db.query("SELECT * FROM foo").all());- readonly filename: string
The filename passed when
new Database()was calledconst db = new Database("mydb.sqlite"); console.log(db.filename); // => "mydb.sqlite" - readonly handle: number
The underlying
sqlite3database handleIn native code, this is not a file descriptor, but an index into an array of database handles
- static MAX_QUERY_CACHE_SIZE: number
Maximum number of distinct SQL strings Database.query keeps cached per
Database. Least-recently-used entries are evicted first. Closes the database at the end of a
usingblock (explicit resource management)using db = new Database("myapp.db"); doSomethingWithDatabase(db); // Automatically closed when `db` goes out of scope- throwOnError?: boolean): void;
Close the database connection.
Statements created with Database.query are finalized immediately. With
throwOnErrorunset orfalse, statements created with Database.prepare keep working until they are finalized or garbage collected, and the underlying connection is released after the last one (sqlite3_close_v2). WiththrowOnError: true, every outstanding statement is finalized, the connection is released immediately (sqlite3_close), and an error is thrown if SQLite fails to close it.It is safe to call this method multiple times. If the database is already closed, this is a no-op. Creating new statements after close throws; using a statement that close finalized throws
Database has closed, excepttoString(), which returns an empty string, andfinalize(), which stays safe to call.@param throwOnErrorIf
true, finalize every outstanding statement and throw if the connection fails to closedb.close();If a
Databaseis garbage collected without being closed, the connection is released once every statement created from it has also been finalized or collected.using db = ...callsclose(true). - op: number,arg?: number | ArrayBufferView<ArrayBufferLike>): number;
See
sqlite3_file_controlfor more information.zDbName: string,op: number,arg?: number | ArrayBufferView<ArrayBufferLike>): number;See
sqlite3_file_controlfor more information. - extension: string,entryPoint?: string): void;
Load a SQLite3 extension
On macOS, this requires linking a custom SQLite3 library because the Apple build of SQLite disables loading extensions. See Database.setCustomSQLite
Bun chooses the Apple build of SQLite on macOS because it brings a ~50% performance improvement.
@param extensionname/path of the extension to load
@param entryPointoptional entry point of the extension
- sql: string,params?: ParamsType
Compile a SQL query and return a Statement object.
This does not cache the compiled query and does not execute the query.
Internally, this calls
sqlite3_prepare_v3.@param sqlThe SQL query to compile
@param paramsOptional bindings for the query
@returnsA Statement instance
// compile the query const stmt = db.query("SELECT * FROM foo WHERE bar = ?"); // run the query stmt.all("baz"); - sql: string
Compile a SQL query and return a Statement object. This is the same as prepare except that it caches the compiled query if possible.
This does not execute the query; it prepares it for later execution.
Internally, this calls
sqlite3_prepare_v3.@param sqlThe SQL query to compile
@returnsA Statement instance
// compile the query const stmt = db.query("SELECT * FROM foo WHERE bar = ?"); // run the query stmt.all("baz"); // run the query again stmt.all(); - sql: string,...bindings: ParamsType[]
Execute a SQL query without returning any results.
This does not cache the query. To run a query multiple times, use prepare instead.
Internally, this calls
sqlite3_prepare_v3followed bysqlite3_stepandsqlite3_finalize.The following types can be used when binding parameters:
JavaScript type SQLite type stringTEXTnumberINTEGERorDECIMALbooleanINTEGER(1 or 0)Uint8ArrayBLOBBufferBLOBbigintINTEGERnullNULLUseful for queries like:
CREATE TABLEINSERT INTOUPDATEDELETE FROMDROP TABLEPRAGMAATTACH DATABASEDETACH DATABASEREINDEXVACUUMEXPLAIN ANALYZECREATE INDEXCREATE TRIGGERCREATE VIEWCREATE VIRTUAL TABLECREATE TEMPORARY TABLE
@param sqlThe SQL query to run
@param bindingsOptional bindings for the query
@returnsA
Changesobject withchangesandlastInsertRowidpropertiesdb.run("CREATE TABLE foo (bar TEXT)"); db.run("INSERT INTO foo VALUES (?)", ["baz"]); // => { changes: 1, lastInsertRowid: 1 } - insideTransaction: (...args: A) => T): (...args: A) => T;
Creates a function that always runs inside a transaction. When the function is invoked, it begins a new transaction. When the function returns, the transaction is committed. If an exception is thrown, the transaction is rolled back (and the exception propagates as usual).
@param insideTransactionThe callback which runs inside a transaction
// setup import { Database } from "bun:sqlite"; const db = Database.open(":memory:"); db.exec( "CREATE TABLE cats (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE, age INTEGER)" ); const insert = db.prepare("INSERT INTO cats (name, age) VALUES ($name, $age)"); const insertMany = db.transaction((cats) => { for (const cat of cats) insert.run(cat); }); insertMany([ { $name: "Joey", $age: 2 }, { $name: "Sally", $age: 4 }, { $name: "Junior", $age: 1 }, ]); - serialized: ArrayBufferLike | TypedArray<ArrayBufferLike>,isReadOnly?: boolean
Load a serialized SQLite3 database
Internally, this calls
sqlite3_deserialize.@param serializedData to load
@returnsDatabaseinstancetest("supports serialize/deserialize", () => { const db = Database.open(":memory:"); db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)"); db.exec('INSERT INTO test (name) VALUES ("Hello")'); db.exec('INSERT INTO test (name) VALUES ("World")'); const input = db.serialize(); const db2 = new Database(input); const stmt = db2.prepare("SELECT * FROM test"); expect(JSON.stringify(stmt.get())).toBe( JSON.stringify({ id: 1, name: "Hello", }), ); expect(JSON.stringify(stmt.all())).toBe( JSON.stringify([ { id: 1, name: "Hello", }, { id: 2, name: "World", }, ]), ); db2.exec("insert into test (name) values ('foo')"); expect(JSON.stringify(stmt.all())).toBe( JSON.stringify([ { id: 1, name: "Hello", }, { id: 2, name: "World", }, { id: 3, name: "foo", }, ]), ); const db3 = Database.deserialize(input, true); try { db3.exec("insert into test (name) values ('foo')"); throw new Error("Expected error"); } catch (e) { expect(e.message).toBe("attempt to write a readonly database"); } });serialized: ArrayBufferLike | TypedArray<ArrayBufferLike>,options?: { readonly: boolean; safeIntegers: boolean; strict: boolean }Load a serialized SQLite3 database. This overload accepts additional options, such as
strictto put the database into strict mode.Internally, this calls
sqlite3_deserialize.@param serializedData to load
@returnsDatabaseinstancetest("supports serialize/deserialize", () => { const db = Database.open(":memory:"); db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)"); db.exec('INSERT INTO test (name) VALUES ("Hello")'); db.exec('INSERT INTO test (name) VALUES ("World")'); const input = db.serialize(); const db2 = Database.deserialize(input, { strict: true }); const stmt = db2.prepare("SELECT * FROM test"); expect(JSON.stringify(stmt.get())).toBe( JSON.stringify({ id: 1, name: "Hello", }), ); expect(JSON.stringify(stmt.all())).toBe( JSON.stringify([ { id: 1, name: "Hello", }, { id: 2, name: "World", }, ]), ); db2.exec("insert into test (name) values ($foo)", { foo: "baz" }); expect(JSON.stringify(stmt.all())).toBe( JSON.stringify([ { id: 1, name: "Hello", }, { id: 2, name: "World", }, { id: 3, name: "baz", }, ]), ); const db3 = Database.deserialize(input, { readonly: true, strict: true }); try { db3.exec("insert into test (name) values ($foo)", { foo: "baz" }); throw new Error("Expected error"); } catch (e) { expect(e.message).toBe("attempt to write a readonly database"); } }); - filename: string,
Open or create a SQLite3 database
@param filenameThe filename of the database to open. Pass an empty string (
"") or":memory:"or undefined for an in-memory database.@param optionsdefaults to
{readwrite: true, create: true}. If a number, then it's treated asSQLITE_OPEN_*constant flags.This is an alias of
new Database()See Database
- @param path
The path to the SQLite library