use std::{
fmt,
sync::Arc,
time::{Duration, Instant},
};
use crate::connection::{Connect, Connection};
use crate::transaction::Transaction;
use self::inner::SharedPool;
use self::options::Options;
pub use self::conn::PoolConnection;
mod conn;
mod executor;
mod inner;
mod options;
pub use self::options::Builder;
pub struct Pool<C>(Arc<SharedPool<C>>);
impl<C> Pool<C>
where
C: Connection + Connect<Connection = C>,
{
pub async fn new(url: &str) -> crate::Result<Self> {
Self::builder().build(url).await
}
async fn with_options(url: &str, options: Options) -> crate::Result<Self> {
let inner = SharedPool::new_arc(url, options).await?;
Ok(Pool(inner))
}
pub fn builder() -> Builder<C> {
Builder::new()
}
pub async fn acquire(&self) -> crate::Result<PoolConnection<C>> {
self.0.acquire().await.map(|conn| conn.attach(&self.0))
}
pub fn try_acquire(&self) -> Option<PoolConnection<C>> {
self.0.try_acquire().map(|conn| conn.attach(&self.0))
}
pub async fn begin(&self) -> crate::Result<Transaction<PoolConnection<C>>> {
Ok(Transaction::new(0, self.acquire().await?).await?)
}
pub async fn close(&self) {
self.0.close().await;
}
pub fn is_closed(&self) -> bool {
self.0.is_closed()
}
pub fn size(&self) -> u32 {
self.0.size()
}
pub fn idle(&self) -> usize {
self.0.num_idle()
}
pub fn max_size(&self) -> u32 {
self.0.options().max_size
}
pub fn connect_timeout(&self) -> Duration {
self.0.options().connect_timeout
}
pub fn min_size(&self) -> u32 {
self.0.options().min_size
}
pub fn max_lifetime(&self) -> Option<Duration> {
self.0.options().max_lifetime
}
pub fn idle_timeout(&self) -> Option<Duration> {
self.0.options().idle_timeout
}
}
impl<C> Clone for Pool<C> {
fn clone(&self) -> Self {
Self(Arc::clone(&self.0))
}
}
impl<C> fmt::Debug for Pool<C>
where
C: Connection + Connect<Connection = C>,
{
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Pool")
.field("url", &self.0.url())
.field("size", &self.0.size())
.field("num_idle", &self.0.num_idle())
.field("is_closed", &self.0.is_closed())
.field("options", self.0.options())
.finish()
}
}
fn deadline_as_timeout(deadline: Instant) -> crate::Result<Duration> {
deadline
.checked_duration_since(Instant::now())
.ok_or(crate::Error::PoolTimedOut(None))
}
#[test]
fn assert_pool_traits() {
fn assert_send_sync<T: Send + Sync>() {}
fn assert_clone<T: Clone>() {}
fn assert_pool<C: Connection + Connect<Connection = C>>() {
assert_send_sync::<Pool<C>>();
assert_clone::<Pool<C>>();
}
}