getConnection(); // Determine query type $query_type = self::getQueryType($sql_query); // Execute the query $query = $database->prepare($sql_query); $query->execute(); $execution_time = number_format((microtime(true) - $start_time) * 1000, 2); // Handle different query types if ($query_type === 'SELECT' || $query_type === 'SHOW' || $query_type === 'DESCRIBE' || $query_type === 'EXPLAIN') { // Return result set $result = $query->fetchAll(PDO::FETCH_ASSOC); $message = 'Query executed successfully. ' . count($result) . ' rows returned.'; return array( 'success' => true, 'message' => $message, 'result' => $result, 'query_type' => $query_type, 'execution_time' => $execution_time, 'affected_rows' => 0 ); } else { // Return affected rows count $affected_rows = $query->rowCount(); $message = 'Query executed successfully. ' . $affected_rows . ' row(s) affected.'; return array( 'success' => true, 'message' => $message, 'query_type' => $query_type, 'execution_time' => $execution_time, 'affected_rows' => $affected_rows, 'result' => array() ); } } catch (PDOException $e) { return array( 'success' => false, 'message' => 'Query execution failed', 'error' => $e->getMessage(), 'query_type' => 'ERROR', 'execution_time' => 0, 'result' => array() ); } } /** * Save query to history * @param int $user_id * @param string $database_name * @param string $sql_query * @return bool */ private static function saveQueryToHistory($user_id, $database_name, $sql_query) { // Create history table if it doesn't exist self::createHistoryTableIfNotExists(); $database = DatabaseFactory::getFactory()->getConnection(); try { $sql = "INSERT INTO sql_query_history (user_id, database_name, query_text, query_timestamp) VALUES (:user_id, :database_name, :query_text, NOW())"; $query = $database->prepare($sql); $query->execute(array( ':user_id' => $user_id, ':database_name' => $database_name, ':query_text' => $sql_query )); // Keep only last 50 queries per user $sql = "DELETE FROM sql_query_history WHERE user_id = :user_id AND id NOT IN ( SELECT id FROM ( SELECT id FROM sql_query_history WHERE user_id = :user_id ORDER BY query_timestamp DESC LIMIT 50 ) AS temp )"; $query = $database->prepare($sql); $query->execute(array(':user_id' => $user_id)); return true; } catch (PDOException $e) { return false; } } /** * Create SQL query history table if it doesn't exist */ private static function createHistoryTableIfNotExists() { $database = DatabaseFactory::getFactory()->getConnection(); try { $sql = "CREATE TABLE IF NOT EXISTS sql_query_history ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, database_name VARCHAR(64) NOT NULL, query_text TEXT NOT NULL, query_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_user_timestamp (user_id, query_timestamp) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"; $database->exec($sql); } catch (PDOException $e) { // Table creation failed } } /** * Get query history for a user * @param int $user_id * @param int $limit * @return array */ public static function getQueryHistory($user_id, $limit = 50) { $database = DatabaseFactory::getFactory()->getConnection(); try { $sql = "SELECT database_name, query_text, query_timestamp FROM sql_query_history WHERE user_id = :user_id ORDER BY query_timestamp DESC LIMIT :limit"; $query = $database->prepare($sql); $query->bindValue(':user_id', $user_id, PDO::PARAM_INT); $query->bindValue(':limit', $limit, PDO::PARAM_INT); $query->execute(); return $query->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { return array(); } } /** * Clear query history for a user * @param int $user_id * @return bool */ public static function clearQueryHistory($user_id) { $database = DatabaseFactory::getFactory()->getConnection(); try { $sql = "DELETE FROM sql_query_history WHERE user_id = :user_id"; $query = $database->prepare($sql); return $query->execute(array(':user_id' => $user_id)); } catch (PDOException $e) { return false; } } /** * Get database schema for autocomplete * @param string $database_name * @return array */ public static function getDatabaseSchema($database_name) { $database = DatabaseFactory::getFactory()->getConnection(); $schema = array(); try { // Get all tables $sql = "SHOW TABLES FROM " . $database_name; $query = $database->prepare($sql); $query->execute(); $tables = $query->fetchAll(PDO::FETCH_COLUMN); foreach ($tables as $table) { // Get columns for each table $sql = "SHOW COLUMNS FROM " . $database_name . "." . $table; $query = $database->prepare($sql); $query->execute(); $columns = $query->fetchAll(PDO::FETCH_ASSOC); $schema[$table] = array_map(function($column) { return $column['Field']; }, $columns); } return $schema; } catch (PDOException $e) { return array(); } } /** * Format SQL query (basic formatting) * @param string $query * @return string */ public static function formatQuery($query) { // Basic SQL formatting $query = trim($query); // Uppercase SQL keywords $keywords = array( 'SELECT', 'FROM', 'WHERE', 'AND', 'OR', 'ORDER BY', 'GROUP BY', 'HAVING', 'LIMIT', 'OFFSET', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'SET', 'DELETE', 'CREATE', 'TABLE', 'ALTER', 'DROP', 'INDEX', 'PRIMARY KEY', 'FOREIGN KEY', 'REFERENCES', 'JOIN', 'INNER JOIN', 'LEFT JOIN', 'RIGHT JOIN', 'ON', 'AS', 'DISTINCT', 'COUNT', 'SUM', 'AVG', 'MIN', 'MAX', 'EXISTS', 'IN', 'BETWEEN', 'LIKE', 'IS NULL', 'IS NOT NULL', 'UNION', 'ALL' ); foreach ($keywords as $keyword) { $query = preg_replace('/\b' . preg_quote($keyword) . '\b/i', $keyword, $query); } // Add line breaks for better readability $query = preg_replace('/\b(FROM|WHERE|GROUP BY|ORDER BY|HAVING|LIMIT|UNION)\b/', "\n$1", $query); $query = preg_replace('/,\s*(\w)/', ",\n $1", $query); return $query; } /** * Determine the type of SQL query * @param string $sql_query * @return string */ private static function getQueryType($sql_query) { $query = strtoupper(trim($sql_query)); if (strpos($query, 'SELECT') === 0) { return 'SELECT'; } elseif (strpos($query, 'INSERT') === 0) { return 'INSERT'; } elseif (strpos($query, 'UPDATE') === 0) { return 'UPDATE'; } elseif (strpos($query, 'DELETE') === 0) { return 'DELETE'; } elseif (strpos($query, 'CREATE') === 0) { return 'CREATE'; } elseif (strpos($query, 'ALTER') === 0) { return 'ALTER'; } elseif (strpos($query, 'DROP') === 0) { return 'DROP'; } elseif (strpos($query, 'SHOW') === 0) { return 'SHOW'; } elseif (strpos($query, 'DESCRIBE') === 0) { return 'DESCRIBE'; } elseif (strpos($query, 'EXPLAIN') === 0) { return 'EXPLAIN'; } else { return 'OTHER'; } } }