44 lines
1.5 KiB
TypeScript
44 lines
1.5 KiB
TypeScript
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();
|
||
}
|
||
}
|