import type { DatabaseAdapter, DatabaseResult, ColumnInfo, FieldDefinition } from "../types.js"; export interface OdbcConfig { /** Full ODBC connection string, e.g. "DSN=MyDSN" or "DRIVER={SQL Server};SERVER=host;DATABASE=db" */ connectionString: string; /** Optional username; appended as UID when not already in the connection string. */ username?: string; /** Optional password; appended as PWD when not already in the connection string. */ password?: string; } export declare class OdbcAdapter implements DatabaseAdapter { private config; private connection; private _lastInsertId; private _inTransaction; /** * Accepts either an OdbcConfig object or a raw connection string. * When created via Database.create("odbc:///DSN=MyDSN"), the "odbc:///" * prefix is stripped by parseDatabaseUrl and the remainder is passed here. */ constructor(config: OdbcConfig | string); /** Extract the raw ODBC connection string from config. */ private getConnectionString; /** * The connection string with credentials applied. ODBC has no separate- * credentials API (odbc.connect() reads only the string), so a username/ * password passed to Database.create() must be folded in as UID/PWD - the * adapter used to drop them. Never used for diagnostics (describeTarget reads * the raw string), so the password never reaches an error message. */ private effectiveConnectionString; /** * The address for a diagnostic message. ODBC hides it inside an opaque * driver keyword string, so this reads the standard keywords and falls back to * the data-source name - it is never used to connect, only to say which target * hung. */ private describeTarget; /** Connect to the ODBC data source. Must be called before using the adapter. */ /** ADR-0044 required adapter capability. */ getDatabaseType(): string; /** 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 sets this false so executeMany rejects BEFORE the first * write rather than risking partial durability. */ supportsAtomicBatch: boolean; connect(): Promise; private ensureConnected; execute(sql: string, params?: unknown[]): unknown; executeMany(sql: string, paramsList: unknown[][]): { totalAffected: number; lastId?: number | bigint; }; 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): DatabaseResult; update(table: string, data: Record, filter: Record): DatabaseResult; delete(table: string, filter: Record | string | Record[]): DatabaseResult; startTransaction(): void; commit(): void; rollback(): void; getTables(): string[]; getColumns(table: string): ColumnInfo[]; 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; /** Execute a write statement (INSERT, UPDATE, DELETE, DDL). */ executeAsync(sql: string, params?: unknown[]): Promise; /** Execute a statement with multiple parameter sets inside a single transaction. */ executeManyAsync(sql: string, paramsList: unknown[][]): Promise<{ totalAffected: number; lastId?: number | bigint; }>; /** The real affected-row count from an odbc result, when the driver reports it. */ private affectedCount; /** Run a SELECT and return all matching rows. */ queryAsync>(sql: string, params?: unknown[]): Promise; /** Run a SELECT with optional LIMIT/OFFSET pagination. */ fetchAsync>(sql: string, params?: unknown[], limit?: number, skip?: number): Promise; /** Run a SELECT and return the first row or null. */ fetchOneAsync>(sql: string, params?: unknown[]): Promise; /** Insert a single row, or a list of rows as a batch. */ insertAsync(table: string, data: Record | Record[]): Promise; /** Update rows in a table matching filter. */ updateAsync(table: string, data: Record, filter: Record | string, params?: unknown[]): Promise; /** Delete rows from a table. */ deleteAsync(table: string, filter: Record | string | Record[], params?: unknown[]): Promise; /** Begin a transaction. */ startTransactionAsync(): Promise; /** Commit the current transaction. */ commitAsync(): Promise; /** Rollback the current transaction. */ rollbackAsync(): Promise; /** List all user tables using ODBC catalog functions. */ tablesAsync(): Promise; /** Get column metadata for a table using ODBC catalog functions. */ columnsAsync(table: string): Promise; /** * The table's primary-key columns from the ODBC catalog (SQLPrimaryKeys), * lower-cased for case-insensitive matching. Empty on any target that does not * report them - the write-guard then requires an explicit filter. */ private primaryKeyColumns; /** Check whether a table exists. */ tableExistsAsync(name: string): Promise; /** Create a table from a FieldDefinition map. Uses generic SQL — works with most ODBC sources. */ createTableAsync(name: string, columns: Record): Promise; /** Get raw column name+type list for a table. */ getTableColumnsAsync(name: string): Promise>; /** Add a column to an existing table. */ addColumnAsync(table: string, colName: string, def: FieldDefinition): Promise; lastInsertId(): number | bigint | null; close(): void; }