1
1
import pg from 'pg' ;
2
+ import {
3
+ defaultPostgreSqlDatabase ,
4
+ getDatabaseNameOrDefault ,
5
+ } from './connectionString' ;
2
6
3
7
const pools : Map < string , pg . Pool > = new Map ( ) ;
8
+ const usageCounter : Map < string , number > = new Map ( ) ;
4
9
5
10
export const getPool = (
6
11
connectionStringOrOptions : string | pg . PoolConfig ,
@@ -15,22 +20,63 @@ export const getPool = (
15
20
? { connectionString }
16
21
: connectionStringOrOptions ;
17
22
18
- //TODO: this should include database name resolution for key
23
+ const database =
24
+ poolOptions . database ??
25
+ ( poolOptions . connectionString
26
+ ? getDatabaseNameOrDefault ( poolOptions . connectionString )
27
+ : undefined ) ;
28
+
29
+ const lookupKey = key ( connectionString , database ) ;
30
+
31
+ updatePoolUsageCounter ( lookupKey , 1 ) ;
32
+
19
33
return (
20
- pools . get ( connectionString ) ??
21
- pools . set ( connectionString , new pg . Pool ( poolOptions ) ) . get ( connectionString ) !
34
+ pools . get ( lookupKey ) ??
35
+ pools . set ( lookupKey , new pg . Pool ( poolOptions ) ) . get ( lookupKey ) !
22
36
) ;
23
37
} ;
24
38
25
- export const endPool = async ( connectionString : string ) : Promise < void > => {
26
- const pool = pools . get ( connectionString ) ;
27
- if ( pool ) {
39
+ export const endPool = async ( {
40
+ connectionString,
41
+ database,
42
+ force,
43
+ } : {
44
+ connectionString : string ;
45
+ database ?: string | undefined ;
46
+ force ?: boolean ;
47
+ } ) : Promise < void > => {
48
+ database = database ?? getDatabaseNameOrDefault ( connectionString ) ;
49
+ const lookupKey = key ( connectionString , database ) ;
50
+
51
+ const pool = pools . get ( lookupKey ) ;
52
+ if ( pool && ( updatePoolUsageCounter ( lookupKey , - 1 ) <= 0 || force === true ) ) {
53
+ await onEndPool ( lookupKey , pool ) ;
54
+ }
55
+ } ;
56
+
57
+ export const onEndPool = async ( lookupKey : string , pool : pg . Pool ) => {
58
+ try {
28
59
await pool . end ( ) ;
29
- pools . delete ( connectionString ) ;
60
+ pools . delete ( lookupKey ) ;
61
+ } catch ( error ) {
62
+ console . log ( `Error while closing the connection pool: ${ lookupKey } ` ) ;
63
+ console . log ( error ) ;
30
64
}
31
65
} ;
32
66
33
67
export const endAllPools = ( ) =>
34
68
Promise . all (
35
- [ ...pools . keys ( ) ] . map ( ( connectionString ) => endPool ( connectionString ) ) ,
69
+ [ ...pools . entries ( ) ] . map ( ( [ lookupKey , pool ] ) => onEndPool ( lookupKey , pool ) ) ,
36
70
) ;
71
+
72
+ const key = ( connectionString : string , database : string | undefined ) =>
73
+ `${ connectionString } |${ database ?? defaultPostgreSqlDatabase } ` ;
74
+
75
+ const updatePoolUsageCounter = ( lookupKey : string , by : 1 | - 1 ) : number => {
76
+ const currentCounter = usageCounter . get ( lookupKey ) ?? 0 ;
77
+ const newCounter = currentCounter + by ;
78
+
79
+ usageCounter . set ( lookupKey , currentCounter + by ) ;
80
+
81
+ return newCounter ;
82
+ } ;
0 commit comments