All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			
		
			
				
	
	
		
			63 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			63 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| //! # Database connection management
 | |
| 
 | |
| use crate::app_config::AppConfig;
 | |
| use diesel::result::{DatabaseErrorKind, Error};
 | |
| use diesel::{Connection, PgConnection};
 | |
| use diesel_migrations::{EmbeddedMigrations, MigrationHarness, embed_migrations};
 | |
| use std::cell::RefCell;
 | |
| 
 | |
| const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
 | |
| 
 | |
| thread_local! {
 | |
|     static POSTGRES_CONNECTION: RefCell<Option<PgConnection>> = const { RefCell::new(None) };
 | |
| }
 | |
| 
 | |
| /// Execute a request on the database
 | |
| pub fn execute<E, I>(cb: E) -> anyhow::Result<I>
 | |
| where
 | |
|     E: FnOnce(&mut PgConnection) -> diesel::QueryResult<I>,
 | |
| {
 | |
|     // 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))
 | |
|     }
 | |
| 
 | |
|     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())
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// Initialize database connection
 | |
| pub fn initialize_conn() -> anyhow::Result<()> {
 | |
|     // Run pending diesel migrations
 | |
|     execute(|db| {
 | |
|         let res = db
 | |
|             .run_pending_migrations(MIGRATIONS)
 | |
|             .expect("Failed to run database migration!");
 | |
| 
 | |
|         for migration in res {
 | |
|             log::info!("Executed database migration {migration}")
 | |
|         }
 | |
| 
 | |
|         Ok(())
 | |
|     })?;
 | |
|     Ok(())
 | |
| }
 |