@@ -2,19 +2,35 @@ import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
22import { PrismaClient , Prisma } from 'src/generated/prisma/client' ;
33import { PrismaPg } from '@prisma/adapter-pg' ;
44import pg from 'pg' ;
5+ import { parseIntSafe } from 'src/utils' ;
56
67@Injectable ( )
78export class PrismaService
89 extends PrismaClient
910 implements OnModuleInit , OnModuleDestroy
1011{
11- private pool : pg . Pool ;
12+ private readonly pool : pg . Pool ;
1213
1314 constructor ( ) {
15+ const databaseUrl = process . env . DATABASE_URL ;
16+
17+ if ( ! databaseUrl ) {
18+ throw new Error ( 'DATABASE_URL environment variable is not set' ) ;
19+ }
20+
21+ const { connectionString, schema, connectionLimit, connectTimeout } =
22+ PrismaService . parseDatabaseUrl ( databaseUrl ) ;
23+
1424 const pool = new pg . Pool ( {
15- connectionString : process . env . DATABASE_URL ,
25+ connectionString,
26+ max : connectionLimit ?? 20 ,
27+ idleTimeoutMillis : 30000 ,
28+ connectionTimeoutMillis : connectTimeout ?? 5000 ,
29+ } ) ;
30+
31+ const adapter = new PrismaPg ( pool , {
32+ schema,
1633 } ) ;
17- const adapter = new PrismaPg ( pool ) ;
1834
1935 super ( {
2036 adapter,
@@ -26,8 +42,46 @@ export class PrismaService
2642
2743 this . pool = pool ;
2844 }
45+
46+ private static parseDatabaseUrl ( databaseUrl : string ) : {
47+ connectionString : string ;
48+ schema : string ;
49+ connectionLimit ?: number ;
50+ connectTimeout ?: number ;
51+ } {
52+ try {
53+ const url = new URL ( databaseUrl ) ;
54+ const schema = url . searchParams . get ( 'schema' ) || 'public' ;
55+ const connectionLimit = url . searchParams . get ( 'connection_limit' ) ;
56+ const connectTimeout = url . searchParams . get ( 'connect_timeout' ) ;
57+
58+ url . searchParams . delete ( 'schema' ) ;
59+ url . searchParams . delete ( 'connection_limit' ) ;
60+ url . searchParams . delete ( 'connect_timeout' ) ;
61+
62+ return {
63+ connectionString : url . toString ( ) ,
64+ schema,
65+ connectionLimit : parseIntSafe ( connectionLimit ) ,
66+ connectTimeout : parseIntSafe ( connectTimeout ) ,
67+ } ;
68+ } catch ( error ) {
69+ throw new Error (
70+ `Invalid DATABASE_URL format: ${ error instanceof Error ? error . message : 'Unknown error' } ` ,
71+ ) ;
72+ }
73+ }
74+
2975 async onModuleInit ( ) {
30- await this . $connect ( ) ;
76+ try {
77+ // Verify pool connectivity
78+ const client = await this . pool . connect ( ) ;
79+ client . release ( ) ;
80+
81+ await this . $connect ( ) ;
82+ } catch ( error ) {
83+ throw new Error ( `Database connection failed: ${ error . message } ` ) ;
84+ }
3185 }
3286
3387 async onModuleDestroy ( ) {
0 commit comments