@probitas/client-sql-sqlite

SQLite client for Probitas scenario testing framework.

This package provides a SQLite client designed for integration testing, with transaction support and in-memory database capabilities.

Features

  • Query Execution: Parameterized queries with type-safe results
  • Transactions: Full transaction support with isolation levels
  • In-Memory Databases: Perfect for isolated test scenarios
  • File-Based Databases: Persist data for stateful testing
  • Resource Management: Implements AsyncDisposable for proper cleanup

Installation

deno add jsr:@probitas/client-sql-sqlite

Quick Start

import { createSqliteClient } from "@probitas/client-sql-sqlite";

// In-memory database for testing
const client = await createSqliteClient({
  path: ":memory:",
});

// Create table
await client.query(`
  CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    active INTEGER DEFAULT 1
  )
`);

// Insert and query with parameters (uses ? placeholders)
await client.query("INSERT INTO users (name) VALUES (?)", ["Alice"]);

const result = await client.query<{ id: number; name: string }>(
  "SELECT id, name FROM users WHERE active = ?",
  [1]
);
console.log(result.rows);

await client.close();

Transactions

import { createSqliteClient } from "@probitas/client-sql-sqlite";
import type { SqlTransaction } from "@probitas/client-sql";

const client = await createSqliteClient({ path: ":memory:" });
await client.transaction(async (tx: SqlTransaction) => {
  await tx.query("INSERT INTO accounts (id, balance) VALUES (?, ?)", [1, 100]);
  await tx.query("INSERT INTO accounts (id, balance) VALUES (?, ?)", [2, 200]);
  // Automatically committed if no error, rolled back on exception
});
await client.close();

Using with using Statement

import { createSqliteClient } from "@probitas/client-sql-sqlite";

await using client = await createSqliteClient({ path: ":memory:" });

await client.query("CREATE TABLE test (id INTEGER PRIMARY KEY)");
// Client automatically closed when block exits
PackageDescription
`@probitas/client-sql`Common SQL types and utilities
`@probitas/client-sql-postgres`PostgreSQL client
`@probitas/client-sql-mysql`MySQL client
`@probitas/client-sql-duckdb`DuckDB client

Installation

deno add jsr:@probitas/client-sql-sqlite

Classes

class

#BusyError

class BusyError extends SqliteError

Error thrown when the database is busy.

NameDescription
name
sqliteKind
Constructor
new BusyError(message: string, options?: SqliteErrorOptions)
Properties
  • readonlynamestring
  • readonlysqliteKind"busy"
class

#ConstraintError

class ConstraintError extends SqlError
ExtendsSqlError

Error thrown when a constraint violation occurs.

NameDescription
name
kind
constraint
Constructor
new ConstraintError(
  message: string,
  constraint: string,
  options?: SqlErrorOptions,
)
Properties
  • readonlynamestring
  • readonlykind"constraint"
  • readonlyconstraintstring
class

#DatabaseLockedError

class DatabaseLockedError extends SqliteError

Error thrown when the database is locked.

NameDescription
name
sqliteKind
Constructor
new DatabaseLockedError(message: string, options?: SqliteErrorOptions)
Properties
  • readonlynamestring
  • readonlysqliteKind"database_locked"
class

#DeadlockError

class DeadlockError extends SqlError
ExtendsSqlError

Error thrown when a deadlock is detected.

NameDescription
name
kind
Constructor
new DeadlockError(message: string, options?: SqlErrorOptions)
Properties
  • readonlynamestring
  • readonlykind"deadlock"
class

#QuerySyntaxError

class QuerySyntaxError extends SqlError
ExtendsSqlError

Error thrown when a SQL query has syntax errors.

NameDescription
name
kind
Constructor
new QuerySyntaxError(message: string, options?: SqlErrorOptions)
Properties
  • readonlynamestring
  • readonlykind"query"
class

#ReadonlyDatabaseError

class ReadonlyDatabaseError extends SqliteError

Error thrown when trying to write to a readonly database.

NameDescription
name
sqliteKind
Constructor
new ReadonlyDatabaseError(message: string, options?: SqliteErrorOptions)
Properties
  • readonlynamestring
  • readonlysqliteKind"readonly"
class

#SqlConnectionError

class SqlConnectionError extends SqlError
ExtendsSqlError

Error thrown when a connection or network-level error occurs.

This includes:

  • Connection refused (server not running)
  • Authentication failure
  • Connection timeout
  • Pool exhaustion
  • TLS handshake failure
  • DNS resolution failure
NameDescription
name
kind
Constructor
new SqlConnectionError(message: string, options?: SqlErrorOptions)
Properties
  • readonlynamestring
  • readonlykind"connection"
class

#SqlError

class SqlError extends ClientError

Base error class for SQL-specific errors. Extends ClientError with SQL-specific properties.

NameDescription
name
kind
sqlState
Constructor
new SqlError(message: string, kind: SqlErrorKind, options?: SqlErrorOptions)
Properties
  • readonlynamestring
  • readonlykindSqlErrorKind
  • readonlysqlStatestring | null
class

#SqliteError

class SqliteError extends SqlError
ExtendsSqlError

Base error class for SQLite-specific errors. Extends SqlError with SQLite-specific properties like extendedCode.

NameDescription
name
extendedCode
Constructor
new SqliteError(message: string, options?: SqliteErrorOptions)
Properties
  • readonlynamestring
  • readonlyextendedCode?number
class

#SqliteTransactionImpl

class SqliteTransactionImpl implements SqlTransaction
ImplementsSqlTransaction
NameDescription
begin()Begin a new transaction.
query()
queryOne()
commit()
rollback()
Constructor
new SqliteTransactionImpl(db: Database)
Methods
static begin(): unknown

Begin a new transaction.

query(): unknown
queryOne(): unknown
commit(): unknown
rollback(): unknown

Interfaces

interface

#SqlErrorOptions

interface SqlErrorOptions extends ErrorOptions

Options for SqlError constructor.

NameDescription
sqlStateSQL State code (e.g., "23505" for unique violation)
Properties
  • readonlysqlState?string

    SQL State code (e.g., "23505" for unique violation)

interface

#SqliteClient

interface SqliteClient extends AsyncDisposable

SQLite client interface.

NameDescription
configThe client configuration.
dialectThe SQL dialect identifier.
query()Execute a SQL query.
queryOne()Execute a query and return the first row or undefined.
transaction()Execute a function within a transaction.
backup()Backup the database to a file.
vacuum()Run VACUUM to rebuild the database file, reclaiming unused space.
close()Close the database connection.
Properties
  • readonlyconfigSqliteClientConfig

    The client configuration.

  • readonlydialect"sqlite"

    The SQL dialect identifier.

Methods
query<T = Record<string, any>>(
  sql: string,
  params?: unknown[],
  options?: SqlQueryOptions,
): Promise<SqlQueryResult<T>>

Execute a SQL query.

Parameters
  • sqlstring
    • SQL query string
  • params?unknown[]
    • Optional query parameters
    • Optional query options
queryOne<T = Record<string, any>>(
  sql: string,
  params?: unknown[],
  options?: SqlQueryOptions,
): Promise<T | undefined>

Execute a query and return the first row or undefined.

Parameters
  • sqlstring
    • SQL query string
  • params?unknown[]
    • Optional query parameters
    • Optional query options
transaction<T>(
  fn: (tx: SqlTransaction) => unknown,
  options?: SqlTransactionOptions | SqliteTransactionOptions,
): Promise<T>

Execute a function within a transaction. Automatically commits on success or rolls back on error.

Parameters
backup(destPath: string): Promise<void>

Backup the database to a file. Uses VACUUM INTO for a consistent backup.

Parameters
  • destPathstring
    • Destination file path for the backup
vacuum(): Promise<void>

Run VACUUM to rebuild the database file, reclaiming unused space.

close(): Promise<void>

Close the database connection.

interface

#SqliteClientConfig

interface SqliteClientConfig extends CommonOptions

Configuration for creating a SQLite client.

NameDescription
pathDatabase file path.
readonlyOpen the database in read-only mode.
walEnable WAL (Write-Ahead Logging) mode.
throwOnErrorWhether to throw an error for query failures.
Properties
  • readonlypathstring

    Database file path. Use ":memory:" for an in-memory database.

  • readonlyreadonly?boolean

    Open the database in read-only mode.

  • readonlywal?boolean

    Enable WAL (Write-Ahead Logging) mode. WAL mode provides better concurrency and performance.

  • readonlythrowOnError?boolean

    Whether to throw an error for query failures. When false, failures are returned as SqlQueryResultError or SqlQueryResultFailure. Can be overridden per-query via SqlQueryOptions.

interface

#SqliteErrorOptions

interface SqliteErrorOptions extends SqlErrorOptions

Options for SqliteError constructor.

NameDescription
extendedCodeSQLite extended error code.
Properties
  • readonlyextendedCode?number

    SQLite extended error code.

interface

#SqliteTransactionOptions

interface SqliteTransactionOptions extends SqlTransactionOptions

SQLite-specific transaction options.

NameDescription
modeTransaction behavior mode.
Properties
interface

#SqlQueryOptions

interface SqlQueryOptions extends CommonOptions

Options for individual SQL queries.

NameDescription
throwOnErrorWhether to throw an error for query failures.
Properties
  • readonlythrowOnError?boolean

    Whether to throw an error for query failures. When false, failures are returned as SqlQueryResultError or SqlQueryResultFailure.

interface

#SqlQueryResultError

interface SqlQueryResultError<T = any> extends SqlQueryResultBase<T>

SQL query result for query errors (syntax errors, constraint violations, etc.).

Server received and processed the query, but it failed due to a SQL error.

NameDescription
processedServer processed the query.
okQuery failed.
errorError describing the SQL error.
rowsEmpty rows for failed queries.
rowCountZero affected rows for failed queries.
lastInsertIdNo lastInsertId for failed queries.
warningsNo warnings for failed queries.
Properties
  • readonlyprocessedtrue

    Server processed the query.

  • readonlyokfalse

    Query failed.

  • readonlyerrorSqlError

    Error describing the SQL error.

  • readonlyrowsreadonly never[]

    Empty rows for failed queries.

  • readonlyrowCount0

    Zero affected rows for failed queries.

  • readonlylastInsertIdnull

    No lastInsertId for failed queries.

  • readonlywarningsnull

    No warnings for failed queries.

interface

#SqlQueryResultFailure

interface SqlQueryResultFailure<T = any> extends SqlQueryResultBase<T>

SQL query result for connection failures (network errors, timeouts, etc.).

Query could not be processed by the server (connection refused, timeout, pool exhausted, authentication failure, etc.).

NameDescription
processedServer did not process the query.
okQuery failed.
errorError describing the failure.
rowsNo rows (query didn't reach server).
rowCountNo row count (query didn't reach server).
lastInsertIdNo lastInsertId (query didn't reach server).
warningsNo warnings (query didn't reach server).
Properties
  • readonlyprocessedfalse

    Server did not process the query.

  • readonlyokfalse

    Query failed.

  • readonlyerrorSqlFailureError

    Error describing the failure.

  • readonlyrowsnull

    No rows (query didn't reach server).

  • readonlyrowCountnull

    No row count (query didn't reach server).

  • readonlylastInsertIdnull

    No lastInsertId (query didn't reach server).

  • readonlywarningsnull

    No warnings (query didn't reach server).

interface

#SqlQueryResultSuccess

interface SqlQueryResultSuccess<T = any> extends SqlQueryResultBase<T>

SQL query result for successful queries.

The query was executed successfully and returned results.

NameDescription
processedServer processed the query.
okQuery succeeded.
errorNo error for successful queries.
rowsQuery result rows.
rowCountNumber of affected rows.
lastInsertIdLast inserted ID (for INSERT statements).
warningsWarning messages from the database.
Properties
  • readonlyprocessedtrue

    Server processed the query.

  • readonlyoktrue

    Query succeeded.

  • readonlyerrornull

    No error for successful queries.

  • readonlyrowsreadonly T[]

    Query result rows.

  • readonlyrowCountnumber

    Number of affected rows.

  • readonlylastInsertIdbigint | string | null

    Last inserted ID (for INSERT statements).

  • readonlywarningsunknown | null

    Warning messages from the database.

interface

#SqlQueryResultSuccessParams

interface SqlQueryResultSuccessParams<T = any>

Parameters for creating a SqlQueryResultSuccess.

NameDescription
rowsThe result rows
rowCountNumber of affected rows (for INSERT/UPDATE/DELETE)
durationQuery execution duration in milliseconds
lastInsertIdLast inserted ID (for INSERT statements)
warningsWarning messages from the database
Properties
  • readonlyrowsreadonly T[]

    The result rows

  • readonlyrowCountnumber

    Number of affected rows (for INSERT/UPDATE/DELETE)

  • readonlydurationnumber

    Query execution duration in milliseconds

  • readonlylastInsertId?bigint | string

    Last inserted ID (for INSERT statements)

  • readonlywarnings?readonly string[]

    Warning messages from the database

interface

#SqlTransaction

interface SqlTransaction

SQL transaction interface. Implementations should provide actual database-specific transaction handling.

NameDescription
query()Execute a query within the transaction.
queryOne()Execute a query and return the first row or undefined.
commit()Commit the transaction.
rollback()Rollback the transaction.
Methods
query<T = Record<string, any>>(
  sql: string,
  params?: unknown[],
  options?: SqlQueryOptions,
): Promise<SqlQueryResult<T>>

Execute a query within the transaction.

Parameters
  • sqlstring
    • SQL query string
  • params?unknown[]
    • Optional query parameters
    • Optional query options
queryOne<T = Record<string, any>>(
  sql: string,
  params?: unknown[],
  options?: SqlQueryOptions,
): Promise<T | undefined>

Execute a query and return the first row or undefined.

Parameters
  • sqlstring
    • SQL query string
  • params?unknown[]
    • Optional query parameters
    • Optional query options
commit(): Promise<void>

Commit the transaction.

rollback(): Promise<void>

Rollback the transaction.

interface

#SqlTransactionOptions

interface SqlTransactionOptions

Options for starting a transaction.

NameDescription
isolationLevelIsolation level for the transaction
Properties

Functions

function

#convertSqliteError

function convertSqliteError(error: unknown): SqlError

Convert a @db/sqlite error to the appropriate error class.

Note: @db/sqlite throws plain Error objects without SQLite error codes. Error classification is based on message content analysis.

Parameters
  • errorunknown
function

#createSqliteClient

function createSqliteClient(config: SqliteClientConfig): Promise<SqliteClient>

Create a new SQLite client instance.

The client provides parameterized queries, transaction support, WAL mode for better concurrency, and SQLite-specific features like backup and vacuum.

Parameters
Returns

Promise<SqliteClient> — A promise resolving to a new SQLite client instance

Examples

Using file-based database

import { createSqliteClient } from "@probitas/client-sql-sqlite";

const client = await createSqliteClient({
  path: "./data.db",
});

const result = await client.query<{ id: number; name: string }>(
  "SELECT * FROM users WHERE id = ?",
  [1],
);
if (result.ok) {
  console.log(result.rows[0]);  // { id: 1, name: "Alice" }
}

await client.close();

Using in-memory database

import { createSqliteClient } from "@probitas/client-sql-sqlite";

const client = await createSqliteClient({
  path: ":memory:",
});
await client.close();

Transaction with auto-commit/rollback

import { createSqliteClient } from "@probitas/client-sql-sqlite";
import type { SqlTransaction } from "@probitas/client-sql";

const client = await createSqliteClient({ path: ":memory:" });
const user = await client.transaction(async (tx: SqlTransaction) => {
  await tx.query("INSERT INTO users (name) VALUES (?)", ["Alice"]);
  const result = await tx.query<{ id: number }>("SELECT last_insert_rowid() as id");
  if (!result.ok) throw result.error;
  return result.rows[0];
});
await client.close();

Database backup

import { createSqliteClient } from "@probitas/client-sql-sqlite";

const client = await createSqliteClient({ path: "./data.db" });
await client.backup("./backup.db");
await client.close();

Using await using for automatic cleanup

import { createSqliteClient } from "@probitas/client-sql-sqlite";

await using client = await createSqliteClient({ path: "./data.db" });

const result = await client.query("SELECT 1");
// Client automatically closed when scope exits
function

#isConnectionError

function isConnectionError(error: unknown): boolean

Check if an error is a connection-level error.

Parameters
  • errorunknown

Types

type

#SqlErrorKind

type SqlErrorKind = "query" | "constraint" | "deadlock" | "connection" | "unknown"

SQL-specific error kinds.

type

#SqlFailureError

type SqlFailureError = SqlConnectionError | AbortError | TimeoutError

Error types that indicate the operation was not processed. These are errors that occur before the query reaches the SQL server.

type

#SqlIsolationLevel

type SqlIsolationLevel = "read_uncommitted" | "read_committed" | "repeatable_read" | "serializable"

Transaction isolation level.

type

#SqliteErrorKind

type SqliteErrorKind = "database_locked" | "readonly" | "busy"

SQLite-specific error kinds.

type

#SqliteTransactionMode

type SqliteTransactionMode = "deferred" | "immediate" | "exclusive"

SQLite transaction behavior mode.

  • "deferred": Locks are acquired on first read/write (default)
  • "immediate": Acquires RESERVED lock immediately
  • "exclusive": Acquires EXCLUSIVE lock immediately
type

#SqlOperationError

type SqlOperationError = QuerySyntaxError | ConstraintError | DeadlockError | SqlError

Error types that indicate an operation was processed by the server. These errors occur after the query reaches the SQL server.

type

#SqlQueryResult

type SqlQueryResult<T = any> = SqlQueryResultSuccess<T> | SqlQueryResultError<T> | SqlQueryResultFailure<T>

SQL query result union type representing all possible result states.

  • Success: processed: true, ok: true, error: null
  • Error: processed: true, ok: false, error: SqlError
  • Failure: processed: false, ok: false, error: SqlConnectionError
Search Documentation