Database Drivers
Learn about all supported database drivers in DriftSQL including PostgreSQL, MySQL, LibSQL/SQLite, and Neon.
Database Drivers
DriftSQL supports multiple database drivers, each optimized for their respective database systems while maintaining a unified API.
Supported Drivers
| Driver | Database | Transactions | Prepared Statements | Helper Methods |
|---|---|---|---|---|
| PostgresDriver | PostgreSQL | ✅ | ❌ | ✅ |
| MySQLDriver | MySQL/MariaDB | ✅ | ❌ | ✅ |
| LibSQLDriver | LibSQL/SQLite/Turso | ✅ | ❌ | ✅ |
| NeonDriver | Neon PostgreSQL | ❌ | ❌ | ✅ |
PostgreSQL Driver
The PostgreSQL driver supports both traditional connections and experimental HTTP connections.
Basic Usage
import { PostgresDriver, SQLClient } from 'driftsql'
const driver = new PostgresDriver({
connectionString: 'postgresql://user:password@localhost:5432/mydb',
})
const client = new SQLClient({ driver })Configuration Options
interface PostgresConfig {
connectionString?: string
experimental?: {
http?: {
url: string
apiKey?: string
}
}
}Features
- Transactions: Full transaction support with automatic rollback on errors
- Connection Pooling: Built-in connection pooling via the
postgreslibrary - Parameter Binding: Uses PostgreSQL's
$1,$2, etc. parameter syntax - HTTP Mode: Experimental HTTP-based connections for serverless environments
Examples
// Raw queries with parameters
const users = await client.query(
'SELECT * FROM users WHERE age > $1 AND city = $2',
[18, 'New York']
)
// Insert with returning
const newUser = await client.query(
'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *',
['John Doe', 'john@example.com']
)await client.transaction(async (tx) => {
// All operations within this callback are part of the transaction
const user = await tx.insert('users', {
name: 'Jane Doe',
email: 'jane@example.com'
})
const profile = await tx.insert('profiles', {
user_id: user.id,
bio: 'Software engineer'
})
// If any operation fails, the entire transaction is rolled back
})const driver = new PostgresDriver({
experimental: {
http: {
url: 'https://your-postgres-http-api.com',
apiKey: 'your-api-key'
}
}
})
// Note: Transactions are not supported in HTTP mode
const users = await client.query('SELECT * FROM users')// Find single record
const user = await client.findFirst('users', { email: 'john@example.com' })
// Find multiple records with options
const activeUsers = await client.findMany('users', {
where: { active: true },
limit: 10,
offset: 0
})
// Insert record
const newUser = await client.insert('users', {
name: 'Alice Smith',
email: 'alice@example.com'
})
// Update record
const updatedUser = await client.update('users',
{ name: 'Alice Johnson' },
{ email: 'alice@example.com' }
)
// Delete records
const deletedCount = await client.delete('users', { active: false })MySQL Driver
The MySQL driver provides full support for MySQL and MariaDB databases.
Basic Usage
import { MySQLDriver, SQLClient } from 'driftsql'
const driver = new MySQLDriver({
connectionString: 'mysql://user:password@localhost:3306/mydb',
})
const client = new SQLClient({ driver })Configuration Options
interface MySQLConfig {
connectionString: string
}Features
- Transactions: Full transaction support with automatic rollback
- Connection Management: Built-in connection handling via
mysql2 - Parameter Binding: Uses MySQL's
?parameter syntax - Helper Methods: Full CRUD operations support
Examples
// Raw queries with parameters
const users = await client.query(
'SELECT * FROM users WHERE age > ? AND city = ?',
[18, 'New York']
)
// Insert query
const result = await client.query(
'INSERT INTO users (name, email) VALUES (?, ?)',
['John Doe', 'john@example.com']
)await client.transaction(async (tx) => {
const user = await tx.insert('users', {
name: 'Jane Doe',
email: 'jane@example.com'
})
const profile = await tx.insert('profiles', {
user_id: user.id,
bio: 'Software engineer'
})
})// All helper methods work the same as PostgreSQL
const user = await client.findFirst('users', { email: 'john@example.com' })
const users = await client.findMany('users', { where: { active: true } })
const newUser = await client.insert('users', { name: 'Bob', email: 'bob@example.com' })LibSQL Driver
The LibSQL driver supports SQLite, LibSQL, and Turso databases with both local and remote connections.
Basic Usage
import { LibSQLDriver, SQLClient } from 'driftsql'
const driver = new LibSQLDriver({
url: 'libsql://your-database.turso.io',
authToken: 'your-auth-token'
})
const client = new SQLClient({ driver })const driver = new LibSQLDriver({
url: 'file:./database.db'
})
const client = new SQLClient({ driver })const driver = new LibSQLDriver({
url: 'libsql://your-database.turso.io',
authToken: 'your-auth-token',
useTursoServerlessDriver: true // Use Turso's serverless driver
})Configuration Options
interface LibSQLConfig {
url: string
authToken?: string
useTursoServerlessDriver?: boolean
}Features
- Transactions: Transaction support (limited in some configurations)
- Local & Remote: Works with both local SQLite files and remote LibSQL/Turso
- Parameter Binding: Uses SQLite's
?parameter syntax - Helper Methods: Full CRUD operations support
- Multiple Backends: Choose between LibSQL and Turso serverless drivers
Examples
// Raw queries with parameters
const users = await client.query(
'SELECT * FROM users WHERE age > ? AND city = ?',
[18, 'New York']
)
// SQLite-specific features
const result = await client.query('PRAGMA table_info(users)')// Helper methods work the same across all drivers
const user = await client.findFirst('users', { email: 'john@example.com' })
const users = await client.findMany('users', {
where: { active: 1 }, // SQLite uses 1/0 for boolean
limit: 10
})// Create tables
await client.query(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`)
// Insert data
const user = await client.insert('users', {
name: 'John Doe',
email: 'john@example.com'
})Neon Driver
The Neon driver is optimized for Neon's serverless PostgreSQL platform.
Basic Usage
import { NeonDriver, SQLClient } from 'driftsql'
const driver = new NeonDriver({
connectionString: 'postgresql://user:password@ep-example.us-east-2.aws.neon.tech/mydb',
})
const client = new SQLClient({ driver })Configuration Options
interface NeonDriverOptions {
connectionString: string
}Features
- Serverless Optimized: Built specifically for Neon's serverless environment
- Helper Methods: Full CRUD operations support
- Parameter Binding: Uses PostgreSQL's
$1,$2, etc. parameter syntax - Fast Cold Starts: Optimized for serverless function environments
The Neon driver does not support transactions due to the serverless nature of Neon's platform.
Examples
// Raw queries with parameters
const users = await client.query(
'SELECT * FROM users WHERE age > $1 AND city = $2',
[18, 'New York']
)
// PostgreSQL features work
const result = await client.query(
'SELECT * FROM users WHERE created_at > NOW() - INTERVAL \'7 days\''
)// All helper methods work
const user = await client.findFirst('users', { email: 'john@example.com' })
const users = await client.findMany('users', {
where: { active: true },
limit: 10
})
const newUser = await client.insert('users', {
name: 'Jane Doe',
email: 'jane@example.com'
})// Perfect for Vercel Edge Functions, Cloudflare Workers, etc.
export async function GET() {
const driver = new NeonDriver({
connectionString: process.env.DATABASE_URL
})
const client = new SQLClient({ driver })
const users = await client.findMany('users', { limit: 10 })
return Response.json({ users })
}Custom Drivers
You can create your own database drivers by implementing the DatabaseDriver interface:
import type { DatabaseDriver, QueryResult } from 'driftsql'
class MyCustomDriver implements DatabaseDriver {
async query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>> {
// Your implementation here
return {
rows: [], // T[]
rowCount: 0,
command: 'SELECT',
}
}
async close(): Promise<void> {
// Cleanup logic
}
// Optional: Implement helper methods
async findFirst?(table: string, where?: Record<string, any>): Promise<QueryResult<any> | null> {
// Implementation
}
async findMany?(
table: string,
options?: {
where?: Record<string, any>
limit?: number
offset?: number
},
): Promise<QueryResult<any>> {
// Implementation
}
// ... other optional methods
}
// Use your custom driver
const client = new SQLClient({ driver: new MyCustomDriver() })Optional Interfaces
For additional functionality, implement these interfaces:
import type { TransactionCapable, PreparedStatementCapable } from 'driftsql'
class MyAdvancedDriver implements DatabaseDriver, TransactionCapable, PreparedStatementCapable {
// ... basic DatabaseDriver implementation
async transaction<T>(callback: (driver: DatabaseDriver) => Promise<T>): Promise<T> {
// Transaction implementation
}
async prepare(sql: string): Promise<PreparedStatement> {
// Prepared statement implementation
}
}Driver Comparison
When to Use Each Driver
- PostgresDriver: Best for traditional PostgreSQL deployments, supports all features
- MySQLDriver: Ideal for MySQL/MariaDB databases, full feature support
- LibSQLDriver: Perfect for SQLite, LibSQL, and Turso. Great for local development and edge deployments
- NeonDriver: Optimized for Neon's serverless PostgreSQL, best for serverless applications
Performance Characteristics
- PostgresDriver: Excellent for high-concurrency applications with connection pooling
- MySQLDriver: Good performance with built-in connection management
- LibSQLDriver: Fast for local operations, variable for remote depending on network
- NeonDriver: Optimized for cold starts and serverless environments
Next Steps
- API Reference - Explore all available methods and options
- Schema Inspection - Generate TypeScript types from your database
- Examples & Recipes - See practical examples for each driver