diff --git a/server/db/check.rs b/server/db/check.rs index effdbc1..932b512 100644 --- a/server/db/check.rs +++ b/server/db/check.rs @@ -50,6 +50,14 @@ pub struct Options { pub fn run(conn: &rusqlite::Connection, opts: &Options) -> Result { let mut printed_error = false; + // Compare stated schema version. + if let Err(e) = db::check_schema_version(conn) { + error!("Schema version is not as expected:\n{}", e); + printed_error = true; + } else { + info!("Schema at expected version {}.", db::EXPECTED_VERSION); + } + // Compare schemas. { let mut expected = rusqlite::Connection::open_in_memory()?; @@ -57,13 +65,16 @@ pub fn run(conn: &rusqlite::Connection, opts: &Options) -> Result { if let Some(diffs) = compare::get_diffs("actual", conn, "expected", &expected)? { error!("Schema is not as expected:\n{}", &diffs); printed_error = true; - warn!("The following analysis may be incorrect or encounter errors due to schema differences."); } else { println!("Schema is as expected."); } info!("Done comparing schemas."); } + if printed_error { + warn!("The following analysis may be incorrect or encounter errors due to schema differences."); + } + let db_uuid = raw::get_db_uuid(&conn)?; // Scan directories. diff --git a/server/db/db.rs b/server/db/db.rs index 4dd551e..d9b4122 100644 --- a/server/db/db.rs +++ b/server/db/db.rs @@ -2025,6 +2025,28 @@ pub fn get_schema_version(conn: &rusqlite::Connection) -> Result, Er |row| row.get(0))?)) } +/// Checks that the schema version in the given database is as expected. +pub(crate) fn check_schema_version(conn: &rusqlite::Connection) -> Result<(), Error> { + let ver = get_schema_version(conn)?.ok_or_else(|| format_err!( + "no such table: version. \ + \ + If you are starting from an \ + empty database, see README.md to complete the \ + installation. If you are starting from a database \ + that predates schema versioning, see guide/schema.md."))?; + if ver < EXPECTED_VERSION { + bail!("Database schema version {} is too old (expected {}); \ + see upgrade instructions in guide/upgrade.md.", + ver, EXPECTED_VERSION); + } else if ver > EXPECTED_VERSION { + bail!("Database schema version {} is too new (expected {}); \ + must use a newer binary to match.", ver, + EXPECTED_VERSION); + + } + Ok(()) +} + /// The recording database. Abstracts away SQLite queries. Also maintains in-memory state /// (loaded on startup, and updated on successful commit) to avoid expensive scans over the /// recording table on common queries. @@ -2060,25 +2082,7 @@ impl Database { pub fn new(clocks: C, mut conn: rusqlite::Connection, read_write: bool) -> Result, Error> { set_integrity_pragmas(&mut conn)?; - { - let ver = get_schema_version(&conn)?.ok_or_else(|| format_err!( - "no such table: version. \ - \ - If you are starting from an \ - empty database, see README.md to complete the \ - installation. If you are starting from a database \ - that predates schema versioning, see guide/schema.md."))?; - if ver < EXPECTED_VERSION { - bail!("Database schema version {} is too old (expected {}); \ - see upgrade instructions in guide/upgrade.md.", - ver, EXPECTED_VERSION); - } else if ver > EXPECTED_VERSION { - bail!("Database schema version {} is too new (expected {}); \ - must use a newer binary to match.", ver, - EXPECTED_VERSION); - - } - } + check_schema_version(&conn)?; // Note: the meta check comes after the version check to improve the error message when // trying to open a version 0 or version 1 database (which lacked the meta table).