client.ts73 lines · main
| 1 | import { drizzle } from 'drizzle-orm/node-postgres'; |
| 2 | import pg from 'pg'; |
| 3 | |
| 4 | import { env } from '../env.js'; |
| 5 | import { log } from '../lib/logger.js'; |
| 6 | |
| 7 | import * as schema from './schema.js'; |
| 8 | |
| 9 | /** |
| 10 | * Control-plane meta-DB pool — **Doltgres-first** (see repo `DOLTGRES-FIRST.md`). |
| 11 | * |
| 12 | * Talks to Doltgres database `briven_control` via `pg` (node-postgres). |
| 13 | * Never use `postgres` (postgres.js) against Doltgres — wire panics |
| 14 | * (`unhandled message "&{}"`). Same rule as the data plane. |
| 15 | * |
| 16 | * Lazy-initialised: `/ready` reports not_configured until BRIVEN_DATABASE_URL |
| 17 | * is set. |
| 18 | */ |
| 19 | let _pool: pg.Pool | null = null; |
| 20 | let _db: ReturnType<typeof drizzle<typeof schema>> | null = null; |
| 21 | |
| 22 | export function getDb() { |
| 23 | if (!env.BRIVEN_DATABASE_URL) { |
| 24 | throw new Error('BRIVEN_DATABASE_URL is not configured'); |
| 25 | } |
| 26 | if (!_db) { |
| 27 | _pool = new pg.Pool({ |
| 28 | connectionString: env.BRIVEN_DATABASE_URL, |
| 29 | max: 10, |
| 30 | idleTimeoutMillis: 30_000, |
| 31 | connectionTimeoutMillis: 5_000, |
| 32 | }); |
| 33 | _db = drizzle(_pool, { schema }); |
| 34 | log.info('db_connected', { max: 10, driver: 'node-postgres' }); |
| 35 | } |
| 36 | return _db; |
| 37 | } |
| 38 | |
| 39 | export function getPool(): pg.Pool { |
| 40 | if (!_pool) { |
| 41 | getDb(); |
| 42 | } |
| 43 | return _pool as pg.Pool; |
| 44 | } |
| 45 | |
| 46 | /** @deprecated Prefer getDb() / getPool(). Kept for ping helper. */ |
| 47 | export function getSqlClient(): pg.Pool { |
| 48 | return getPool(); |
| 49 | } |
| 50 | |
| 51 | export async function pingDb(): Promise<boolean> { |
| 52 | if (!env.BRIVEN_DATABASE_URL) return false; |
| 53 | try { |
| 54 | const pool = getPool(); |
| 55 | await pool.query('SELECT 1'); |
| 56 | return true; |
| 57 | } catch (err) { |
| 58 | log.warn('db_ping_failed', { |
| 59 | message: err instanceof Error ? err.message : String(err), |
| 60 | }); |
| 61 | return false; |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | export async function closeDb(): Promise<void> { |
| 66 | if (_pool) { |
| 67 | await _pool.end(); |
| 68 | _pool = null; |
| 69 | _db = null; |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | export { schema }; |