r2d2_postgres/
lib.rs

1//! Postgres support for the `r2d2` connection pool.
2#![warn(missing_docs)]
3pub use postgres;
4pub use r2d2;
5
6use postgres::tls::{MakeTlsConnect, TlsConnect};
7use postgres::{Client, Config, Error, Socket};
8use r2d2::ManageConnection;
9
10/// An `r2d2::ManageConnection` for `postgres::Client`s.
11///
12/// ## Example
13///
14/// ```no_run
15/// use std::thread;
16/// use r2d2_postgres::{postgres::NoTls, PostgresConnectionManager};
17///
18/// fn main() {
19///     let manager = PostgresConnectionManager::new(
20///         "host=localhost user=postgres".parse().unwrap(),
21///         NoTls,
22///     );
23///     let pool = r2d2::Pool::new(manager).unwrap();
24///
25///     for i in 0..10i32 {
26///         let pool = pool.clone();
27///         thread::spawn(move || {
28///             let mut client = pool.get().unwrap();
29///             client.execute("INSERT INTO foo (bar) VALUES ($1)", &[&i]).unwrap();
30///         });
31///     }
32/// }
33/// ```
34#[derive(Debug)]
35pub struct PostgresConnectionManager<T> {
36    config: Config,
37    tls_connector: T,
38}
39
40impl<T> PostgresConnectionManager<T>
41where
42    T: MakeTlsConnect<Socket> + Clone + 'static + Sync + Send,
43    T::TlsConnect: Send,
44    T::Stream: Send,
45    <T::TlsConnect as TlsConnect<Socket>>::Future: Send,
46{
47    /// Creates a new `PostgresConnectionManager`.
48    pub fn new(config: Config, tls_connector: T) -> PostgresConnectionManager<T> {
49        PostgresConnectionManager {
50            config,
51            tls_connector,
52        }
53    }
54}
55
56impl<T> ManageConnection for PostgresConnectionManager<T>
57where
58    T: MakeTlsConnect<Socket> + Clone + 'static + Sync + Send,
59    T::TlsConnect: Send,
60    T::Stream: Send,
61    <T::TlsConnect as TlsConnect<Socket>>::Future: Send,
62{
63    type Connection = Client;
64    type Error = Error;
65
66    fn connect(&self) -> Result<Client, Error> {
67        self.config.connect(self.tls_connector.clone())
68    }
69
70    fn is_valid(&self, client: &mut Client) -> Result<(), Error> {
71        client.simple_query("").map(|_| ())
72    }
73
74    fn has_broken(&self, client: &mut Client) -> bool {
75        client.is_closed()
76    }
77}