pdo = new PDO($dsn, DB_USER, DB_PASS, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_PERSISTENT => false ]); logMessage('INFO', 'Database', 'Connection established successfully'); } catch (PDOException $e) { logMessage('CRITICAL', 'Database', 'Connection failed: ' . $e->getMessage()); // Fallback: create SQLite database for emergency $this->createEmergencyDatabase(); throw new Exception('Database connection failed. Emergency mode activated.'); } } /** * Get singleton instance */ public static function getInstance() { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; } /** * Execute query with parameters */ public function query($sql, $params = []) { $this->queryCount++; $this->lastQuery = ['sql' => $sql, 'params' => $params]; try { $stmt = $this->pdo->prepare($sql); $stmt->execute($params); // Log slow queries $start = microtime(true); $stmt->execute($params); $duration = (microtime(true) - $start) * 1000; if ($duration > 1000) { // > 1 second logMessage('WARNING', 'Database', 'Slow query detected', [ 'duration' => round($duration, 2) . 'ms', 'sql' => $sql, 'params' => $params ]); } return $stmt; } catch (PDOException $e) { logMessage('ERROR', 'Database', 'Query failed: ' . $e->getMessage(), [ 'sql' => $sql, 'params' => $params ]); throw $e; } } /** * Insert data into table */ public function insert($table, $data) { $columns = implode(', ', array_keys($data)); $placeholders = ':' . implode(', :', array_keys($data)); $sql = "INSERT INTO $table ($columns) VALUES ($placeholders) RETURNING id"; $stmt = $this->query($sql, $data); $result = $stmt->fetch(); return $result['id'] ?? null; } /** * Update data in table */ public function update($table, $data, $where, $whereParams = []) { $setParts = []; foreach ($data as $key => $value) { $setParts[] = "$key = :$key"; } $setClause = implode(', ', $setParts); $sql = "UPDATE $table SET $setClause WHERE $where"; $params = array_merge($data, $whereParams); $this->query($sql, $params); return true; } /** * Delete from table */ public function delete($table, $where, $params = []) { $sql = "DELETE FROM $table WHERE $where"; $this->query($sql, $params); return true; } /** * Select with pagination */ public function select($table, $columns = '*', $where = '1=1', $params = [], $orderBy = null, $limit = null, $offset = 0) { $sql = "SELECT $columns FROM $table WHERE $where"; if ($orderBy) { $sql .= " ORDER BY $orderBy"; } if ($limit) { $sql .= " LIMIT $limit OFFSET $offset"; } $stmt = $this->query($sql, $params); return $stmt->fetchAll(); } /** * Get single row */ public function getRow($table, $columns = '*', $where = '1=1', $params = []) { $rows = $this->select($table, $columns, $where, $params, null, 1); return $rows[0] ?? null; } /** * Get count */ public function count($table, $where = '1=1', $params = []) { $sql = "SELECT COUNT(*) as count FROM $table WHERE $where"; $stmt = $this->query($sql, $params); $result = $stmt->fetch(); return (int) ($result['count'] ?? 0); } /** * Begin transaction */ public function beginTransaction() { return $this->pdo->beginTransaction(); } /** * Commit transaction */ public function commit() { return $this->pdo->commit(); } /** * Rollback transaction */ public function rollback() { return $this->pdo->rollBack(); } /** * Get last inserted ID */ public function lastInsertId() { return $this->pdo->lastInsertId(); } /** * Get query count */ public function getQueryCount() { return $this->queryCount; } /** * Get last query */ public function getLastQuery() { return $this->lastQuery; } /** * Check if table exists */ public function tableExists($tableName) { try { $sql = "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = :table)"; $stmt = $this->query($sql, ['table' => $tableName]); $result = $stmt->fetch(); return $result['exists'] === 't'; } catch (Exception $e) { return false; } } /** * Create emergency SQLite database */ private function createEmergencyDatabase() { $sqlitePath = TEMP_DIR . 'weval-mind-emergency.db'; try { $this->pdo = new PDO("sqlite:$sqlitePath"); $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); logMessage('EMERGENCY', 'Database', 'Emergency SQLite database created at: ' . $sqlitePath); } catch (PDOException $e) { logMessage('CRITICAL', 'Database', 'Emergency database creation failed: ' . $e->getMessage()); } } /** * Health check */ public function healthCheck() { try { $stmt = $this->query("SELECT 1 as health_check"); $result = $stmt->fetch(); return [ 'status' => 'healthy', 'query_count' => $this->queryCount, 'last_query' => $this->lastQuery['sql'] ?? null ]; } catch (Exception $e) { return [ 'status' => 'unhealthy', 'error' => $e->getMessage(), 'emergency_mode' => true ]; } } } // Helper function to get database instance function getDB() { return DatabaseConnection::getInstance(); } // Test connection on include try { $db = getDB(); logMessage('INFO', 'Database', 'Database module loaded successfully'); } catch (Exception $e) { logMessage('ERROR', 'Database', 'Database module failed to load: ' . $e->getMessage()); } ?>