2019-10-03 06:34:41 +02:00
use crate ::{ err , maybe_update } ;
2019-10-04 00:02:23 +02:00
use std ::collections ::HashMap ;
2019-10-03 06:34:41 +02:00
use url ::Url ;
#[ derive(Debug) ]
pub struct PostgresConfig {
pub user : String ,
pub host : String ,
pub password : Option < String > ,
pub database : String ,
2019-10-04 00:02:23 +02:00
pub port : u16 ,
2019-10-03 06:34:41 +02:00
pub ssl_mode : String ,
}
impl Default for PostgresConfig {
fn default ( ) -> Self {
Self {
user : " postgres " . to_string ( ) ,
host : " localhost " . to_string ( ) ,
password : None ,
database : " mastodon_development " . to_string ( ) ,
2019-10-04 00:02:23 +02:00
port : 5432 ,
2019-10-03 06:34:41 +02:00
ssl_mode : " prefer " . to_string ( ) ,
}
}
}
fn none_if_empty ( item : & str ) -> Option < String > {
Some ( item ) . filter ( | i | ! i . is_empty ( ) ) . map ( String ::from )
}
impl PostgresConfig {
2019-10-04 00:02:23 +02:00
/// Configure Postgres and return a connection
pub fn from_env ( env_vars : HashMap < String , String > ) -> Self {
// use openssl::ssl::{SslConnector, SslMethod};
// use postgres_openssl::MakeTlsConnector;
// let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
// builder.set_ca_file("/etc/ssl/cert.pem").unwrap();
// let connector = MakeTlsConnector::new(builder.build());
// TODO: add TLS support, remove `NoTls`
match env_vars . get ( " DATABASE_URL " ) {
Some ( url ) = > {
log ::warn! ( " DATABASE_URL env variable set. Connecting to Postgres with that URL and ignoring any values set in DB_HOST, DB_USER, DB_NAME, DB_PASS, or DB_PORT. " ) ;
PostgresConfig ::from_url ( Url ::parse ( url ) . unwrap ( ) )
}
None = > Self ::default ( )
. maybe_update_user ( env_vars . get ( " USER " ) . map ( String ::from ) )
. maybe_update_user ( env_vars . get ( " DB_USER " ) . map ( String ::from ) )
. maybe_update_host ( env_vars . get ( " DB_HOST " ) . map ( String ::from ) )
. maybe_update_password ( env_vars . get ( " DB_PASS " ) . map ( String ::from ) )
. maybe_update_db ( env_vars . get ( " DB_NAME " ) . map ( String ::from ) )
. maybe_update_sslmode ( env_vars . get ( " DB_SSLMODE " ) . map ( String ::from ) ) }
. log ( )
}
maybe_update! ( maybe_update_user ; user : String ) ;
maybe_update! ( maybe_update_host ; host : String ) ;
maybe_update! ( maybe_update_db ; database : String ) ;
maybe_update! ( maybe_update_port ; port : u16 ) ;
maybe_update! ( maybe_update_sslmode ; ssl_mode : String ) ;
maybe_update! ( maybe_update_password ; Some ( password : String ) ) ;
2019-10-03 06:34:41 +02:00
2019-10-04 00:02:23 +02:00
fn from_url ( url : Url ) -> Self {
2019-10-03 06:34:41 +02:00
let ( mut user , mut host , mut sslmode , mut password ) = ( None , None , None , None ) ;
for ( k , v ) in url . query_pairs ( ) {
match k . to_string ( ) . as_str ( ) {
" user " = > { user = Some ( v . to_string ( ) ) ; } ,
" password " = > { password = Some ( v . to_string ( ) ) ; } ,
" host " = > { host = Some ( v . to_string ( ) ) ; } ,
" sslmode " = > { sslmode = Some ( v . to_string ( ) ) ; } ,
_ = > { err ::die_with_msg ( format! ( " Unsupported parameter {} in DATABASE_URL. \n Flodgatt supports only `user`, `password`, `host`, and `sslmode` parameters. " , k ) ) }
}
}
Self ::default ( )
// Values from query parameter
. maybe_update_user ( user )
. maybe_update_password ( password )
. maybe_update_host ( host )
. maybe_update_sslmode ( sslmode )
// Values from URL (which override query values if both are present)
. maybe_update_user ( none_if_empty ( url . username ( ) ) )
. maybe_update_host ( url . host_str ( ) . filter ( | h | ! h . is_empty ( ) ) . map ( String ::from ) )
. maybe_update_password ( url . password ( ) . map ( String ::from ) )
2019-10-04 00:02:23 +02:00
. maybe_update_port ( url . port ( ) )
2019-10-03 06:34:41 +02:00
. maybe_update_db ( none_if_empty ( & url . path ( ) [ 1 .. ] ) )
}
2019-10-04 00:02:23 +02:00
fn log ( self ) -> Self {
log ::warn! ( " Postgres configuration: \n {:#?} " , & self ) ;
self
}
2019-10-03 06:34:41 +02:00
}