use std::sync::{Arc, Mutex};
use crate::{
Connection, CursorImpl, Error, ParameterCollectionRef, Preallocated, Prepared,
connection::{ConnectionTransitions, FailedStateTransition},
handles::{StatementConnection, StatementParent},
};
pub type SharedConnection<'env> = Arc<Mutex<Connection<'env>>>;
unsafe impl StatementParent for SharedConnection<'_> {}
impl<'env> ConnectionTransitions for SharedConnection<'env> {
type StatementParent = Self;
fn into_cursor(
self,
query: &str,
params: impl ParameterCollectionRef,
query_timeout_sec: Option<usize>,
) -> Result<Option<CursorImpl<StatementConnection<Self>>>, FailedStateTransition<Self>> {
let guard = self
.lock()
.expect("Shared connection lock must not be poisned");
let result = guard.execute(query, params, query_timeout_sec);
let result = result.map(|opt| opt.map(|cursor| cursor.into_stmt().into_sys()));
drop(guard);
if let Err(error) = result {
return Err(FailedStateTransition {
error,
previous: self,
});
}
let Some(stmt_ptr) = result.unwrap() else {
return Ok(None);
};
let stmt = unsafe { StatementConnection::new(stmt_ptr, self) };
let cursor = unsafe { CursorImpl::new(stmt) };
Ok(Some(cursor))
}
fn into_prepared(self, query: &str) -> Result<Prepared<StatementConnection<Self>>, Error> {
let guard = self
.lock()
.expect("Shared connection lock must not be poisoned");
let stmt = guard.prepare(query)?;
let stmt_ptr = stmt.into_handle().into_sys();
drop(guard);
let stmt = unsafe { StatementConnection::new(stmt_ptr, self) };
let prepared = Prepared::new(stmt);
Ok(prepared)
}
fn into_preallocated(self) -> Result<Preallocated<StatementConnection<Self>>, Error> {
let guard = self
.lock()
.expect("Shared connection lock must not be poisoned");
let stmt = guard.preallocate()?;
let stmt_ptr = stmt.into_handle().into_sys();
drop(guard);
let stmt = unsafe { StatementConnection::new(stmt_ptr, self) };
let preallocated = unsafe { Preallocated::new(stmt) };
Ok(preallocated)
}
}