refactor: move db migrations into isolated functions

This commit is contained in:
Greg Heartsfield 2022-10-09 08:54:03 -05:00
parent 2af5f9fbe8
commit 3e8adf978f

View File

@ -83,16 +83,32 @@ CREATE INDEX IF NOT EXISTS user_verification_event_index ON user_verification(me
); );
/// Determine the current application database schema version. /// Determine the current application database schema version.
pub fn db_version(conn: &mut Connection) -> Result<usize> { pub fn curr_db_version(conn: &mut Connection) -> Result<usize> {
let query = "PRAGMA user_version;"; let query = "PRAGMA user_version;";
let curr_version = conn.query_row(query, [], |row| row.get(0))?; let curr_version = conn.query_row(query, [], |row| row.get(0))?;
Ok(curr_version) Ok(curr_version)
} }
fn mig_init(conn: &mut PooledConnection) -> Result<usize> {
match conn.execute_batch(INIT_SQL) {
Ok(()) => {
info!(
"database pragma/schema initialized to v{}, and ready",
DB_VERSION
);
}
Err(err) => {
error!("update failed: {}", err);
panic!("database could not be initialized");
}
}
Ok(DB_VERSION)
}
/// Upgrade DB to latest version, and execute pragma settings /// Upgrade DB to latest version, and execute pragma settings
pub fn upgrade_db(conn: &mut PooledConnection) -> Result<()> { pub fn upgrade_db(conn: &mut PooledConnection) -> Result<()> {
// check the version. // check the version.
let mut curr_version = db_version(conn)?; let mut curr_version = curr_db_version(conn)?;
info!("DB version = {:?}", curr_version); info!("DB version = {:?}", curr_version);
debug!( debug!(
@ -113,18 +129,58 @@ pub fn upgrade_db(conn: &mut PooledConnection) -> Result<()> {
Ordering::Less => { Ordering::Less => {
// initialize from scratch // initialize from scratch
if curr_version == 0 { if curr_version == 0 {
match conn.execute_batch(INIT_SQL) { curr_version = mig_init(conn)?;
Ok(()) => {
info!("database pragma/schema initialized to v6, and ready");
} }
Err(err) => { // for initialized but out-of-date schemas, proceed to
error!("update failed: {}", err); // upgrade sequentially until we are current.
panic!("database could not be initialized"); if curr_version == 1 {
curr_version = mig_1_to_2(conn)?;
} }
if curr_version == 2 {
curr_version = mig_2_to_3(conn)?;
}
if curr_version == 3 {
curr_version = mig_3_to_4(conn)?;
}
if curr_version == 4 {
curr_version = mig_4_to_5(conn)?;
}
if curr_version == 5 {
curr_version = mig_5_to_6(conn)?;
}
if curr_version == DB_VERSION {
info!(
"All migration scripts completed successfully. Welcome to v{}.",
DB_VERSION
);
}
}
// Database is current, all is good
Ordering::Equal => {
debug!("Database version was already current (v{})", DB_VERSION);
}
// Database is newer than what this code understands, abort
Ordering::Greater => {
panic!(
"Database version is newer than supported by this executable (v{} > v{})",
curr_version, DB_VERSION
);
} }
} }
if curr_version == 1 { // Setup PRAGMA
conn.execute_batch(STARTUP_SQL)?;
debug!("SQLite PRAGMA startup completed");
Ok(())
}
//// Migration Scripts
fn mig_1_to_2(conn: &mut PooledConnection) -> Result<usize> {
// only change is adding a hidden column to events. // only change is adding a hidden column to events.
let upgrade_sql = r##" let upgrade_sql = r##"
ALTER TABLE event ADD hidden INTEGER; ALTER TABLE event ADD hidden INTEGER;
@ -134,16 +190,16 @@ PRAGMA user_version = 2;
match conn.execute_batch(upgrade_sql) { match conn.execute_batch(upgrade_sql) {
Ok(()) => { Ok(()) => {
info!("database schema upgraded v1 -> v2"); info!("database schema upgraded v1 -> v2");
curr_version = 2;
} }
Err(err) => { Err(err) => {
error!("update failed: {}", err); error!("update failed: {}", err);
panic!("database could not be upgraded"); panic!("database could not be upgraded");
} }
} }
} Ok(2)
}
if curr_version == 2 { fn mig_2_to_3(conn: &mut PooledConnection) -> Result<usize> {
// this version lacks the tag column // this version lacks the tag column
info!("database schema needs update from 2->3"); info!("database schema needs update from 2->3");
let upgrade_sql = r##" let upgrade_sql = r##"
@ -161,7 +217,6 @@ PRAGMA user_version = 3;
match conn.execute_batch(upgrade_sql) { match conn.execute_batch(upgrade_sql) {
Ok(()) => { Ok(()) => {
info!("database schema upgraded v2 -> v3"); info!("database schema upgraded v2 -> v3");
curr_version = 3;
} }
Err(err) => { Err(err) => {
error!("update failed: {}", err); error!("update failed: {}", err);
@ -187,11 +242,12 @@ PRAGMA user_version = 3;
} }
} }
} }
info!("Updated tag values");
tx.commit()?; tx.commit()?;
info!("Upgrade complete"); Ok(3)
} }
if curr_version == 3 { fn mig_3_to_4(conn: &mut PooledConnection) -> Result<usize> {
info!("database schema needs update from 3->4"); info!("database schema needs update from 3->4");
let upgrade_sql = r##" let upgrade_sql = r##"
-- incoming metadata events with nip05 -- incoming metadata events with nip05
@ -211,16 +267,16 @@ PRAGMA user_version = 4;
match conn.execute_batch(upgrade_sql) { match conn.execute_batch(upgrade_sql) {
Ok(()) => { Ok(()) => {
info!("database schema upgraded v3 -> v4"); info!("database schema upgraded v3 -> v4");
curr_version = 4;
} }
Err(err) => { Err(err) => {
error!("update failed: {}", err); error!("update failed: {}", err);
panic!("database could not be upgraded"); panic!("database could not be upgraded");
} }
} }
} Ok(4)
}
if curr_version == 4 { fn mig_4_to_5(conn: &mut PooledConnection) -> Result<usize> {
info!("database schema needs update from 4->5"); info!("database schema needs update from 4->5");
let upgrade_sql = r##" let upgrade_sql = r##"
DROP TABLE IF EXISTS event_ref; DROP TABLE IF EXISTS event_ref;
@ -230,17 +286,16 @@ PRAGMA user_version=5;
match conn.execute_batch(upgrade_sql) { match conn.execute_batch(upgrade_sql) {
Ok(()) => { Ok(()) => {
info!("database schema upgraded v4 -> v5"); info!("database schema upgraded v4 -> v5");
// uncomment if we have a newer version
//curr_version = 5;
} }
Err(err) => { Err(err) => {
error!("update failed: {}", err); error!("update failed: {}", err);
panic!("database could not be upgraded"); panic!("database could not be upgraded");
} }
} }
} Ok(5)
}
if curr_version == 5 { fn mig_5_to_6(conn: &mut PooledConnection) -> Result<usize> {
info!("database schema needs update from 5->6"); info!("database schema needs update from 5->6");
// We need to rebuild the tags table. iterate through the // We need to rebuild the tags table. iterate through the
// event table. build event from json, insert tags into a // event table. build event from json, insert tags into a
@ -291,23 +346,5 @@ PRAGMA user_version=5;
let start = Instant::now(); let start = Instant::now();
conn.execute("VACUUM;", [])?; conn.execute("VACUUM;", [])?;
info!("vacuumed DB after tags rebuild in {:?}", start.elapsed()); info!("vacuumed DB after tags rebuild in {:?}", start.elapsed());
} Ok(6)
}
// Database is current, all is good
Ordering::Equal => {
debug!("Database version was already current (v{})", DB_VERSION);
}
// Database is newer than what this code understands, abort
Ordering::Greater => {
panic!(
"Database version is newer than supported by this executable (v{} > v{})",
curr_version, DB_VERSION
);
}
}
// Setup PRAGMA
conn.execute_batch(STARTUP_SQL)?;
debug!("SQLite PRAGMA startup completed");
Ok(())
} }