bb8_postgres/
lib.rs

1//! Postgres support for the `bb8` connection pool.
2#![deny(missing_docs, missing_debug_implementations)]
3
4pub use bb8;
5pub use tokio_postgres;
6
7use tokio_postgres::config::Config;
8use tokio_postgres::tls::{MakeTlsConnect, TlsConnect};
9use tokio_postgres::{Client, Error, Socket};
10
11use std::fmt;
12use std::str::FromStr;
13
14/// A `bb8::ManageConnection` for `tokio_postgres::Connection`s.
15#[derive(Clone)]
16pub struct PostgresConnectionManager<Tls>
17where
18    Tls: MakeTlsConnect<Socket>,
19{
20    config: Config,
21    tls: Tls,
22}
23
24impl<Tls> PostgresConnectionManager<Tls>
25where
26    Tls: MakeTlsConnect<Socket>,
27{
28    /// Create a new `PostgresConnectionManager` with the specified `config`.
29    pub fn new(config: Config, tls: Tls) -> PostgresConnectionManager<Tls> {
30        PostgresConnectionManager { config, tls }
31    }
32
33    /// Create a new `PostgresConnectionManager`, parsing the config from `params`.
34    pub fn new_from_stringlike<T>(
35        params: T,
36        tls: Tls,
37    ) -> Result<PostgresConnectionManager<Tls>, Error>
38    where
39        T: ToString,
40    {
41        let stringified_params = params.to_string();
42        let config = Config::from_str(&stringified_params)?;
43        Ok(Self::new(config, tls))
44    }
45}
46
47impl<Tls> bb8::ManageConnection for PostgresConnectionManager<Tls>
48where
49    Tls: MakeTlsConnect<Socket> + Clone + Send + Sync + 'static,
50    <Tls as MakeTlsConnect<Socket>>::Stream: Send + Sync,
51    <Tls as MakeTlsConnect<Socket>>::TlsConnect: Send,
52    <<Tls as MakeTlsConnect<Socket>>::TlsConnect as TlsConnect<Socket>>::Future: Send,
53{
54    type Connection = Client;
55    type Error = Error;
56
57    async fn connect(&self) -> Result<Self::Connection, Self::Error> {
58        let (client, connection) = self.config.connect(self.tls.clone()).await?;
59        // The connection object performs the actual communication with the database,
60        // so spawn it off to run on its own.
61        tokio::spawn(async move { connection.await.map(|_| ()) });
62        Ok(client)
63    }
64
65    async fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Self::Error> {
66        conn.simple_query("").await.map(|_| ())
67    }
68
69    fn has_broken(&self, conn: &mut Self::Connection) -> bool {
70        conn.is_closed()
71    }
72}
73
74impl<Tls> fmt::Debug for PostgresConnectionManager<Tls>
75where
76    Tls: MakeTlsConnect<Socket>,
77{
78    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79        f.debug_struct("PostgresConnectionManager")
80            .field("config", &self.config)
81            .finish()
82    }
83}