Skip to content

fix(store): back up sqlite stores only before a pending migration - #33

Merged
jadb merged 1 commit into
mainfrom
fix/backup-before-migrate
Oct 1, 2026
Merged

jadb merged 1 commit into
mainfrom
fix/backup-before-migrate

Conversation

@jadb

@jadb jadb commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

foo backs up its SQLite stores only when a migration is pending, and keeps the newest 5 backups.

Bug

schema.go and embed.go called sqlstore.BackupBeforeMigrate on every store open, so every schema list / embed search added a .dbs/*.bak file. kit's BackupBeforeMigrate is a plain copy by design (deciding whether to back up is the caller's job), and foo's stores recorded no schema revision to decide with. No kit change needed.

Fix

  • internal/schema and internal/embed stores get SchemaVersion = 1; migrate() runs setup in a transaction and stamps PRAGMA user_version (only raises it, so a file from a newer foo keeps its revision).
  • New internal/dbbackup.BeforeMigrate(dbPath, target): reads the stamp read-only and copies (via kit's BackupBeforeMigrate) only when it's below target; an unreadable file is copied anyway.
  • Retention: newest 5 per store (dbbackup.Keep) in $XDG_STATE_HOME/foo/.dbs/, pruned right after a new backup, ordered by the timestamp in the name; files not named like that store's backups are never touched.
  • Stores from earlier builds (no stamp) get one backup on the first open after upgrading, which also trims old clutter to 5.

Tests

internal/dbbackup (no backup on repeated opens / newer stamp; exactly one on a pending migration; unreadable file; retention with unrelated files kept; timestamp ordering), store version stamp tests, cmd/foo/commands/storeopen_test.go (repeated opens leave 0 backups; an older store gets exactly 1 over 3 opens). Rebased on #32; its dry-run no-write tests pass.

Docs

concepts.md (state table, backup/retention/rollback), config.md (XDG_STATE_HOME), troubleshooting.md (.bak clutter).

Every store open (schema list, embed search, ...) left a new
.dbs/*.bak: openSchemaStore/openEmbedStore called kit
sqlstore.BackupBeforeMigrate unconditionally; that helper is a plain
copy primitive, and the stores recorded no schema revision to gate on.

- schema + embed stores: SchemaVersion stamped into PRAGMA
  user_version inside the migrate tx; raised, never lowered
- internal/dbbackup: BeforeMigrate copies only when recorded revision
  < target (read-only probe); unreadable file -> copy anyway
- retention: newest 5 backups per store, ordered by name timestamp;
  other stores' copies + unrelated files untouched
- stamp-less stores from earlier builds: one copy on first open,
  existing clutter trimmed to 5; later opens copy nothing
- openers: only the backup block changed
- docs: state table + backup/rollback note, XDG_STATE_HOME row,
  troubleshooting row for .bak clutter
@jadb
jadb merged commit b4ea7e5 into main Oct 1, 2026
2 checks passed
@jadb
jadb deleted the fix/backup-before-migrate branch October 1, 2026 16:33
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