discord-media-server
Version:
Self-hosted Discord bot for scanning and serving information on local media files.
151 lines (139 loc) • 5.03 kB
JavaScript
// lib/setupDatabase.js
import fs from 'fs';
import path from 'path';
export async function createTables(config) {
if (config.dbType === 'mysql') {
const mysql = await import('mysql2/promise');
let pool;
try {
pool = mysql.createPool({
host: config.dbConfig.host,
user: config.dbConfig.user,
password: config.dbConfig.password,
waitForConnections: true,
connectionLimit: 5
});
/*
const conn = await mysql.createConnection({
host: config.dbConfig.host,
user: config.dbConfig.user,
password: config.dbConfig.password
});
*/
await pool.query(`CREATE DATABASE IF NOT EXISTS \`${config.dbConfig.database}\``);
await pool.query(`USE \`${config.dbConfig.database}\``);
await pool.query(`
CREATE TABLE IF NOT EXISTS Movie_Info (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
year VARCHAR(10),
filename TEXT NOT NULL,
poster TEXT,
poster_fallback TEXT,
filepath TEXT,
filesize BIGINT,
imdb VARCHAR(20),
format VARCHAR(20),
runtime VARCHAR(50),
rating VARCHAR(10),
overview TEXT,
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(title, year)
)
`);
await pool.query(`CREATE INDEX IF NOT EXISTS idx_title ON Movie_Info(title)`);
await pool.query(`CREATE INDEX IF NOT EXISTS idx_year ON Movie_Info(year)`);
await pool.query(`CREATE INDEX IF NOT EXISTS idx_title_year ON Movie_Info(title, year)`);
await pool.query(`ALTER TABLE Movie_Info ADD FULLTEXT(title, year, overview)`);
// Ensure FULLTEXT index exists
await pool.query(`
CREATE FULLTEXT INDEX IF NOT EXISTS idx_title_year
ON Movie_Info (title, year)
`).catch(err => {
// Some MySQL versions don’t support IF NOT EXISTS with FULLTEXT
if (err.code === 'ER_DUP_KEYNAME') {
console.log("MySQL: FULLTEXT index already exists on Movie_Info");
} else {
throw err;
}
});
//await conn.end();
console.log(`MySQL tables created.`);
} catch (err) {
console.error('MySQL setup failed:', err.message);
throw err;
} finally {
if (pool) await pool.end();
}
} else {
let db;
const dbFile = config.dbConfig.filename;
console.log('Attempting to create DB at:', dbFile);
console.log('Directory exists?', fs.existsSync(path.dirname(dbFile)));
const dir = path.dirname(dbFile);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
try {
console.log("SETUP DB PATH:", path.resolve(dbFile));
//const sqlite3 = (await import('better-sqlite3')).default;
//const sqlite3 = await import('sqlite3');
//const db = new sqlite3(dbFile);
const sqlite3pkg = await import('sqlite3');
const sqlite3 = sqlite3pkg.default.verbose();
const { open } = await import('sqlite');
db = await open({
filename: dbFile,
driver: sqlite3.Database
});
await db.exec(`
CREATE TABLE IF NOT EXISTS Movie_Info (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
year TEXT,
filename TEXT NOT NULL,
poster TEXT,
poster_fallback TEXT,
filepath TEXT,
filesize INTEGER,
imdb TEXT,
format TEXT,
runtime TEXT,
rating TEXT,
overview TEXT,
added_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE(title, year)
)
`);
await db.exec(`
CREATE VIRTUAL TABLE IF NOT EXISTS Movie_Search
USING fts5(title, year, content='Movie_Info', content_rowid='id')
`);
await db.exec(`
CREATE TRIGGER IF NOT EXISTS movie_ai AFTER INSERT ON Movie_Info
BEGIN
INSERT INTO Movie_Search(rowid, title, year) VALUES (new.id, new.title, new.year);
END;
`);
await db.exec(`
CREATE TRIGGER IF NOT EXISTS movie_ad AFTER DELETE ON Movie_Info
BEGIN
INSERT INTO Movie_Search(Movie_Search, rowid, title, year) VALUES('delete', old.id, old.title, old.year);
END;
`);
await db.exec(`
CREATE TRIGGER IF NOT EXISTS movie_au AFTER UPDATE ON Movie_Info
BEGIN
INSERT INTO Movie_Search(Movie_Search, rowid, title, year) VALUES('delete', old.id, old.title, old.year);
INSERT INTO Movie_Search(rowid, title, year) VALUES (new.id, new.title, new.year);
END;
`);
console.log(`SQLite tables created.`);
} catch (err) {
console.error("SQLite Database setup failed:", err);
throw err;
} finally {
if (db) await db.close();
}
}
}