use sqlx::postgres::PgPoolOptions;
use sqlx::PgPool;
use crate::error::StorageError;
use crate::types::DatabaseConfig;
pub async fn create_database_client(config: &DatabaseConfig) -> Result<PgPool, StorageError> {
if config.host.is_empty() {
return Err(StorageError::ConfigError("host is required".to_string()));
}
if config.port == 0 {
return Err(StorageError::ConfigError("port is required".to_string()));
}
if config.database.is_empty() {
return Err(StorageError::ConfigError(
"database is required".to_string(),
));
}
if config.user.is_empty() {
return Err(StorageError::ConfigError("user is required".to_string()));
}
if config.password.is_empty() {
return Err(StorageError::ConfigError(
"password is required".to_string(),
));
}
let database_url = format!(
"postgres://{}:{}@{}:{}/{}",
config.user, config.password, config.host, config.port, config.database
);
let pool = PgPoolOptions::new()
.max_connections(config.max.unwrap_or(10))
.acquire_timeout(std::time::Duration::from_millis(
config.connection_timeout_millis.unwrap_or(2000),
))
.idle_timeout(std::time::Duration::from_millis(
config.idle_timeout_millis.unwrap_or(30000),
))
.connect(&database_url)
.await?;
Ok(pool)
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_create_client_empty_host() {
let config = DatabaseConfig {
host: "".to_string(),
port: 5432,
database: "test".to_string(),
user: "user".to_string(),
password: "pass".to_string(),
max: None,
idle_timeout_millis: None,
connection_timeout_millis: None,
};
let result = create_database_client(&config).await;
assert!(result.is_err());
}
}