import type { DatabaseAdapter, DatabaseResult, ColumnInfo, FieldDefinition } from "../types.js"; export declare class SQLiteAdapter implements DatabaseAdapter { private db; private _lastInsertId; /** ADR-0044: readable/writable native boolean. */ autocommit: boolean; /** * ADR-0044 / DBA-P02: every built-in adapter can guarantee an atomic * multi-row batch by default. A test-only deployment representing one that * cannot (a standalone MongoDB without a replica set is the motivating real * case) sets this false so executeMany rejects BEFORE the first write. */ supportsAtomicBatch: boolean; /** ADR-0044 required adapter capability. */ getDatabaseType(): string; /** * ADR-0044 canonical lifecycle name. A genuine no-op: `node:sqlite` opens * the file synchronously in the constructor (see the timeout note below), * so by the time a caller could reach connect() the adapter is already * connected — repeated calls open no additional physical connection. */ connect(): void; /** * TINA4_DATABASE_CONNECT_TIMEOUT DOES NOT APPLY HERE, deliberately. * * There is no connect() to bound: `node:sqlite` opens the file in this * SYNCHRONOUS constructor, and a synchronous call cannot be interrupted by a * timer on the same thread - the event loop only gets to run the timer after * `new DatabaseSync()` has already returned. There is also no host and no port * to name in a timeout error. The one case that could still block is a local * file on a wedged network mount, which is a kernel-level stall no JS bound * can reach. Stated here so the exclusion reads as a decision rather than an * adapter somebody forgot. */ constructor(dbPath: string); execute(sql: string, params?: unknown[]): unknown; executeMany(sql: string, paramsList: unknown[][]): DatabaseResult; query>(sql: string, params?: unknown[]): T[]; fetch>(sql: string, params?: unknown[], limit?: number, skip?: number): T[]; fetchOne>(sql: string, params?: unknown[]): T | null; insert(table: string, data: Record | Record[]): DatabaseResult; update(table: string, data: Record, filter: Record | string, params?: unknown[]): DatabaseResult; delete(table: string, filter: Record | string | Record[], params?: unknown[]): DatabaseResult; private _inTransaction; startTransaction(): void; commit(): void; rollback(): void; getTables(): string[]; getColumns(table: string): ColumnInfo[]; lastInsertId(): number | bigint | null; private _closed; /** ADR-0044 (DBA-L02): idempotent — node:sqlite's DatabaseSync.close() * throws when called on an already-closed database, so a second close() * must not reach it. */ close(): void; /** * Atomically increment and return the next value of a tina4_sequences row. * * DB-contract B (no duplicate primary keys under concurrency): the old * read-increment-read path in Database.sequenceNext() yields at every `await` * between the read and the write, so two concurrent async callers can read the * same `current_value` and return the same id. This method runs the WHOLE * operation — ensure-table, seed-if-absent, and the increment-and-return — as * ONE synchronous burst on the single shared `node:sqlite` connection. Because * `node:sqlite` is synchronous and JavaScript is single-threaded, no other * async task can interleave between the statements (there is no `await` * inside), so the increment is atomic and every caller gets a distinct id. * This is the Node analog of the Python master holding SQLiteAdapter._write_lock * across the whole op. * * On SQLite >= 3.35 a single `UPDATE ... SET current_value = current_value + 1 * ... RETURNING current_value` is itself atomic and returns the new value in * one statement (read via prepare().all() — stmt.run() does not surface * RETURNING rows). Older SQLite does `UPDATE ... + 1` then `SELECT`, still * race-safe because both run in the same synchronous burst. * * @throws if the sequence row vanishes mid-increment (never silently returns 1). */ sequenceNextSqlite(seqName: string, seedValue: number): number; tableExists(name: string): boolean; createTable(name: string, columns: Record): void; getTableColumns(name: string): Array<{ name: string; type: string; }>; addColumn(table: string, colName: string, def: FieldDefinition): void; }