prax_sqlx/
connection.rs

1//! Connection wrapper for SQLx.
2
3use crate::config::DatabaseBackend;
4use crate::error::SqlxResult;
5use crate::pool::SqlxPool;
6
7/// A database connection acquired from the pool.
8pub enum SqlxConnection {
9    /// PostgreSQL connection
10    #[cfg(feature = "postgres")]
11    Postgres(sqlx::pool::PoolConnection<sqlx::Postgres>),
12    /// MySQL connection
13    #[cfg(feature = "mysql")]
14    MySql(sqlx::pool::PoolConnection<sqlx::MySql>),
15    /// SQLite connection
16    #[cfg(feature = "sqlite")]
17    Sqlite(sqlx::pool::PoolConnection<sqlx::Sqlite>),
18}
19
20impl SqlxConnection {
21    /// Acquire a connection from the pool.
22    pub async fn acquire(pool: &SqlxPool) -> SqlxResult<Self> {
23        match pool {
24            #[cfg(feature = "postgres")]
25            SqlxPool::Postgres(p) => {
26                let conn = p.acquire().await?;
27                Ok(Self::Postgres(conn))
28            }
29            #[cfg(feature = "mysql")]
30            SqlxPool::MySql(p) => {
31                let conn = p.acquire().await?;
32                Ok(Self::MySql(conn))
33            }
34            #[cfg(feature = "sqlite")]
35            SqlxPool::Sqlite(p) => {
36                let conn = p.acquire().await?;
37                Ok(Self::Sqlite(conn))
38            }
39        }
40    }
41
42    /// Get the database backend type.
43    pub fn backend(&self) -> DatabaseBackend {
44        match self {
45            #[cfg(feature = "postgres")]
46            Self::Postgres(_) => DatabaseBackend::Postgres,
47            #[cfg(feature = "mysql")]
48            Self::MySql(_) => DatabaseBackend::MySql,
49            #[cfg(feature = "sqlite")]
50            Self::Sqlite(_) => DatabaseBackend::Sqlite,
51        }
52    }
53}
54
55/// A transaction handle.
56pub enum SqlxTransaction<'c> {
57    /// PostgreSQL transaction
58    #[cfg(feature = "postgres")]
59    Postgres(sqlx::Transaction<'c, sqlx::Postgres>),
60    /// MySQL transaction
61    #[cfg(feature = "mysql")]
62    MySql(sqlx::Transaction<'c, sqlx::MySql>),
63    /// SQLite transaction
64    #[cfg(feature = "sqlite")]
65    Sqlite(sqlx::Transaction<'c, sqlx::Sqlite>),
66}
67
68impl<'c> SqlxTransaction<'c> {
69    /// Commit the transaction.
70    pub async fn commit(self) -> SqlxResult<()> {
71        match self {
72            #[cfg(feature = "postgres")]
73            Self::Postgres(tx) => tx.commit().await?,
74            #[cfg(feature = "mysql")]
75            Self::MySql(tx) => tx.commit().await?,
76            #[cfg(feature = "sqlite")]
77            Self::Sqlite(tx) => tx.commit().await?,
78        }
79        Ok(())
80    }
81
82    /// Rollback the transaction.
83    pub async fn rollback(self) -> SqlxResult<()> {
84        match self {
85            #[cfg(feature = "postgres")]
86            Self::Postgres(tx) => tx.rollback().await?,
87            #[cfg(feature = "mysql")]
88            Self::MySql(tx) => tx.rollback().await?,
89            #[cfg(feature = "sqlite")]
90            Self::Sqlite(tx) => tx.rollback().await?,
91        }
92        Ok(())
93    }
94
95    /// Get the database backend type.
96    pub fn backend(&self) -> DatabaseBackend {
97        match self {
98            #[cfg(feature = "postgres")]
99            Self::Postgres(_) => DatabaseBackend::Postgres,
100            #[cfg(feature = "mysql")]
101            Self::MySql(_) => DatabaseBackend::MySql,
102            #[cfg(feature = "sqlite")]
103            Self::Sqlite(_) => DatabaseBackend::Sqlite,
104        }
105    }
106}
107
108impl SqlxPool {
109    /// Begin a transaction.
110    pub async fn begin(&self) -> SqlxResult<SqlxTransaction<'_>> {
111        match self {
112            #[cfg(feature = "postgres")]
113            Self::Postgres(pool) => {
114                let tx = pool.begin().await?;
115                Ok(SqlxTransaction::Postgres(tx))
116            }
117            #[cfg(feature = "mysql")]
118            Self::MySql(pool) => {
119                let tx = pool.begin().await?;
120                Ok(SqlxTransaction::MySql(tx))
121            }
122            #[cfg(feature = "sqlite")]
123            Self::Sqlite(pool) => {
124                let tx = pool.begin().await?;
125                Ok(SqlxTransaction::Sqlite(tx))
126            }
127        }
128    }
129}