voyager 3: release_texts, the searchable strings of a release (migration 6200)
Test and deploy / test (push) Failing after 52s
Test and deploy / edge (push) Successful in 1m52s
Test and deploy / deploy (push) Skipped

One table and one trigram index for every string search matches against:
the release name (kind 1, stored once more) and what anyone learns later
(the prober's file names inside an archive, NFO titles, par2 set names,
media titles), appended by insert, never an update of the releases row.
Kinds and the per-kind cap in lib/release/text_kind.ts (textsToStore).
The judge's dirty mark follows an insert or delete. Migration 6000 loses
its two trigram indexes on releases.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Daan MeijerandClaude Fable 5.1 committed 2026-10-25 20:33:28 +01:00
1 parent 346493b6c3
commit bc4e17e86f
5 files changed
+161 -13

No files matched your search

@@ -0,0 +1,35 @@
import { BaseSchema } from '@adonisjs/lucid/schema'
/**
* release_texts (REBUILD.md, "Voyager 3 … Schema"): every string search matches against, one table, one trigram
* index. The release name goes in (kind 1) with whatever anyone learns later: the prober's file names inside an
* archive, NFO titles, par2 set names, media titles (lib/release/text_kind.ts). Appending is an insert, never an
* update of the wide releases row; a repeat insert is a no-op by the primary key; the judge's dirty mark follows
* (judge_dirty_by_release_id, migration 4900), so a rule can react to a name arriving later. On the NVMe: search
* reads it. releases keeps name and inner_name for display, without trigram indexes (migration 6000).
*/
export default class extends BaseSchema {
async up() {
this.schema.raw(`
CREATE TABLE release_texts (
release_id bigint NOT NULL,
-- lib/release/text_kind.ts: 1 name, 2 file, 3 nfo, 4 par2, 5 media.
kind smallint NOT NULL,
text varchar(255) NOT NULL,
PRIMARY KEY (release_id, kind, text)
)`)
this.schema.raw(
`CREATE INDEX release_texts_trgm ON release_texts USING gin (text gin_trgm_ops) WITH (fastupdate = on, gin_pending_list_limit = 65536)`
)
this.schema.raw(
`CREATE TRIGGER judge_dirty_insert AFTER INSERT ON release_texts REFERENCING NEW TABLE AS new_rows FOR EACH STATEMENT EXECUTE FUNCTION judge_dirty_by_release_id()`
)
this.schema.raw(
`CREATE TRIGGER judge_dirty_delete AFTER DELETE ON release_texts REFERENCING OLD TABLE AS old_rows FOR EACH STATEMENT EXECUTE FUNCTION judge_dirty_by_release_id()`
)
}
async down() {
this.schema.raw(`DROP TABLE IF EXISTS release_texts`)
}
}