Files
order_site/apps/backend/src/db/client.ts
T

61 lines
1.7 KiB
TypeScript

import { Pool } from 'pg'
import type { PoolClient, QueryResult, QueryResultRow } from 'pg'
import { runtimeConfig } from '../config/runtime.js'
let poolInstance: Pool | null = null
export function getDb(): Pool {
if (!poolInstance) {
poolInstance = new Pool({
connectionString: String(runtimeConfig.database?.url || '').trim(),
ssl: runtimeConfig.database?.ssl ? { rejectUnauthorized: false } : false,
max: Number(runtimeConfig.database?.maxConnections || 10),
idleTimeoutMillis: Number(runtimeConfig.database?.idleTimeoutMs || 30_000),
connectionTimeoutMillis: Number(runtimeConfig.database?.connectionTimeoutMs || 5_000),
statement_timeout: Number(runtimeConfig.database?.statementTimeoutMs || 15_000),
})
}
return poolInstance
}
export async function query(text: string, params?: unknown[]): Promise<QueryResult<any>>
export async function query<T extends QueryResultRow>(
text: string,
params?: unknown[],
): Promise<QueryResult<T>>
export async function query<T extends QueryResultRow>(
text: string,
params: unknown[] = [],
): Promise<QueryResult<T>> {
const pool = getDb()
return pool.query<T>(text, params)
}
export async function withTransaction<T>(fn: (client: PoolClient) => Promise<T>): Promise<T> {
const client = await getDb().connect()
try {
await client.query('BEGIN')
const result = await fn(client)
await client.query('COMMIT')
return result
} catch (error) {
await client.query('ROLLBACK')
throw error
} finally {
client.release()
}
}
export async function closeDb(): Promise<void> {
if (!poolInstance) {
return
}
const pool = poolInstance
poolInstance = null
await pool.end()
}