Files
music-agregator/db/schema.sql
T
2026-07-25 12:07:27 +02:00

85 lines
3.6 KiB
SQL

-- Cached parsed-torrent metadata. Mirrors the Rust `ParsedTorrent` struct
-- field-for-field. A UUID `id` is the PK so rows can be inserted during the
-- fast path (title-only, no info_hash yet) and updated when the background
-- resolver finishes.
--
-- A row exists in one of three states:
-- 'partial' - title-derived fields only, awaiting background resolution
-- 'resolving'- a background resolver task is currently fetching torrent bytes
-- 'resolved' - full torrent-derived data filled in
CREATE TABLE parsed_torrents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
info_hash TEXT NOT NULL DEFAULT '',
raw_title TEXT NOT NULL DEFAULT '',
artist TEXT NOT NULL DEFAULT '',
album TEXT NOT NULL DEFAULT '',
year INTEGER NOT NULL DEFAULT 0,
release_type TEXT NOT NULL DEFAULT 'unknown',
genres JSONB NOT NULL DEFAULT '[]'::jsonb,
label TEXT NOT NULL DEFAULT '',
source TEXT NOT NULL DEFAULT 'unknown',
rip_type TEXT NOT NULL DEFAULT '',
format TEXT NOT NULL DEFAULT 'unknown',
bitrate TEXT NOT NULL DEFAULT '',
bit_depth INTEGER NOT NULL DEFAULT 0,
sample_rate INTEGER NOT NULL DEFAULT 0,
track_names JSONB NOT NULL DEFAULT '[]'::jsonb,
track_count INTEGER NOT NULL DEFAULT 0,
release_count INTEGER NOT NULL DEFAULT 0,
audio_file_count INTEGER NOT NULL DEFAULT 0,
total_audio_size BIGINT NOT NULL DEFAULT 0,
has_cover_art BOOLEAN NOT NULL DEFAULT false,
has_cue_sheet BOOLEAN NOT NULL DEFAULT false,
has_rip_log BOOLEAN NOT NULL DEFAULT false,
parsed_successfully BOOLEAN NOT NULL DEFAULT false,
parse_errors JSONB NOT NULL DEFAULT '[]'::jsonb,
-- cache-control columns (not part of ParsedTorrent)
state TEXT NOT NULL DEFAULT 'partial',
indexer TEXT NOT NULL DEFAULT '',
magnet TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- enum-backed fields (release_type, source, format) are stored as their
-- `as_str()` repr in plain TEXT rather than native ENUMs, so adding a variant
-- to the Rust enum needs no migration.
-- lets the background resolver find rows still awaiting torrent resolution
CREATE INDEX parsed_torrents_state_idx
ON parsed_torrents (state)
WHERE state IN ('partial', 'resolving');
-- dedup resolved torrents by info_hash (only meaningful once non-empty)
CREATE UNIQUE INDEX parsed_torrents_info_hash_uidx
ON parsed_torrents (info_hash)
WHERE info_hash != '';
-- Albums that music-agregator has pointed tora at. One row per
-- (album_id, quality) pair: a re-monitor of the same album at the same
-- quality is rejected by the UNIQUE constraint until the previous row is
-- removed. The `torrent_id` column links back to tora's torrent; it's what
-- the startup notification subscriber uses to look up which album a
-- STATE_CHANGED -> FINISHED event belongs to.
CREATE TABLE monitored_albums (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
album_id TEXT NOT NULL,
torrent_id UUID NOT NULL,
quality TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
completed_at TIMESTAMPTZ,
UNIQUE (album_id, quality)
);
CREATE UNIQUE INDEX monitored_albums_torrent_id_uidx
ON monitored_albums (torrent_id);