infoalloggi-monorepo/apps/infoalloggi/src/server/db.ts

88 lines
2.1 KiB
TypeScript
Raw Normal View History

2025-08-04 17:45:44 +02:00
import {
2025-08-28 18:27:07 +02:00
DeduplicateJoinsPlugin,
HandleEmptyInListsPlugin,
Kysely,
type LogEvent,
PostgresDialect,
replaceWithNoncontingentExpression,
type Transaction,
2025-08-04 17:45:44 +02:00
} from "kysely";
2025-08-28 18:27:07 +02:00
import { Pool } from "pg";
import { env } from "~/env";
2025-08-04 17:45:44 +02:00
import type Database from "~/schemas/Database";
import type PublicSchema from "~/schemas/public/PublicSchema";
2025-08-28 18:27:07 +02:00
2025-08-04 17:45:44 +02:00
/**
* The database connection pool.
*/
const pool = new Pool({
//connectionTimeoutMillis: 2000,
2025-08-28 18:27:07 +02:00
database: env.POSTGRES_DB,
2025-08-29 16:18:32 +02:00
host: env.PGHOST,
//idleTimeoutMillis: 30000,
2025-08-29 16:18:32 +02:00
max: 10,
2025-08-28 18:27:07 +02:00
password: env.POSTGRES_PASSWORD,
port: Number.parseInt(env.PGPORT),
2025-08-29 16:18:32 +02:00
user: env.POSTGRES_USER,
2025-08-04 17:45:44 +02:00
});
pool.on("error", (err) => {
const pgErr = err as { code?: string };
// "admin_shutdown" error sent during backups
const isAdminShutdown = pgErr.code === "57P01";
const hour = new Date().getHours();
// Consider it a backup window if it's between 00:00 and 02:00
const isBackupWindow = hour === 0 || hour === 1;
if (isAdminShutdown && isBackupWindow) return;
console.error("PG error:", err);
});
2025-08-04 17:45:44 +02:00
type Db = typeof db;
type Trx = Transaction<PublicSchema>;
export type Querier = Db | Trx;
/**
* The database instance.
*/
export const db = new Kysely<Database>({
2025-08-28 18:27:07 +02:00
dialect: new PostgresDialect({
pool: pool,
}),
log: (_event) => {
//DbLogger(event);
2025-08-28 18:27:07 +02:00
},
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
//plugins: [new SerializePlugin()]
//plugins: [new CamelCasePlugin()],
plugins: [
new DeduplicateJoinsPlugin(),
new HandleEmptyInListsPlugin({
strategy: replaceWithNoncontingentExpression,
}),
//new ParseJSONResultsPlugin(),
2025-08-28 18:27:07 +02:00
],
2025-08-04 17:45:44 +02:00
});
const _DbLogger = (event: LogEvent) => {
2025-09-04 11:32:17 +02:00
if (
event.level === "query" &&
event.query.sql !== "begin" &&
event.query.sql !== "commit"
) {
console.log();
2025-08-28 18:27:07 +02:00
console.log("\x1b[33mquery:\x1b[0m", event.query.sql);
console.log("\x1b[36mparams:\x1b[0m", event.query.parameters);
2025-09-04 11:32:17 +02:00
//console.log("\x1b[32mtaken:\x1b[0m", event.queryDurationMillis, "ms");
2025-08-28 18:27:07 +02:00
}
if (event.level === "error") {
2025-09-04 11:32:17 +02:00
console.error();
2025-08-28 18:27:07 +02:00
console.error("\x1b[33mquery:\x1b[0m", event.query.sql);
console.error("\x1b[36mparams:\x1b[0m", event.query.parameters);
2025-09-04 11:32:17 +02:00
//console.error("\x1b[31merror:\x1b[0m", event.error);
2025-08-28 18:27:07 +02:00
}
2025-08-04 17:45:44 +02:00
};