use std::str::FromStr;
use deadpool_postgres::{Manager, ManagerConfig, Pool, RecyclingMethod, Runtime};
use tokio_postgres::{
tls::{MakeTlsConnect, TlsConnect},
Config, NoTls, Socket,
};
pub struct Connection;
pub struct ConnectionBuilder<Tls>
where
Tls: MakeTlsConnect<Socket> + Clone + Send + Sync + 'static,
Tls::Stream: Sync + Send,
Tls::TlsConnect: Sync + Send,
<Tls::TlsConnect as TlsConnect<Socket>>::Future: Send,
{
url: String,
tls: Tls,
recycling_method: RecyclingMethod,
max_pool_size: Option<usize>,
runtime: Option<Runtime>,
}
impl<Tls> ConnectionBuilder<Tls>
where
Tls: MakeTlsConnect<Socket> + Clone + Send + Sync + 'static,
Tls::Stream: Sync + Send,
Tls::TlsConnect: Sync + Send,
<Tls::TlsConnect as TlsConnect<Socket>>::Future: Send,
{
fn to(url: impl Into<String>) -> ConnectionBuilder<NoTls> {
ConnectionBuilder {
url: url.into(),
tls: NoTls,
recycling_method: RecyclingMethod::Fast,
max_pool_size: None,
runtime: None,
}
}
pub fn tls<NewTls>(self, tls: NewTls) -> ConnectionBuilder<NewTls>
where
NewTls: MakeTlsConnect<Socket> + Clone + Send + Sync + 'static,
NewTls::Stream: Sync + Send,
NewTls::TlsConnect: Sync + Send,
<NewTls::TlsConnect as TlsConnect<Socket>>::Future: Send,
{
ConnectionBuilder {
tls,
url: self.url,
recycling_method: self.recycling_method,
runtime: self.runtime,
max_pool_size: self.max_pool_size,
}
}
pub fn max_pool_size(mut self, n: usize) -> Self {
self.max_pool_size = Some(n);
self
}
pub fn connect(self) -> Result<(), crate::Error> {
let config = Config::from_str(&self.url)?;
let manager_config = ManagerConfig {
recycling_method: self.recycling_method,
};
let manager = Manager::from_config(config, self.tls, manager_config);
let mut builder = Pool::builder(manager).runtime(Runtime::Tokio1);
if let Some(n) = self.max_pool_size {
builder = builder.max_size(n);
}
let pool = builder.build()?;
crate::set_pool(pool)?;
Ok(())
}
}
impl Connection {
pub fn build(connection_string: impl Into<String>) -> ConnectionBuilder<NoTls> {
ConnectionBuilder::<NoTls>::to(connection_string)
}
}