Files
kindexr/internal/db/migrations/001_initial.sql
T
enki 1b7b70426c feat: Phase 0 bootstrap — kindexr boots, migrates, serves /health
- config: koanf-based loading (defaults → YAML → KINDEXR_ env vars)
- db: embedded SQLite migrations with BEGIN/END-aware statement splitter
- server: chi router, GET /health returns JSON stats
- cmd/kindexr: graceful SIGTERM shutdown
- cmd/kindexr-cli: stub
- deploy: systemd unit, example config, nginx snippet
- all packages covered by race-clean tests
2026-05-16 18:45:15 -07:00

121 lines
3.6 KiB
SQL

CREATE TABLE torrents (
event_id TEXT PRIMARY KEY,
info_hash TEXT NOT NULL,
pubkey TEXT NOT NULL,
created_at INTEGER NOT NULL,
ingested_at INTEGER NOT NULL,
title TEXT NOT NULL,
description TEXT,
size_bytes INTEGER,
category TEXT,
newznab_cat INTEGER,
imdb_id TEXT,
tmdb_id TEXT,
tvdb_id TEXT,
season INTEGER,
episode INTEGER,
quality TEXT,
source TEXT,
raw_event TEXT NOT NULL
);
CREATE UNIQUE INDEX idx_torrents_event_id ON torrents(event_id);
CREATE INDEX idx_torrents_info_hash ON torrents(info_hash);
CREATE INDEX idx_torrents_pubkey ON torrents(pubkey);
CREATE INDEX idx_torrents_imdb ON torrents(imdb_id) WHERE imdb_id IS NOT NULL;
CREATE INDEX idx_torrents_tmdb ON torrents(tmdb_id) WHERE tmdb_id IS NOT NULL;
CREATE INDEX idx_torrents_tvdb ON torrents(tvdb_id) WHERE tvdb_id IS NOT NULL;
CREATE INDEX idx_torrents_created ON torrents(created_at DESC);
CREATE INDEX idx_torrents_cat ON torrents(newznab_cat);
CREATE VIRTUAL TABLE torrents_fts USING fts5(
title, description,
content='torrents',
content_rowid='rowid',
tokenize='unicode61 remove_diacritics 2'
);
CREATE TRIGGER torrents_ai AFTER INSERT ON torrents BEGIN
INSERT INTO torrents_fts(rowid, title, description) VALUES (new.rowid, new.title, new.description);
END;
CREATE TRIGGER torrents_ad AFTER DELETE ON torrents BEGIN
INSERT INTO torrents_fts(torrents_fts, rowid, title, description) VALUES ('delete', old.rowid, old.title, old.description);
END;
CREATE TRIGGER torrents_au AFTER UPDATE ON torrents BEGIN
INSERT INTO torrents_fts(torrents_fts, rowid, title, description) VALUES ('delete', old.rowid, old.title, old.description);
INSERT INTO torrents_fts(rowid, title, description) VALUES (new.rowid, new.title, new.description);
END;
CREATE TABLE files (
event_id TEXT NOT NULL,
idx INTEGER NOT NULL,
path TEXT NOT NULL,
size_bytes INTEGER,
PRIMARY KEY (event_id, idx),
FOREIGN KEY (event_id) REFERENCES torrents(event_id) ON DELETE CASCADE
);
CREATE TABLE trackers (
event_id TEXT NOT NULL,
url TEXT NOT NULL,
PRIMARY KEY (event_id, url),
FOREIGN KEY (event_id) REFERENCES torrents(event_id) ON DELETE CASCADE
);
CREATE TABLE tags (
event_id TEXT NOT NULL,
tag TEXT NOT NULL,
PRIMARY KEY (event_id, tag),
FOREIGN KEY (event_id) REFERENCES torrents(event_id) ON DELETE CASCADE
);
CREATE INDEX idx_tags_tag ON tags(tag);
CREATE TABLE publishers (
pubkey TEXT PRIMARY KEY,
npub TEXT,
name TEXT,
trust REAL DEFAULT 0,
notes TEXT,
blocked INTEGER DEFAULT 0,
torrents_n INTEGER DEFAULT 0,
first_seen INTEGER,
last_seen INTEGER
);
CREATE TABLE relays (
url TEXT PRIMARY KEY,
enabled INTEGER DEFAULT 1,
last_event INTEGER,
last_sync INTEGER,
notes TEXT
);
CREATE TABLE api_keys (
key TEXT PRIMARY KEY,
label TEXT NOT NULL,
created_at INTEGER NOT NULL,
visibility TEXT NOT NULL DEFAULT 'all',
curation_set TEXT,
last_used INTEGER
);
CREATE TABLE health (
info_hash TEXT PRIMARY KEY,
seeders INTEGER,
leechers INTEGER,
checked_at INTEGER NOT NULL
);
CREATE TABLE comments (
event_id TEXT PRIMARY KEY,
torrent_event_id TEXT NOT NULL,
pubkey TEXT NOT NULL,
created_at INTEGER NOT NULL,
content TEXT NOT NULL,
raw_event TEXT NOT NULL,
FOREIGN KEY (torrent_event_id) REFERENCES torrents(event_id) ON DELETE CASCADE
);