Use sqlx built-in migration tracking
Replaces hand-rolled raw_sql migration with sqlx::migrate!() macro.
Migrations are now tracked in _sqlx_migrations and only run once.
Existing databases work because our DDL uses IF NOT EXISTS.
Assisted-by: Claude Opus 4.6 via pi
diff --git a/Cargo.toml b/Cargo.toml
index 61ebb6a..b39bfb0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,7 +15,7 @@ clap = { version = "*", features = ["derive", "env"] }
rand = "*"
serde = { version = "*", features = ["derive"] }
serde_json = "*"
-sqlx = { version = "*", features = ["runtime-tokio", "sqlite"] }
+sqlx = { version = "*", features = ["runtime-tokio", "sqlite", "migrate"] }
thiserror = "*"
tokio = { version = "*", features = ["full"] }
xdg = "*"
diff --git a/src/db.rs b/src/db.rs
index 35d6f6c..5aa5edb 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -20,20 +20,10 @@ pub async fn connect(path: &Path) -> Result<SqlitePool, RangerError> {
.connect_with(options)
.await?;
- migrate(&pool).await?;
+ sqlx::migrate!().run(&pool).await?;
Ok(pool)
}
-async fn migrate(pool: &SqlitePool) -> Result<(), RangerError> {
- sqlx::raw_sql(include_str!("../migrations/001_initial.sql"))
- .execute(pool)
- .await?;
- sqlx::raw_sql(include_str!("../migrations/002_unique_backlog_name.sql"))
- .execute(pool)
- .await?;
- Ok(())
-}
-
#[cfg(test)]
mod tests {
use super::*;
diff --git a/src/error.rs b/src/error.rs
index 899704e..8df5d6f 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -6,6 +6,8 @@ pub enum RangerError {
AmbiguousPrefix(String),
#[error("database error: {0}")]
Db(#[from] sqlx::Error),
+ #[error("migration error: {0}")]
+ Migrate(#[from] sqlx::migrate::MigrateError),
#[error("io error: {0}")]
Io(#[from] std::io::Error),
}