sql_middleware/tx_outcome.rs
1use crate::pool::MiddlewarePoolConnection;
2
3#[cfg(feature = "sqlite")]
4use crate::sqlite::SqliteConnection;
5#[cfg(feature = "sqlite")]
6use crate::types::StatementCacheMode;
7
8/// Outcome returned by committing or rolling back a backend transaction.
9///
10/// Most backends do not need to surface anything after commit/rollback, but `SQLite`
11/// consumes the pooled connection for the transaction and needs to hand it back
12/// (with its translation and statement-cache defaults) so callers can keep using the pooled wrapper.
13///
14/// If you started a raw `SQLite` transaction, continue using the connection from the returned
15/// outcome instead of the pre-transaction wrapper to preserve the translation/cache flags and
16/// pool state.
17#[derive(Debug, Default)]
18pub struct TxOutcome {
19 restored_connection: Option<MiddlewarePoolConnection>,
20}
21
22impl TxOutcome {
23 /// Outcome with no connection to restore (common for Postgres, Turso, MSSQL).
24 #[must_use]
25 pub fn without_restored_connection() -> Self {
26 Self {
27 restored_connection: None,
28 }
29 }
30
31 /// Outcome that includes a connection restored to its pooled wrapper.
32 #[must_use]
33 pub fn with_restored_connection(conn: MiddlewarePoolConnection) -> Self {
34 Self {
35 restored_connection: Some(conn),
36 }
37 }
38
39 /// Borrow the restored connection, if present.
40 #[must_use]
41 pub fn restored_connection(&self) -> Option<&MiddlewarePoolConnection> {
42 self.restored_connection.as_ref()
43 }
44
45 /// Consume the outcome and take ownership of the restored connection, if present.
46 pub fn into_restored_connection(self) -> Option<MiddlewarePoolConnection> {
47 self.restored_connection
48 }
49
50 /// Restore any pooled connection contained in this outcome back into the caller's slot.
51 ///
52 /// This is primarily useful for `SQLite`, where the transaction API consumes the pooled wrapper
53 /// and returns it on commit/rollback. Other backends return an empty outcome, making this a
54 /// no-op.
55 pub fn restore_into(self, conn_slot: &mut MiddlewarePoolConnection) {
56 if let Some(conn) = self.into_restored_connection() {
57 *conn_slot = conn;
58 }
59 }
60
61 /// Consume the outcome and unwrap the `SQLite` connection plus wrapper defaults.
62 #[cfg(feature = "sqlite")]
63 pub fn into_sqlite_parts(self) -> Option<(SqliteConnection, bool, StatementCacheMode)> {
64 match self.restored_connection {
65 Some(MiddlewarePoolConnection::Sqlite {
66 mut conn,
67 translate_placeholders,
68 statement_cache_mode,
69 }) => conn
70 .take()
71 .map(|conn| (conn, translate_placeholders, statement_cache_mode)),
72 _ => None,
73 }
74 }
75}