tempo_cli/db/
mod.rs

1pub mod advanced_queries;
2pub mod connection;
3pub mod migrations;
4pub mod pool;
5pub mod queries;
6
7use anyhow::Result;
8use std::path::Path;
9use std::sync::OnceLock;
10
11pub use connection::Database;
12pub use pool::{DatabasePool, PoolConfig, PooledConnectionGuard};
13
14/// Global database pool instance
15static DB_POOL: OnceLock<DatabasePool> = OnceLock::new();
16
17pub fn initialize_database(db_path: &Path) -> Result<Database> {
18    println!("Initializing database at: {:?}", db_path);
19    let db = Database::new(db_path)?;
20    println!("Database connection created");
21
22    // Run migrations
23    println!("Running migrations...");
24    migrations::run_migrations(&db.connection)?;
25    println!("Migrations completed");
26
27    Ok(db)
28}
29
30pub fn get_database_path() -> Result<std::path::PathBuf> {
31    let data_dir = dirs::data_dir()
32        .or_else(dirs::home_dir)
33        .ok_or_else(|| anyhow::anyhow!("Could not determine data directory"))?;
34
35    let tempo_dir = data_dir.join(".tempo");
36    std::fs::create_dir_all(&tempo_dir)?;
37
38    Ok(tempo_dir.join("data.db"))
39}
40
41/// Initialize the global database pool
42pub fn initialize_pool() -> Result<()> {
43    let db_path = get_database_path()?;
44    let pool = DatabasePool::new_with_defaults(db_path)?;
45
46    DB_POOL
47        .set(pool)
48        .map_err(|_| anyhow::anyhow!("Database pool already initialized"))?;
49
50    Ok(())
51}
52
53/// Initialize the global database pool with custom configuration
54pub fn initialize_pool_with_config(config: PoolConfig) -> Result<()> {
55    let db_path = get_database_path()?;
56    let pool = DatabasePool::new(db_path, config)?;
57
58    DB_POOL
59        .set(pool)
60        .map_err(|_| anyhow::anyhow!("Database pool already initialized"))?;
61
62    Ok(())
63}
64
65/// Get a connection from the global pool
66pub async fn get_connection() -> Result<PooledConnectionGuard> {
67    let pool = DB_POOL.get().ok_or_else(|| {
68        anyhow::anyhow!("Database pool not initialized. Call initialize_pool() first.")
69    })?;
70
71    pool.get_connection().await
72}
73
74/// Get pool statistics
75pub fn get_pool_stats() -> Result<pool::PoolStats> {
76    let pool = DB_POOL
77        .get()
78        .ok_or_else(|| anyhow::anyhow!("Database pool not initialized"))?;
79
80    pool.stats()
81}
82
83/// Close the global pool
84pub fn close_pool() -> Result<()> {
85    if let Some(pool) = DB_POOL.get() {
86        pool.close()?;
87    }
88    Ok(())
89}