Skip to content

Phase 0D: Schema-versioned migrations with PRAGMA user_version, backup, integrity check - #17

Merged
hardcoreerik merged 2 commits into
mainfrom
feat/schema-versioned-migrations
Aug 6, 2026
Merged

Phase 0D: Schema-versioned migrations with PRAGMA user_version, backup, integrity check#17
hardcoreerik merged 2 commits into
mainfrom
feat/schema-versioned-migrations

Conversation

@hardcoreerik

Copy link
Copy Markdown
Owner

Summary

  • Replaces ad-hoc _migrate() with a sequential _MIGRATIONS list of (version, fn) pairs — new migrations append without renumbering existing entries
  • apply_schema() now reads PRAGMA user_version, runs only migrations with version > current, and stamps the new version inside the same transaction as each migration's ALTER TABLEs
  • Pre-migration WAL checkpoint + shutil.copy2 backup to backups/ subfolder before touching any existing database; no backup for brand-new or in-memory connections
  • PRAGMA integrity_check runs after all migrations succeed; failure raises MigrationError
  • MigrationError(RuntimeError) raised (not swallowed) on any migration or integrity failure — message always includes what failed and where the backup is
  • apply_schema() accepts optional db_path for backup; both MonitorStore call sites updated to pass self._path

Test plan

  • test_migrates_v0_schema_and_preserves_existing_rows — full v0→current migration, all columns present, pre-existing rows intact
  • test_migrates_v1_schema_adding_only_node_columns — skips already-applied v1 message migration, applies only v2 node columns
  • test_creates_pre_migration_backup_for_existing_database — backup file appears under backups/ with correct stem pattern
  • test_idempotent_reapply_is_a_no_op — second apply_schema() on already-current DB produces no additional backup
  • test_fresh_database_reaches_current_version_without_a_backup — new DB stamped at CURRENT_SCHEMA_VERSION, no backups/ directory created
  • test_db_path_is_optional — in-memory connection with no db_path does not raise
  • test_migration_error_does_not_lose_existing_data — simulated migration failure leaves user_version=0 and pre-existing row untouched
  • test_integrity_check_failure_raises_clear_error — fake PRAGMA integrity_check returning non-"ok" raises MigrationError

Full suite: 369 passed, ruff clean, mypy clean.

🤖 Generated with Claude Code

…on backup, integrity check

Replaces the ad-hoc _migrate() function with a sequential _MIGRATIONS list
of (version, fn) pairs. apply_schema() now tracks database schema version
via PRAGMA user_version, runs only pending migrations, takes a WAL-checkpointed
file backup before any migration touches an existing database, and verifies
integrity after all migrations succeed. New MigrationError is raised (not
silently swallowed) on any failure.

Each migration runs in its own `with conn:` transaction with the version stamp
inside the same transaction, so a failure never leaves user_version pointing
past a migration that did not apply. Brand-new databases skip migrations
entirely and are stamped at CURRENT_SCHEMA_VERSION on creation; no backup
is taken (nothing to protect). apply_schema() now accepts an optional db_path
so callers with a real file can enable backup; in-memory connections pass None.

8 new tests cover: v0→current migration with row preservation; v1→current
(skipping v1 migration already applied); backup creation; idempotent re-apply;
fresh DB reaches current version without backup; in-memory DB without db_path;
migration failure leaves DB unchanged; post-migration integrity-check failure.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@hardcoreerik, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 9 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 84d67a6d-7175-41c0-b099-cb4b56c50115

📥 Commits

Reviewing files that changed from the base of the PR and between 3e847ff and 4986fcb.

📒 Files selected for processing (3)
  • src/meshchat/database/schema.py
  • src/meshchat/services/monitor_store.py
  • tests/test_schema_migrations.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hardcoreerik
hardcoreerik merged commit 2f65d9e into main Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant