repo/sqlite: add migration mechanism
This commit is contained in:
parent
62ad59ab76
commit
4203b21097
2 changed files with 70 additions and 13 deletions
|
@ -40,9 +40,13 @@ fn main() {
|
|||
let xdg_dirs = BaseDirectories::with_prefix(env!("CARGO_PKG_NAME")).unwrap();
|
||||
let repo = match SqliteRepo::new(xdg_dirs) {
|
||||
Ok(repo) => repo,
|
||||
Err(err) => return eprintln!("Cannot connect to repository: {}", err),
|
||||
Err(err) => return eprintln!("Cannot connect to repository: {err}"),
|
||||
};
|
||||
|
||||
if let Err(err) = repo.upgrade() {
|
||||
return eprintln!("Cannot upgrade database: {err}");
|
||||
}
|
||||
|
||||
match args.command {
|
||||
cli::SubCommand::Add(args) => {
|
||||
cli::add::execute(repo, args);
|
||||
|
|
|
@ -62,18 +62,6 @@ impl SqliteRepo {
|
|||
let file_path = xdg_dirs.get_data_file(SCHEMA_FILE);
|
||||
let conn = Connection::open(file_path).map_err(|_| Error::Connect)?;
|
||||
|
||||
/*
|
||||
conn.execute_batch(&format!(
|
||||
"BEGIN; {} COMMIT;",
|
||||
include_str!("../../database/schema.sql")
|
||||
))
|
||||
.map_err(|err| match err {
|
||||
rusqlite::Error::SqlInputError { .. } => panic!("{}", err),
|
||||
_ => err,
|
||||
})
|
||||
.ok();
|
||||
*/
|
||||
|
||||
Ok(Self { conn })
|
||||
}
|
||||
}
|
||||
|
@ -261,3 +249,68 @@ impl SqliteRepo {
|
|||
Ok(row)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! run_migration {
|
||||
($this:ident, $ver:ident = $version:expr) => {
|
||||
$this
|
||||
.conn
|
||||
.execute_batch(&format!(
|
||||
"BEGIN; {} COMMIT;",
|
||||
include_str!(concat!("../../database/migrations/", $version, ".sql"))
|
||||
))
|
||||
.map_err(|_| MigrationError::Upgrade)?;
|
||||
|
||||
$ver.replace($version);
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: move migration to a separate repository.
|
||||
#[derive(Debug)]
|
||||
pub enum MigrationError {
|
||||
Upgrade,
|
||||
DeleteInfo,
|
||||
InsertInfo,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for MigrationError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
MigrationError::Upgrade => f.write_str("Cannot upgrade the migration to a new version"),
|
||||
MigrationError::DeleteInfo => {
|
||||
f.write_str("Cannot delete the tas info from the database")
|
||||
}
|
||||
MigrationError::InsertInfo => {
|
||||
f.write_str("Cannot insert a new tas information to the database")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for MigrationError {}
|
||||
|
||||
impl SqliteRepo {
|
||||
pub fn upgrade(&self) -> Result<(), MigrationError> {
|
||||
let mut version = self.version();
|
||||
if version.is_none() {
|
||||
run_migration!(self, version = 202208162308);
|
||||
}
|
||||
|
||||
self.conn
|
||||
.execute("DELETE FROM _tas_info", [])
|
||||
.map_err(|_| MigrationError::DeleteInfo)?;
|
||||
self.conn
|
||||
.execute(
|
||||
"INSERT INTO _tas_info (version) VALUES (?)",
|
||||
[version.unwrap()],
|
||||
)
|
||||
.map_err(|_| MigrationError::InsertInfo)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn version(&self) -> Option<i64> {
|
||||
self.conn
|
||||
.query_row("SELECT version FROM _tas_info", [], |r| r.get("version"))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue