use std::path::{Path, PathBuf};
use eyre::Result;
use sqlx::{
Sqlite, SqlitePool,
migrate::{MigrateDatabase, Migrator},
};
use tracing::info;
use super::shared_init::config_path;
static MIGRATOR: Migrator = sqlx::migrate!();
pub const DB_SCHEMA_VERSION: u64 = 4;
pub async fn init_sqlite_db(db_url: Option<String>) -> Result<()> {
let db_url = db_url.unwrap_or(default_db_path().to_string_lossy().into_owned());
if Sqlite::database_exists(&db_url).await.unwrap_or(false) {
info!("Database {} already exists", db_url);
return Ok(());
}
info!("Creating database {}", db_url);
if let Some(parent) = Path::new(&db_url).parent() {
std::fs::create_dir_all(parent)?;
}
match Sqlite::create_database(&db_url).await {
Ok(_) => {
info!("Create {} db success", &db_url);
let db = SqlitePool::connect(&db_url).await?;
match MIGRATOR.run(&db).await {
Ok(_) => info!("Migrations run successfully"),
Err(error) => panic!("Failed to run migrations: {error}"),
}
}
Err(error) => panic!("error: {error}"),
}
Ok(())
}
pub async fn sqlite_conn(db_url: Option<String>) -> Result<SqlitePool> {
let db_url = db_url.unwrap_or(default_db_path().to_string_lossy().into_owned());
match SqlitePool::connect(&db_url).await {
Ok(sqlite) => Ok(sqlite),
Err(error) => eyre::bail!("Error connecting to db: {}", error),
}
}
pub async fn sqlite_truncate_wal(conn: &SqlitePool) -> Result<()> {
sqlx::query("PRAGMA wal_checkpoint(TRUNCATE)")
.execute(conn)
.await?;
Ok(())
}
pub fn db_file_name(schema_version: u64) -> String {
format!("mevlog-sqlite-v{schema_version}.db")
}
pub fn default_db_path() -> PathBuf {
config_path().join(db_file_name(DB_SCHEMA_VERSION))
}