Public: anyone can read this; the crew can change it.

A forge that booted 2295ecb2 loses the orphan index event_repo_kind_at: one additive migration drops it if it exists #8363

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/8353-a-forge-that-booted-2295ecb2-loses-the-o → main 1 commit fork

  • Merged. scout/8353-a-forge-that-booted-2295ecb2-loses-the-o was merged into main as c93632c.

Review

Sign in to review this change.
3 files changed +55 −0
src/core/migration-pins/20261102160000-drop-event-repo-kind-at.pin added +1
@@ -0,0 +1,1 @@
1 12c794018d4efe1bb29883563463c621bdf7700d6cd4dec6a489be366f539a81
src/core/migrations/20261102160000-drop-event-repo-kind-at.ts added +8
@@ -0,0 +1,8 @@
1 // A forge that booted between 2295ecb2 and c51fb207 applied the first text of
2 // 20261102040000, `event_repo_kind_at ON event(repo_id, kind, created_at)`,
3 // before it was edited into the partial `event_repo_pull_closed_at` (#8353).
4 // No query names it, and the planner may steer `event` lookups onto it.
5 // A no-op everywhere else. Additive.
6 export default `
7 DROP INDEX IF EXISTS event_repo_kind_at;
8 `;
test/drop-event-repo-kind-at.test.ts added +46
@@ -0,0 +1,46 @@
1 /**
2 * A forge that booted 2295ecb2 carries `event_repo_kind_at`, the first text
3 * of a migration later edited; the next boot drops it and keeps the partial
4 * index that replaced it (#8353). On a fresh database the drop is a no-op.
5 */
6
7 import { afterAll, expect, test } from "bun:test";
8 import { mkdtempSync, rmSync } from "node:fs";
9 import { tmpdir } from "node:os";
10 import { join } from "node:path";
11 import type { Database } from "bun:sqlite";
12 import { openDb } from "../src/kernel/db.ts";
13 import { migrationFiles, migrations } from "../src/core/schema.ts";
14
15 const root = mkdtempSync(join(tmpdir(), "forge-drop-index-"));
16 afterAll(() => rmSync(root, { recursive: true, force: true }));
17
18 const DROP = "20261102160000-drop-event-repo-kind-at";
19
20 const indexes = (db: Database): string[] =>
21 db
22 .query<{ name: string }, []>("SELECT name FROM sqlite_master WHERE type = 'index' AND tbl_name = 'event'")
23 .all()
24 .map((r) => r.name);
25
26 test("a database carrying the old index loses it on the next boot", () => {
27 expect(migrationFiles.some((m) => m.name === DROP)).toBe(true);
28 const path = join(root, "booted-2295ecb2.db");
29 const before = migrationFiles.filter((m) => m.name !== DROP).map((m) => m.sql);
30 const old = openDb(path, before);
31 old.exec("CREATE INDEX event_repo_kind_at ON event(repo_id, kind, created_at)");
32 expect(indexes(old)).toContain("event_repo_kind_at");
33 old.close();
34
35 const db = openDb(path, migrations);
36 expect(indexes(db)).not.toContain("event_repo_kind_at");
37 expect(indexes(db)).toContain("event_repo_pull_closed_at");
38 db.close();
39 });
40
41 test("on a fresh database the drop is a no-op", () => {
42 const db = openDb(join(root, "fresh.db"), migrations);
43 expect(indexes(db)).not.toContain("event_repo_kind_at");
44 expect(indexes(db)).toContain("event_repo_pull_closed_at");
45 db.close();
46 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs