Drizzle Adapter

The Drizzle adapter integrates c15t Backend with Drizzle ORM, a lightweight, type-safe SQL query builder with schema declaration.

Installation

Install Drizzle ORM and the appropriate database driver:

# For PostgreSQL
npm install drizzle-orm pg @types/pg
# For MySQL
npm install drizzle-orm mysql2 @types/mysql2
# For SQLite
npm install drizzle-orm better-sqlite3 @types/better-sqlite3

Configuration

  1. Define your schema using Drizzle's schema builder:
// schema.ts
import { pgTable, uuid, text, timestamp } from 'drizzle-orm/pg-core';
 
export const users = pgTable('users', {
  id: uuid('id').primaryKey().defaultRandom(),
  name: text('name').notNull(),
  email: text('email').notNull().unique(),
  createdAt: timestamp('created_at').defaultNow()
});
  1. Configure the c15t instance with the Drizzle adapter:
import { c15tInstance } from '@c15t/backend';
import { drizzleAdapter } from '@c15t/backend/db/adapters/drizzle';
import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
 
// Create a PostgreSQL connection
const pool = new Pool({
  connectionString: process.env.DATABASE_URL
});
 
// Initialize Drizzle with the connection
const db = drizzle(pool);
 
// Create the c15t instance
const instance = c15tInstance({
  baseURL: 'http://localhost:3000',
  database: drizzleAdapter({
    client: db,
    // Optional: Pass your schema for type checking
    schema: { users }
  }),
});

MySQL Configuration

import { drizzle } from 'drizzle-orm/mysql2';
import mysql from 'mysql2/promise';
 
const connection = await mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'c15t'
});
 
const db = drizzle(connection);
 
const instance = c15tInstance({
  database: drizzleAdapter({ client: db }),
});

SQLite Configuration

import { drizzle } from 'drizzle-orm/better-sqlite3';
import Database from 'better-sqlite3';
 
const sqlite = new Database('database.db');
const db = drizzle(sqlite);
 
const instance = c15tInstance({
  database: drizzleAdapter({ client: db }),
});

Usage Examples

Basic CRUD Operations

// Create a new record
const user = await instance.database.create('users', {
  name: 'John Doe',
  email: 'john@example.com'
});
 
// Find records
const users = await instance.database.find('users', {
  where: { email: 'john@example.com' },
  orderBy: { createdAt: 'desc' },
  limit: 10
});
 
// Update a record
const updatedUser = await instance.database.update(
  'users',
  { where: { id: user.id } },
  { name: 'John Smith' }
);
 
// Delete a record
await instance.database.delete('users', { where: { id: user.id } });

Transactions

await instance.database.transaction(async (trx) => {
  const user = await trx.create('users', {
    name: 'Alice',
    email: 'alice@example.com'
  });
  
  await trx.create('profiles', {
    userId: user.id,
    bio: 'Software engineer'
  });
});

Migrations

Use Drizzle Kit for schema migrations:

npm install -D drizzle-kit
 
# Generate a migration
npx drizzle-kit generate:pg
 
# Apply migrations
npx drizzle-kit push:pg

Type Safety

The Drizzle adapter provides excellent type safety:

import { users } from './schema';
import { InferModel } from 'drizzle-orm';
 
// Infer types from your schema
type User = InferModel<typeof users>;
 
// Type-safe operations
const users = await instance.database.find<User>('users', {
  where: { email: 'john@example.com' }
});

Best Practices

  • Define schema using Drizzle's builders - Leverage type safety and schema validation
  • Use prepared statements - Drizzle uses prepared statements for all queries
  • Implement connection pooling - Configure appropriate pool sizes for production
  • Use migrations for schema changes - Manage schema changes with Drizzle Kit

Limitations

  • Some complex queries may require direct Drizzle client usage
  • Table names must match schema definitions

On this page

c15t.com