use diesel::Connection;
use diesel::pg::PgConnection;
use diesel::r2d2::ConnectionManager;
use diesel::r2d2::Pool;
use diesel::r2d2::PooledConnection;
use ErrorResult;
use r2d2::Error as PoolError;
use rocket::http::Status;
use rocket::Outcome;
use rocket::request::FromRequest;
use rocket::request::Outcome as RequestOutcome;
use rocket::Request;
use rocket::State;
use std::ops::Deref;
pub type PostgreSQLPool = Pool<ConnectionManager<PgConnection>>;
pub struct DatabaseConnection(pub PooledConnection<ConnectionManager<PgConnection>>);
impl<'a, 'r> FromRequest<'a, 'r> for DatabaseConnection {
type Error = ();
fn from_request(request: &'a Request<'r>) -> RequestOutcome<Self, Self::Error> {
let pool = request.guard::<State<PostgreSQLPool>>()?;
match pool.get() {
Ok(connection) => Outcome::Success(DatabaseConnection(connection)),
Err(error) => {
warn!(target:"request", "Can't get a connection from the pool: {}", error);
Outcome::Failure((Status::ServiceUnavailable, ()))
},
}
}
}
impl Deref for DatabaseConnection {
type Target = PgConnection;
fn deref(&self) -> &Self::Target {
&self.0
}
}
pub fn initialize_database_pool(url: &str, max_size: u32) -> Result<PostgreSQLPool, PoolError> {
let manager = ConnectionManager::<PgConnection>::new(url);
Pool::builder()
.max_size(max_size)
.build(manager)
}
pub fn test_database_connection(database_url: &str) -> ErrorResult<()> {
PgConnection::establish(database_url)?;
Ok(())
}