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