db+game: schema_version on saves with ordered idempotent backfill (v2 bodies, v3 crew) — no more DB wipes

This commit is contained in:
2026-09-28 23:25:06 +00:00
parent f5cba45b42
commit c7580d92bd
4 changed files with 139 additions and 14 deletions
+10 -1
View File
@@ -24,7 +24,8 @@ CREATE TABLE IF NOT EXISTS saves (
id INTEGER PRIMARY KEY AUTOINCREMENT,
seed TEXT NOT NULL,
turn INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL
created_at TEXT NOT NULL,
schema_version INTEGER -- which save-schema version this row was backfilled up to (NULL = v1)
);
CREATE TABLE IF NOT EXISTS solar_systems (
@@ -98,6 +99,14 @@ async function open(file: string): Promise<GameDb> {
const raw = bytes ? new SQL.Database(new Uint8Array(bytes)) : new SQL.Database();
raw.exec(DDL); // no-op for tables that already exist in an older file
// Idempotent evolution for files created by older code: CREATE TABLE IF NOT EXISTS above cannot
// add columns, so check and add any that are missing. This is what makes DB wipes unnecessary —
// old saves open fine and get backfilled by ensureSave (see lib/game/save.ts).
const saveCols = raw.exec('PRAGMA table_info(saves)')[0]?.values.map((v) => v[1]) ?? [];
if (!saveCols.includes('schema_version')) {
raw.exec('ALTER TABLE saves ADD COLUMN schema_version INTEGER');
}
const instance: GameDb = { db: drizzle(raw, { schema }), raw, file };
// First run: stamp when this DB was created and land the file on disk so the ./db volume