11import path from "node:path" ;
2+ import { currentUser } from "@clerk/nextjs/server" ;
23import { sql } from "drizzle-orm" ;
4+ import { upstashCache } from "drizzle-orm/cache/upstash" ;
35import { drizzle } from "drizzle-orm/node-postgres" ;
46import { migrate } from "drizzle-orm/node-postgres/migrator" ;
57import { err , ok , type Result , ResultAsync } from "neverthrow" ;
@@ -8,7 +10,9 @@ import { addUserToOpsDb } from "@/ops/useOps";
810import * as schema from "../../drizzle/schema" ;
911import { getOwner } from "./useOwner" ;
1012import { addUserToTenantDb } from "./useUser" ;
11- import { upstashCache } from "drizzle-orm/cache/upstash" ;
13+
14+ const connectionPool = new Map < string , Database > ( ) ;
15+ const connectionTimestamps = new Map < string , number > ( ) ;
1216
1317function handleError ( message : string ) {
1418 return ( error : unknown ) => {
@@ -25,44 +29,49 @@ function getDatabaseName(ownerId: string): Result<string, string> {
2529}
2630
2731export async function isDatabaseReady ( ) : Promise < boolean > {
28- return await ResultAsync . fromPromise (
29- migrateDatabase ( ) ,
30- handleError ( "Migration failed" ) ,
31- )
32- . andThen ( ( ) =>
33- ResultAsync . fromPromise (
34- addUserToTenantDb ( ) ,
35- handleError ( "Failed to add user to tenant database" ) ,
36- ) ,
37- )
38- . andThen ( ( ) =>
39- ResultAsync . fromPromise (
40- addUserToOpsDb ( ) ,
41- handleError ( "Failed to add user to ops database" ) ,
42- ) ,
43- )
44- . match (
45- ( ) => true ,
46- ( ) => false ,
47- ) ;
32+ try {
33+ const migrationResult = await migrateDatabase ( ) ;
34+
35+ if ( ! migrationResult ) {
36+ return false ;
37+ }
38+
39+ const userData = await currentUser ( ) ;
40+ if ( ! userData ) {
41+ throw new Error ( "No user found" ) ;
42+ }
43+
44+ await Promise . all ( [ addUserToTenantDb ( userData ) , addUserToOpsDb ( userData ) ] ) ;
45+
46+ return true ;
47+ } catch ( error ) {
48+ console . error ( "Database setup failed:" , error ) ;
49+ return false ;
50+ }
4851}
4952
5053async function migrateDatabase ( ) : Promise < boolean > {
51- return await ResultAsync . fromPromise (
54+ const dbResult = await ResultAsync . fromPromise (
5255 database ( ) ,
5356 handleError ( "Failed to get database" ) ,
54- )
55- . andThen ( ( db ) => {
56- const migrationsFolder = path . resolve ( process . cwd ( ) , "drizzle" ) ;
57- return ResultAsync . fromPromise (
58- migrate ( db , { migrationsFolder : migrationsFolder } ) ,
59- handleError ( "Failed to migrate database" ) ,
60- ) ;
61- } )
62- . match (
63- ( ) => true ,
64- ( ) => false ,
65- ) ;
57+ ) ;
58+
59+ if ( dbResult . isErr ( ) ) {
60+ return false ;
61+ }
62+
63+ const db = dbResult . value ;
64+ const migrationsFolder = path . resolve ( process . cwd ( ) , "drizzle" ) ;
65+
66+ const migrateResult = await ResultAsync . fromPromise (
67+ migrate ( db , { migrationsFolder : migrationsFolder } ) ,
68+ handleError ( "Failed to migrate database" ) ,
69+ ) ;
70+
71+ return migrateResult . match (
72+ ( ) => true ,
73+ ( ) => false ,
74+ ) ;
6675}
6776
6877export async function database ( ) : Promise < Database > {
@@ -75,6 +84,12 @@ export async function database(): Promise<Database> {
7584}
7685
7786export async function getDatabaseForOwner ( ownerId : string ) : Promise < Database > {
87+ const cachedConnection = connectionPool . get ( ownerId ) ;
88+ if ( cachedConnection ) {
89+ connectionTimestamps . set ( ownerId , Date . now ( ) ) ;
90+ return cachedConnection ;
91+ }
92+
7893 const databaseName = getDatabaseName ( ownerId ) . match (
7994 ( value ) => {
8095 return value ;
@@ -109,6 +124,9 @@ export async function getDatabaseForOwner(ownerId: string): Promise<Database> {
109124 } ,
110125 ) ;
111126
127+ connectionPool . set ( ownerId , tenantDb ) ;
128+ connectionTimestamps . set ( ownerId , Date . now ( ) ) ;
129+
112130 return tenantDb ;
113131}
114132
@@ -122,6 +140,9 @@ export async function deleteDatabase(ownerId: string) {
122140 } ,
123141 ) ;
124142
143+ connectionPool . delete ( ownerId ) ;
144+ connectionTimestamps . delete ( ownerId ) ;
145+
125146 const sslMode = process . env . DATABASE_SSL === "true" ? "?sslmode=require" : "" ;
126147
127148 const ownerDb = drizzle ( `${ process . env . DATABASE_URL } /manage${ sslMode } ` , {
0 commit comments