store.ts

2.4 KB · raw

1import type { Database } from "bun:sqlite";23/** A repo row as the console edits it (§24): every repo the sync found, public or not. */4export type AdminRepo = {5	name: string;6	public: number;7	category: string;8	homepage: string;9	/** Shown languages, joined by ", "; '' shows the detected one. */10	languages: string;11	issues_paused: number;12	/** Hidden paths, one per line; '' hides nothing. */13	hidden_paths: string;14	last_sync_at: number | null;15	last_sync_error: string | null;16};1718export type RepoEdit = Omit<AdminRepo, "name" | "last_sync_at" | "last_sync_error">;1920export function allRepos(db: Database): AdminRepo[] {21	return db.query<AdminRepo, []>("SELECT * FROM repos ORDER BY name").all();22}2324export function findRepo(db: Database, name: string): AdminRepo | null {25	return db.query<AdminRepo, [string]>("SELECT * FROM repos WHERE name = ?").get(name);26}2728export function updateRepo(db: Database, name: string, edit: RepoEdit): void {29	db.query(30		`UPDATE repos SET public = ?, category = ?, homepage = ?, languages = ?, issues_paused = ?,31		hidden_paths = ?32		WHERE name = ?`,33	).run(34		edit.public,35		edit.category,36		edit.homepage,37		edit.languages,38		edit.issues_paused,39		edit.hidden_paths,40		name,41	);42}4344// Every kepr.db table that names a repo, and its column.45const REPO_COLUMNS = [46	["repos", "name"],47	["repo_text", "repo"],48	["release_settings", "repo"],49	["downloads", "repo"],50	["download_days", "repo"],51	["installs", "repo"],52	["issues", "repo"],53	["blocked_reporters", "repo"],54] as const;5556/** Moves a renamed repo's settings, texts, issues and counts to its new name, and records it. */57export function moveRepoRows(db: Database, from: string, to: string): void {58	db.transaction(() => {59		for (const [table, column] of REPO_COLUMNS) {60			db.query(`UPDATE ${table} SET ${column} = ? WHERE ${column} = ?`).run(to, from);61		}62		db.query("DELETE FROM renamed WHERE old = ?").run(to);63		db.query("INSERT OR REPLACE INTO renamed (old, new) VALUES (?, ?)").run(from, to);64	})();65}6667/** Writes site settings in one transaction; an empty value removes the key, so defaults apply. */68export function saveSettings(db: Database, values: Record<string, string>): void {69	db.transaction(() => {70		for (const [key, value] of Object.entries(values)) {71			if (value === "") db.query("DELETE FROM settings WHERE key = ?").run(key);72			else db.query("INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)").run(key, value);73		}74	})();75}