#![cfg_attr(docsrs, feature(doc_cfg))]
#![allow(rustdoc::private_intra_doc_links)]
extern crate self as diesel_connection;
#[doc(hidden)]
pub extern crate static_init;
use cfg_block::cfg_block;
pub use derive_diesel_connection::PoolContext;
use diesel::r2d2::{self, ConnectionManager, PoolError, R2D2Connection};
use env_url::*;
pub trait ConnectionInfo: ServiceURL {
type Connection: R2D2Connection + 'static;
fn create_pool() -> Result<r2d2::Pool<ConnectionManager<Self::Connection>>, ParseError> {
#[cfg(feature = "dotenv")]
dotenvy::dotenv().ok();
let database_url = <Self as ServiceURL>::service_url()?;
let max_connections = std::env::var("MAX_DB_CONNECTIONS")
.unwrap_or_else(|_| String::from("20"))
.parse::<u32>()
.unwrap();
let connection_manager: ConnectionManager<Self::Connection> =
ConnectionManager::new(database_url);
let pool = r2d2::Pool::builder()
.max_size(max_connections)
.build_unchecked(connection_manager);
Ok(pool)
}
}
pub trait PoolContext: ConnectionInfo {
fn pool() -> &'static r2d2::Pool<ConnectionManager<<Self>::Connection>>;
fn get_connection(
) -> Result<r2d2::PooledConnection<ConnectionManager<Self::Connection>>, PoolError> {
<Self as PoolContext>::pool().get()
}
}
cfg_block! {
#[cfg(any(doc, all(feature = "postgres", not(feature = "mysql"), not(feature = "sqlite"))))] {
pub use pg::PooledConnection;
#[derive(EnvURL, PoolContext)]
#[env_url(env_prefix = "DATABASE", default = "postgresql://localhost:5432")]
pub struct ConnectionPool;
impl ConnectionInfo for ConnectionPool {
type Connection = pg::Connection;
}
pub fn get_connection() -> Result<PooledConnection, PoolError> {
<ConnectionPool as PoolContext>::get_connection()
}
}
#[cfg(all(feature = "mysql", not(feature = "postgres"), not(feature = "sqlite")))] {
pub use mysql::PooledConnection;
#[derive(EnvURL, PoolContext)]
#[env_url(env_prefix = "DATABASE", default = "mysql://localhost:3306")]
pub struct ConnectionPool;
impl ConnectionInfo for ConnectionPool {
type Connection = mysql::Connection;
}
pub fn get_connection() -> Result<PooledConnection, PoolError> {
<ConnectionPool as PoolContext>::get_connection()
}
}
#[cfg(all(feature = "sqlite", not(feature = "mysql"), not(feature = "postgres")))] {
pub use sqlite::PooledConnection;
#[derive(EnvURL, PoolContext)]
#[env_url(env_prefix = "DATABASE", default = "sqlite://./db.sqlite")]
pub struct ConnectionPool;
impl ConnectionInfo for ConnectionPool {
type Connection = sqlite::Connection;
}
pub fn get_connection() -> Result<PooledConnection, PoolError> {
<ConnectionPool as PoolContext>::get_connection()
}
}
}
#[cfg(any(doc, feature = "mysql"))]
#[cfg_attr(docsrs, doc(cfg(feature = "mysql")))]
pub mod mysql {
use super::*;
pub type Connection = diesel::mysql::MysqlConnection;
pub type PooledConnection = r2d2::PooledConnection<ConnectionManager<Connection>>;
}
#[cfg(any(doc, feature = "postgres"))]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres")))]
pub mod pg {
use super::*;
pub type Connection = diesel::pg::PgConnection;
pub type PooledConnection = r2d2::PooledConnection<ConnectionManager<Connection>>;
}
#[cfg(any(doc, feature = "sqlite"))]
#[cfg_attr(docsrs, doc(cfg(feature = "sqlite")))]
pub mod sqlite {
use super::*;
pub type Connection = diesel::sqlite::SqliteConnection;
pub type PooledConnection = r2d2::PooledConnection<ConnectionManager<Connection>>;
}