Files
radio-explorer/server/db/index.js
Marco Mooren e0a60f7b64 Add player functionality with HLS support and API integration
- Implemented a new Player class in player.js to handle audio playback, including HLS support using hls.js.
- Created a shared API module in api.js for making HTTP requests with proper error handling.
- Added DOM utility functions in dom.js for creating and clearing elements.
- Introduced WebSocket connection handling in ws.js for real-time updates.
- Developed a comprehensive CSS stylesheet for styling the application, including a high-contrast theme.
2026-05-10 14:43:00 +02:00

60 lines
2.2 KiB
JavaScript

import Database from 'better-sqlite3';
import { readFileSync, mkdirSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { randomUUID } from 'node:crypto';
const __dirname = dirname(fileURLToPath(import.meta.url));
let db;
export function initDb(dbPath) {
const abs = resolve(dbPath);
mkdirSync(dirname(abs), { recursive: true });
db = new Database(abs);
db.pragma('journal_mode = WAL');
db.pragma('foreign_keys = ON');
const schema = readFileSync(resolve(__dirname, 'schema.sql'), 'utf8');
db.exec(schema);
runMigrations(db);
return db;
}
export function getDb() {
if (!db) throw new Error('DB not initialized');
return db;
}
// Idempotent migrations for upgrading older DBs that pre-date a column.
function runMigrations(db) {
const stationCols = new Set(db.prepare("PRAGMA table_info(stations)").all().map((c) => c.name));
if (!stationCols.has('uuid')) {
db.exec('ALTER TABLE stations ADD COLUMN uuid TEXT');
}
if (!stationCols.has('category')) {
db.exec('ALTER TABLE stations ADD COLUMN category TEXT');
}
const streamCols = new Set(db.prepare("PRAGMA table_info(streams)").all().map((c) => c.name));
if (!streamCols.has('uuid')) {
db.exec('ALTER TABLE streams ADD COLUMN uuid TEXT');
}
// Backfill UUIDs. For RB stations, prefer the existing source_ref so the
// public UUID matches the upstream Radio-Browser stationuuid.
const setStationUuid = db.prepare('UPDATE stations SET uuid = ? WHERE id = ?');
for (const row of db.prepare("SELECT id, source, source_ref FROM stations WHERE uuid IS NULL OR uuid = ''").all()) {
const u = (row.source === 'radiobrowser' && row.source_ref) ? row.source_ref : randomUUID();
setStationUuid.run(u, row.id);
}
const setStreamUuid = db.prepare('UPDATE streams SET uuid = ? WHERE id = ?');
for (const row of db.prepare("SELECT id FROM streams WHERE uuid IS NULL OR uuid = ''").all()) {
setStreamUuid.run(randomUUID(), row.id);
}
db.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_stations_uuid ON stations(uuid)');
db.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_streams_uuid ON streams(uuid)');
db.exec('CREATE INDEX IF NOT EXISTS idx_stations_category ON stations(category)');
}