Mutations
create
Inserts a row and returns it after fetching it back.
const customer = await svc.create({
name: 'Alice',
status: 'active',
});
Pass projection to return only specific fields. The return type narrows to PartialDTO<T>:
const partial = await svc.create(input, { projection: ['id', 'name'] });
Use createOnly when you don't need the created row back:
await svc.createOnly(input);
update
The standard way to update a row is to pass a partial object. Only the fields you include are changed; everything else is untouched.
// Update one field
await svc.updateOnly(id, { status: 'inactive' });
// Update and get the result back
const updated = await svc.update(id, { name: 'Alice Smith', status: 'active' });
// Set a field to null
await svc.updateOnly(id, { nickname: null });
SQL expressions in updates
When you need to compute a value on the database side, use sql.Raw() from @sqb/builder. A field value can be either a plain value or a SqlElement — they can be mixed in the same patch object:
import { sql } from '@sqb/builder';
// Increment a counter atomically
await svc.updateOnly(id, { loginCount: sql.Raw('login_count + 1') });
// Mix plain values and SQL expressions
await svc.updateOnly(id, {
status: 'active',
balance: sql.Raw('balance + 100'),
updatedAt: new Date(),
});
updateMany
Applies a partial update to all rows matching the filter. The input patch is the first argument; filter options go in the second.
import { sql } from '@sqb/builder';
// Update all matching rows
const affected = await svc.updateMany(
{ status: 'suspended' },
{ filter: 'trialEndsAt < now()' },
);
// With a SQL expression
const affected = await svc.updateMany(
{ loginCount: sql.Raw('login_count + 1') },
{ filter: sql.Eq('status', 'active') },
);
delete / deleteMany
// Delete by id
const affected = await svc.delete(id); // returns 1 or 0
// Delete all rows matching a filter
const affected = await svc.deleteMany({
filter: sql.Eq('status', 'inactive'),
});
// OPRA filter string
const affected = await svc.deleteMany({
filter: 'status = "inactive"',
});
Singleton mutations
SqbSingletonService methods work the same way but without an id argument:
// Create the singleton row (typically done once at startup)
await settings.for(ctx).createOnly({ theme: 'light', maintenanceMode: false });
// Partial update
await settings.for(ctx).updateOnly({ maintenanceMode: true });
// Update and return
const updated = await settings.for(ctx).update({ theme: 'dark', maintenanceMode: false });
// Delete (rare — resets the singleton)
await settings.for(ctx).delete();