1+ import { attachDatabasePool } from "@vercel/functions" ;
12import { sql } from "drizzle-orm" ;
23import { drizzle } from "drizzle-orm/node-postgres" ;
34import { err , ok , type Result } from "neverthrow" ;
5+ import { Pool } from "pg" ;
46import type { Database } from "@/drizzle/types" ;
57import * as schema from "../../drizzle/schema" ;
68import { getOwner } from "./useOwner" ;
79
8- const dbInstances = new Map < string , Database > ( ) ;
10+ const poolInstances = new Map < string , Pool > ( ) ;
911
1012export function getDatabaseName ( ownerId : string ) : Result < string , string > {
1113 if ( ! ownerId . startsWith ( "org_" ) && ! ownerId . startsWith ( "user_" ) ) {
@@ -31,19 +33,22 @@ export async function getDatabaseForOwner(ownerId: string): Promise<Database> {
3133 } ,
3234 ) ;
3335
34- const sslMode = process . env . DATABASE_SSL === "true" ? "?sslmode=require" : "" ;
35- const connectionString = `${ process . env . DATABASE_URL } /${ databaseName } ${ sslMode } ` ;
36-
37- if ( ! dbInstances . has ( ownerId ) ) {
38- dbInstances . set (
39- ownerId ,
40- drizzle ( connectionString , {
41- schema,
42- } ) ,
43- ) ;
36+ if ( ! poolInstances . has ( ownerId ) ) {
37+ const sslMode = process . env . DATABASE_SSL === "true" ? "?sslmode=require" : "" ;
38+ const connectionString = `${ process . env . DATABASE_URL } /${ databaseName } ${ sslMode } ` ;
39+
40+ const pool = new Pool ( {
41+ connectionString,
42+ min : 1 ,
43+ idleTimeoutMillis : 5000 ,
44+ connectionTimeoutMillis : 5000 ,
45+ } ) ;
46+
47+ attachDatabasePool ( pool ) ;
48+ poolInstances . set ( ownerId , pool ) ;
4449 }
4550
46- return dbInstances . get ( ownerId ) ! ;
51+ return drizzle ( poolInstances . get ( ownerId ) ! , { schema } ) ;
4752}
4853
4954export async function deleteDatabase ( ownerId : string ) {
@@ -54,22 +59,32 @@ export async function deleteDatabase(ownerId: string) {
5459 } ,
5560 ) ;
5661
57- const sslMode = process . env . DATABASE_SSL === "true" ? "?sslmode=require" : "" ;
62+ const pool = poolInstances . get ( ownerId ) ;
63+ if ( pool ) {
64+ await pool . end ( ) ;
65+ poolInstances . delete ( ownerId ) ;
66+ }
5867
59- const ownerDb = drizzle ( `${ process . env . DATABASE_URL } /manage${ sslMode } ` , {
60- schema,
68+ const sslMode = process . env . DATABASE_SSL === "true" ? "?sslmode=require" : "" ;
69+ const managePool = new Pool ( {
70+ connectionString : `${ process . env . DATABASE_URL } /manage${ sslMode } ` ,
71+ min : 1 ,
72+ idleTimeoutMillis : 5000 ,
73+ connectionTimeoutMillis : 5000 ,
6174 } ) ;
6275
63- // Terminate all connections to the database before dropping
76+ const ownerDb = drizzle ( managePool , { schema } ) ;
77+
6478 await ownerDb . execute ( sql `
6579 SELECT pg_terminate_backend(pid)
6680 FROM pg_stat_activity
6781 WHERE datname = ${ databaseName }
6882 AND pid <> pg_backend_pid()
6983 ` ) ;
7084
71- // Drop the database with FORCE option (PostgreSQL 13+)
7285 await ownerDb . execute (
7386 sql `DROP DATABASE ${ sql . identifier ( databaseName ) } WITH (FORCE)` ,
7487 ) ;
88+
89+ await managePool . end ( ) ;
7590}
0 commit comments