Database Adapters
Connect genaql to any supported database with the appropriate adapter.
PostgreSQL
postgres.ts
import { createClient } from 'genaql';
import { Pool } from 'pg';
const pool = new Pool({
host: 'localhost',
port: 5432,
database: 'myapp',
user: 'postgres',
password: 'secret',
// Or use connection string
// connectionString: process.env.DATABASE_URL
});
const db = createClient({
dialect: 'postgres',
pool,
// Optional: log all queries
logging: process.env.NODE_ENV === 'development'
});
// Test connection
await db.raw('SELECT NOW()');MySQL
mysql.ts
import { createClient } from 'genaql';
import mysql from 'mysql2/promise';
const pool = mysql.createPool({
host: 'localhost',
port: 3306,
database: 'myapp',
user: 'root',
password: 'secret',
waitForConnections: true,
connectionLimit: 10
});
const db = createClient({
dialect: 'mysql',
pool
});SQLite
sqlite.ts
import { createClient } from 'genaql';
import Database from 'better-sqlite3';
// File-based database
const db = createClient({
dialect: 'sqlite',
database: './data/app.db'
});
// In-memory database (great for testing)
const testDb = createClient({
dialect: 'sqlite',
database: ':memory:'
});
// With better-sqlite3 instance
const sqlite = new Database('./data/app.db');
const db = createClient({
dialect: 'sqlite',
connection: sqlite
});Connection Options
options.ts
const db = createClient({
// Required
dialect: 'postgres' | 'mysql' | 'sqlite',
// Database connection (one of these)
pool: Pool, // pg or mysql2 pool
connection: Connection, // Single connection
database: string, // SQLite file path
// Optional
schema: Schema, // For type safety
logging: boolean | ((sql: string) => void),
validate: boolean, // Runtime validation
// Pool settings (PostgreSQL/MySQL)
poolConfig: {
min: 2,
max: 10,
idleTimeoutMs: 30000
}
});Custom Adapters
custom-adapter.ts
import { createAdapter, Adapter } from 'genaql';
const customAdapter: Adapter = {
dialect: 'custom',
async query(sql: string, params: unknown[]) {
// Execute query and return rows
return rows;
},
async execute(sql: string, params: unknown[]) {
// Execute statement (INSERT/UPDATE/DELETE)
return { rowCount, lastInsertId };
},
escape(value: unknown): string {
// Escape value for safe SQL interpolation
return escaped;
},
placeholder(index: number): string {
// Return placeholder syntax ($1, ?, etc.)
return `$${index + 1}`;
}
};
const db = createClient({
dialect: 'custom',
adapter: customAdapter
});Best Practice
Always use connection pooling in production. Create the pool once at startup and reuse it for all queries. Don't create new connections per request.