/** * Centralized SQL Database Wrapper — PostgreSQL, MySQL, MSSQL, SQLite * * ALL SQL database access MUST go through this file. * NEVER create connection pools anywhere else. * NEVER import `pg`/`mysql2`/`mssql`/`better-sqlite3` directly in other files. * * Mirrors the MongoDB wrapper pattern (src/core/db/index.ts): * - Singleton pool per URI (prevents connection exhaustion) * - Parameterized queries ALWAYS (prevents SQL injection) * - Graceful shutdown with closePool() * - Next.js hot-reload persistence via globalThis * * Driver auto-detection from DATABASE_URL scheme: * postgresql:// or postgres:// → pg * mysql:// → mysql2 * mssql:// → mssql * file: or sqlite: → better-sqlite3 * * Install the driver for your database: * PostgreSQL: npm install pg @types/pg * MySQL: npm install mysql2 * MSSQL: npm install mssql * SQLite: npm install better-sqlite3 @types/better-sqlite3 */ export { connect, getPool, closePool, gracefulShutdown, withTransaction, } from './sql-connection.js'; export type { PoolOptions, ResultSet } from './sql-connection.js'; /** * Query a single row. Returns null if not found. * ALWAYS use parameterized queries — NEVER interpolate values. * * @example * const user = await queryOne('SELECT * FROM users WHERE id = $1', [userId]); */ export declare function queryOne(sql: string, params?: unknown[]): Promise; /** * Query multiple rows. * * @example * const users = await queryMany('SELECT * FROM users WHERE role = $1 LIMIT $2', ['admin', 50]); */ export declare function queryMany(sql: string, params?: unknown[]): Promise; /** * Count rows in a table with optional WHERE clause. * * @example * const total = await count('users', { role: 'admin' }); */ export declare function count(table: string, where?: Record): Promise; /** * Execute a raw SQL statement. * * @example * await execute('UPDATE users SET active = $1 WHERE last_login < $2', [false, cutoffDate]); */ export declare function execute(sql: string, params?: unknown[]): Promise<{ rowCount: number; rows?: unknown[]; }>; /** * Insert a single row into a table. * * @example * await insertOne('users', { email: 'a@b.com', name: 'Alice', created_at: new Date() }); */ export declare function insertOne(table: string, data: Record): Promise<{ rowCount: number; rows?: unknown[]; }>; /** * Insert multiple rows in a single statement. * * @example * await insertMany('events', [{ type: 'click', ts: new Date() }, { type: 'view', ts: new Date() }]); */ export declare function insertMany(table: string, rows: Record[]): Promise; /** * Update a single row matching the WHERE clause. * * @example * await updateOne('users', { id: 1 }, { name: 'Bob', updated_at: new Date() }); */ export declare function updateOne(table: string, where: Record, set: Record): Promise<{ rowCount: number; rows?: unknown[]; }>; /** * Delete a single row matching the WHERE clause. * * @example * await deleteOne('tokens', { token: 'abc123' }); */ export declare function deleteOne(table: string, where: Record): Promise<{ rowCount: number; rows?: unknown[]; }>; /** * Build a parameterized WHERE clause from a key-value object. * NEVER string-interpolate user input into SQL — use this instead. * * @example * const { clause, values } = buildWhere({ email: 'a@b.com', active: true }); * // clause: '"email" = $1 AND "active" = $2' * // values: ['a@b.com', true] */ export declare function buildWhere(where: Record, startIdx?: number): { clause: string; values: unknown[]; }; //# sourceMappingURL=sql.d.ts.map