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