-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathdb.ts
More file actions
53 lines (46 loc) · 1.61 KB
/
db.ts
File metadata and controls
53 lines (46 loc) · 1.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import { drizzle, type PostgresJsDatabase } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import * as schema from '../database/schema'
type DB = PostgresJsDatabase<typeof schema>
let _client: ReturnType<typeof postgres> | undefined
let _db: DB | undefined
/**
* Lazily create the Drizzle client on first access.
* Prevents build-time prerendering from crashing when DATABASE_URL
* isn't available (Railway injects env vars only at deploy time).
*/
function getDB(): DB {
if (!_db) {
_client = postgres(env.DATABASE_URL, {
max: 10,
idle_timeout: 20,
connect_timeout: 10,
})
_db = drizzle(_client, { schema })
// Gracefully close all connections on shutdown.
// Prevents leaked pools during dev HMR and ensures clean prod teardown.
function shutdown() {
_client?.end({ timeout: 5 }).catch(() => {})
}
process.on('SIGTERM', shutdown)
process.on('SIGINT', shutdown)
}
return _db
}
/**
* Lazily-initialized Drizzle database client.
* The connection is created on first property access — not at import time.
* This prevents build-time prerendering from failing when DATABASE_URL
* isn't available (e.g., Railway injects variables only at deploy time).
*/
export const db: DB = new Proxy({} as DB, {
get(_, prop) {
const instance = getDB()
if (typeof prop !== 'string') {
return Reflect.get(instance as object, prop)
}
const value = (instance as unknown as Record<string, unknown>)[prop]
// Bind methods so they keep the correct `this` context
return typeof value === 'function' ? value.bind(instance) : value
},
})