kundencenter/packages/platform/src/db.ts

45 lines
1.5 KiB
TypeScript
Raw Normal View History

import mysql from 'mysql2/promise';
import type { Pool, PoolConnection, RowDataPacket, ResultSetHeader } from 'mysql2/promise';
import { config } from './config.js';
export const pool: Pool = mysql.createPool({
...config.db,
connectionLimit: 10,
charset: 'utf8mb4',
timezone: 'Z',
dateStrings: false,
namedPlaceholders: false,
});
// Alle Zeiten in UTC, auch die DB-Defaults (CURRENT_TIMESTAMP) – sonst Versatz zur Serverzeit.
(pool as unknown as { on(e: string, f: (c: { query(s: string): void }) => void): void }).on('connection', (c) => c.query("SET time_zone = '+00:00'"));
export type Row = RowDataPacket;
type Exec = Pick<Pool | PoolConnection, 'execute'>;
export async function query<T extends Row = Row>(sql: string, params: unknown[] = [], c: Exec = pool): Promise<T[]> {
const [rows] = await c.execute<T[]>(sql, params as never[]);
return rows;
}
export async function one<T extends Row = Row>(sql: string, params: unknown[] = [], c: Exec = pool): Promise<T | undefined> {
return (await query<T>(sql, params, c))[0];
}
export async function run(sql: string, params: unknown[] = [], c: Exec = pool): Promise<ResultSetHeader> {
const [res] = await c.execute<ResultSetHeader>(sql, params as never[]);
return res;
}
export async function tx<T>(fn: (c: PoolConnection) => Promise<T>): Promise<T> {
const c = await pool.getConnection();
try {
await c.beginTransaction();
const out = await fn(c);
await c.commit();
return out;
} catch (e) {
await c.rollback();
throw e;
} finally {
c.release();
}
}