82 lines
2.4 KiB
Rust
82 lines
2.4 KiB
Rust
use std::{sync::OnceLock, time::Duration};
|
|
|
|
use redis::{aio::MultiplexedConnection as RedisConnection, Client as RedisClient, RedisResult};
|
|
use sqlx::{postgres::PgPoolOptions, Pool, Postgres};
|
|
use crate::error::SirenResult;
|
|
|
|
static POOL: OnceLock<Pool<Postgres>> = OnceLock::new();
|
|
static REDIS: OnceLock<RedisClient> = OnceLock::new();
|
|
|
|
pub async fn initialize() -> SirenResult<()> {
|
|
log::info!("Initializing database...");
|
|
let db_user = std::env::var("DATABASE_USER").unwrap_or("siren".to_string());
|
|
let db_password = std::env::var("DATABASE_PASSWORD").expect("DATABASE_PASSWORD must be set");
|
|
let db_host: String = std::env::var("DATABASE_HOST").expect("DATABASE_HOST must be set");
|
|
let db_port = std::env::var("DATABASE_PORT").unwrap_or("5432".to_string());
|
|
let db_name = std::env::var("DATABASE_NAME").unwrap_or("siren".to_string());
|
|
|
|
// Setup Postgres pool connection
|
|
let pool = PgPoolOptions::new()
|
|
.max_connections(5)
|
|
.acquire_timeout(Duration::from_secs(30))
|
|
.connect(&format!(
|
|
"postgres://{}:{}@{}:{}/{}",
|
|
db_user, db_password, db_host, db_port, db_name
|
|
))
|
|
.await?;
|
|
match POOL.set(pool) {
|
|
Ok(_) => {}
|
|
Err(_) => {
|
|
log::warn!("Database pool already initialized");
|
|
}
|
|
}
|
|
|
|
// Setup Redis connection
|
|
let redis = {
|
|
let host = std::env::var("REDIS_HOST").unwrap_or("localhost".to_string());
|
|
let port = std::env::var("REDIS_PORT").unwrap_or("6379".to_string());
|
|
let url = format!("redis://{}:{}", host, port);
|
|
RedisClient::open(url).expect("Failed to create redis client")
|
|
};
|
|
match REDIS.set(redis) {
|
|
Ok(_) => {}
|
|
Err(_) => {
|
|
log::warn!("Redis client already initialized");
|
|
}
|
|
}
|
|
|
|
// Run migrations
|
|
match run_migrations().await {
|
|
Ok(_) => log::debug!("Successfully ran migrations"),
|
|
Err(e) => log::error!("Failed to run migrations: {}", e),
|
|
}
|
|
|
|
log::info!("Database initialized");
|
|
Ok(())
|
|
}
|
|
|
|
pub fn pool() -> &'static Pool<Postgres> {
|
|
POOL.get().unwrap()
|
|
}
|
|
|
|
fn redis() -> &'static RedisClient {
|
|
REDIS.get().unwrap()
|
|
}
|
|
|
|
pub fn redis_connection() -> RedisResult<redis::Connection> {
|
|
let conn = redis().get_connection()?;
|
|
Ok(conn)
|
|
}
|
|
|
|
pub async fn redis_async_connection() -> RedisResult<RedisConnection> {
|
|
let conn = redis().get_multiplexed_async_connection().await?;
|
|
Ok(conn)
|
|
}
|
|
|
|
async fn run_migrations() -> SirenResult<()> {
|
|
log::debug!("Running migrations");
|
|
let pool = pool();
|
|
sqlx::migrate!().run(pool).await?;
|
|
Ok(())
|
|
}
|