fix(sqlite) Migrate revert with no-transaction (#4024)

* Fix migration reverts for no-TX SQLite

* Add regression test

---------

Co-authored-by: Markus Gasser <markus.gasser@frauscher.com>
This commit is contained in:
Dosenpfand 2025-09-15 02:43:39 +02:00 committed by GitHub
parent 81526898d4
commit c52e129e83
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 30 additions and 1 deletions

View File

@ -207,7 +207,7 @@ CREATE TABLE IF NOT EXISTS {table_name} (
let start = Instant::now();
if migration.no_tx {
execute_migration(self, table_name, migration).await?;
revert_migration(self, table_name, migration).await?;
} else {
// Use a single transaction for the actual migration script and the essential bookkeeping so we never
// execute migrations twice. See https://github.com/launchbadge/sqlx/issues/1966.

View File

@ -77,6 +77,29 @@ async fn no_tx(mut conn: PoolConnection<Sqlite>) -> anyhow::Result<()> {
Ok(())
}
#[sqlx::test(migrations = false)]
async fn no_tx_reversible(mut conn: PoolConnection<Sqlite>) -> anyhow::Result<()> {
clean_up(&mut conn).await?;
let migrator = Migrator::new(Path::new("tests/sqlite/migrations_no_tx_reversible")).await?;
// run migration
migrator.run(&mut conn).await?;
// check outcome
let res: String = conn.fetch_one("PRAGMA JOURNAL_MODE").await?.get(0);
assert_eq!(res, "wal".to_string());
// roll back
migrator.undo(&mut conn, -1).await?;
// check outcome
let res: String = conn.fetch_one("PRAGMA JOURNAL_MODE").await?.get(0);
assert_eq!(res, "delete".to_string());
Ok(())
}
/// Ensure that we have a clean initial state.
async fn clean_up(conn: &mut SqliteConnection) -> anyhow::Result<()> {
conn.execute("DROP TABLE migrations_simple_test").await.ok();

View File

@ -0,0 +1,3 @@
-- no-transaction
PRAGMA JOURNAL_MODE = DELETE;

View File

@ -0,0 +1,3 @@
-- no-transaction
PRAGMA JOURNAL_MODE = WAL;