use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf;
use std::time::Duration;
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct GlobalDatabaseConfig {
#[serde(default)]
pub servers: HashMap<String, DbConnConfig>,
#[serde(default)]
pub auto_provision: Option<bool>,
}
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
#[serde(deny_unknown_fields)]
pub struct DbConnConfig {
#[serde(default)]
pub engine: Option<DbEngineCfg>,
pub dsn: Option<String>,
pub host: Option<String>,
pub port: Option<u16>,
pub user: Option<String>,
pub password: Option<String>, pub dbname: Option<String>, #[serde(default)]
pub params: Option<HashMap<String, String>>,
pub file: Option<String>, pub path: Option<PathBuf>,
#[serde(default)]
pub pool: Option<PoolCfg>,
pub server: Option<String>,
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum DbEngineCfg {
Postgres,
Mysql,
Sqlite,
}
#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct PoolCfg {
pub max_conns: Option<u32>,
pub min_conns: Option<u32>,
#[serde(with = "modkit_utils::humantime_serde::option", default)]
pub acquire_timeout: Option<Duration>,
#[serde(with = "modkit_utils::humantime_serde::option", default)]
pub idle_timeout: Option<Duration>,
#[serde(with = "modkit_utils::humantime_serde::option", default)]
pub max_lifetime: Option<Duration>,
pub test_before_acquire: Option<bool>,
}
impl PoolCfg {
#[cfg(feature = "pg")]
#[must_use]
pub fn apply_pg(
&self,
mut opts: sqlx::postgres::PgPoolOptions,
) -> sqlx::postgres::PgPoolOptions {
if let Some(max_conns) = self.max_conns {
opts = opts.max_connections(max_conns);
}
if let Some(min_conns) = self.min_conns {
opts = opts.min_connections(min_conns);
}
if let Some(acquire_timeout) = self.acquire_timeout {
opts = opts.acquire_timeout(acquire_timeout);
}
if let Some(idle_timeout) = self.idle_timeout {
opts = opts.idle_timeout(Some(idle_timeout));
}
if let Some(max_lifetime) = self.max_lifetime {
opts = opts.max_lifetime(Some(max_lifetime));
}
if let Some(test_before_acquire) = self.test_before_acquire {
opts = opts.test_before_acquire(test_before_acquire);
}
opts
}
#[cfg(feature = "mysql")]
#[must_use]
pub fn apply_mysql(
&self,
mut opts: sqlx::mysql::MySqlPoolOptions,
) -> sqlx::mysql::MySqlPoolOptions {
if let Some(max_conns) = self.max_conns {
opts = opts.max_connections(max_conns);
}
if let Some(min_conns) = self.min_conns {
opts = opts.min_connections(min_conns);
}
if let Some(acquire_timeout) = self.acquire_timeout {
opts = opts.acquire_timeout(acquire_timeout);
}
if let Some(idle_timeout) = self.idle_timeout {
opts = opts.idle_timeout(Some(idle_timeout));
}
if let Some(max_lifetime) = self.max_lifetime {
opts = opts.max_lifetime(Some(max_lifetime));
}
if let Some(test_before_acquire) = self.test_before_acquire {
opts = opts.test_before_acquire(test_before_acquire);
}
opts
}
#[cfg(feature = "sqlite")]
#[must_use]
pub fn apply_sqlite(
&self,
mut opts: sqlx::sqlite::SqlitePoolOptions,
) -> sqlx::sqlite::SqlitePoolOptions {
if let Some(max_conns) = self.max_conns {
opts = opts.max_connections(max_conns);
}
if let Some(min_conns) = self.min_conns {
opts = opts.min_connections(min_conns);
}
if let Some(acquire_timeout) = self.acquire_timeout {
opts = opts.acquire_timeout(acquire_timeout);
}
if let Some(idle_timeout) = self.idle_timeout {
opts = opts.idle_timeout(Some(idle_timeout));
}
if let Some(max_lifetime) = self.max_lifetime {
opts = opts.max_lifetime(Some(max_lifetime));
}
if let Some(test_before_acquire) = self.test_before_acquire {
opts = opts.test_before_acquire(test_before_acquire);
}
opts
}
}