1
+ use diesel:: { ConnectionError , ConnectionResult } ;
2
+ use diesel_async:: pooled_connection:: bb8:: Pool ;
3
+ use diesel_async:: pooled_connection:: AsyncDieselConnectionManager ;
4
+ use diesel_async:: AsyncPgConnection ;
5
+ use futures_util:: future:: BoxFuture ;
6
+ use futures_util:: FutureExt ;
7
+ use std:: time:: Duration ;
8
+
9
+ #[ tokio:: main]
10
+ async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
11
+ let db_url = std:: env:: var ( "DATABASE_URL" ) . expect ( "Env var `DATABASE_URL` not set" ) ;
12
+
13
+ // First we have to construct a connection manager with our custom `establish_connection`
14
+ // function
15
+ let mgr = AsyncDieselConnectionManager :: < AsyncPgConnection > :: new_with_setup (
16
+ db_url,
17
+ establish_connection,
18
+ ) ;
19
+ // From that connection we can then create a pool, here given with some example settings.
20
+ let pool = Pool :: builder ( )
21
+ . max_size ( 10 )
22
+ . min_idle ( Some ( 5 ) )
23
+ . max_lifetime ( Some ( Duration :: from_secs ( 60 * 60 * 24 ) ) )
24
+ . idle_timeout ( Some ( Duration :: from_secs ( 60 * 2 ) ) )
25
+ . build ( mgr)
26
+ . await ?;
27
+
28
+ // Now we can use our pool to run queries over a TLS-secured connection:
29
+ let conn = pool. get ( ) . await ?;
30
+ let _ = conn;
31
+
32
+ Ok ( ( ) )
33
+ }
34
+
35
+ fn establish_connection ( config : & str ) -> BoxFuture < ConnectionResult < AsyncPgConnection > > {
36
+ let fut = async {
37
+ let rustls_config = rustls:: ClientConfig :: builder ( )
38
+ . with_safe_defaults ( )
39
+ . with_root_certificates ( root_certs ( ) )
40
+ . with_no_client_auth ( ) ;
41
+ let tls = tokio_postgres_rustls:: MakeRustlsConnect :: new ( rustls_config) ;
42
+ let ( client, conn) = tokio_postgres:: connect ( config, tls)
43
+ . await
44
+ . map_err ( |e| ConnectionError :: BadConnection ( e. to_string ( ) ) ) ?;
45
+ tokio:: spawn ( async move {
46
+ if let Err ( e) = conn. await {
47
+ eprintln ! ( "Database connection: {e}" ) ;
48
+ }
49
+ } ) ;
50
+ AsyncPgConnection :: try_from ( client) . await
51
+ } ;
52
+ fut. boxed ( )
53
+ }
54
+
55
+ fn root_certs ( ) -> rustls:: RootCertStore {
56
+ let mut roots = rustls:: RootCertStore :: empty ( ) ;
57
+ let certs = rustls_native_certs:: load_native_certs ( ) . expect ( "Certs not loadable!" ) ;
58
+ let certs: Vec < _ > = certs. into_iter ( ) . map ( |cert| cert. 0 ) . collect ( ) ;
59
+ roots. add_parsable_certificates ( & certs) ;
60
+ roots
61
+ }
0 commit comments