Documentation / @zerotal/orm / index / DB
Variable: DB
constDB:object
Defined in: packages/orm/src/db/DB.ts:169
The DB facade — the entry point for database access outside the model layer.
Bundles table queries, raw SQL, transactions, replica routing and N+1 detection over the connection resolved for the current call site. Connection resolution is context-aware: inside a DB.transaction callback every query automatically uses the transaction connection (via TransactionContext AsyncLocalStorage), and when read replicas are configured, reads route to a replica while writes and transactions go to the primary.
Type Declaration
Connections
onPrimary()
onPrimary():
object
Return a query builder scoped to the primary connection, bypassing the replica pool entirely.
Use this for read-your-writes scenarios — when you need to query data immediately after a mutation and cannot wait for replication lag.
Returns
object
table()
table(
name):QueryBuilder
Parameters
name
string
Returns
Example
await DB.table('orders').insert({ total: 99 });
// Read the just-inserted row from primary, not a potentially-lagging replica:
const order = await DB.onPrimary().table('orders').where('id', id).first();
advisoryLock()
advisoryLock<
T>(key,callback):Promise<T>
Acquire a database advisory lock for the duration of a callback. The lock is released automatically when the callback resolves or rejects.
Dialect-aware: pg_advisory_lock() on PostgreSQL, GET_LOCK() on MySQL.
Throws UnsupportedDialectError (E_UNSUPPORTED_DIALECT) on SQLite, which
has no advisory-lock primitive.
Type Parameters
T
T
Parameters
key
number
Integer lock key (application-defined).
callback
() => Promise<T>
Work to perform while the lock is held.
Returns
Promise<T>
Throws
On SQLite (no advisory-lock primitive).
Queries
raw()
raw<
T>(sql, ...rest):Promise<T[]>
Execute raw SQL.
Tagged-template form (parameterized, safe):
await DB.rawSELECT * FROM users WHERE id = ${id}
String form (splits on ? placeholders, same safety):
await DB.raw('SELECT * FROM users WHERE id = ?', [id])
await DB.raw('SELECT 1 + 1 AS n')
Type Parameters
T
T = Record<string, unknown>
Parameters
sql
string | TemplateStringsArray
rest
...unknown[]
Returns
Promise<T[]>
preventNPlusOne()
preventNPlusOne(
options?):void
Configure N+1 query detection.
Detection is automatically active in local and development environments
(warn mode, threshold 5). Call this to change the threshold, switch to
'throw' mode, or enable detection in other environments.
Parameters
options?
Returns
void
Example
// bootstrap/app.ts
DB.preventNPlusOne({ threshold: 3, mode: 'throw' });
allowNPlusOne()
allowNPlusOne(
pattern,options?):void
Suppress N+1 warnings for queries containing pattern as a substring.
Parameters
pattern
string
A table name or any substring of the SQL shape.
options?
{ once: true } suppresses only for the current request.
once?
boolean
Returns
void
Example
DB.allowNPlusOne('activity_logs'); // all requests
DB.allowNPlusOne('taggings', { once: true }); // this request only
Tables
table()
table(
tableName):QueryBuilder
Start a chainable QueryBuilder against a table on the current connection.
Parameters
tableName
string
Returns
Transactions
transaction()
transaction<
T>(callback,attempts?):Promise<T>
Run a callback inside a database transaction.
All BaseModel and DB queries made within the callback automatically use the transaction connection via AsyncLocalStorage (TransactionContext). Works in any environment — request handlers, console commands, seeders.
Bun auto-commits on resolve and auto-rolls-back on throw. NEVER call tx.commit() or tx.rollback() manually.
Nested calls use a SAVEPOINT so an inner rollback does not abort the outer
transaction. Pass attempts > 1 to automatically retry on deadlock /
serialization failures.
Type Parameters
T
T
Parameters
callback
(tx?) => Promise<T>
Work to run inside the transaction.
attempts?
number = 1
Max attempts on deadlock-like errors (default 1 = no retry).
Returns
Promise<T>
beginTransaction()
beginTransaction():
Promise<ManualTransaction>
Begin a transaction with manual commit/rollback control. Run queries via
the returned handle (handle.sql or handle.table()), then call
handle.commit() or handle.rollback().
Prefer DB.transaction(cb) for automatic commit/rollback — this is for the
rarer cases where the transaction boundary cannot be expressed as a callback.
Returns
Promise<ManualTransaction>
Example
const t = await DB.beginTransaction();
try {
await t.table('accounts').where('id', 1).decrement('balance', 100);
await t.commit();
} catch (e) { await t.rollback(); throw e; }
currentTx()
currentTx():
unknown
Return the active transaction connection (from the ALS transaction context
or the legacy request-scoped transaction), or undefined when none is open.
Returns
unknown
Example
// Raw SQL (parameterised)
const rows = await DB.raw`SELECT * FROM users WHERE id = ${id}`;
// Fluent query builder
const active = await DB.table('users').where('active', true).get();
// Transaction — all queries inside use the tx connection automatically
await DB.transaction(async () => {
await DB.table('accounts').where('id', 1).decrement('balance', 100);
await DB.table('accounts').where('id', 2).increment('balance', 100);
});