80 lines
2.9 KiB
JavaScript
80 lines
2.9 KiB
JavaScript
import path from "path";
|
|
import grabDirNames from "../data/grab-dir-names";
|
|
import {} from "../types";
|
|
import { SQL } from "bun";
|
|
/** Reuse one client per distinct connection config to avoid exhausting MariaDB connections. */
|
|
const clientCache = new Map();
|
|
/** Cache key each client was created with */
|
|
const clientKeys = new WeakMap();
|
|
/**
|
|
* Cache key covering everything that affects the connection, not just the
|
|
* database name.
|
|
*/
|
|
export function mariadbClientCacheKey(config) {
|
|
return JSON.stringify({
|
|
db_name: config?.db_name || "__default__",
|
|
db_config: config?.db_config || null,
|
|
ssl_ca: config?.ssl_ca || null,
|
|
ssl_reject_unauthorized: config?.ssl_reject_unauthorized ?? null,
|
|
});
|
|
}
|
|
export default function grabMariaDBClient({ config, }) {
|
|
const cacheKey = mariadbClientCacheKey(config);
|
|
const cached = clientCache.get(cacheKey);
|
|
if (cached) {
|
|
return cached;
|
|
}
|
|
// Prefer the process-wide client when it was created from the same config
|
|
if (global.MARIADB_CLIENT &&
|
|
clientKeys.get(global.MARIADB_CLIENT) === cacheKey) {
|
|
clientCache.set(cacheKey, global.MARIADB_CLIENT);
|
|
return global.MARIADB_CLIENT;
|
|
}
|
|
const { ROOT_DIR } = grabDirNames();
|
|
try {
|
|
// Verify the server certificate unless explicitly disabled
|
|
const rejectUnauthorized = config.ssl_reject_unauthorized !== false;
|
|
const tls = config.ssl_ca
|
|
? {
|
|
ca: Bun.file(path.resolve(ROOT_DIR, config.ssl_ca)),
|
|
rejectUnauthorized,
|
|
}
|
|
: {
|
|
rejectUnauthorized,
|
|
};
|
|
const MariaDBClient = new SQL({
|
|
hostname: process.env.BUN_MARIADB_SERVER_HOST,
|
|
username: process.env.BUN_MARIADB_SERVER_USERNAME,
|
|
password: process.env.BUN_MARIADB_SERVER_PASSWORD,
|
|
database: config.db_name,
|
|
port: process.env.BUN_MARIADB_SERVER_PORT
|
|
? Number(process.env.BUN_MARIADB_SERVER_PORT)
|
|
: undefined,
|
|
tls,
|
|
...config.db_config,
|
|
adapter: "mariadb",
|
|
});
|
|
/**
|
|
* A closed client can't run queries, so forget it on close: the next
|
|
* grab (or `ensureInit`) creates a fresh one.
|
|
*/
|
|
const close = MariaDBClient.close.bind(MariaDBClient);
|
|
MariaDBClient.close = (...args) => {
|
|
if (clientCache.get(cacheKey) === MariaDBClient) {
|
|
clientCache.delete(cacheKey);
|
|
}
|
|
if (global.MARIADB_CLIENT === MariaDBClient) {
|
|
global.MARIADB_CLIENT = undefined;
|
|
}
|
|
return close(...args);
|
|
};
|
|
clientKeys.set(MariaDBClient, cacheKey);
|
|
clientCache.set(cacheKey, MariaDBClient);
|
|
return MariaDBClient;
|
|
}
|
|
catch (error) {
|
|
console.error(`Couldn't grab MariaDB Client => ` + error.message);
|
|
return;
|
|
}
|
|
}
|