DriftSQL

API Reference

Complete API reference for DriftSQL including SQLClient methods, types, and interfaces.

API Reference

Complete reference for all DriftSQL classes, methods, and types.

SQLClient

The main client class for interacting with databases.

Constructor

new SQLClient<DatabaseType>(options: ClientOptions)

Parameters

  • options.driver - The primary database driver to use
  • options.fallbackDrivers? - Optional array of fallback drivers for high availability

Type Parameters

  • DatabaseType - Optional type parameter for database schema (generated by inspectDB)

Example

import { PostgresDriver, SQLClient } from 'driftsql'
import type { Database } from './db-types' // Generated types

const driver = new PostgresDriver({
  connectionString: 'postgresql://user:password@localhost:5432/mydb',
})

const client = new SQLClient<Database>({ driver })

Query Methods

query()

Execute raw SQL queries with optional parameters.

query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>

Parameters

  • sql - The SQL query string
  • params? - Optional array of parameters for the query

Returns

Promise resolving to QueryResult<T> containing:

  • rows: T[] - Array of result rows
  • rowCount: number - Number of affected/returned rows
  • command?: string - SQL command executed
  • fields?: QueryField[] - Field metadata (when available)

Examples

// Simple select
const users = await client.query<User>('SELECT * FROM users')

// With parameters
const user = await client.query<User>(
  'SELECT * FROM users WHERE id = $1',
  [123]
)

// Insert with returning
const newUser = await client.query<User>(
  'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *',
  ['John Doe', 'john@example.com']
)
// Simple select
const users = await client.query<User>('SELECT * FROM users')

// With parameters
const user = await client.query<User>(
  'SELECT * FROM users WHERE id = ?',
  [123]
)

// Insert
const result = await client.query(
  'INSERT INTO users (name, email) VALUES (?, ?)',
  ['John Doe', 'john@example.com']
)
// Simple select
const users = await client.query<User>('SELECT * FROM users')

// With parameters
const user = await client.query<User>(
  'SELECT * FROM users WHERE id = ?',
  [123]
)

// Insert
const result = await client.query(
  'INSERT INTO users (name, email) VALUES (?, ?)',
  ['John Doe', 'john@example.com']
)

Helper Methods

findFirst()

Find the first record matching the given conditions.

findFirst<K extends keyof DatabaseType>(
  table: K,
  where?: Partial<DatabaseType[K]>
): Promise<DatabaseType[K] | null>

Parameters

  • table - Table name (typed when using generated schema)
  • where? - Optional conditions object

Returns

Promise resolving to the first matching record or null if not found.

Example

// Find user by email
const user = await client.findFirst('users', {
  email: 'john@example.com',
})

// Find user by multiple conditions
const user = await client.findFirst('users', {
  email: 'john@example.com',
  active: true,
})

// Find without conditions (gets first record)
const firstUser = await client.findFirst('users')

findMany()

Find multiple records matching the given conditions.

findMany<K extends keyof DatabaseType>(
  table: K,
  options?: {
    where?: Partial<DatabaseType[K]>
    limit?: number
    offset?: number
  }
): Promise<DatabaseType[K][]>

Parameters

  • table - Table name (typed when using generated schema)
  • options? - Query options object
    • where? - Conditions to match
    • limit? - Maximum number of records to return
    • offset? - Number of records to skip

Returns

Promise resolving to an array of matching records.

Example

// Find all active users
const users = await client.findMany('users', {
  where: { active: true },
})

// With pagination
const users = await client.findMany('users', {
  where: { active: true },
  limit: 10,
  offset: 20,
})

// All records (use with caution)
const allUsers = await client.findMany('users')

insert()

Insert a new record into the specified table.

insert<K extends keyof DatabaseType>(
  table: K,
  data: Partial<DatabaseType[K]>
): Promise<DatabaseType[K]>

Parameters

  • table - Table name (typed when using generated schema)
  • data - Data to insert

Returns

Promise resolving to the inserted record (with generated fields like ID).

Example

// Insert new user
const user = await client.insert('users', {
  name: 'Jane Doe',
  email: 'jane@example.com',
  active: true,
})

// Insert with partial data (other fields will be default/null)
const user = await client.insert('users', {
  name: 'Bob Smith',
})

update()

Update records in the specified table.

update<K extends keyof DatabaseType>(
  table: K,
  data: Partial<DatabaseType[K]>,
  where: Partial<DatabaseType[K]>
): Promise<DatabaseType[K] | null>

Parameters

  • table - Table name (typed when using generated schema)
  • data - Data to update
  • where - Conditions to match records for update

Returns

Promise resolving to the updated record or null if no records were updated.

Example

// Update user by ID
const updatedUser = await client.update('users', { name: 'Jane Smith', active: false }, { id: 123 })

// Update by email
const updatedUser = await client.update('users', { last_login: new Date() }, { email: 'jane@example.com' })

delete()

Delete records from the specified table.

delete<K extends keyof DatabaseType>(
  table: K,
  where: Partial<DatabaseType[K]>
): Promise<number>

Parameters

  • table - Table name (typed when using generated schema)
  • where - Conditions to match records for deletion

Returns

Promise resolving to the number of deleted records.

Example

// Delete user by ID
const deletedCount = await client.delete('users', { id: 123 })

// Delete inactive users
const deletedCount = await client.delete('users', { active: false })

// Delete by multiple conditions
const deletedCount = await client.delete('users', {
  active: false,
  last_login: null,
})

Transaction Methods

transaction()

Execute multiple operations within a database transaction.

transaction<T>(callback: (client: SQLClient<DatabaseType>) => Promise<T>): Promise<T>

Parameters

  • callback - Function containing the transaction operations

Returns

Promise resolving to the callback's return value.

Transactions are automatically rolled back if any operation fails or if an error is thrown.

Example

const result = await client.transaction(async (tx) => {
  // Create user
  const user = await tx.insert('users', {
    name: 'John Doe',
    email: 'john@example.com',
  })

  // Create profile
  const profile = await tx.insert('profiles', {
    user_id: user.id,
    bio: 'Software engineer',
  })

  // Update user with profile reference
  await tx.update('users', { profile_id: profile.id }, { id: user.id })

  return { user, profile }
})

supportsTransactions()

Check if the current driver supports transactions.

supportsTransactions(): boolean

Returns

true if the driver supports transactions, false otherwise.

Example

if (client.supportsTransactions()) {
  await client.transaction(async (tx) => {
    // Transaction operations
  })
} else {
  // Handle operations without transactions
}

Prepared Statements

prepare()

Prepare a SQL statement for repeated execution (when supported by the driver).

prepare(sql: string): Promise<PreparedStatement>

Parameters

  • sql - The SQL statement to prepare

Returns

Promise resolving to a PreparedStatement object.

Prepared statements are not currently supported by any of the built-in drivers, but the interface is available for custom driver implementations.

supportsPreparedStatements()

Check if the current driver supports prepared statements.

supportsPreparedStatements(): boolean

Returns

true if the driver supports prepared statements, false otherwise.

Utility Methods

getDriver()

Get the underlying database driver instance.

getDriver(): DatabaseDriver

Returns

The current database driver instance.

Example

const driver = client.getDriver()
console.log('Using driver:', driver.constructor.name)

close()

Close the database connection and clean up resources.

close(): Promise<void>

Example

// Close connection when done
await client.close()

// Or use in process cleanup
process.on('SIGINT', async () => {
  await client.close()
  process.exit(0)
})

Types and Interfaces

QueryResult<T>

The result object returned by query operations.

interface QueryResult<T = any> {
  rows: T[] // Array of result rows
  rowCount: number // Number of affected/returned rows
  command?: string // SQL command executed
  fields?: QueryField[] // Field metadata (when available)
}

QueryField

Metadata about result fields.

interface QueryField {
  name: string // Field name
  dataTypeID: number // Database-specific type ID
}

DatabaseDriver

Interface that all database drivers must implement.

interface DatabaseDriver {
  query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>
  findFirst?(table: string, where?: Record<string, any>): Promise<QueryResult<any> | null>
  findMany?(
    table: string,
    options?: {
      where?: Record<string, any>
      limit?: number
      offset?: number
    },
  ): Promise<QueryResult<any>>
  insert?(table: string, data: Record<string, any>): Promise<QueryResult<any>>
  update?(table: string, data: Record<string, any>, where: Record<string, any>): Promise<QueryResult<any>>
  delete?(table: string, where: Record<string, any>): Promise<number>
  close(): Promise<void>
}

TransactionCapable

Interface for drivers that support transactions.

interface TransactionCapable {
  transaction<T>(callback: (driver: DatabaseDriver) => Promise<T>): Promise<T>
}

PreparedStatementCapable

Interface for drivers that support prepared statements.

interface PreparedStatementCapable {
  prepare(sql: string): Promise<PreparedStatement>
}

interface PreparedStatement {
  execute<T = any>(params?: any[]): Promise<QueryResult<T>>
  finalize(): Promise<void>
}

Error Handling

DatabaseError

Base error class for database-related errors.

class DatabaseError extends Error {
  constructor(
    message: string,
    public readonly driverType: string,
    public readonly originalError?: Error
  )
}

QueryError

Error thrown when a query fails.

class QueryError extends DatabaseError {
  constructor(driverType: string, sql: string, originalError?: Error)
}

ConnectionError

Error thrown when a connection fails.