Disables prepared statements when PGBOUNCER=true (required for PgBouncer transaction mode). Adds DATABASE_DIRECT_URL so migrations always use a direct connection, bypassing the pool. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
31 lines
1.2 KiB
TypeScript
31 lines
1.2 KiB
TypeScript
import { drizzle } from "drizzle-orm/postgres-js";
|
|
import postgres from "postgres";
|
|
import * as schema from "~/database/schema";
|
|
|
|
// Cache the client on globalThis so HMR re-evaluations and multiple server
|
|
// modules share a single connection pool instead of each opening their own.
|
|
declare global {
|
|
// eslint-disable-next-line no-var
|
|
var __pgClient: ReturnType<typeof postgres> | undefined;
|
|
// eslint-disable-next-line no-var
|
|
var __pgDb: ReturnType<typeof drizzle<typeof schema>> | undefined;
|
|
}
|
|
|
|
function getDb() {
|
|
if (!globalThis.__pgDb) {
|
|
if (!process.env.DATABASE_URL) throw new Error("DATABASE_URL is required");
|
|
globalThis.__pgClient ??= postgres(process.env.DATABASE_URL, {
|
|
prepare: process.env.PGBOUNCER !== "true",
|
|
});
|
|
globalThis.__pgDb = drizzle(globalThis.__pgClient, { schema });
|
|
}
|
|
return globalThis.__pgDb;
|
|
}
|
|
|
|
// Export a Proxy so callers can use `db.query.foo` etc. without calling getDb() themselves.
|
|
// The proxy defers the DATABASE_URL check until the first actual property access.
|
|
export const db = new Proxy({} as ReturnType<typeof drizzle<typeof schema>>, {
|
|
get(_target, prop) {
|
|
return getDb()[prop as keyof ReturnType<typeof drizzle<typeof schema>>];
|
|
},
|
|
});
|