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