feat: add r2d2_mysql

Closes #5
This commit is contained in:
Dmitriy Pleshevskiy 2021-10-22 00:59:04 +03:00
parent ff24f783fe
commit cbe9d5e77c
5 changed files with 994 additions and 41 deletions

923
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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))
}
}

View file

@ -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
View 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)
}
}