Run schema upgrades in one transaction and roll back stray failures - #196
Conversation
This lands PR #191 on main. That PR was opened against the fix-delete-txn-rollback branch and merged there as 583015d, so when #190 was squash-merged to main its content was left behind on the feature branch. This is a clean cherry-pick of that squash commit. Original description: mport_upgrade_master_schema ignored the return value of every upgrade step, ran them outside any transaction, and bumped user_version even when a step had failed. A registry that hit an error part way through (a lock, a step that no longer applies) was left half upgraded with a version number that did not match its schema, and the failure was reported as success. Run every step and the version bump inside one BEGIN IMMEDIATE transaction, stop at the first failing step, and roll back. Step 12to13 loses its own nested transaction, which would now fail to start inside the outer one. Roll back the remaining transactions that could be left open on error: verify when its COMMIT fails, and merge on any failure inside its per-bundle transaction. Switch the rollbacks in verify and the orphan purge to sqlite3_exec so a failing ROLLBACK cannot overwrite the error being reported. Add a test that fakes a version 11 registry, makes step 12to13 fail, and checks the version and the rows step 11to12 added are both rolled back, then that a retry on the same connection succeeds. (cherry picked from commit 583015d) AI-Assisted-By: Claude Fable 5.1 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VqVYKWFCX58Cb5NiGHHjzo Signed-off-by: Lucas Holt <luke@foolishgames.com>
|
Claude finished @laffer1's task in 1m 55s —— View job Code Review: Run schema upgrades in one transaction and roll back stray failuresTasks
SummaryThis is a clean, well-scoped cherry-pick that does what the PR body claims. I traced every changed function against its callers and the shared error-handling macros (
No correctness, memory-safety, SQL-injection, or error-propagation issues found. The pattern (rollback via raw Not verified in this session: I was unable to execute build/test commands ( |
Reviewer's GuideSchema upgrades now execute all migration steps and the version bump atomically, with fail-fast rollback that preserves the original error; related transaction failure paths were hardened, and a regression test verifies partial-upgrade recovery and retryability. Sequence diagram for atomic schema upgrade and rollbacksequenceDiagram
participant Caller
participant Upgrade as mport_upgrade_master_schema
participant Runner as run_master_schema_upgrades
participant SQLite
Caller->>Upgrade: mport_upgrade_master_schema(db, databaseVersion)
Upgrade->>SQLite: mport_db_do(BEGIN IMMEDIATE TRANSACTION)
Upgrade->>Runner: run_master_schema_upgrades(db, databaseVersion)
Runner->>SQLite: mport_upgrade_master_schema_11to12(db)
Runner->>SQLite: mport_upgrade_master_schema_12to13(db)
alt upgrade step fails
Runner-->>Upgrade: RETURN_CURRENT_ERROR
Upgrade->>SQLite: sqlite3_exec(ROLLBACK)
Upgrade-->>Caller: error, schema and version unchanged
else all steps succeed
Runner-->>Upgrade: MPORT_OK
Upgrade->>SQLite: mport_set_database_version(db)
Upgrade->>SQLite: mport_db_do(COMMIT TRANSACTION)
Upgrade-->>Caller: MPORT_OK
end
Sequence diagram for retrying a failed schema upgradesequenceDiagram
participant Test
participant Upgrade as mport_upgrade_master_schema
participant SQLite
Test->>Upgrade: upgrade version 11 connection
Upgrade->>SQLite: BEGIN IMMEDIATE TRANSACTION
Upgrade->>SQLite: mport_upgrade_master_schema_11to12(db)
Upgrade->>SQLite: mport_upgrade_master_schema_12to13(db)
SQLite-->>Upgrade: failure
Upgrade->>SQLite: sqlite3_exec(ROLLBACK)
Upgrade-->>Test: error
Test->>SQLite: verify version and rows restored
Test->>Upgrade: retry on same connection
Upgrade->>SQLite: BEGIN IMMEDIATE TRANSACTION
Upgrade->>SQLite: run remaining upgrade steps
Upgrade->>SQLite: mport_set_database_version(db)
Upgrade->>SQLite: COMMIT TRANSACTION
Upgrade-->>Test: MPORT_OK
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Lands #191 on main.
Why this PR exists
#191 was opened with
fix-delete-txn-rollbackas its base branch rather thanmain. GitHub merged it into that branch as 583015d and marked it merged. When #190 was then squash-merged into main, only #190's own commit was carried over, so #191's changes never reached main. Main'smport_upgrade_master_schemastill runs upgrade steps with no error checking and no rollback.This is a clean cherry-pick of 583015d onto current main, with no conflicts and no other changes.
What #191 does
mport_upgrade_master_schemaruns every step and theuser_versionbump inside oneBEGIN IMMEDIATEtransaction, stops at the first failing step, and rolls back. Step 12to13 drops its own nested transaction.verifyrolls back when itsCOMMITfails;mergerolls back on any failure inside its per-bundle transaction.verifyand the orphan purge go throughsqlite3_execso a failingROLLBACKcannot overwrite the error being reported.Verification on this branch
-Werror.kyua test: 92/92 passed, including the new upgrade rollback test.Once this merges,
fix-delete-txn-rollbackcan be deleted.🤖 Generated with Claude Code
https://claude.ai/code/session_01VqVYKWFCX58Cb5NiGHHjzo
Summary by Sourcery
Make schema upgrades and related database operations roll back cleanly on failure.
Bug Fixes:
Enhancements:
Tests: