odbc_api/
shared_connection.rs1use std::sync::{Arc, Mutex};
2
3use crate::{
4 Connection, CursorImpl, Error, ParameterCollectionRef, Preallocated, Prepared,
5 connection::{ConnectionTransitions, FailedStateTransition},
6 handles::{StatementConnection, StatementParent},
7};
8
9pub type SharedConnection<'env> = Arc<Mutex<Connection<'env>>>;
12
13unsafe impl StatementParent for SharedConnection<'_> {}
18
19impl<'env> ConnectionTransitions for SharedConnection<'env> {
20 type StatementParent = Self;
21
22 fn into_cursor(
23 self,
24 query: &str,
25 params: impl ParameterCollectionRef,
26 query_timeout_sec: Option<usize>,
27 ) -> Result<Option<CursorImpl<StatementConnection<Self>>>, FailedStateTransition<Self>> {
28 let guard = self
29 .lock()
30 .expect("Shared connection lock must not be poisned");
31 let result = guard.execute(query, params, query_timeout_sec);
34 let result = result.map(|opt| opt.map(|cursor| cursor.into_stmt().into_sys()));
35 drop(guard);
36 if let Err(error) = result {
37 return Err(FailedStateTransition {
38 error,
39 previous: self,
40 });
41 }
42 let Some(stmt_ptr) = result.unwrap() else {
43 return Ok(None);
44 };
45 let stmt = unsafe { StatementConnection::new(stmt_ptr, self) };
47 let cursor = unsafe { CursorImpl::new(stmt) };
49 Ok(Some(cursor))
50 }
51
52 fn into_prepared(self, query: &str) -> Result<Prepared<StatementConnection<Self>>, Error> {
53 let guard = self
54 .lock()
55 .expect("Shared connection lock must not be poisoned");
56 let stmt = guard.prepare(query)?;
57 let stmt_ptr = stmt.into_handle().into_sys();
58 drop(guard);
59 let stmt = unsafe { StatementConnection::new(stmt_ptr, self) };
61 let prepared = Prepared::new(stmt);
63 Ok(prepared)
64 }
65
66 fn into_preallocated(self) -> Result<Preallocated<StatementConnection<Self>>, Error> {
67 let guard = self
68 .lock()
69 .expect("Shared connection lock must not be poisoned");
70 let stmt = guard.preallocate()?;
71 let stmt_ptr = stmt.into_handle().into_sys();
72 drop(guard);
73 let stmt = unsafe { StatementConnection::new(stmt_ptr, self) };
75 let preallocated = unsafe { Preallocated::new(stmt) };
77 Ok(preallocated)
78 }
79}