PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_TIMEOUT => 5 ]); // Enable WAL mode for concurrency and performance $pdo->exec('PRAGMA journal_mode = WAL;'); $pdo->exec('PRAGMA foreign_keys = ON;'); // Initialize tables if needed init_db_schema($pdo); return $pdo; } function init_db_schema(PDO $pdo): void { $pdo->exec(" CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL, role TEXT NOT NULL DEFAULT 'admin', created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS announcements ( id INTEGER PRIMARY KEY AUTOINCREMENT, is_active INTEGER NOT NULL DEFAULT 1, type TEXT NOT NULL DEFAULT 'holiday', headline TEXT NOT NULL, message TEXT NOT NULL, start_date TEXT NULL, end_date TEXT NULL, show_banner INTEGER NOT NULL DEFAULT 1, show_in_hours INTEGER NOT NULL DEFAULT 1, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS menu_categories ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, description TEXT NULL, sort_order INTEGER NOT NULL DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS menu_items ( id INTEGER PRIMARY KEY AUTOINCREMENT, category_id INTEGER NOT NULL REFERENCES menu_categories(id) ON DELETE CASCADE, name TEXT NOT NULL, description TEXT NULL, price TEXT NOT NULL, badge TEXT NULL, is_available INTEGER NOT NULL DEFAULT 1, sort_order INTEGER NOT NULL DEFAULT 0, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); "); // Seed default admin user if table is empty (username: admin / password: password) $stmt = $pdo->query("SELECT COUNT(*) as count FROM users"); $userCount = $stmt->fetchColumn(); if ($userCount == 0) { $defaultPassHash = password_hash('password', PASSWORD_DEFAULT); $insert = $pdo->prepare("INSERT INTO users (username, password_hash, role) VALUES (?, ?, 'admin')"); $insert->execute(['admin', $defaultPassHash]); } }