Creating an Adapter
Add support for a new database engine.
1. Create the adapter
For another SQL engine, the sql folder probably does most of the work: MySQL, MariaDB and SQLite share it, and each only supplies an SqlDriver with its own dialect. Otherwise, add a folder under packages/database/src/adapters/ and export a factory that returns DatabaseAdapter:
export function createExampleAdapter(options: { url: string }): DatabaseAdapter {
return {
...createExampleRepositories(options),
provider: "postgresql",
async connect() {},
async disconnect() {},
async ping() {
return { ok: true, latencyMs: 0, serverVersion: null };
},
async initialize() {
return { applied: [] };
},
};
}connect must throw DatabaseConnectionError with a message free of credentials.
2. Implement every repository
Parse input with the shared schemas. Translate unique-constraint failures into ConflictError, and missing records into NotFoundError.
users.createFirstOwner must be atomic: when five requests race, exactly one succeeds.
3. Add migrations
Implement Migration and use runMigrations from packages/database/src/migrations. Each migration must be safe to run twice.
4. Run the contract suite
import { describeDatabaseContract } from "../../repositories/contract-suite";
describeDatabaseContract("example", {
setup,
reset,
teardown,
unreachable,
unreachableSecret: "s3cret",
});5. Register it
Add a case in createDatabase in packages/database/src/index.ts, and set the engine's status to supported in DATABASE_ENGINES. The dashboard reads that list, so it updates automatically. Update this documentation and the install page in the same change.