1
Fork 0
shimmeringmoon/src/context/db.rs

98 lines
3.3 KiB
Rust

// {{{ Imports
use anyhow::{anyhow, Context};
use include_dir::{include_dir, Dir};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use rusqlite_migration::Migrations;
use std::sync::LazyLock;
use crate::arcaea::import_charts::{import_songlist, NOTECOUNT_DATA};
use crate::context::hash::{hash_bytes, hash_files};
use crate::context::paths::ShimmeringPaths;
use crate::context::process_jackets::process_jackets;
// }}}
pub type SqlitePool = r2d2::Pool<SqliteConnectionManager>;
pub fn connect_db(paths: &ShimmeringPaths) -> anyhow::Result<SqlitePool> {
let db_path = paths.db_path();
let mut conn = rusqlite::Connection::open(&db_path)
.with_context(|| "Could not connect to sqlite database")?;
conn.pragma_update(None, "journal_mode", "WAL")?;
// {{{ Run migrations
static MIGRATIONS_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/migrations");
static MIGRATIONS: LazyLock<Migrations> = LazyLock::new(|| {
Migrations::from_directory(&MIGRATIONS_DIR).expect("Could not load migrations")
});
MIGRATIONS
.to_latest(&mut conn)
.with_context(|| "Could not run migrations")?;
println!("✅ Ensured db schema is up to date");
// }}}
// {{{ Check if we need to reprocess jackets
let current_raw_jackets_hash = hash_files(&paths.raw_jackets_path())?;
let current_songlist_hash = hash_files(&paths.songlist_path())?;
let current_cc_data_hash = hash_files(&paths.cc_data_path())?;
let current_notecount_hash = hash_bytes(NOTECOUNT_DATA);
let (prev_raw_jackets_hash, prev_songlist_hash, prev_cc_data_hash, prev_notecount_hash) = conn
.query_row("SELECT * FROM metadata", (), |row| {
Ok((
row.get_ref("raw_jackets_hash")?.as_str()?.to_owned(),
row.get_ref("songlist_hash")?.as_str()?.to_owned(),
row.get_ref("cc_data_hash")?.as_str()?.to_owned(),
row.get_ref("notecount_hash")?.as_str()?.to_owned(),
))
})
.with_context(|| anyhow!("No metadata row found"))?;
let mut should_reprocess_jackets = true;
if current_songlist_hash != prev_songlist_hash
|| current_cc_data_hash != prev_cc_data_hash
|| current_notecount_hash != prev_notecount_hash
{
println!("😞 Chart data hash mismatch. Re-importing everything");
// {{ Import songlist & update hashes
import_songlist(paths, &mut conn).context("Failed to import songlist file")?;
conn.execute(
"
UPDATE metadata
SET songlist_hash=?,
cc_data_hash=?,
notecount_hash=?
",
(
current_songlist_hash,
current_cc_data_hash,
current_notecount_hash,
),
)?;
// }}}
} else if current_raw_jackets_hash != prev_raw_jackets_hash {
println!("😞 Jacket hashes do not match. Re-running the processing pipeline");
} else if !paths.recognition_matrix_path().exists() {
println!("😞 Jacket recognition matrix not found.");
} else if !paths.jackets_path().exists() {
println!("😞 Processed jackets not found.");
} else {
println!("✅ Jacket hashes match. Skipping jacket processing");
should_reprocess_jackets = false;
}
if should_reprocess_jackets {
process_jackets(paths, &conn)?;
conn.prepare("UPDATE metadata SET raw_jackets_hash=?")?
.execute([current_raw_jackets_hash])?;
println!("✅ Jacket processing pipeline run succesfully");
}
// }}}
Pool::new(SqliteConnectionManager::file(&db_path))
.with_context(|| "Could not open sqlite database.")
}