use std::time::Duration;
use klauthed_core::config::DatabaseConfig;
use mongodb::Client;
use mongodb::bson::doc;
use mongodb::options::ClientOptions;
use crate::error::DataError;
pub async fn connect(config: &DatabaseConfig) -> Result<Client, DataError> {
let uri = config.url.as_deref().unwrap_or("mongodb://127.0.0.1:27017");
let mut opts = ClientOptions::parse(uri)
.await
.map_err(|e| DataError::Outbox(format!("mongodb URI parse error: {e}")))?;
opts.server_selection_timeout = Some(Duration::from_secs(config.pool.acquire_timeout_secs));
Client::with_options(opts).map_err(|e| DataError::Outbox(format!("mongodb client error: {e}")))
}
pub async fn connect_verified(config: &DatabaseConfig) -> Result<Client, DataError> {
let client = connect(config).await?;
ping(&client).await?;
Ok(client)
}
pub async fn ping(client: &Client) -> Result<(), DataError> {
client
.database("admin")
.run_command(doc! { "ping": 1 })
.await
.map_err(|e| DataError::Outbox(format!("mongodb ping failed: {e}")))?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use klauthed_core::config::DatabaseConfig;
#[tokio::test]
#[ignore = "requires a live MongoDB at MONGODB_URL"]
async fn connect_verified_and_ping() {
let url =
std::env::var("MONGODB_URL").unwrap_or_else(|_| "mongodb://127.0.0.1:27017".to_owned());
let config = DatabaseConfig { url: Some(url), ..Default::default() };
let client = connect_verified(&config).await.expect("connect+ping");
ping(&client).await.expect("second ping");
}
}