@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
AsyncDisposablefor 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
await client.transaction(async (tx) => {
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
});
Using with using Statement
await using client = await createSqliteClient({ path: ":memory:" });
await client.query("CREATE TABLE test (id INTEGER PRIMARY KEY)");
// Client automatically closed when block exits
Related Packages
| Package | Description |
|---|---|
@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 |
Links
Installation
deno add jsr:@probitas/client-sql-sqliteClasses
#BusyError
class BusyError extends SqliteErrorSqliteErrorError thrown when the database is busy.
| Name | Description |
|---|---|
name | — |
sqliteKind | — |
Constructor
new BusyError(message: string, options?: SqliteErrorOptions)Properties
- readonly
namestring - readonly
sqliteKind"busy"
#ConstraintError
class ConstraintError extends SqlErrorSqlErrorError thrown when a constraint violation occurs.
| Name | Description |
|---|---|
name | — |
kind | — |
constraint | — |
Constructor
new ConstraintError(message: string, constraint: string, options?: SqlErrorOptions)Properties
- readonly
namestring - readonly
kind"constraint" - readonly
constraintstring
#DatabaseLockedError
class DatabaseLockedError extends SqliteErrorSqliteErrorError thrown when the database is locked.
| Name | Description |
|---|---|
name | — |
sqliteKind | — |
Constructor
new DatabaseLockedError(message: string, options?: SqliteErrorOptions)Properties
- readonly
namestring - readonly
sqliteKind"database_locked"
#DeadlockError
class DeadlockError extends SqlErrorSqlErrorError thrown when a deadlock is detected.
Constructor
new DeadlockError(message: string, options?: SqlErrorOptions)Properties
- readonly
namestring - readonly
kind"deadlock"
#QuerySyntaxError
class QuerySyntaxError extends SqlErrorSqlErrorError thrown when a SQL query has syntax errors.
Constructor
new QuerySyntaxError(message: string, options?: SqlErrorOptions)Properties
- readonly
namestring - readonly
kind"query"
#ReadonlyDatabaseError
class ReadonlyDatabaseError extends SqliteErrorSqliteErrorError thrown when trying to write to a readonly database.
| Name | Description |
|---|---|
name | — |
sqliteKind | — |
Constructor
new ReadonlyDatabaseError(message: string, options?: SqliteErrorOptions)Properties
- readonly
namestring - readonly
sqliteKind"readonly"
#SqlError
class SqlError extends ClientErrorClientErrorBase error class for SQL-specific errors. Extends ClientError with SQL-specific properties.
Constructor
new SqlError(message: string, kind: SqlErrorKind, options?: SqlErrorOptions)Properties
- readonly
namestring - readonly
sqlState?string
#SqliteError
class SqliteError extends SqlErrorSqlErrorBase error class for SQLite-specific errors. Extends SqlError with SQLite-specific properties like extendedCode.
| Name | Description |
|---|---|
name | — |
extendedCode | — |
Constructor
new SqliteError(message: string, options?: SqliteErrorOptions)Properties
- readonly
namestring - readonly
extendedCode?number
#SqliteTransactionImpl
class SqliteTransactionImpl implements SqlTransactionSqlTransaction| Name | Description |
|---|---|
begin() | Begin a new transaction. |
query() | — |
queryOne() | — |
commit() | — |
rollback() | — |
Constructor
new SqliteTransactionImpl(db: Database)Methods
static begin(): unknownBegin a new transaction.
query(): unknownqueryOne(): unknowncommit(): unknownrollback(): unknown#SqlQueryResult
class SqlQueryResult<T = Record<string, any>>SQL query result with rows, metadata, and transformation methods.
| Name | Description |
|---|---|
ok | — |
rows | — |
rowCount | — |
duration | — |
metadata | — |
map() | Map rows to a new type. |
as() | Create class instances from rows. |
Constructor
new SqlQueryResult(init: SqlQueryResultInit<T>)Properties
- readonly
okboolean - readonly
rowCountnumber - readonly
durationnumber
Methods
map(): unknownMap rows to a new type.
as(): unknownCreate class instances from rows.
#SqlRows
class SqlRows<T> extends Array<T>Array<T>Row array with first/last helper methods.
Implements ReadonlyArray
| Name | Description |
|---|---|
first() | Get the first row, or undefined if empty. |
firstOrThrow() | Get the first row, or throw if empty. |
last() | Get the last row, or undefined if empty. |
lastOrThrow() | Get the last row, or throw if empty. |
Constructor
new SqlRows(items: readonly T[])Methods
first(): unknownGet the first row, or undefined if empty.
firstOrThrow(): unknownGet the first row, or throw if empty.
last(): unknownGet the last row, or undefined if empty.
lastOrThrow(): unknownGet the last row, or throw if empty.
Interfaces
#SqlErrorOptions
interface SqlErrorOptions extends ErrorOptionsOptions for SqlError constructor.
| Name | Description |
|---|---|
sqlState | SQL State code (e.g., "23505" for unique violation) |
Properties
- readonly
sqlState?stringSQL State code (e.g., "23505" for unique violation)
#SqliteClient
interface SqliteClient extends AsyncDisposableSQLite client interface.
| Name | Description |
|---|---|
config | The client configuration. |
dialect | The 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
The client configuration.
- readonly
dialect"sqlite"The SQL dialect identifier.
Methods
query<T = Record<string, any>>(sql: string, params?: unknown[]): Promise<SqlQueryResult<T>>Execute a SQL query.
Parameters
sqlstring- SQL query string
params?unknown[]- Optional query parameters
queryOne<T = Record<string, any>>(sql: string, params?: unknown[]): Promise<T | undefined>Execute a query and return the first row or undefined.
Parameters
sqlstring- SQL query string
params?unknown[]- Optional query parameters
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
fn(tx: SqlTransaction) => unknown- Function to execute within transaction
- Transaction options
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.
#SqliteClientConfig
interface SqliteClientConfig extends CommonOptionsConfiguration for creating a SQLite client.
| Name | Description |
|---|---|
path | Database file path. |
readonly | Open the database in read-only mode. |
wal | Enable WAL (Write-Ahead Logging) mode. |
Properties
- readonly
pathstringDatabase file path. Use ":memory:" for an in-memory database.
- readonly
readonly?booleanOpen the database in read-only mode.
- readonly
wal?booleanEnable WAL (Write-Ahead Logging) mode. WAL mode provides better concurrency and performance.
#SqliteErrorOptions
interface SqliteErrorOptions extends SqlErrorOptionsOptions for SqliteError constructor.
| Name | Description |
|---|---|
extendedCode | SQLite extended error code. |
Properties
- readonly
extendedCode?numberSQLite extended error code.
#SqliteTransactionOptions
interface SqliteTransactionOptions extends SqlTransactionOptionsSQLite-specific transaction options.
| Name | Description |
|---|---|
mode | Transaction behavior mode. |
Properties
Transaction behavior mode.
#SqlQueryResultExpectation
interface SqlQueryResultExpectation<T>Expectation interface for SQL query results.
All methods return this for chaining.
| Name | Description |
|---|---|
ok() | Verify query succeeded |
notOk() | Verify query failed |
noContent() | Verify result has no rows |
hasContent() | Verify result has rows |
rows() | Verify exact row count |
rowsAtLeast() | Verify minimum row count |
rowsAtMost() | Verify maximum row count |
rowCount() | Verify exact affected row count |
rowCountAtLeast() | Verify minimum affected row count |
rowCountAtMost() | Verify maximum affected row count |
rowContains() | Verify a row contains the given subset |
rowMatch() | Custom row validation |
mapContains() | Verify mapped data contains the given subset |
mapMatch() | Custom mapped data validation |
asContains() | Verify instance contains the given subset |
asMatch() | Custom instance validation |
lastInsertId() | Verify exact lastInsertId |
hasLastInsertId() | Verify lastInsertId is present |
durationLessThan() | Verify query duration is below threshold |
Methods
ok(): thisVerify query succeeded
notOk(): thisVerify query failed
noContent(): thisVerify result has no rows
hasContent(): thisVerify result has rows
rows(count: number): thisVerify exact row count
Parameters
countnumber
rowsAtLeast(count: number): thisVerify minimum row count
Parameters
countnumber
rowsAtMost(count: number): thisVerify maximum row count
Parameters
countnumber
rowCount(count: number): thisVerify exact affected row count
Parameters
countnumber
rowCountAtLeast(count: number): thisVerify minimum affected row count
Parameters
countnumber
rowCountAtMost(count: number): thisVerify maximum affected row count
Parameters
countnumber
rowContains(subset: Partial<T>): thisVerify a row contains the given subset
Parameters
subsetPartial<T>
rowMatch(matcher: (rows: SqlRows<T>) => unknown): thisCustom row validation
Parameters
matcher(rows: SqlRows<T>) => unknown
mapContains<U>(mapper: (row: T) => unknown, subset: Partial<U>): thisVerify mapped data contains the given subset
Parameters
mapper(row: T) => unknownsubsetPartial<U>
mapMatch<U>(mapper: (row: T) => unknown, matcher: (mapped: U[]) => unknown): thisCustom mapped data validation
Parameters
mapper(row: T) => unknownmatcher(mapped: U[]) => unknown
asContains<U>(ctor: (row: T) => unknown, subset: Partial<U>): thisVerify instance contains the given subset
Parameters
ctor(row: T) => unknownsubsetPartial<U>
asMatch<U>(ctor: (row: T) => unknown, matcher: (instances: U[]) => unknown): thisCustom instance validation
Parameters
ctor(row: T) => unknownmatcher(instances: U[]) => unknown
lastInsertId(expected: bigint | string): thisVerify exact lastInsertId
Parameters
expectedbigint | string
hasLastInsertId(): thisVerify lastInsertId is present
durationLessThan(ms: number): thisVerify query duration is below threshold
Parameters
msnumber
#SqlQueryResultInit
interface SqlQueryResultInit<T>Options for creating a SqlQueryResult.
| Name | Description |
|---|---|
ok | Whether the query succeeded |
rows | The result rows |
rowCount | Number of affected rows (for INSERT/UPDATE/DELETE) |
duration | Query execution duration in milliseconds |
metadata | Additional metadata |
Properties
- readonly
okbooleanWhether the query succeeded
- readonly
rowsreadonly T[]The result rows
- readonly
rowCountnumberNumber of affected rows (for INSERT/UPDATE/DELETE)
- readonly
durationnumberQuery execution duration in milliseconds
Additional metadata
#SqlQueryResultMetadata
interface SqlQueryResultMetadataMetadata for SQL query results.
| Name | Description |
|---|---|
lastInsertId | Last inserted ID (for INSERT statements) |
warnings | Warning messages from the database |
Properties
- readonly
lastInsertId?bigint | stringLast inserted ID (for INSERT statements)
- readonly
warnings?readonly string[]Warning messages from the database
#SqlTransaction
interface SqlTransactionSQL transaction interface. Implementations should provide actual database-specific transaction handling.
| Name | Description |
|---|---|
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[]): Promise<SqlQueryResult<T>>Execute a query within the transaction.
Parameters
sqlstring- SQL query string
params?unknown[]- Optional query parameters
queryOne<T = Record<string, any>>(sql: string, params?: unknown[]): Promise<T | undefined>Execute a query and return the first row or undefined.
Parameters
sqlstring- SQL query string
params?unknown[]- Optional query parameters
commit(): Promise<void>Commit the transaction.
rollback(): Promise<void>Rollback the transaction.
#SqlTransactionOptions
interface SqlTransactionOptionsOptions for starting a transaction.
| Name | Description |
|---|---|
isolationLevel | Isolation level for the transaction |
Properties
Isolation level for the transaction
Functions
#convertSqliteError
function convertSqliteError(error: unknown): SqlErrorConvert 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
#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
configSqliteClientConfig- SQLite client configuration
Returns
Promise<SqliteClient> — A promise resolving to a new SQLite client instance
Examples
Using file-based database
const client = await createSqliteClient({
path: "./data.db",
});
const result = await client.query<{ id: number; name: string }>(
"SELECT * FROM users WHERE id = ?",
[1],
);
console.log(result.rows.first());
await client.close();
Using in-memory database
const client = await createSqliteClient({
path: ":memory:",
});
Transaction with auto-commit/rollback
const user = await client.transaction(async (tx) => {
await tx.query("INSERT INTO users (name) VALUES (?)", ["Alice"]);
const result = await tx.query("SELECT last_insert_rowid() as id");
return result.rows.first();
});
Database backup
// Create a backup of the database
await client.backup("./backup.db");
Using await using for automatic cleanup
await using client = await createSqliteClient({ path: "./data.db" });
const result = await client.query("SELECT 1");
// Client automatically closed when scope exits
#expectSqlQueryResult
function expectSqlQueryResult<T = Record<string, any>>(result: SqlQueryResult<T>): SqlQueryResultExpectation<T>Create an expectation for a SQL query result.
Parameters
resultSqlQueryResult<T>
Type Aliases
#SqlErrorKind
type SqlErrorKind = "query" | "constraint" | "deadlock" | "unknown"SQL-specific error kinds.
#SqlIsolationLevel
type SqlIsolationLevel = "read_uncommitted" | "read_committed" | "repeatable_read" | "serializable"Transaction isolation level.
#SqliteErrorKind
type SqliteErrorKind = "database_locked" | "readonly" | "busy"SQLite-specific error kinds.
#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
