Finished messenger
This commit is contained in:
289
application/model/SqlModel.php
Normal file
289
application/model/SqlModel.php
Normal file
@@ -0,0 +1,289 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class SqlModel
|
||||
*
|
||||
* Model for executing raw SQL queries
|
||||
*/
|
||||
class SqlModel
|
||||
{
|
||||
/**
|
||||
* Execute a SQL query and return the result
|
||||
* @param string $database_name
|
||||
* @param string $sql_query
|
||||
* @param int $user_id
|
||||
* @return array
|
||||
*/
|
||||
public static function executeQuery($database_name, $sql_query, $user_id = null)
|
||||
{
|
||||
$start_time = microtime(true);
|
||||
|
||||
// Save query to history if user_id is provided
|
||||
if ($user_id) {
|
||||
self::saveQueryToHistory($user_id, $database_name, $sql_query);
|
||||
}
|
||||
|
||||
try {
|
||||
$database = DatabaseFactory::getFactory()->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';
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user