zirv_db_sqlx/db.rs
1use std::sync::OnceLock;
2use sqlx::{Pool, MySql, mysql::MySqlPoolOptions};
3use zirv_config::read_config;
4
5// Our global, one-time-initialized pool
6static DB_POOL: OnceLock<Pool<MySql>> = OnceLock::new();
7
8/// Initializes the global database pool exactly once.
9///
10/// This function should be called early in your application's lifecycle (for example, in your `main` function).
11/// It reads the configuration for the maximum number of database connections and the database URL.
12/// If no value is provided for the maximum connections, it defaults to 10.
13///
14/// # Panics
15/// - If no database URL is provided in the configuration.
16/// - If the pool fails to be created.
17/// - If the global pool is already initialized.
18pub async fn init_db_pool() {
19 let max_database_connections: u32 = read_config!("database.max_connections", u32).unwrap_or(10);
20 let database_url = read_config!("database.url", String).unwrap();
21
22 let pool = MySqlPoolOptions::new()
23 .max_connections(max_database_connections)
24 .connect(&database_url)
25 .await
26 .expect("Failed to create MySQL pool.");
27
28 // Attempt to set the static DB_POOL. If `set` fails, the pool was already set.
29 DB_POOL
30 .set(pool)
31 .expect("DB_POOL can only be initialized once!");
32}
33
34/// Retrieves a reference to the global database pool.
35///
36/// # Panics
37/// Panics if `init_db_pool` has not been called, as the pool will not be initialized.
38///
39/// # Returns
40/// A reference to the initialized `Pool<MySql>`.
41pub fn get_db_pool() -> &'static Pool<MySql> {
42 DB_POOL
43 .get()
44 .expect("DB pool not initialized! Call init_db_pool first.")
45}