diff options
Diffstat (limited to 'srcs/phpmyadmin/libraries/classes/Server/Status')
| -rw-r--r-- | srcs/phpmyadmin/libraries/classes/Server/Status/Data.php | 430 | ||||
| -rw-r--r-- | srcs/phpmyadmin/libraries/classes/Server/Status/Monitor.php | 546 |
2 files changed, 0 insertions, 976 deletions
diff --git a/srcs/phpmyadmin/libraries/classes/Server/Status/Data.php b/srcs/phpmyadmin/libraries/classes/Server/Status/Data.php deleted file mode 100644 index 7d352f7..0000000 --- a/srcs/phpmyadmin/libraries/classes/Server/Status/Data.php +++ /dev/null @@ -1,430 +0,0 @@ -<?php -/* vim: set expandtab sw=4 ts=4 sts=4: */ -/** - * PhpMyAdmin\Server\Status\Data class - * Used by server_status_*.php pages - * - * @package PhpMyAdmin - */ -declare(strict_types=1); - -namespace PhpMyAdmin\Server\Status; - -use PhpMyAdmin\Url; - -/** - * This class provides data about the server status - * - * All properties of the class are read-only - * - * TODO: Use lazy initialisation for some of the properties - * since not all of the server_status_*.php pages need - * all the data that this class provides. - * - * @package PhpMyAdmin - */ -class Data -{ - public $status; - public $sections; - public $variables; - public $used_queries; - public $allocationMap; - public $links; - public $db_isLocal; - public $section; - public $sectionUsed; - public $selfUrl; - public $dataLoaded; - - /** - * An empty setter makes the above properties read-only - * - * @param string $a key - * @param mixed $b value - * - * @return void - */ - public function __set($a, $b) - { - // Discard everything - } - - /** - * Gets the allocations for constructor - * - * @return array - */ - private function _getAllocations() - { - return [ - // variable name => section - // variable names match when they begin with the given string - - 'Com_' => 'com', - 'Innodb_' => 'innodb', - 'Ndb_' => 'ndb', - 'Handler_' => 'handler', - 'Qcache_' => 'qcache', - 'Threads_' => 'threads', - 'Slow_launch_threads' => 'threads', - - 'Binlog_cache_' => 'binlog_cache', - 'Created_tmp_' => 'created_tmp', - 'Key_' => 'key', - - 'Delayed_' => 'delayed', - 'Not_flushed_delayed_rows' => 'delayed', - - 'Flush_commands' => 'query', - 'Last_query_cost' => 'query', - 'Slow_queries' => 'query', - 'Queries' => 'query', - 'Prepared_stmt_count' => 'query', - - 'Select_' => 'select', - 'Sort_' => 'sort', - - 'Open_tables' => 'table', - 'Opened_tables' => 'table', - 'Open_table_definitions' => 'table', - 'Opened_table_definitions' => 'table', - 'Table_locks_' => 'table', - - 'Rpl_status' => 'repl', - 'Slave_' => 'repl', - - 'Tc_' => 'tc', - - 'Ssl_' => 'ssl', - - 'Open_files' => 'files', - 'Open_streams' => 'files', - 'Opened_files' => 'files', - ]; - } - - /** - * Gets the sections for constructor - * - * @return array - */ - private function _getSections() - { - return [ - // section => section name (description) - 'com' => 'Com', - 'query' => __('SQL query'), - 'innodb' => 'InnoDB', - 'ndb' => 'NDB', - 'handler' => __('Handler'), - 'qcache' => __('Query cache'), - 'threads' => __('Threads'), - 'binlog_cache' => __('Binary log'), - 'created_tmp' => __('Temporary data'), - 'delayed' => __('Delayed inserts'), - 'key' => __('Key cache'), - 'select' => __('Joins'), - 'repl' => __('Replication'), - 'sort' => __('Sorting'), - 'table' => __('Tables'), - 'tc' => __('Transaction coordinator'), - 'files' => __('Files'), - 'ssl' => 'SSL', - 'other' => __('Other'), - ]; - } - - /** - * Gets the links for constructor - * - * @return array - */ - private function _getLinks() - { - $links = []; - // variable or section name => (name => url) - - $links['table'][__('Flush (close) all tables')] = [ - 'url' => $this->selfUrl, - 'params' => Url::getCommon(['flush' => 'TABLES'], ''), - ]; - $links['table'][__('Show open tables')] = [ - 'url' => 'sql.php', - 'params' => Url::getCommon([ - 'sql_query' => 'SHOW OPEN TABLES', - 'goto' => $this->selfUrl, - ], ''), - ]; - - if ($GLOBALS['replication_info']['master']['status']) { - $links['repl'][__('Show slave hosts')] = [ - 'url' => 'sql.php', - 'params' => Url::getCommon([ - 'sql_query' => 'SHOW SLAVE HOSTS', - 'goto' => $this->selfUrl, - ], ''), - ]; - $links['repl'][__('Show master status')] = [ - 'url' => '#replication_master', - 'params' => '', - ]; - } - if ($GLOBALS['replication_info']['slave']['status']) { - $links['repl'][__('Show slave status')] = [ - 'url' => '#replication_slave', - 'params' => '', - ]; - } - - $links['repl']['doc'] = 'replication'; - - $links['qcache'][__('Flush query cache')] = [ - 'url' => $this->selfUrl, - 'params' => Url::getCommon(['flush' => 'QUERY CACHE'], ''), - ]; - $links['qcache']['doc'] = 'query_cache'; - - $links['threads']['doc'] = 'mysql_threads'; - - $links['key']['doc'] = 'myisam_key_cache'; - - $links['binlog_cache']['doc'] = 'binary_log'; - - $links['Slow_queries']['doc'] = 'slow_query_log'; - - $links['innodb'][__('Variables')] = [ - 'url' => 'server_engines.php', - 'params' => Url::getCommon(['engine' => 'InnoDB'], ''), - ]; - $links['innodb'][__('InnoDB Status')] = [ - 'url' => 'server_engines.php', - 'params' => Url::getCommon([ - 'engine' => 'InnoDB', - 'page' => 'Status', - ], ''), - ]; - $links['innodb']['doc'] = 'innodb'; - - return $links; - } - - /** - * Calculate some values - * - * @param array $server_status contains results of SHOW GLOBAL STATUS - * @param array $server_variables contains results of SHOW GLOBAL VARIABLES - * - * @return array - */ - private function _calculateValues(array $server_status, array $server_variables) - { - // Key_buffer_fraction - if (isset($server_status['Key_blocks_unused']) - && isset($server_variables['key_cache_block_size']) - && isset($server_variables['key_buffer_size']) - && $server_variables['key_buffer_size'] != 0 - ) { - $server_status['Key_buffer_fraction_%'] - = 100 - - $server_status['Key_blocks_unused'] - * $server_variables['key_cache_block_size'] - / $server_variables['key_buffer_size'] - * 100; - } elseif (isset($server_status['Key_blocks_used']) - && isset($server_variables['key_buffer_size']) - && $server_variables['key_buffer_size'] != 0 - ) { - $server_status['Key_buffer_fraction_%'] - = $server_status['Key_blocks_used'] - * 1024 - / $server_variables['key_buffer_size']; - } - - // Ratio for key read/write - if (isset($server_status['Key_writes']) - && isset($server_status['Key_write_requests']) - && $server_status['Key_write_requests'] > 0 - ) { - $key_writes = $server_status['Key_writes']; - $key_write_requests = $server_status['Key_write_requests']; - $server_status['Key_write_ratio_%'] - = 100 * $key_writes / $key_write_requests; - } - - if (isset($server_status['Key_reads']) - && isset($server_status['Key_read_requests']) - && $server_status['Key_read_requests'] > 0 - ) { - $key_reads = $server_status['Key_reads']; - $key_read_requests = $server_status['Key_read_requests']; - $server_status['Key_read_ratio_%'] - = 100 * $key_reads / $key_read_requests; - } - - // Threads_cache_hitrate - if (isset($server_status['Threads_created']) - && isset($server_status['Connections']) - && $server_status['Connections'] > 0 - ) { - $server_status['Threads_cache_hitrate_%'] - = 100 - $server_status['Threads_created'] - / $server_status['Connections'] * 100; - } - return $server_status; - } - - /** - * Sort variables into arrays - * - * @param array $server_status contains results of SHOW GLOBAL STATUS - * @param array $allocations allocations for sections - * @param array $allocationMap map variables to their section - * @param array $sectionUsed is a section used? - * @param array $used_queries used queries - * - * @return array ($allocationMap, $sectionUsed, $used_queries) - */ - private function _sortVariables( - array $server_status, - array $allocations, - array $allocationMap, - array $sectionUsed, - array $used_queries - ) { - foreach ($server_status as $name => $value) { - $section_found = false; - foreach ($allocations as $filter => $section) { - if (mb_strpos($name, $filter) !== false) { - $allocationMap[$name] = $section; - $sectionUsed[$section] = true; - $section_found = true; - if ($section == 'com' && $value > 0) { - $used_queries[$name] = $value; - } - break; // Only exits inner loop - } - } - if (! $section_found) { - $allocationMap[$name] = 'other'; - $sectionUsed['other'] = true; - } - } - return [ - $allocationMap, - $sectionUsed, - $used_queries, - ]; - } - - /** - * Constructor - */ - public function __construct() - { - $this->selfUrl = basename($GLOBALS['PMA_PHP_SELF']); - - // get status from server - $server_status_result = $GLOBALS['dbi']->tryQuery('SHOW GLOBAL STATUS'); - $server_status = []; - if ($server_status_result === false) { - $this->dataLoaded = false; - } else { - $this->dataLoaded = true; - while ($arr = $GLOBALS['dbi']->fetchRow($server_status_result)) { - $server_status[$arr[0]] = $arr[1]; - } - $GLOBALS['dbi']->freeResult($server_status_result); - } - - // for some calculations we require also some server settings - $server_variables = $GLOBALS['dbi']->fetchResult( - 'SHOW GLOBAL VARIABLES', - 0, - 1 - ); - - // cleanup of some deprecated values - $server_status = self::cleanDeprecated($server_status); - - // calculate some values - $server_status = $this->_calculateValues( - $server_status, - $server_variables - ); - - // split variables in sections - $allocations = $this->_getAllocations(); - - $sections = $this->_getSections(); - - // define some needful links/commands - $links = $this->_getLinks(); - - // Variable to contain all com_ variables (query statistics) - $used_queries = []; - - // Variable to map variable names to their respective section name - // (used for js category filtering) - $allocationMap = []; - - // Variable to mark used sections - $sectionUsed = []; - - // sort vars into arrays - list( - $allocationMap, $sectionUsed, $used_queries - ) = $this->_sortVariables( - $server_status, - $allocations, - $allocationMap, - $sectionUsed, - $used_queries - ); - - // admin commands are not queries (e.g. they include COM_PING, - // which is excluded from $server_status['Questions']) - unset($used_queries['Com_admin_commands']); - - // Set all class properties - $this->db_isLocal = false; - $serverHostToLower = mb_strtolower( - $GLOBALS['cfg']['Server']['host'] - ); - if ($serverHostToLower === 'localhost' - || $GLOBALS['cfg']['Server']['host'] === '127.0.0.1' - || $GLOBALS['cfg']['Server']['host'] === '::1' - ) { - $this->db_isLocal = true; - } - $this->status = $server_status; - $this->sections = $sections; - $this->variables = $server_variables; - $this->used_queries = $used_queries; - $this->allocationMap = $allocationMap; - $this->links = $links; - $this->sectionUsed = $sectionUsed; - } - - /** - * cleanup of some deprecated values - * - * @param array $server_status status array to process - * - * @return array - */ - public static function cleanDeprecated(array $server_status) - { - $deprecated = [ - 'Com_prepare_sql' => 'Com_stmt_prepare', - 'Com_execute_sql' => 'Com_stmt_execute', - 'Com_dealloc_sql' => 'Com_stmt_close', - ]; - foreach ($deprecated as $old => $new) { - if (isset($server_status[$old]) && isset($server_status[$new])) { - unset($server_status[$old]); - } - } - return $server_status; - } -} diff --git a/srcs/phpmyadmin/libraries/classes/Server/Status/Monitor.php b/srcs/phpmyadmin/libraries/classes/Server/Status/Monitor.php deleted file mode 100644 index efa9e40..0000000 --- a/srcs/phpmyadmin/libraries/classes/Server/Status/Monitor.php +++ /dev/null @@ -1,546 +0,0 @@ -<?php -/* vim: set expandtab sw=4 ts=4 sts=4: */ -/** - * functions for displaying server status sub item: monitor - * - * @usedby server_status_monitor.php - * - * @package PhpMyAdmin - */ -declare(strict_types=1); - -namespace PhpMyAdmin\Server\Status; - -use PhpMyAdmin\DatabaseInterface; -use PhpMyAdmin\SysInfo; -use PhpMyAdmin\Util; - -/** - * functions for displaying server status sub item: monitor - * - * @package PhpMyAdmin - */ -class Monitor -{ - /** - * @var DatabaseInterface - */ - private $dbi; - - /** - * Monitor constructor. - * @param DatabaseInterface $dbi DatabaseInterface instance - */ - public function __construct($dbi) - { - $this->dbi = $dbi; - } - - /** - * Returns JSON for real-time charting data - * - * @param string $requiredData Required data - * - * @return array JSON - */ - public function getJsonForChartingData(string $requiredData): array - { - $ret = json_decode($requiredData, true); - $statusVars = []; - $serverVars = []; - $sysinfo = $cpuload = $memory = 0; - - /* Accumulate all required variables and data */ - list($serverVars, $statusVars, $ret) = $this->getJsonForChartingDataGet( - $ret, - $serverVars, - $statusVars, - $sysinfo, - $cpuload, - $memory - ); - - // Retrieve all required status variables - $statusVarValues = []; - if (count($statusVars)) { - $statusVarValues = $this->dbi->fetchResult( - "SHOW GLOBAL STATUS WHERE Variable_name='" - . implode("' OR Variable_name='", $statusVars) . "'", - 0, - 1 - ); - } - - // Retrieve all required server variables - $serverVarValues = []; - if (count($serverVars)) { - $serverVarValues = $this->dbi->fetchResult( - "SHOW GLOBAL VARIABLES WHERE Variable_name='" - . implode("' OR Variable_name='", $serverVars) . "'", - 0, - 1 - ); - } - - // ...and now assign them - $ret = $this->getJsonForChartingDataSet($ret, $statusVarValues, $serverVarValues); - - $ret['x'] = microtime(true) * 1000; - return $ret; - } - - /** - * Assign the variables for real-time charting data - * - * @param array $ret Real-time charting data - * @param array $statusVarValues Status variable values - * @param array $serverVarValues Server variable values - * - * @return array - */ - private function getJsonForChartingDataSet( - array $ret, - array $statusVarValues, - array $serverVarValues - ): array { - foreach ($ret as $chart_id => $chartNodes) { - foreach ($chartNodes as $node_id => $nodeDataPoints) { - foreach ($nodeDataPoints as $point_id => $dataPoint) { - switch ($dataPoint['type']) { - case 'statusvar': - $ret[$chart_id][$node_id][$point_id]['value'] - = $statusVarValues[$dataPoint['name']]; - break; - case 'servervar': - $ret[$chart_id][$node_id][$point_id]['value'] - = $serverVarValues[$dataPoint['name']]; - break; - } - } - } - } - return $ret; - } - - /** - * Get called to get JSON for charting data - * - * @param array $ret Real-time charting data - * @param array $serverVars Server variable values - * @param array $statusVars Status variable values - * @param mixed $sysinfo System info - * @param mixed $cpuload CPU load - * @param mixed $memory Memory - * - * @return array - */ - private function getJsonForChartingDataGet( - array $ret, - array $serverVars, - array $statusVars, - $sysinfo, - $cpuload, - $memory - ) { - // For each chart - foreach ($ret as $chartId => $chartNodes) { - // For each data series - foreach ($chartNodes as $nodeId => $nodeDataPoints) { - // For each data point in the series (usually just 1) - foreach ($nodeDataPoints as $pointId => $dataPoint) { - list($serverVars, $statusVars, $ret[$chartId][$nodeId][$pointId]) - = $this->getJsonForChartingDataSwitch( - $dataPoint['type'], - $dataPoint['name'], - $serverVars, - $statusVars, - $ret[$chartId][$nodeId][$pointId], - $sysinfo, - $cpuload, - $memory - ); - } /* foreach */ - } /* foreach */ - } - return [ - $serverVars, - $statusVars, - $ret, - ]; - } - - /** - * Switch called to get JSON for charting data - * - * @param string $type Type - * @param string $pName Name - * @param array $serverVars Server variable values - * @param array $statusVars Status variable values - * @param array $ret Real-time charting data - * @param mixed $sysinfo System info - * @param mixed $cpuload CPU load - * @param mixed $memory Memory - * - * @return array - */ - private function getJsonForChartingDataSwitch( - $type, - $pName, - array $serverVars, - array $statusVars, - array $ret, - $sysinfo, - $cpuload, - $memory - ) { - switch ($type) { - /* We only collect the status and server variables here to - * read them all in one query, - * and only afterwards assign them. - * Also do some white list filtering on the names - */ - case 'servervar': - if (! preg_match('/[^a-zA-Z_]+/', $pName)) { - $serverVars[] = $pName; - } - break; - - case 'statusvar': - if (! preg_match('/[^a-zA-Z_]+/', $pName)) { - $statusVars[] = $pName; - } - break; - - case 'proc': - $result = $this->dbi->query('SHOW PROCESSLIST'); - $ret['value'] = $this->dbi->numRows($result); - break; - - case 'cpu': - if (! $sysinfo) { - $sysinfo = SysInfo::get(); - } - if (! $cpuload) { - $cpuload = $sysinfo->loadavg(); - } - - if (SysInfo::getOs() == 'Linux') { - $ret['idle'] = $cpuload['idle']; - $ret['busy'] = $cpuload['busy']; - } else { - $ret['value'] = $cpuload['loadavg']; - } - - break; - - case 'memory': - if (! $sysinfo) { - $sysinfo = SysInfo::get(); - } - if (! $memory) { - $memory = $sysinfo->memory(); - } - - $ret['value'] = isset($memory[$pName]) ? $memory[$pName] : 0; - break; - } - - return [ - $serverVars, - $statusVars, - $ret, - ]; - } - - /** - * Returns JSON for log data with type: slow - * - * @param int $start Unix Time: Start time for query - * @param int $end Unix Time: End time for query - * - * @return array - */ - public function getJsonForLogDataTypeSlow(int $start, int $end): array - { - $query = 'SELECT start_time, user_host, '; - $query .= 'Sec_to_Time(Sum(Time_to_Sec(query_time))) as query_time, '; - $query .= 'Sec_to_Time(Sum(Time_to_Sec(lock_time))) as lock_time, '; - $query .= 'SUM(rows_sent) AS rows_sent, '; - $query .= 'SUM(rows_examined) AS rows_examined, db, sql_text, '; - $query .= 'COUNT(sql_text) AS \'#\' '; - $query .= 'FROM `mysql`.`slow_log` '; - $query .= 'WHERE start_time > FROM_UNIXTIME(' . $start . ') '; - $query .= 'AND start_time < FROM_UNIXTIME(' . $end . ') GROUP BY sql_text'; - - $result = $this->dbi->tryQuery($query); - - $return = [ - 'rows' => [], - 'sum' => [], - ]; - - while ($row = $this->dbi->fetchAssoc($result)) { - $type = mb_strtolower( - mb_substr( - $row['sql_text'], - 0, - mb_strpos($row['sql_text'], ' ') - ) - ); - - switch ($type) { - case 'insert': - case 'update': - //Cut off big inserts and updates, but append byte count instead - if (mb_strlen($row['sql_text']) > 220) { - $implodeSqlText = implode( - ' ', - Util::formatByteDown( - mb_strlen($row['sql_text']), - 2, - 2 - ) - ); - $row['sql_text'] = mb_substr($row['sql_text'], 0, 200) - . '... [' . $implodeSqlText . ']'; - } - break; - default: - break; - } - - if (! isset($return['sum'][$type])) { - $return['sum'][$type] = 0; - } - $return['sum'][$type] += $row['#']; - $return['rows'][] = $row; - } - - $return['sum']['TOTAL'] = array_sum($return['sum']); - $return['numRows'] = count($return['rows']); - - $this->dbi->freeResult($result); - return $return; - } - - /** - * Returns JSon for log data with type: general - * - * @param int $start Unix Time: Start time for query - * @param int $end Unix Time: End time for query - * @param bool $isTypesLimited Whether to limit types or not - * @param bool $removeVariables Whether to remove variables or not - * - * @return array - */ - public function getJsonForLogDataTypeGeneral( - int $start, - int $end, - bool $isTypesLimited, - bool $removeVariables - ): array { - $limitTypes = ''; - if ($isTypesLimited) { - $limitTypes = 'AND argument REGEXP \'^(INSERT|SELECT|UPDATE|DELETE)\' '; - } - - $query = 'SELECT TIME(event_time) as event_time, user_host, thread_id, '; - $query .= 'server_id, argument, count(argument) as \'#\' '; - $query .= 'FROM `mysql`.`general_log` '; - $query .= 'WHERE command_type=\'Query\' '; - $query .= 'AND event_time > FROM_UNIXTIME(' . $start . ') '; - $query .= 'AND event_time < FROM_UNIXTIME(' . $end . ') '; - $query .= $limitTypes . 'GROUP by argument'; // HAVING count > 1'; - - $result = $this->dbi->tryQuery($query); - - $return = [ - 'rows' => [], - 'sum' => [], - ]; - $insertTables = []; - $insertTablesFirst = -1; - $i = 0; - - while ($row = $this->dbi->fetchAssoc($result)) { - preg_match('/^(\w+)\s/', $row['argument'], $match); - $type = mb_strtolower($match[1]); - - if (! isset($return['sum'][$type])) { - $return['sum'][$type] = 0; - } - $return['sum'][$type] += $row['#']; - - switch ($type) { - /** @noinspection PhpMissingBreakStatementInspection */ - case 'insert': - // Group inserts if selected - if ($removeVariables - && preg_match( - '/^INSERT INTO (`|\'|"|)([^\s\\1]+)\\1/i', - $row['argument'], - $matches - ) - ) { - $insertTables[$matches[2]]++; - if ($insertTables[$matches[2]] > 1) { - $return['rows'][$insertTablesFirst]['#'] - = $insertTables[$matches[2]]; - - // Add a ... to the end of this query to indicate that - // there's been other queries - $temp = $return['rows'][$insertTablesFirst]['argument']; - $return['rows'][$insertTablesFirst]['argument'] - .= $this->getSuspensionPoints( - $temp[strlen($temp) - 1] - ); - - // Group this value, thus do not add to the result list - continue 2; - } else { - $insertTablesFirst = $i; - $insertTables[$matches[2]] += $row['#'] - 1; - } - } - // No break here - - case 'update': - // Cut off big inserts and updates, - // but append byte count therefor - if (mb_strlen($row['argument']) > 220) { - $row['argument'] = mb_substr($row['argument'], 0, 200) - . '... [' - . implode( - ' ', - Util::formatByteDown( - mb_strlen($row['argument']), - 2, - 2 - ) - ) - . ']'; - } - break; - - default: - break; - } - - $return['rows'][] = $row; - $i++; - } - - $return['sum']['TOTAL'] = array_sum($return['sum']); - $return['numRows'] = count($return['rows']); - - $this->dbi->freeResult($result); - - return $return; - } - - /** - * Return suspension points if needed - * - * @param string $lastChar Last char - * - * @return string Return suspension points if needed - */ - private function getSuspensionPoints(string $lastChar): string - { - if ($lastChar != '.') { - return '<br>...'; - } - - return ''; - } - - /** - * Returns JSON for logging vars - * - * @param string|null $name Variable name - * @param string|null $value Variable value - * - * @return array JSON - */ - public function getJsonForLoggingVars(?string $name, ?string $value): array - { - if (isset($name) && isset($value)) { - $escapedValue = $this->dbi->escapeString($value); - if (! is_numeric($escapedValue)) { - $escapedValue = "'" . $escapedValue . "'"; - } - - if (! preg_match("/[^a-zA-Z0-9_]+/", $name)) { - $this->dbi->query( - 'SET GLOBAL ' . $name . ' = ' . $escapedValue - ); - } - } - - $loggingVars = $this->dbi->fetchResult( - 'SHOW GLOBAL VARIABLES WHERE Variable_name IN' - . ' ("general_log","slow_query_log","long_query_time","log_output")', - 0, - 1 - ); - return $loggingVars; - } - - /** - * Returns JSON for query_analyzer - * - * @param string $database Database name - * @param string $query SQL query - * - * @return array JSON - */ - public function getJsonForQueryAnalyzer( - string $database, - string $query - ): array { - global $cached_affected_rows; - - $return = []; - - if (strlen($database) > 0) { - $this->dbi->selectDb($database); - } - - if ($profiling = Util::profilingSupported()) { - $this->dbi->query('SET PROFILING=1;'); - } - - // Do not cache query - $sqlQuery = preg_replace( - '/^(\s*SELECT)/i', - '\\1 SQL_NO_CACHE', - $query - ); - - $this->dbi->tryQuery($sqlQuery); - $return['affectedRows'] = $cached_affected_rows; - - $result = $this->dbi->tryQuery('EXPLAIN ' . $sqlQuery); - while ($row = $this->dbi->fetchAssoc($result)) { - $return['explain'][] = $row; - } - - // In case an error happened - $return['error'] = $this->dbi->getError(); - - $this->dbi->freeResult($result); - - if ($profiling) { - $return['profiling'] = []; - $result = $this->dbi->tryQuery( - 'SELECT seq,state,duration FROM INFORMATION_SCHEMA.PROFILING' - . ' WHERE QUERY_ID=1 ORDER BY seq' - ); - while ($row = $this->dbi->fetchAssoc($result)) { - $return['profiling'][] = $row; - } - $this->dbi->freeResult($result); - } - return $return; - } -} |
