sql_middleware/pool/
interaction.rs

1use super::connection::MiddlewarePoolConnection;
2use crate::error::SqlMiddlewareDbError;
3use crate::pool::AnyConnWrapper;
4
5impl MiddlewarePoolConnection {
6    /// Interact with the connection asynchronously.
7    ///
8    /// This hands the raw driver client into your closure on the async runtime.
9    /// Keep the closure non-blocking—doing heavy work here will stall the runtime.
10    /// For `SQLite`, use `with_blocking_sqlite` / `interact_sync` instead.
11    ///
12    /// # Errors
13    /// Returns `SqlMiddlewareDbError::Unimplemented` for unsupported database types.
14    #[allow(unused_variables)]
15    pub async fn interact_async<F, Fut>(
16        &mut self,
17        func: F,
18    ) -> Result<Fut::Output, SqlMiddlewareDbError>
19    where
20        F: FnOnce(AnyConnWrapper<'_>) -> Fut + Send + 'static,
21        Fut: std::future::Future<Output = Result<(), SqlMiddlewareDbError>> + Send + 'static,
22    {
23        match self {
24            #[cfg(feature = "postgres")]
25            MiddlewarePoolConnection::Postgres { client: pg_obj, .. } => {
26                // `PooledConnection` dereferences to the underlying `tokio_postgres::Client`.
27                let client: &mut tokio_postgres::Client = pg_obj;
28                Ok(func(AnyConnWrapper::Postgres(client)).await)
29            }
30            #[cfg(feature = "mssql")]
31            MiddlewarePoolConnection::Mssql {
32                conn: mssql_obj, ..
33            } => {
34                // Get client from Object
35                let client = &mut **mssql_obj;
36                Ok(func(AnyConnWrapper::Mssql(client)).await)
37            }
38            #[cfg(feature = "sqlite")]
39            MiddlewarePoolConnection::Sqlite { .. } => Err(SqlMiddlewareDbError::Unimplemented(
40                "interact_async is not supported for SQLite; use interact_sync instead".to_string(),
41            )),
42            #[allow(unreachable_patterns)]
43            _ => Err(SqlMiddlewareDbError::Unimplemented(
44                "interact_async is not implemented for this database type".to_string(),
45            )),
46        }
47    }
48
49    /// Interact with the connection synchronously
50    ///
51    /// # Errors
52    /// Returns `SqlMiddlewareDbError::Unimplemented` for unsupported database types.
53    #[allow(unused_variables)]
54    pub async fn interact_sync<F, R>(&self, f: F) -> Result<R, SqlMiddlewareDbError>
55    where
56        F: FnOnce(AnyConnWrapper) -> R + Send + 'static,
57        R: Send + 'static,
58    {
59        match self {
60            #[cfg(feature = "sqlite")]
61            MiddlewarePoolConnection::Sqlite {
62                conn: sqlite_conn, ..
63            } => {
64                let conn = sqlite_conn.as_ref().ok_or_else(|| {
65                    SqlMiddlewareDbError::ExecutionError(
66                        "SQLite connection already taken from pool wrapper".into(),
67                    )
68                })?;
69
70                conn.with_connection(move |conn| {
71                    let wrapper = AnyConnWrapper::Sqlite(conn);
72                    Ok(f(wrapper))
73                })
74                .await
75            }
76            #[cfg(feature = "postgres")]
77            MiddlewarePoolConnection::Postgres { .. } => Err(SqlMiddlewareDbError::Unimplemented(
78                "interact_sync is not supported for Postgres; use interact_async instead"
79                    .to_string(),
80            )),
81            #[cfg(feature = "mssql")]
82            MiddlewarePoolConnection::Mssql { .. } => Err(SqlMiddlewareDbError::Unimplemented(
83                "interact_sync is not supported for SQL Server; use interact_async instead"
84                    .to_string(),
85            )),
86            #[allow(unreachable_patterns)]
87            _ => Err(SqlMiddlewareDbError::Unimplemented(
88                "interact_sync is not implemented for this database type".to_string(),
89            )),
90        }
91    }
92}