1
1
use crate :: Config ;
2
2
use postgres:: Connection ;
3
- use std :: marker :: PhantomData ;
3
+ use r2d2_postgres :: PostgresConnectionManager ;
4
4
5
- #[ cfg( test) ]
6
- use std:: sync:: { Arc , Mutex , MutexGuard } ;
5
+ pub ( crate ) type PoolConnection = r2d2:: PooledConnection < PostgresConnectionManager > ;
6
+
7
+ const DEFAULT_SCHEMA : & str = "public" ;
7
8
8
9
#[ derive( Debug , Clone ) ]
9
- pub enum Pool {
10
- R2D2 ( r2d2:: Pool < r2d2_postgres:: PostgresConnectionManager > ) ,
11
- #[ cfg( test) ]
12
- Simple ( Arc < Mutex < Connection > > ) ,
10
+ pub struct Pool {
11
+ pool : r2d2:: Pool < PostgresConnectionManager > ,
13
12
}
14
13
15
14
impl Pool {
16
15
pub fn new ( config : & Config ) -> Result < Pool , PoolError > {
16
+ Self :: new_inner ( config, DEFAULT_SCHEMA )
17
+ }
18
+
19
+ #[ cfg( test) ]
20
+ pub ( crate ) fn new_with_schema ( config : & Config , schema : & str ) -> Result < Pool , PoolError > {
21
+ Self :: new_inner ( config, schema)
22
+ }
23
+
24
+ fn new_inner ( config : & Config , schema : & str ) -> Result < Pool , PoolError > {
17
25
crate :: web:: metrics:: MAX_DB_CONNECTIONS . set ( config. max_pool_size as i64 ) ;
18
26
19
- let manager = r2d2_postgres :: PostgresConnectionManager :: new (
27
+ let manager = PostgresConnectionManager :: new (
20
28
config. database_url . as_str ( ) ,
21
29
r2d2_postgres:: TlsMode :: None ,
22
30
)
@@ -25,73 +33,54 @@ impl Pool {
25
33
let pool = r2d2:: Pool :: builder ( )
26
34
. max_size ( config. max_pool_size )
27
35
. min_idle ( Some ( config. min_pool_idle ) )
36
+ . connection_customizer ( Box :: new ( SetSchema :: new ( schema) ) )
28
37
. build ( manager)
29
38
. map_err ( PoolError :: PoolCreationFailed ) ?;
30
39
31
- Ok ( Pool :: R2D2 ( pool) )
32
- }
33
-
34
- #[ cfg( test) ]
35
- pub ( crate ) fn new_simple ( conn : Arc < Mutex < Connection > > ) -> Self {
36
- Pool :: Simple ( conn)
40
+ Ok ( Pool { pool } )
37
41
}
38
42
39
- pub fn get ( & self ) -> Result < DerefConnection < ' _ > , PoolError > {
40
- match self {
41
- Self :: R2D2 ( r2d2) => match r2d2. get ( ) {
42
- Ok ( conn) => Ok ( DerefConnection :: Connection ( conn, PhantomData ) ) ,
43
- Err ( err) => {
44
- crate :: web:: metrics:: FAILED_DB_CONNECTIONS . inc ( ) ;
45
- Err ( PoolError :: ConnectionError ( err) )
46
- }
47
- } ,
48
-
49
- #[ cfg( test) ]
50
- Self :: Simple ( mutex) => Ok ( DerefConnection :: Guard (
51
- mutex. lock ( ) . expect ( "failed to lock the connection" ) ,
52
- ) ) ,
43
+ pub fn get ( & self ) -> Result < PoolConnection , PoolError > {
44
+ match self . pool . get ( ) {
45
+ Ok ( conn) => Ok ( conn) ,
46
+ Err ( err) => {
47
+ crate :: web:: metrics:: FAILED_DB_CONNECTIONS . inc ( ) ;
48
+ Err ( PoolError :: ConnectionError ( err) )
49
+ }
53
50
}
54
51
}
55
52
56
53
pub ( crate ) fn used_connections ( & self ) -> u32 {
57
- match self {
58
- Self :: R2D2 ( conn) => conn. state ( ) . connections - conn. state ( ) . idle_connections ,
59
-
60
- #[ cfg( test) ]
61
- Self :: Simple ( ..) => 0 ,
62
- }
54
+ self . pool . state ( ) . connections - self . pool . state ( ) . idle_connections
63
55
}
64
56
65
57
pub ( crate ) fn idle_connections ( & self ) -> u32 {
66
- match self {
67
- Self :: R2D2 ( conn) => conn. state ( ) . idle_connections ,
68
-
69
- #[ cfg( test) ]
70
- Self :: Simple ( ..) => 0 ,
71
- }
58
+ self . pool . state ( ) . idle_connections
72
59
}
73
60
}
74
61
75
- pub enum DerefConnection < ' a > {
76
- Connection (
77
- r2d2:: PooledConnection < r2d2_postgres:: PostgresConnectionManager > ,
78
- PhantomData < & ' a ( ) > ,
79
- ) ,
80
-
81
- #[ cfg( test) ]
82
- Guard ( MutexGuard < ' a , Connection > ) ,
62
+ #[ derive( Debug ) ]
63
+ struct SetSchema {
64
+ schema : String ,
83
65
}
84
66
85
- impl < ' a > std:: ops:: Deref for DerefConnection < ' a > {
86
- type Target = Connection ;
87
-
88
- fn deref ( & self ) -> & Connection {
89
- match self {
90
- Self :: Connection ( conn, ..) => conn,
67
+ impl SetSchema {
68
+ fn new ( schema : & str ) -> Self {
69
+ Self {
70
+ schema : schema. into ( ) ,
71
+ }
72
+ }
73
+ }
91
74
92
- #[ cfg( test) ]
93
- Self :: Guard ( guard) => & guard,
75
+ impl r2d2:: CustomizeConnection < Connection , postgres:: Error > for SetSchema {
76
+ fn on_acquire ( & self , conn : & mut Connection ) -> Result < ( ) , postgres:: Error > {
77
+ if self . schema != DEFAULT_SCHEMA {
78
+ conn. execute (
79
+ & format ! ( "SET search_path TO {}, {};" , self . schema, DEFAULT_SCHEMA ) ,
80
+ & [ ] ,
81
+ ) ?;
94
82
}
83
+ Ok ( ( ) )
95
84
}
96
85
}
97
86
0 commit comments