/** * db-client — unified driver adapter interface. * * Phase 1 implemented: connect / close / health. * Phase 2 adds: schema introspection, query execution, data CRUD, * and structure management. Methods that don't apply to every driver * (e.g. table operations on Redis) remain optional. */ import type { DbClientConnection, DbClientHealth, DbClientObjectDetails, DbClientOverview, DbClientQueryResult, DbClientSchemaNode, DbClientSchemaNodeType, DbDriver } from '$shared/types/db-client'; export interface SchemaOpts { database?: string; schema?: string; } export interface ColumnDefinition { name: string; type: string; nullable?: boolean; default?: string | null; primary?: boolean; unique?: boolean; autoIncrement?: boolean; } export interface TableDefinition { name: string; columns: ColumnDefinition[]; primaryKey?: string[]; } export interface IndexDefinition { name: string; columns: string[]; unique?: boolean; } export type AlterOperation = | { kind: 'add-column'; column: ColumnDefinition } | { kind: 'drop-column'; name: string } | { kind: 'rename-column'; name: string; newName: string } | { kind: 'modify-column'; column: ColumnDefinition }; /** * A connection-bound executor handed to `withTransaction`'s callback. Every * call runs on the same transaction's connection, so a batch of statements * commits or rolls back atomically. */ export interface DbClientTxContext { executeRead(q: string, params?: unknown[], opts?: { database?: string; limit?: number }): Promise; executeWrite(q: string, params?: unknown[], opts?: { database?: string }): Promise; } export interface DbClientDriverAdapter { readonly kind: DbDriver; connect(conn: DbClientConnection, tunnelPort?: number): Promise; close(): Promise; isAlive(): boolean; health(): Promise; overview?(opts?: SchemaOpts): Promise; listDatabases?(): Promise; listSchemas?(database?: string): Promise; listObjects?(database?: string, schema?: string): Promise; getObjectDetails?( name: string, type: DbClientSchemaNodeType, database?: string, schema?: string ): Promise; executeRead?(q: string, params?: unknown[], opts?: { database?: string; limit?: number }): Promise; executeWrite?(q: string, params?: unknown[], opts?: { database?: string }): Promise; explain?(q: string, opts?: { database?: string }): Promise; cancel?(): Promise; /** * Run `fn` inside a single database transaction on one dedicated * connection. Implemented only by drivers that can guarantee atomicity * (a pooled driver must reserve a connection). If `fn` throws, the * transaction is rolled back and the error re-thrown. Absence of this * method signals the caller to fall back to non-transactional execution. */ withTransaction?(fn: (tx: DbClientTxContext) => Promise, opts?: { database?: string }): Promise; // Structure createDatabase?(name: string): Promise; dropDatabase?(name: string): Promise; renameDatabase?(name: string, newName: string): Promise; /** Empty every table/collection in a database without dropping the schema. */ resetDatabase?(opts?: SchemaOpts): Promise; /** Redis FLUSHDB — wipe every key in the selected logical database. */ flushDatabase?(): Promise; createTable?(definition: TableDefinition, opts?: SchemaOpts): Promise; alterTable?(name: string, operations: AlterOperation[], opts?: SchemaOpts): Promise; dropTable?(name: string, opts?: SchemaOpts): Promise; truncateTable?(name: string, opts?: SchemaOpts): Promise; /** Truncate and reset the auto-increment / sequence / identity counter. */ resetTable?(name: string, opts?: SchemaOpts): Promise; renameTable?(name: string, newName: string, opts?: SchemaOpts): Promise; duplicateTable?(name: string, newName: string, opts?: SchemaOpts & { withData?: boolean }): Promise; /** Best-effort CREATE statement for an object (DDL), for copy-to-clipboard. */ getCreateStatement?(name: string, type: DbClientSchemaNodeType, opts?: SchemaOpts): Promise; createIndex?(tableName: string, def: IndexDefinition, opts?: SchemaOpts): Promise; dropIndex?(tableName: string, indexName: string, opts?: SchemaOpts): Promise; createView?(name: string, query: string, opts?: SchemaOpts): Promise; dropView?(name: string, opts?: SchemaOpts): Promise; // Data CRUD (parameterized) insertRow?(table: string, row: Record, opts?: SchemaOpts): Promise; updateRow?(table: string, pk: Record, changes: Record, opts?: SchemaOpts): Promise; deleteRows?(table: string, pks: Record[], opts?: SchemaOpts): Promise; }