2023-05-24 14:19:46 +00:00
|
|
|
//! # Database connection management
|
|
|
|
|
|
|
|
use crate::app_config::AppConfig;
|
2023-06-13 13:24:13 +00:00
|
|
|
use diesel::result::{DatabaseErrorKind, Error};
|
2023-05-24 14:19:46 +00:00
|
|
|
use diesel::{Connection, PgConnection};
|
|
|
|
use std::cell::RefCell;
|
|
|
|
thread_local! {
|
|
|
|
static POSTGRES_CONNECTION: RefCell<Option<PgConnection>> = RefCell::new(None);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Execute a request on the database
|
|
|
|
pub fn execute<E, I>(cb: E) -> anyhow::Result<I>
|
|
|
|
where
|
2023-06-13 13:24:13 +00:00
|
|
|
E: FnOnce(&mut PgConnection) -> diesel::QueryResult<I>,
|
2023-05-24 14:19:46 +00:00
|
|
|
{
|
|
|
|
// Establish connection if required
|
|
|
|
if POSTGRES_CONNECTION.with(|i| i.borrow().is_none()) {
|
|
|
|
let database_url = AppConfig::get().db_connection_chain();
|
|
|
|
let conn = PgConnection::establish(&database_url)
|
|
|
|
.unwrap_or_else(|_| panic!("Error connecting to {}", database_url));
|
|
|
|
|
|
|
|
POSTGRES_CONNECTION.with(|i| *i.borrow_mut() = Some(conn))
|
|
|
|
}
|
|
|
|
|
2023-06-13 13:24:13 +00:00
|
|
|
match POSTGRES_CONNECTION.with(|i| cb(i.borrow_mut().as_mut().unwrap())) {
|
|
|
|
Ok(res) => Ok(res),
|
|
|
|
Err(e) => {
|
|
|
|
if matches!(
|
|
|
|
e,
|
|
|
|
Error::DatabaseError(DatabaseErrorKind::ClosedConnection, _)
|
|
|
|
| Error::BrokenTransactionManager
|
|
|
|
) {
|
|
|
|
log::warn!("Connection to database closed, dropping handle!");
|
|
|
|
POSTGRES_CONNECTION.with(|i| *i.borrow_mut() = None)
|
|
|
|
}
|
|
|
|
|
|
|
|
log::error!("Database query error! {:?}", e);
|
|
|
|
Err(e.into())
|
|
|
|
}
|
|
|
|
}
|
2023-05-24 14:19:46 +00:00
|
|
|
}
|