UNPKG

discord-media-server

Version:

Self-hosted Discord bot for scanning and serving information on local media files.

133 lines (111 loc) 3.86 kB
// lib/database.js (universal MySQL + SQLite handler) import dotenv from 'dotenv'; dotenv.config(); import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; import { CONFIG_DIR, DATA_DIR } from './setupConfig.js'; let db; let isSQLite = false; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Lazy-loaded config & connection let initialized = false; /** Initializes DB connection based on config.json */ export async function initDatabase() { if (initialized) return; try { const dbType = process.env.DB_TYPE || 'sqlite'; isSQLite = dbType === 'sqlite'; if (isSQLite) { const sqlite3 = (await import('better-sqlite3')).default; const dbFileName = path.basename(process.env.DB_FILE || 'media.sqlite'); const dataDir = DATA_DIR || path.resolve(CONFIG_DIR || __dirname, 'data'); const sqlitePath = path.resolve(dataDir, dbFileName); fs.mkdirSync(path.dirname(sqlitePath), { recursive: true }); db = new sqlite3(sqlitePath); if (!db || typeof db.prepare !== 'function') { throw new Error(`Failed to initialize SQLite DB at: ${sqlitePath}`); } //console.log(`SQLite DB loaded: ${sqlitePath}`); } else { const mysql = await import('mysql2/promise'); db = await mysql.createConnection({ host: process.env.DB_HOST || 'localhost', user: process.env.DB_USER, password: process.env.DB_PASS, database: process.env.DB_NAME }); if (!db || typeof db.prepare !== 'function') { throw new Error('Failed to initialize SQLite database.'); } //console.log(`MySQL DB connected: ${config.dbConfig.database || config.dbName}`); } initialized = true; } catch(err) { console.log(`\ninitDatabase error:\nPlease run setup first.\n\n${err.message}`) } } /** Connects to SQLite for setup validation */ export async function connectSQLite(config) { const sqlite3 = (await import('better-sqlite3')).default; const dbFileName = path.basename(process.env.DB_FILE || 'media.sqlite'); const dataDir = DATA_DIR || path.resolve(CONFIG_DIR || __dirname, 'data'); const dbPath = path.resolve(dataDir, dbFileName); // Ensure the folder exists fs.mkdirSync(path.dirname(dbPath), { recursive: true }); try { const db = new sqlite3(dbPath); db.exec('SELECT 1'); db.close(); console.log(`SQLite database ready at ${dbPath}`); } catch (err) { console.error('SQLite connection failed:', err.message); process.exit(1); } } /** Connects to MySQL for setup validation */ export async function connectMySQL(config) { try { const mysql = await import('mysql2/promise'); const db = await mysql.createConnection({ host: config.host, user: config.user, password: config.password, database: config.database }); await db.query('SELECT 1'); await db.end(); console.log('MySQL connection successful'); } catch (err) { console.error('MySQL connection failed:', err.message); process.exit(1); } } export async function query(sql, params = []) { if (!initialized) await initDatabase(); if (!db) { throw new Error('Database is not initialized.'); } if (isSQLite) { const stmt = db.prepare(sql); if (sql.trim().toLowerCase().startsWith('select')) { return stmt.all(...params); } else { return stmt.run(...params); } } else { const [rows] = await db.execute(sql, params); return rows; } } export async function close() { if (!initialized) return; if (isSQLite) { db.close(); } else { await db.end(); } } export { isSQLite };