Backup, restore and the demo reset each handled the SQLite file
themselves: backup.impl closed and reinitialized the connection, built
MaintenanceRepository with new, and assumed the database was
data/travel.db. That tied the whole chain to one local file and hid two
bugs.
They now go through DATABASE_BACKUP, a port declared in the shared
database kernel (snapshot, verify, keep a copy before a restore, replace).
SqliteDatabaseBackup implements it with what the code did before:
VACUUM INTO for a consistent copy, and a close, copy, sidecar drop,
rename and reopen through DatabaseLifecycle for a restore. BackupService
injects it and hands it to backup.impl. The demo reset and the baseline
save use the same port; the first baseline is saved by DemoResetJob once
the app is up, because the boot-time seed runs before anything can be
injected. Another engine can plug in a logical dump behind the port.
Fixes on the way:
- The backup and the restore ignored TREK_DB_FILE. The backup looked for
data/travel.db and, with the database elsewhere, silently left it out
of the archive; the restore wrote data/travel.db and never replaced
the live database. Both now use DatabaseLifecycle.file, the path the
connection runs on, and the pre-restore copy sits next to it.
- A failed VACUUM INTO fell back to archiving the live WAL-mode file
without a word, the torn copy the snapshot exists to prevent. The
backup now fails: nothing is archived or committed, the existing
backups are untouched, a partial snapshot is removed, and the log says
why. A missing database file and a failed checkpoint are logged too.