use crate::ClientHolder;
use mongodb::options::ClientOptions;
use mongodb::{Client, ClientSession, Database};
use std::error;
use std::sync::Arc;
use tokio::sync::Mutex;
async fn get_client(data: &Arc<Mutex<ClientHolder>>) -> Result<Client, Box<dyn error::Error>> {
let client_holder = data.lock().await;
if client_holder.connected {
let client = client_holder.client.clone().unwrap();
return Ok(client);
}
let client_options = client_holder.client_options.clone();
drop(client_holder);
let new_client = connect(client_options).await?;
let mut client_holder = data.lock().await;
client_holder.client = Some(new_client.clone());
client_holder.connected = true;
drop(client_holder);
Ok(new_client)
}
pub async fn get(
data: &Arc<Mutex<ClientHolder>>,
database_name: &str,
) -> Result<Database, Box<dyn error::Error>> {
let db = get_client(data).await?.database(database_name);
Ok(db)
}
pub async fn disconnect(data: &Arc<Mutex<ClientHolder>>) {
let mut client_holder = data.lock().await;
client_holder.connected = false;
}
async fn connect(client_options: ClientOptions) -> Result<Client, Box<dyn error::Error>> {
let new_client = Client::with_options(client_options)?;
Ok(new_client)
}
pub async fn start_transaction(
data: &Arc<Mutex<ClientHolder>>,
) -> Result<ClientSession, Box<dyn error::Error>> {
let client = get_client(data).await?;
let mut session = client.start_session(None).await?;
session.start_transaction(None).await?;
Ok(session)
}
pub async fn commit_transaction(session: &mut ClientSession) -> Result<(), Box<dyn error::Error>> {
session.commit_transaction().await?;
Ok(())
}
pub async fn abort_transaction(session: &mut ClientSession) -> Result<(), Box<dyn error::Error>> {
session.abort_transaction().await?;
Ok(())
}