From bb1e5c6a950444659cafe83cb144450f0874eef3 Mon Sep 17 00:00:00 2001 From: josh Date: Sat, 12 Sep 2026 19:41:13 -0400 Subject: [PATCH] fix config --- src/lib/server/db/index.ts | 48 +++++++++++++++++++++++------------- src/lib/server/db/schema.sql | 7 +++--- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/lib/server/db/index.ts b/src/lib/server/db/index.ts index 6cb691a..6c4b9dc 100644 --- a/src/lib/server/db/index.ts +++ b/src/lib/server/db/index.ts @@ -153,24 +153,38 @@ export function db(): Database.Database { if (_db) return _db; mkdirSync(dirname(resolve(config.dbPath)), { recursive: true }); - _db = new Database(config.dbPath); - _db.pragma('journal_mode = WAL'); - _db.pragma('foreign_keys = ON'); - dropLegacyBetaTables(_db); - _db.exec(schemaSql); - migrateServers(_db); - migrateTable(_db, 'scripts', SCRIPTS_COLUMNS); - migrateTable(_db, 'script_versions', SCRIPT_VERSIONS_COLUMNS); - migrateTable(_db, 'beta_scripts', BETA_SCRIPTS_COLUMNS); - migrateTable(_db, 'deployment_scripts', DEPLOYMENT_SCRIPTS_COLUMNS); - migrateTable(_db, 'deployments', DEPLOYMENTS_COLUMNS); - _db.exec( - `CREATE UNIQUE INDEX IF NOT EXISTS idx_scripts_one_baseline_per_scope - ON scripts(scope_type, scope_value) WHERE kind = 'baseline'` - ); - _db.exec(`CREATE INDEX IF NOT EXISTS idx_scripts_kind ON scripts(kind)`); - backfillMultiScriptJoins(_db); + const handle = new Database(config.dbPath); + // Do all the risky init on a local handle first — only assign the module + // singleton once migrations succeed. A half-migrated handle that's cached + // silently breaks every subsequent query without a chance to retry. + try { + handle.pragma('journal_mode = WAL'); + handle.pragma('foreign_keys = ON'); + dropLegacyBetaTables(handle); + handle.exec(schemaSql); + migrateServers(handle); + // Column additions must run BEFORE any statement that references the + // new columns. schema.sql cannot include those references — see the + // comment there. + migrateTable(handle, 'scripts', SCRIPTS_COLUMNS); + migrateTable(handle, 'script_versions', SCRIPT_VERSIONS_COLUMNS); + migrateTable(handle, 'beta_scripts', BETA_SCRIPTS_COLUMNS); + migrateTable(handle, 'deployment_scripts', DEPLOYMENT_SCRIPTS_COLUMNS); + migrateTable(handle, 'deployments', DEPLOYMENTS_COLUMNS); + // Kind-referencing indexes: safe here because migrateTable above just + // ALTER'd the column into existence if it was missing. + handle.exec( + `CREATE UNIQUE INDEX IF NOT EXISTS idx_scripts_one_baseline_per_scope + ON scripts(scope_type, scope_value) WHERE kind = 'baseline'` + ); + handle.exec(`CREATE INDEX IF NOT EXISTS idx_scripts_kind ON scripts(kind)`); + backfillMultiScriptJoins(handle); + } catch (err) { + handle.close(); + throw err; + } + _db = handle; return _db; } diff --git a/src/lib/server/db/schema.sql b/src/lib/server/db/schema.sql index aef4431..7e92349 100644 --- a/src/lib/server/db/schema.sql +++ b/src/lib/server/db/schema.sql @@ -45,10 +45,9 @@ CREATE TABLE IF NOT EXISTS scripts ( created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')) ); CREATE INDEX IF NOT EXISTS idx_scripts_scope ON scripts(scope_type, scope_value); -CREATE INDEX IF NOT EXISTS idx_scripts_kind ON scripts(kind); --- At most one baseline per (scope_type, scope_value). Partial unique index. -CREATE UNIQUE INDEX IF NOT EXISTS idx_scripts_one_baseline_per_scope - ON scripts(scope_type, scope_value) WHERE kind = 'baseline'; +-- kind-referencing indexes are created in db/index.ts AFTER migrateTable adds +-- the column to legacy DBs. Putting them here would fail with "no such column: +-- kind" on an existing pre-kind DB, breaking boot. CREATE TABLE IF NOT EXISTS script_versions ( id INTEGER PRIMARY KEY AUTOINCREMENT,