use rusqlite::Connection;
use rusqlite_migration::{Migrations, M};
use crate::error::{Error, Result};
const INITIAL: &str = include_str!("V001__Initial_navigation_data.sql");
pub(super) const SCHEMA_VERSION: u32 = 1;
pub(super) fn migrate(conn: &mut Connection) -> Result<()> {
conn.pragma_update(None, "foreign_keys", "ON")?;
let foreign_keys_enabled: i64 =
conn.pragma_query_value(None, "foreign_keys", |row| row.get(0))?;
if foreign_keys_enabled == 1 {
migrations().to_latest(conn)?;
Ok(())
} else {
Err(Error::Database(
"failed to enable SQLite foreign keys; migrate() should not called inside an active transaction".into(),
))
}
}
fn migrations() -> Migrations<'static> {
Migrations::new(vec![M::up(INITIAL)])
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn migrations_are_valid() {
migrations().validate().expect("migrations should be valid");
}
#[test]
fn fresh_database_runs_migrations() {
let mut conn = Connection::open_in_memory().unwrap();
migrate(&mut conn).unwrap();
let version: i64 = conn
.pragma_query_value(None, "user_version", |row| row.get(0))
.unwrap();
assert_eq!(version, SCHEMA_VERSION as i64);
}
#[test]
fn running_twice_is_idempotent() {
let mut conn = Connection::open_in_memory().unwrap();
migrate(&mut conn).unwrap();
migrate(&mut conn).unwrap();
}
}