import grabMariaDBClient from "../functions/grab-mariadb-client"; /** * Resolve a shared MariaDB client. Prefer the global client so schema sync * and CRUD do not open a new connection per query. */ export function resolveClient(config) { if (!config) { return global.MARIADB_CLIENT; } // Returns the global client when it was created from the same config return grabMariaDBClient({ config }); } /** * Keep the event loop alive until `fn` settles. * An idle Bun.SQL connection does not hold the process open, so a query sent * on it after something else released the loop (e.g. an inquirer prompt * releasing stdin) lets Bun exit silently mid-query. */ export async function holdEventLoop(fn) { const timer = setInterval(() => { }, 1 << 30); try { return await fn(); } finally { clearInterval(timer); } } /** * Convert driver rows to plain objects. * - BigInt -> number (or string when outside the safe integer range) * - Date -> ISO string (matches the generated `string` typedefs) * - Buffers / typed arrays (BLOB, VECTOR) are kept as-is */ function normalizeValue(value) { if (typeof value == "bigint") { const num = Number(value); return Number.isSafeInteger(num) ? num : value.toString(); } if (value instanceof Date) { return Number.isNaN(value.getTime()) ? null : value.toISOString(); } return value; } function normalizeRows(res) { if (!Array.isArray(res)) return undefined; return res.map((row) => { if (!row || typeof row != "object") return row; const normalized = {}; for (const [key, value] of Object.entries(row)) { normalized[key] = normalizeValue(value); } return normalized; }); } /** * # Main DB Handler Function */ export default async function dbHandler({ query, values, config, client }) { try { const CLIENT = client || resolveClient(config); if (!CLIENT) { throw new Error(`Couldn't grab MariaDB Client.`); } const res = await holdEventLoop(() => CLIENT.unsafe(query, values)); const count = res.count; const res_array = normalizeRows(res); const last_insert_id = res_array?.[0] ? res_array[0]?.id : undefined; const affected_rows = res_array?.[0] ? res_array.length : undefined; const insert_return = { count, last_insert_id, affected_rows, }; return { success: true, payload: res_array, single_res: res_array?.[0], insert_return, count, db_res: res, }; } catch (error) { return { success: false, error: "DB Handler Error => " + error.message, msg: "DB Handler Error => " + error.message, }; } }