use serde::{Deserialize, Serialize};
#[cfg(feature = "limbo")]
use std::path::PathBuf;
use std::time::Duration;
use wae_types::{WaeError, WaeResult};
pub type DatabaseResult<T> = WaeResult<T>;
pub type DatabaseError = WaeError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum RecyclingMethod {
Fast,
Verified,
Clean,
}
impl Default for RecyclingMethod {
fn default() -> Self {
Self::Verified
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PoolConfig {
pub max_connections: usize,
pub min_idle: Option<usize>,
pub connect_timeout_ms: Option<u64>,
pub wait_timeout_ms: Option<u64>,
pub idle_timeout_ms: Option<u64>,
pub max_lifetime_ms: Option<u64>,
pub recycling_method: RecyclingMethod,
pub health_check_enabled: bool,
pub health_check_interval_ms: Option<u64>,
}
impl Default for PoolConfig {
fn default() -> Self {
Self {
max_connections: 10,
min_idle: None,
connect_timeout_ms: Some(5000),
wait_timeout_ms: Some(30000),
idle_timeout_ms: Some(600000),
max_lifetime_ms: Some(1800000),
recycling_method: RecyclingMethod::default(),
health_check_enabled: true,
health_check_interval_ms: Some(30000),
}
}
}
impl PoolConfig {
pub fn new(max_connections: usize) -> Self {
Self { max_connections, ..Default::default() }
}
pub fn with_min_idle(mut self, min_idle: usize) -> Self {
self.min_idle = Some(min_idle);
self
}
pub fn with_connect_timeout(mut self, timeout: Duration) -> Self {
self.connect_timeout_ms = Some(timeout.as_millis() as u64);
self
}
pub fn with_wait_timeout(mut self, timeout: Duration) -> Self {
self.wait_timeout_ms = Some(timeout.as_millis() as u64);
self
}
pub fn with_idle_timeout(mut self, timeout: Duration) -> Self {
self.idle_timeout_ms = Some(timeout.as_millis() as u64);
self
}
pub fn with_max_lifetime(mut self, lifetime: Duration) -> Self {
self.max_lifetime_ms = Some(lifetime.as_millis() as u64);
self
}
pub fn with_recycling_method(mut self, method: RecyclingMethod) -> Self {
self.recycling_method = method;
self
}
pub fn with_health_check(mut self, enabled: bool) -> Self {
self.health_check_enabled = enabled;
self
}
pub fn with_health_check_interval(mut self, interval: Duration) -> Self {
self.health_check_interval_ms = Some(interval.as_millis() as u64);
self
}
pub fn connect_timeout(&self) -> Option<Duration> {
self.connect_timeout_ms.map(Duration::from_millis)
}
pub fn wait_timeout(&self) -> Option<Duration> {
self.wait_timeout_ms.map(Duration::from_millis)
}
pub fn idle_timeout(&self) -> Option<Duration> {
self.idle_timeout_ms.map(Duration::from_millis)
}
pub fn max_lifetime(&self) -> Option<Duration> {
self.max_lifetime_ms.map(Duration::from_millis)
}
pub fn health_check_interval(&self) -> Option<Duration> {
self.health_check_interval_ms.map(Duration::from_millis)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DatabaseConfig {
#[cfg(feature = "limbo")]
Limbo {
path: Option<PathBuf>,
},
#[cfg(feature = "postgres")]
Postgres {
connection_string: String,
pool_config: PoolConfig,
},
#[cfg(feature = "mysql")]
MySql {
connection_string: String,
pool_config: PoolConfig,
},
}
impl DatabaseConfig {
#[cfg(feature = "limbo")]
pub fn limbo_in_memory() -> Self {
Self::Limbo { path: None }
}
#[cfg(feature = "limbo")]
pub fn limbo_file<P: Into<PathBuf>>(path: P) -> Self {
Self::Limbo { path: Some(path.into()) }
}
#[cfg(feature = "postgres")]
pub fn postgres<S: Into<String>>(connection_string: S) -> Self {
Self::Postgres { connection_string: connection_string.into(), pool_config: PoolConfig::default() }
}
#[cfg(feature = "postgres")]
pub fn postgres_with_max_connections<S: Into<String>>(connection_string: S, max_connections: usize) -> Self {
Self::Postgres { connection_string: connection_string.into(), pool_config: PoolConfig::new(max_connections) }
}
#[cfg(feature = "postgres")]
pub fn postgres_with_pool_config<S: Into<String>>(connection_string: S, pool_config: PoolConfig) -> Self {
Self::Postgres { connection_string: connection_string.into(), pool_config }
}
#[cfg(feature = "mysql")]
pub fn mysql<S: Into<String>>(connection_string: S) -> Self {
Self::MySql { connection_string: connection_string.into(), pool_config: PoolConfig::default() }
}
#[cfg(feature = "mysql")]
pub fn mysql_with_max_connections<S: Into<String>>(connection_string: S, max_connections: usize) -> Self {
Self::MySql { connection_string: connection_string.into(), pool_config: PoolConfig::new(max_connections) }
}
#[cfg(feature = "mysql")]
pub fn mysql_with_pool_config<S: Into<String>>(connection_string: S, pool_config: PoolConfig) -> Self {
Self::MySql { connection_string: connection_string.into(), pool_config }
}
}