interface
ReservedSQL
interface ReservedSQL
A connection reserved from the pool with SQL.reserve. Call release to return it to the pool.
- options: Merge<SQLiteOptions, PostgresOrMySQLOptions> | Merge<PostgresOrMySQLOptions, SQLiteOptions>
Current client options
- values: any[],
Creates a SQL array parameter
@param valuesArray values to bind
@param typeNameOrTypeIDElement type name or type ID; defaults to JSON when omitted
@returnsThe array parameter, ready to interpolate into a query
const array = sql.array([1, 2, 3], "INT"); await sql`CREATE TABLE users_posts (user_id INT, posts_id INT[])`; await sql`INSERT INTO users_posts (user_id, posts_id) VALUES (${user.id}, ${array})`; Begins a new transaction.
Reserves a connection for the transaction and passes a scoped
sqlinstance to the callback.sql.beginresolves with the callback's return value.BEGINis sent automatically, and if anything fails,ROLLBACKis sent so the connection can be released and execution can continue.const [user, account] = await sql.begin(async sql => { const [user] = await sql` insert into users ( name ) values ( 'Murray' ) returning * ` const [account] = await sql` insert into accounts ( user_id ) values ( ${ user.user_id } ) returning * ` return [user, account] })options: string,Begins a new transaction with options.
Reserves a connection for the transaction and passes a scoped
sqlinstance to the callback.sql.beginresolves with the callback's return value.BEGINis sent with the given options, and if anything fails,ROLLBACKis sent so the connection can be released and execution can continue.const [user, account] = await sql.begin("read write", async sql => { const [user] = await sql` insert into users ( name ) values ( 'Murray' ) returning * ` const [account] = await sql` insert into accounts ( user_id ) values ( ${ user.user_id } ) returning * ` return [user, account] })- name: string,
Begins a distributed transaction, also known as Two-Phase Commit. In phase 1 the coordinator prepares each node, making sure its data is written and ready to commit; in phase 2 the nodes commit or roll back based on the coordinator's decision, ensuring durability and releasing locks.
beginDistributedrolls back automatically if an exception is not caught; otherwise you commit or roll back later with commitDistributed or rollbackDistributed.In PostgreSQL and MySQL, distributed transactions persist beyond the original session, so privileged users or coordinators can commit or roll them back later, which supports recovery and administrative tasks. PostgreSQL implements them with
PREPARE TRANSACTION; MySQL uses XA Transactions. MSSQL also supports distributed/XA transactions, but ties them to the original session, the DTC coordinator, and the specific connection: they are committed or rolled back under the same rules as regular transactions, with no manual intervention from other sessions, and are used to coordinate transactions across Linked Servers.await sql.beginDistributed("numbers", async sql => { await sql`create table if not exists numbers (a int)`; await sql`insert into numbers values(1)`; }); // later you can call await sql.commitDistributed("numbers"); // or await sql.rollbackDistributed("numbers"); - options?: { timeout: number }): Promise<void>;
Closes the database connection. With
timeout: 0it closes immediately; with no timeout it waits for all queries to finish first.@param optionsOptional
timeoutin secondsawait sql.close({ timeout: 1 }); - name: string): Promise<void>;
Commits a distributed transaction, also known as a prepared transaction in PostgreSQL or an XA transaction in MySQL
@param nameName of the distributed transaction
await sql.commitDistributed("my_distributed_transaction"); - name: string,
Begins a distributed transaction. Alias of beginDistributed.
- end(options?: { timeout: number }): Promise<void>;
Closes the database connection. Alias of SQL.close.
@param optionsOptional
timeoutin secondsawait sql.end({ timeout: 1 }); - filename: string,values?: any[] | Record<string, any>
Reads a file and runs its contents as a query. Pass
valuesif the file uses positional parameters ($1,$2, ...). With the SQLite adapter,valuesmay also be an object of named parameters (:name,$name, or@nameplaceholders); keys keep the prefix unless the connection setsstrict: true.const result = await sql.file("query.sql", [1, 2, 3]); Flushes any pending operations
sql.flush();- channel: string,onnotify: (payload: string) => void,onlisten?: () => void
Subscribe to a PostgreSQL
LISTENchannel. Resolves once the server has acknowledged the subscription, with a handle that removes it again.Every call is its own registration: several on one channel share a single server-side subscription and each receives every notification. All of them share one dedicated connection, opened by the first
listen()and closed when the last registration is removed. If it drops, it is reconnected with exponential backoff and every channel is re-subscribed;onlistenruns again each time.A throwing
onnotifyoronlistenis reported as an uncaught exception.@param channelChannel name, quoted for you; at most 63 bytes, the PostgreSQL identifier limit
@param onnotifyReceives each notification's payload
@param onlistenRuns once the
LISTENis acknowledged, initially and after every reconnectconst subscription = await sql.listen("events", payload => console.log(payload)); await sql.notify("events", "hello"); await subscription.unlisten(); - channel: string,payload?: string): Promise<void>;
Send a PostgreSQL
NOTIFYviapg_notify. Runs as a normal query on this handle, so on asql.begin()transaction it is delivered on commit and discarded on rollback. Omittingpayloadsends an empty one, like a bareNOTIFY channel.await sql.notify("events", JSON.stringify({ id: 1 })); await sql.notify("cache-invalidated"); Releases the client back to the connection pool
Reserves a connection from the pool and returns a client that wraps that single connection. Use it to run queries on an isolated connection.
Calling
reserve()on a reserved client returns a new reserved connection, not the same one (behavior matches thepostgrespackage).@param optionssignalaborts the reservation while it is still waiting for a connection; the returned promise rejects withsignal.reasonand no connection is taken from the pool. Aborting after the promise resolved has no effect: the caller owns the connection and mustrelease()it.const reserved = await sql.reserve(); await reserved`select * from users`; await reserved.release(); // In production, release in a finally block const reserved = await sql.reserve(); try { // ... queries } finally { await reserved.release(); } // Bun supports Symbol.dispose and Symbol.asyncDispose, // so `using` releases the connection at the end of the scope using reserved = await sql.reserve() await reserved`select * from users` // Give up on the reservation if no connection frees up in time const reserved = await sql.reserve({ signal: AbortSignal.timeout(5000) });- name: string): Promise<void>;
Rolls back a distributed transaction, also known as a prepared transaction in PostgreSQL or an XA transaction in MySQL
@param nameName of the distributed transaction
await sql.rollbackDistributed("my_distributed_transaction"); Begins a new transaction. Alias of begin.
Reserves a connection for the transaction and passes a scoped
sqlinstance to the callback.sql.transactionresolves with the callback's return value.BEGINis sent automatically, and if anything fails,ROLLBACKis sent so the connection can be released and execution can continue.const [user, account] = await sql.transaction(async sql => { const [user] = await sql` insert into users ( name ) values ( 'Murray' ) returning * ` const [account] = await sql` insert into accounts ( user_id ) values ( ${ user.user_id } ) returning * ` return [user, account] })options: string,Begins a new transaction with options. Alias of begin.
Reserves a connection for the transaction and passes a scoped
sqlinstance to the callback.sql.transactionresolves with the callback's return value.BEGINis sent with the given options, and if anything fails,ROLLBACKis sent so the connection can be released and execution can continue.const [user, account] = await sql.transaction("read write", async sql => { const [user] = await sql` insert into users ( name ) values ( 'Murray' ) returning * ` const [account] = await sql` insert into accounts ( user_id ) values ( ${ user.user_id } ) returning * ` return [user, account] });- string: string,values?: any[] | Record<string, any>
Executes any query string as-is. This can lead to SQL injection if the string contains untrusted input.
sql.unsafecan be nested inside a safesqlexpression, for example when only part of the query is unsafe.With the SQLite adapter,
valuesmay also be an object of named parameters (:name,$name, or@nameplaceholders). Object keys keep the prefix unless the connection setsstrict: true.const result = await sql.unsafe(`select ${danger} from users where id = ${dragons}`) const row = await sql.unsafe("select * from users where id = :id", { ":id": 1 })
Referenced types
interface Query<T>
A pending SQL query. Extends Promise, so it can be awaited, and adds methods to control how it runs.
- onrejected?: null | (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
Attaches a callback for only the rejection of the Promise.
@param onrejectedThe callback to execute when the Promise is rejected.
@returnsA Promise for the completion of the callback.
- onfinally?: null | () => void): Promise<T>;
Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The resolved value cannot be modified from the callback.
@param onfinallyThe callback to execute when the Promise is settled (fulfilled or rejected).
@returnsA Promise for the completion of the callback.
- onfulfilled?: null | (value: T) => TResult1 | PromiseLike<TResult1>,onrejected?: null | (reason: any) => TResult2 | PromiseLike<TResult2>): Promise<TResult1 | TResult2>;
Attaches callbacks for the resolution and/or rejection of the Promise.
@param onfulfilledThe callback to execute when the Promise is resolved.
@param onrejectedThe callback to execute when the Promise is rejected.
@returnsA Promise for the completion of which ever callback is executed.