1
1
import type { PoolConfig } from 'pg' ;
2
-
3
2
import pg from 'pg' ;
4
3
import { migrate } from 'drizzle-orm/node-postgres/migrator' ;
5
4
import { NodePgDatabase , drizzle } from 'drizzle-orm/node-postgres' ;
6
-
7
5
import * as schema from '~~/db/schema' ;
8
6
9
7
const { Pool } = pg ;
10
8
9
+ interface DbConfig extends PoolConfig {
10
+ migrationFolder : string ;
11
+ }
12
+
11
13
class DbConnect {
12
14
static #instance: DbConnect ;
15
+ #config: DbConfig ;
13
16
#database: NodePgDatabase < typeof schema > ;
14
17
#pool: pg . Pool ;
15
18
16
- private constructor ( config : PoolConfig = { } ) {
17
- const defaultConfig : PoolConfig = {
19
+ private constructor ( config : Partial < DbConfig > = { } ) {
20
+ this . #config = this . #buildConfig( config ) ;
21
+ this . #pool = new Pool ( this . #config) ;
22
+ this . #database = drizzle ( this . #pool, { schema } ) ;
23
+ }
24
+
25
+ #buildConfig( partialConfig : Partial < DbConfig > ) : DbConfig {
26
+ const defaultConfig : DbConfig = {
18
27
user : process . env . DB_USER ,
19
28
password : process . env . DB_PASSWORD ,
20
29
host : process . env . DB_HOST ,
21
- port : process . env . DB_PORT ? parseInt ( process . env . DB_PORT ) : 5432 ,
30
+ port : parseInt ( process . env . DB_PORT || ' 5432' , 10 ) ,
22
31
database : process . env . DB_NAME ,
32
+ migrationFolder : 'db/migrations' ,
33
+ ssl : process . env . DB_SSL === 'true' ? { rejectUnauthorized : false } : undefined ,
23
34
} ;
24
35
25
- this . #pool = new Pool ( { ...defaultConfig , ...config } ) ;
26
- this . #database = drizzle ( this . #pool, { schema } ) ;
36
+ return { ...defaultConfig , ...partialConfig } ;
27
37
}
28
38
29
- public static getInstance ( ) {
39
+ public static getInstance ( config ?: Partial < DbConfig > ) {
30
40
if ( ! DbConnect . #instance) {
31
- DbConnect . #instance = new DbConnect ( ) ;
41
+ DbConnect . #instance = new DbConnect ( config ) ;
32
42
}
33
43
return DbConnect . #instance;
34
44
}
@@ -40,21 +50,24 @@ class DbConnect {
40
50
static get database ( ) {
41
51
return DbConnect . getInstance ( ) . #database;
42
52
}
53
+
54
+ public async runMigrations ( ) {
55
+ const client = await this . #pool. connect ( ) ;
56
+ try {
57
+ const db = drizzle ( client ) ;
58
+ await migrate ( db , { migrationsFolder : this . #config. migrationFolder } ) ;
59
+ } catch ( error : any ) {
60
+ console . error ( 'Database migration failed:' , error ?. message || 'Unknown error' ) ;
61
+ throw error ;
62
+ } finally {
63
+ client . release ( ) ;
64
+ }
65
+ }
66
+
43
67
}
44
68
45
69
export const drainDbPool = DbConnect . drainPool ;
46
- export const useDatabase = ( ) => DbConnect . database ;
47
-
48
70
export const runDbMigrations = async ( ) => {
49
- const client = new pg . Client ( {
50
- user : process . env . DB_USER ,
51
- password : process . env . DB_PASSWORD ,
52
- host : process . env . DB_HOST ,
53
- port : process . env . DB_PORT ? parseInt ( process . env . DB_PORT ) : 5432 ,
54
- database : process . env . DB_NAME ,
55
- } ) ;
56
- await client . connect ( ) ;
57
- const db = drizzle ( client ) ;
58
- await migrate ( db , { migrationsFolder : 'db/migrations' } ) ;
59
- await client . end ( ) ;
60
- }
71
+ await DbConnect . getInstance ( ) . runMigrations ( ) ;
72
+ } ;
73
+ export const useDatabase = ( ) => DbConnect . database ;
0 commit comments