Fluent Builder
Build queries programmatically with the fluent API for dynamic query construction.
When to Use
Use the fluent builder when you need to construct queries dynamically based on runtime conditions. For static queries, prefer the cook template literal.
SELECT Builder
select.ts
import { select } from 'genaql';
const query = select('users')
.columns('id', 'name', 'email')
.where('active', '=', true)
.where('role', 'in', ['admin', 'moderator'])
.orderBy('created_at', 'desc')
.limit(10)
.offset(20);
const { sql, params } = query.toParams();Dynamic Conditions
dynamic.ts
// Build query based on filters
function searchUsers(filters: UserFilters) {
let query = select('users').columns('*');
if (filters.name) {
query = query.where('name', 'like', `%${filters.name}%`);
}
if (filters.role) {
query = query.where('role', '=', filters.role);
}
if (filters.minAge) {
query = query.where('age', '>=', filters.minAge);
}
if (filters.sortBy) {
query = query.orderBy(filters.sortBy, filters.sortDir || 'asc');
}
return query.limit(filters.limit || 20);
}INSERT Builder
insert.ts
import { insert } from 'genaql';
// Single row
const query = insert('users')
.columns('name', 'email')
.values(['John', 'john@test.com'])
.returning('id');
// Multiple rows
const bulkQuery = insert('users')
.columns('name', 'email')
.values([
['John', 'john@test.com'],
['Jane', 'jane@test.com'],
['Bob', 'bob@test.com']
])
.returning('id');
// With conflict handling (upsert)
const upsertQuery = insert('users')
.columns('email', 'name')
.values(['john@test.com', 'John'])
.onConflict('email')
.doUpdate({ name: 'John Updated' })
.returning('*');UPDATE Builder
update.ts
import { update } from 'genaql';
const query = update('users')
.set({ status: 'active', verified: true })
.where('id', '=', 1)
.returning('*');
// Increment/decrement
const incrementQuery = update('posts')
.set({ views: raw('views + 1') })
.where('id', '=', 42);DELETE Builder
delete.ts
import { deleteFrom } from 'genaql';
const query = deleteFrom('users')
.where('id', '=', 1)
.returning('id', 'email');
// Delete with multiple conditions
const bulkDelete = deleteFrom('sessions')
.where('expired', '=', true)
.orWhere('created_at', '<', '2024-01-01');Builder Methods
| Method | Description |
|---|---|
.columns(...cols) | Specify columns to select/insert |
.where(col, op, val) | Add AND condition |
.orWhere(col, op, val) | Add OR condition |
.whereIn(col, vals) | Add IN condition |
.whereNull(col) | Add IS NULL condition |
.join(table, on) | Add INNER JOIN |
.leftJoin(table, on) | Add LEFT JOIN |
.orderBy(col, dir) | Add ORDER BY |
.groupBy(...cols) | Add GROUP BY |
.having(col, op, val) | Add HAVING |
.limit(n) | Add LIMIT |
.offset(n) | Add OFFSET |
.returning(...cols) | Add RETURNING |
Immutability
All builder methods return a new query object, leaving the original unchanged. This makes it safe to create variations from a base query.