use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseConfig {
pub url: String,
#[serde(default = "default_pool_size")]
pub pool_size: u32,
#[serde(default = "default_pool_timeout")]
pub pool_timeout_secs: u64,
#[serde(default = "default_statement_timeout")]
pub statement_timeout_secs: u64,
#[serde(default)]
pub replica_urls: Vec<String>,
#[serde(default)]
pub read_from_replica: bool,
#[serde(default)]
pub pools: PoolsConfig,
}
impl Default for DatabaseConfig {
fn default() -> Self {
Self {
url: String::new(),
pool_size: default_pool_size(),
pool_timeout_secs: default_pool_timeout(),
statement_timeout_secs: default_statement_timeout(),
replica_urls: Vec::new(),
read_from_replica: false,
pools: PoolsConfig::default(),
}
}
}
fn default_pool_size() -> u32 {
50
}
fn default_pool_timeout() -> u64 {
30
}
fn default_statement_timeout() -> u64 {
30
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct PoolsConfig {
#[serde(default)]
pub default: Option<PoolConfig>,
#[serde(default)]
pub jobs: Option<PoolConfig>,
#[serde(default)]
pub observability: Option<PoolConfig>,
#[serde(default)]
pub analytics: Option<PoolConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PoolConfig {
pub size: u32,
#[serde(default = "default_pool_timeout")]
pub timeout_secs: u64,
pub statement_timeout_secs: Option<u64>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_database_config() {
let config = DatabaseConfig::default();
assert_eq!(config.pool_size, 50);
assert_eq!(config.pool_timeout_secs, 30);
}
#[test]
fn test_parse_database_config() {
let toml = r#"
url = "postgres://localhost/test"
pool_size = 100
replica_urls = ["postgres://replica1/test", "postgres://replica2/test"]
read_from_replica = true
"#;
let config: DatabaseConfig = toml::from_str(toml).unwrap();
assert_eq!(config.pool_size, 100);
assert_eq!(config.replica_urls.len(), 2);
assert!(config.read_from_replica);
}
}