101 lines
3.1 KiB
TypeScript
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;
|
|
`)
|
|
}
|
|
}
|