mobc_diesel/
lib.rs

1extern crate diesel;
2extern crate mobc;
3
4#[macro_use]
5extern crate async_trait;
6
7use diesel::{Connection, ConnectionError};
8use mobc::Manager as ManageConnection;
9use std::convert::Into;
10use std::fmt;
11use std::marker::PhantomData;
12
13pub struct ConnectionManager<T> {
14    database_url: String,
15    _marker: PhantomData<T>,
16}
17
18unsafe impl<T: Send + 'static> Sync for ConnectionManager<T> {}
19
20impl<T> ConnectionManager<T> {
21    pub fn new<S: Into<String>>(database_url: S) -> Self {
22        ConnectionManager {
23            database_url: database_url.into(),
24            _marker: PhantomData,
25        }
26    }
27}
28
29#[derive(Debug)]
30pub enum Error {
31    ConnectionError(ConnectionError),
32    QueryError(diesel::result::Error),
33}
34
35impl fmt::Display for Error {
36    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37        match *self {
38            Error::ConnectionError(ref e) => e.fmt(f),
39            Error::QueryError(ref e) => e.fmt(f),
40        }
41    }
42}
43
44impl ::std::error::Error for Error {
45    fn description(&self) -> &str {
46        match *self {
47            Error::ConnectionError(ref e) => e.description(),
48            Error::QueryError(ref e) => e.description(),
49        }
50    }
51}
52
53#[async_trait]
54impl<T> ManageConnection for ConnectionManager<T>
55where
56    T: Connection + Send + 'static,
57{
58    type Connection = T;
59    type Error = Error;
60
61    async fn connect(&self) -> Result<T, Error> {
62        T::establish(&self.database_url).map_err(Error::ConnectionError)
63    }
64
65    async fn check(&self, conn: T) -> Result<T, Error> {
66        conn.execute("SELECT 1")
67            .map(|_| conn)
68            .map_err(Error::QueryError)
69    }
70}