49 lines
1.3 KiB
TypeScript
49 lines
1.3 KiB
TypeScript
import mysql, { type Pool, type PoolConnection, type RowDataPacket } from "mysql2/promise";
|
|
|
|
let pool: Pool | undefined;
|
|
|
|
export function getPool(): Pool {
|
|
if (!pool) {
|
|
const databaseUrl = process.env.DATABASE_URL;
|
|
if (!databaseUrl) throw new Error("DATABASE_URL is not set");
|
|
const url = new URL(databaseUrl);
|
|
pool = mysql.createPool({
|
|
host: url.hostname,
|
|
port: url.port ? Number(url.port) : 3306,
|
|
user: decodeURIComponent(url.username),
|
|
password: decodeURIComponent(url.password),
|
|
database: decodeURIComponent(url.pathname.replace(/^\//, "")),
|
|
connectionLimit: 10,
|
|
dateStrings: true,
|
|
timezone: "Z",
|
|
charset: "utf8mb4",
|
|
supportBigNumbers: true,
|
|
multipleStatements: false,
|
|
});
|
|
}
|
|
return pool;
|
|
}
|
|
|
|
export async function closePool(): Promise<void> {
|
|
if (!pool) return;
|
|
await pool.end();
|
|
pool = undefined;
|
|
}
|
|
|
|
export async function withTransaction<T>(fn: (conn: PoolConnection) => Promise<T>): Promise<T> {
|
|
const conn = await getPool().getConnection();
|
|
try {
|
|
await conn.beginTransaction();
|
|
const result = await fn(conn);
|
|
await conn.commit();
|
|
return result;
|
|
} catch (error) {
|
|
await conn.rollback();
|
|
throw error;
|
|
} finally {
|
|
conn.release();
|
|
}
|
|
}
|
|
|
|
export type { RowDataPacket };
|