use rusqlite::{Connection, Result, NO_PARAMS};
use std::{
fs::read_dir,
path::{Path, PathBuf},
};
use crate::dirs::setup_dirs;
mod embedded {
use refinery::embed_migrations;
embed_migrations!("src/db/migrations");
}
static DB_VERSION: i64 = 3;
pub fn check_stats_db() -> bool {
let db_dir = setup_dirs::get_db_dir();
Path::new(&db_dir).exists()
&& read_dir(&db_dir)
.unwrap()
.filter(|item| item.is_ok() && item.as_ref().unwrap().file_name() == "stats.db")
.count()
> 0
}
pub fn check_for_migration(path: &PathBuf) -> bool {
let conn = Connection::open(path).expect("Unreachable DB");
let db_version: Result<i64, rusqlite::Error> =
conn.query_row("PRAGMA user_version", NO_PARAMS, |row| row.get(0));
if let Ok(version) = db_version {
version == DB_VERSION
} else {
false
}
}
pub fn do_migration(path: &PathBuf) -> Result<(), rusqlite::Error> {
let mut conn = Connection::open(path)?;
let db_version: i64 = conn.query_row("PRAGMA user_version", NO_PARAMS, |row| row.get(0))?;
let mut stmt = conn.prepare(
"SELECT
sql
FROM
sqlite_master
WHERE
name = 'passage_stats'
AND
type = 'table'",
)?;
let table_exists = stmt.exists(NO_PARAMS)?;
drop(stmt);
if db_version == 0 && table_exists {
conn.execute(
"ALTER TABLE passage_stats RENAME TO ancient_passage_stats",
NO_PARAMS,
)?;
}
if let Err(a) = embedded::migrations::runner().run(&mut conn) {
println!("Error during migration: {}", a);
return Err(rusqlite::Error::InvalidPath(path.to_path_buf()));
}
if db_version == 0 && table_exists {
conn.execute(
"INSERT INTO passage_stats (
row_id,
passage,
wpm,
accuracy,
highest_combo,
game_mode,
when_played_secs
) SELECT
row_id,
passage,
wpm,
accuracy,
highest_combo,
instant_death,
when_played_secs
FROM ancient_passage_stats",
NO_PARAMS,
)?;
conn.execute("DROP TABLE ancient_passage_stats", NO_PARAMS)?;
}
Ok(())
}
pub fn create_database(path: &PathBuf) -> Result<(), rusqlite::Error> {
println!("CREATING DB");
let mut conn = Connection::open(path)?;
if embedded::migrations::runner().run(&mut conn).is_err() {
return Err(rusqlite::Error::InvalidPath(path.to_path_buf()));
}
Ok(())
}
pub fn db_path(base_path: &PathBuf) -> PathBuf {
base_path.join("stats.db")
}