#![allow(clippy::too_many_arguments)]
use std::{str::FromStr, time::Duration};
use colored::Colorize;
use sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr};
use tracing::debug;
#[cfg(feature = "memory-database")]
use std::sync::Arc;
#[derive(Clone)]
pub struct DatabaseClient {
pub name: String,
#[cfg(feature = "memory-database")]
pub connection: Arc<DatabaseConnection>,
#[cfg(not(feature = "memory-database"))]
pub connection: DatabaseConnection,
}
impl DatabaseClient {
#[cfg(feature = "memory-database")]
pub async fn new_with_memory_database(name: String) -> Result<Self, DbErr> {
Ok(DatabaseClient {
name,
connection: Arc::new(Database::connect("sqlite::memory:").await?),
})
}
pub async fn new(
name: String,
dabaset_url: String,
min_pool_size: u32,
max_pool_size: u32,
logging: Option<bool>,
logging_level: Option<String>,
acquire_timeout: Option<u64>,
max_lifetime: Option<u64>,
idle_timeout: Option<u64>,
connect_timeout: Option<u64>,
) -> Result<Self, DbErr> {
let mut options = ConnectOptions::new(dabaset_url);
options
.min_connections(min_pool_size)
.max_connections(max_pool_size);
if let Some(enabled) = logging {
options.sqlx_logging(enabled);
}
if let Some(level) = logging_level
&& let Ok(level) = log::LevelFilter::from_str(&level)
{
options.sqlx_logging_level(level);
}
if let Some(seconds) = acquire_timeout {
options.acquire_timeout(Duration::from_secs(seconds));
}
if let Some(seconds) = max_lifetime {
options.max_lifetime(Duration::from_secs(seconds));
}
if let Some(seconds) = idle_timeout {
options.idle_timeout(Duration::from_secs(seconds));
}
if let Some(seconds) = connect_timeout {
options.connect_timeout(Duration::from_secs(seconds));
}
debug!("Database connection options: \n{:#?}", options);
let connection = Database::connect(options)
.await
.map_err(|e| DbErr::Custom(e.to_string().red().to_string()))?;
Ok(Self {
name,
#[cfg(feature = "memory-database")]
connection: Arc::new(connection),
#[cfg(not(feature = "memory-database"))]
connection,
})
}
}