Skip to Content
DocsDatabase adaptersWriting an adapter

Writing an adapter

An adapter implements DatabaseAdapter from @quickben/core. Core does validation, access, hooks, relations and cursors. The adapter stores and queries plain documents.

interface DatabaseAdapter<TRaw = unknown> { readonly name: string; readonly raw: TRaw; // native client for custom queries init(schema: DatabaseSchema): Promise<void>; find(args: FindArgs): Promise<DocumentData[]>; // where, sort, limit, offset, select findOne(args: Omit<FindArgs, "limit" | "offset">): Promise<DocumentData | null>; count(args: { collection: string; where?: WhereNode }): Promise<number>; create(args: { collection: string; data: DocumentData }): Promise<DocumentData>; update(args: { collection: string; id: string; data: DocumentData; }): Promise<DocumentData | null>; delete(args: { collection: string; id: string }): Promise<boolean>; transaction<T>(fn: (tx: DatabaseAdapter<TRaw>) => Promise<T>): Promise<T>; close?(): Promise<void>; }

Rules

TopicRule
IdsStrings. Core generates UUIDv7 ids, so ids sort by creation time.
RelationsStored as ids. No joins. Core loads related documents.
ValuesReturn values as core wrote them. Dates are ISO strings.
UniqueThrow ConflictError for a taken unique value or id. null never conflicts.
Filterswhere is a normalized WhereNode tree. matchesWhere(doc, node) is the reference.
SortingcompareBySort and compareValues are the reference. Nulls last ascending.
CursorsNot your concern. Core turns cursors into where filters.
Transactionstransaction(fn) passes an adapter bound to the transaction. Nested calls join it.

WhereNode

type WhereNode = { and: WhereNode[] } | { or: WhereNode[] } | { field: string; op: WhereOperator; value: unknown };

Contract tests

The monorepo has a shared suite. Every adapter runs it:

packages/db-foo/test/contract.test.ts
import { runAdapterContractTests } from "@quickben/adapter-tests"; import { fooAdapter } from "../src"; runAdapterContractTests(() => fooAdapter());

createAdapter must return a new, empty adapter for each test. The suite covers CRUD, every where operator, sorting with nulls, page and cursor pagination, select, count, unique conflicts, transaction rollback and relation loading.

@quickben/adapter-tests is private to the monorepo. To add an adapter, open a pull request. See Contributing.

Last updated on