Soft Delete
softDelete configures the table to set deletedAt to current time instead of deleting records. All queries on such table will filter out deleted records by default.
ts
import { defineTable } from './table-factory';
export const SomeTable = defineTable('some', (t) => ({
id: t.identity().primaryKey(),
deletedAt: t.timestamp().nullable(),
}))
// true is for using `deletedAt` column
.softDelete();
// or provide a different column name
export const OtherTable = defineTable('other', (t) => ({
id: t.identity().primaryKey(),
myDeletedAt: t.timestamp().nullable(),
})).softDelete('myDeletedAt');
const db = orchidORM(
{ databaseURL: '...' },
{
someTable: SomeTable,
},
);
// deleted records are ignored by default
const onlyNonDeleted = await db.someTable;includeDeleted disables the default deletedAt filter:
ts
const allRecords = await db.someTable.includeDeleted();delete behavior is altered:
ts
await db.someTable.find(1).delete();
// is equivalent to:
await db.someTable.find(1).update({ deletedAt: sql`now()` });Soft delete still follows the mutation condition safety rules. The default deletedAt IS NULL filter is implicit and does not authorize a mutation by itself, so an empty effective user filter throws:
ts
await db.someTable.where({}).delete(); // throws
await db.someTable.where({ id: undefined }).delete(); // throws
await db.someTable.where({ id: 1 }).delete(); // allowed
await db.someTable.all().delete(); // soft-deletes all non-deleted recordshardDelete deletes records bypassing the softDelete behavior:
ts
await db.someTable.find(1).hardDelete();
await db.someTable.all().hardDelete();hardDelete also requires an effective condition or explicit all().