parent
ff24f783fe
commit
cbe9d5e77c
5 changed files with 994 additions and 41 deletions
923
Cargo.lock
generated
923
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -17,8 +17,10 @@ async = ["async-trait"]
|
|||
sync = []
|
||||
|
||||
bb8_postgres = ["async", "bb8", "bb8-postgres"]
|
||||
|
||||
r2d2_postgres = ["sync", "r2d2", "r2d2-postgres"]
|
||||
r2d2_sqlite = ["sync", "r2d2", "r2d2-sqlite"]
|
||||
r2d2_mysql = ["sync", "r2d2", "r2d2-mysql"]
|
||||
|
||||
[dependencies]
|
||||
async-trait = { version = "0.1", optional = true }
|
||||
|
@ -29,6 +31,7 @@ bb8-postgres = { version = "0.7", optional = true }
|
|||
r2d2 = { version = "0.8", optional = true }
|
||||
r2d2-postgres = { package = "r2d2_postgres", version = "0.18", optional = true }
|
||||
r2d2-sqlite = { package = "r2d2_sqlite", version = "0.19", optional = true }
|
||||
r2d2-mysql = { package = "r2d2_mysql", version = "18.0", optional = true }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
|
10
src/error.rs
10
src/error.rs
|
@ -8,6 +8,9 @@ use r2d2_postgres::postgres::Error as PostgresError;
|
|||
#[cfg(feature = "r2d2_sqlite")]
|
||||
use r2d2_sqlite::rusqlite::Error as RusqliteError;
|
||||
|
||||
#[cfg(feature = "r2d2_mysql")]
|
||||
use r2d2_mysql::mysql::Error as MysqlError;
|
||||
|
||||
/// A helper type for any result with persistence error.
|
||||
///
|
||||
/// Use this type in your repository or in something else that implements methods for your persistence.
|
||||
|
@ -72,3 +75,10 @@ impl From<RusqliteError> for Error {
|
|||
Self::PersistenceError(Box::new(err))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "r2d2_mysql")]
|
||||
impl From<MysqlError> for Error {
|
||||
fn from(err: MysqlError) -> Self {
|
||||
Self::PersistenceError(Box::new(err))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,14 @@ pub mod r2d2_postgres;
|
|||
#[cfg(feature = "r2d2_sqlite")]
|
||||
pub mod r2d2_sqlite;
|
||||
|
||||
/// This module contains implementation for sync interface of mysql database.
|
||||
///
|
||||
/// The implementation uses `r2d2` as the pool and `mysql` as the client.
|
||||
///
|
||||
/// **Note:** This mod requires enabling the `r2d2_mysql` feature.
|
||||
#[cfg(feature = "r2d2_mysql")]
|
||||
pub mod r2d2_mysql;
|
||||
|
||||
/// This module contains implementations for errors and result, that this
|
||||
/// crate uses
|
||||
pub mod error;
|
||||
|
|
91
src/r2d2_mysql.rs
Normal file
91
src/r2d2_mysql.rs
Normal file
|
@ -0,0 +1,91 @@
|
|||
#[cfg(feature = "nightly")]
|
||||
use crate::syn::TransactionClient;
|
||||
use crate::syn::{ConnectionClient, PersistencePool};
|
||||
pub use r2d2::{Pool, PooledConnection};
|
||||
pub use r2d2_mysql::mysql;
|
||||
pub use r2d2_mysql::MysqlConnectionManager as Manager;
|
||||
|
||||
/// Inner connection of r2d2 implementation.
|
||||
pub type InnerConn = PooledConnection<Manager>;
|
||||
/// Inner transaction of `mysql`.
|
||||
pub type InnerTrx<'t> = mysql::Transaction<'t>;
|
||||
|
||||
/// It creates new persistence of r2d2 mysql implementation.
|
||||
#[must_use]
|
||||
pub fn new(pool: &Pool<Manager>) -> Persistence {
|
||||
Persistence(pool)
|
||||
}
|
||||
|
||||
/// Persistence wrap over r2d2 pool.
|
||||
#[derive(Clone)]
|
||||
pub struct Persistence<'p>(&'p Pool<Manager>);
|
||||
|
||||
impl PersistencePool for Persistence<'_> {
|
||||
type Conn = Connection;
|
||||
|
||||
fn get_connection(&self) -> crate::Result<Self::Conn> {
|
||||
self.0
|
||||
.get()
|
||||
.map_err(|_| crate::Error::GetConnection)
|
||||
.map(Connection)
|
||||
}
|
||||
}
|
||||
|
||||
/// Connection wrap over r2d2 mysql inner connection.
|
||||
pub struct Connection(InnerConn);
|
||||
|
||||
impl ConnectionClient for Connection {
|
||||
type InnerConn = InnerConn;
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
type Trx<'t> = Transaction<'t>;
|
||||
|
||||
fn inner(&mut self) -> &mut Self::InnerConn {
|
||||
&mut self.0
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
fn start_transaction(&mut self) -> crate::Result<Self::Trx<'_>> {
|
||||
self.0
|
||||
.start_transaction(mysql::TxOpts::default())
|
||||
.map_err(|_| crate::Error::UpgradeToTransaction)
|
||||
.map(Transaction)
|
||||
}
|
||||
}
|
||||
|
||||
/// Transaction wrap over `mysql` transaction.
|
||||
///
|
||||
/// **Note:** requires nightly rust channel and enabling the `nightly` feature.
|
||||
///
|
||||
/// # Limits
|
||||
///
|
||||
/// Mysql doesn't support nested transactions
|
||||
pub struct Transaction<'me>(InnerTrx<'me>);
|
||||
|
||||
impl<'me> ConnectionClient for Transaction<'me> {
|
||||
type InnerConn = InnerTrx<'me>;
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
type Trx<'t> = Transaction<'t>;
|
||||
|
||||
fn inner(&mut self) -> &mut Self::InnerConn {
|
||||
&mut self.0
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
fn start_transaction(&mut self) -> crate::Result<Self::Trx<'_>> {
|
||||
// Mysql doesn't support nested transactions
|
||||
Err(crate::Error::UpgradeToNestedTransaction)
|
||||
}
|
||||
}
|
||||
|
||||
impl TransactionClient for Transaction<'_> {
|
||||
fn commit(self) -> crate::Result<()> {
|
||||
self.0.commit().map_err(|_| crate::Error::CommitTransaction)
|
||||
}
|
||||
fn rollback(self) -> crate::Result<()> {
|
||||
self.0
|
||||
.rollback()
|
||||
.map_err(|_| crate::Error::RollbackTransaction)
|
||||
}
|
||||
}
|
Reference in a new issue