The store's migrations are a table of steps, applied in order

schema::migrate was thirteen hand-copied blocks of "if version < N, apply,
stamp N". The versions are now a STEPS list (SQL, or code for v8). migrate walks
the list, applies each step a store hasn't had and stamps it. A new version is a
new entry at the end; there is no block to copy.

DRY pass #2, batch 2, F7 (#5372).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 14:21:47 -04:00
co-authored by Claude Opus 5.5
parent 61658946d7
commit 8aa854d60b
+33 -50
View File
@@ -4,7 +4,8 @@
//! `#tags` are NOT stored as such (derived at query time into labels), matching
//! docs/sync.md.
//!
//! Migrations are gated on `PRAGMA user_version`; bump it and add a block per change.
//! Migrations are gated on `PRAGMA user_version`; a change is a new entry at the end of
//! [`STEPS`].
use rusqlite::{params, Connection, OptionalExtension};
@@ -331,60 +332,42 @@ const SCHEMA_V13: &str = r#"
DROP TABLE saved_filters;
"#;
/// One schema version's change: SQL, or code for a change SQL alone can't make.
enum Step {
Sql(&'static str),
Code(fn(&Connection) -> rusqlite::Result<()>),
}
/// Every version in order: entry N brings a store to version N + 1. A change is a
/// new entry at the end; [`migrate`] applies each one a store hasn't had yet.
const STEPS: &[Step] = &[
Step::Sql(SCHEMA_V1),
Step::Sql(SCHEMA_V2),
Step::Sql(SCHEMA_V3),
Step::Sql(SCHEMA_V4),
Step::Sql(SCHEMA_V5),
Step::Sql(SCHEMA_V6),
Step::Sql(SCHEMA_V7),
Step::Code(migrate_v8),
Step::Sql(SCHEMA_V9),
Step::Sql(SCHEMA_V10),
Step::Sql(SCHEMA_V11),
Step::Sql(SCHEMA_V12),
Step::Sql(SCHEMA_V13),
];
pub fn migrate(conn: &Connection) -> rusqlite::Result<()> {
conn.execute_batch("PRAGMA foreign_keys = ON;")?;
let version: i64 = conn.query_row("PRAGMA user_version", [], |r| r.get(0))?;
if version < 1 {
conn.execute_batch(SCHEMA_V1)?;
conn.execute_batch("PRAGMA user_version = 1;")?;
for (to, step) in (1..).zip(STEPS) {
if version >= to {
continue;
}
if version < 2 {
conn.execute_batch(SCHEMA_V2)?;
conn.execute_batch("PRAGMA user_version = 2;")?;
match step {
Step::Sql(sql) => conn.execute_batch(sql)?,
Step::Code(apply) => apply(conn)?,
}
if version < 3 {
conn.execute_batch(SCHEMA_V3)?;
conn.execute_batch("PRAGMA user_version = 3;")?;
}
if version < 4 {
conn.execute_batch(SCHEMA_V4)?;
conn.execute_batch("PRAGMA user_version = 4;")?;
}
if version < 5 {
conn.execute_batch(SCHEMA_V5)?;
conn.execute_batch("PRAGMA user_version = 5;")?;
}
if version < 6 {
conn.execute_batch(SCHEMA_V6)?;
conn.execute_batch("PRAGMA user_version = 6;")?;
}
if version < 7 {
conn.execute_batch(SCHEMA_V7)?;
conn.execute_batch("PRAGMA user_version = 7;")?;
}
if version < 8 {
migrate_v8(conn)?;
conn.execute_batch("PRAGMA user_version = 8;")?;
}
if version < 9 {
conn.execute_batch(SCHEMA_V9)?;
conn.execute_batch("PRAGMA user_version = 9;")?;
}
if version < 10 {
conn.execute_batch(SCHEMA_V10)?;
conn.execute_batch("PRAGMA user_version = 10;")?;
}
if version < 11 {
conn.execute_batch(SCHEMA_V11)?;
conn.execute_batch("PRAGMA user_version = 11;")?;
}
if version < 12 {
conn.execute_batch(SCHEMA_V12)?;
conn.execute_batch("PRAGMA user_version = 12;")?;
}
if version < 13 {
conn.execute_batch(SCHEMA_V13)?;
conn.execute_batch("PRAGMA user_version = 13;")?;
conn.execute_batch(&format!("PRAGMA user_version = {to};"))?;
}
Ok(())
}