use sqlx::ConnectOptions;
use secrecy::ExposeSecret;
use secrecy::Secret;
use sqlx::postgres::PgPoolOptions;
use sqlx::postgres::{PgConnectOptions, PgSslMode};
use sqlx::Pool;
use sqlx::Postgres;
#[derive(serde::Deserialize, Clone)]
pub struct DatabaseSettings {
pub username: String,
pub password: Secret<String>,
pub port: u16,
pub host: String,
pub database_name: String,
pub require_ssl: bool,
}
impl DatabaseSettings {
pub fn connection_string(&self) -> String {
format!(
"postgres://{}:{}@{}:{}/{}",
self.username,
self.password.expose_secret(),
self.host,
self.port,
self.database_name
)
}
pub fn connection_string_with_secret(&self) -> String {
format!(
"postgres://{}:{}@{}:{}/{}",
self.username, "*******", self.host, self.port, self.database_name
)
}
pub fn without_db(&self) -> PgConnectOptions {
let ssl_mode = if self.require_ssl {
PgSslMode::Require
} else {
PgSslMode::Prefer
};
PgConnectOptions::new()
.host(&self.host)
.username(&self.username)
.password(self.password.expose_secret())
.port(self.port)
.ssl_mode(ssl_mode)
}
pub fn with_db(&self) -> PgConnectOptions {
let mut options = self.without_db().database(&self.database_name);
options.log_statements(log::LevelFilter::Debug);
options
}
pub fn connect(&self) -> Pool<Postgres> {
self.log();
PgPoolOptions::new()
.acquire_timeout(std::time::Duration::from_secs(2))
.connect_lazy_with(self.with_db())
}
fn log(&self) {
let line = format!(
"PgConnect: connection_string={}",
self.connection_string_with_secret()
);
if !crate::core::cacheable::exists2s(&line) {
log::info!("{}", line);
crate::core::cacheable::put2s(&line, "");
}
}
}