This repository has been archived on 2026-06-15. You can view files and clone it, but cannot push or open issues or pull requests.
Files
MediaLore/src/lib/db.ts
2026-04-05 18:15:08 -04:00

101 lines
3.1 KiB
TypeScript

import path from 'path'
import fs from 'fs'
import Database from 'better-sqlite3'
const CONFIG_PATH = process.env.CONFIG_PATH ?? process.cwd()
const DB_PATH = path.resolve(CONFIG_PATH, 'medialore.db')
let _db: Database.Database | null = null
export function getDb(): Database.Database {
if (_db) return _db
_db = new Database(DB_PATH)
_db.pragma('journal_mode = WAL')
_db.pragma('foreign_keys = ON')
initDb(_db)
return _db
}
function initDb(db: Database.Database): void {
db.exec(`
CREATE TABLE IF NOT EXISTS tag_categories (
id TEXT PRIMARY KEY,
name TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS tags (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
category_id TEXT NOT NULL REFERENCES tag_categories(id) ON DELETE CASCADE
);
CREATE UNIQUE INDEX IF NOT EXISTS tags_name_category ON tags(name, category_id);
CREATE TABLE IF NOT EXISTS media_tags (
media_key TEXT NOT NULL,
tag_id TEXT NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
PRIMARY KEY (media_key, tag_id)
);
CREATE TABLE IF NOT EXISTS libraries (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
path TEXT NOT NULL,
type TEXT NOT NULL CHECK(type IN ('games', 'mixed', 'movies', 'tv')),
cover_ext TEXT NULL
);
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
username TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
role TEXT NOT NULL CHECK(role IN ('admin', 'user')),
created_at INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS library_permissions (
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
library_id TEXT NOT NULL REFERENCES libraries(id) ON DELETE CASCADE,
PRIMARY KEY (user_id, library_id)
);
CREATE TABLE IF NOT EXISTS user_settings (
user_id TEXT PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
mixed_autoplay INTEGER NOT NULL DEFAULT 1,
mixed_loop INTEGER NOT NULL DEFAULT 1,
mixed_muted INTEGER NOT NULL DEFAULT 1,
movies_autoplay INTEGER NOT NULL DEFAULT 1,
movies_loop INTEGER NOT NULL DEFAULT 0,
movies_muted INTEGER NOT NULL DEFAULT 0,
tv_autoplay INTEGER NOT NULL DEFAULT 1,
tv_loop INTEGER NOT NULL DEFAULT 0,
tv_muted INTEGER NOT NULL DEFAULT 0
);
`)
migrateLibrariesType(db)
}
function migrateLibrariesType(db: Database.Database): void {
const row = db
.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='libraries'")
.get() as { sql: string } | undefined
if (row && !row.sql.includes("'movies'")) {
db.exec(`
BEGIN TRANSACTION;
CREATE TABLE libraries_new (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
path TEXT NOT NULL,
type TEXT NOT NULL CHECK(type IN ('games', 'mixed', 'movies', 'tv')),
cover_ext TEXT NULL
);
INSERT INTO libraries_new SELECT * FROM libraries;
DROP TABLE libraries;
ALTER TABLE libraries_new RENAME TO libraries;
COMMIT;
`)
}
}