diff --git a/ChangeLog b/ChangeLog index e957a020bc..062f5cb404 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,7 @@ phpMyAdmin - ChangeLog + rfe #1410 Added support for AES_ENCRYPT for blob fields + rfe #1423 Clarify option text for icon/text settings + [interface] Upgraded CodeMirror to 3.x series ++ rfe #1363 Improved query profiler 4.0.3.0 (not yet released) - bug #3941 Recent tables list always empty diff --git a/js/functions.js b/js/functions.js index de254e6717..54c4c227a9 100644 --- a/js/functions.js +++ b/js/functions.js @@ -1675,6 +1675,14 @@ function PMA_createProfilingChartJqplot(target, data) showDataLabels: true } }, + highlighter: { + show:true, + tooltipLocation: 'se', + sizeAdjust: 0, + tooltipAxes: 'pieref', + useAxesFormatters: false, + formatString:'%s, %.9Ps' + }, legend: { show: true, location: 'e' diff --git a/js/sql.js b/js/sql.js index cdf06690d3..bfeb4dc869 100644 --- a/js/sql.js +++ b/js/sql.js @@ -579,6 +579,9 @@ function makeProfilingChart() { if ($('#profilingchart').length === 0 || $('#profilingchart').html().length !== 0 + || !$.jqplot + || !$.jqplot.Highlighter + || !$.jqplot.PieRenderer ) { return; } @@ -594,3 +597,42 @@ function makeProfilingChart() PMA_createProfilingChartJqplot('profilingchart', data); } + +/* + * initialize profiling data tables + */ +function initProfilingTables() +{ + if (!$.tablesorter) { + return; + } + + $('#profiletable').tablesorter({ + widgets: ['zebra'], + sortList: [[0,0]], + textExtraction: function (node) { + if (node.children.length > 0) { + return node.children[0].innerHTML; + } else { + return node.innerHTML; + } + } + }); + + $('#profilesummarytable').tablesorter({ + widgets: ['zebra'], + sortList: [[1,1]], + textExtraction: function (node) { + if (node.children.length > 0) { + return node.children[0].innerHTML; + } else { + return node.innerHTML; + } + } + }); +} + +AJAX.registerOnload('sql.js', function () { + makeProfilingChart(); + initProfilingTables(); +}); \ No newline at end of file diff --git a/libraries/sql.lib.php b/libraries/sql.lib.php index b7b42385f7..74b6649d82 100644 --- a/libraries/sql.lib.php +++ b/libraries/sql.lib.php @@ -484,32 +484,49 @@ function PMA_getHtmlForPrintViewHeader($db, $sql_query, $num_rows) */ function PMA_getHtmlForProfilingChart($url_query, $pma_token, $profiling_results) { + $profiling_stats = array( + 'total_time' => 0, + 'states' => array(), + ); $profiling_table = ''; - $profiling_table .= ''; $profiling_table .= '
' . __('Profiling') . '' . "\n"; $profiling_table .= '
'; - $profiling_table .= '' . "\n"; - $profiling_table .= ' ' . "\n"; - $profiling_table .= '
' . __('Status') + $profiling_table .= '

' . __('Detailed profile') . '

'; + $profiling_table .= '' . "\n"; + $profiling_table .= ' ' . "\n"; + $profiling_table .= ' ' . "\n"; + $profiling_table .= ' ' . "\n"; - $profiling_table .= ' ' . "\n"; - $profiling_table .= ' ' . "\n"; + . '
' . "\n"; + $profiling_table .= ' ' . "\n"; + $profiling_table .= ' ' . "\n"; $chart_json = Array(); + $i = 1; foreach ($profiling_results as $one_result) { - $profiling_table .= ' ' . "\n"; - $profiling_table .= '' . "\n"; + if (isset($profiling_stats['states'][ucwords($one_result['Status'])])) { + $profiling_stats['states'][ucwords($one_result['Status'])]['time'] += $one_result['Duration']; + $profiling_stats['states'][ucwords($one_result['Status'])]['calls']++; + } else { + $profiling_stats['states'][ucwords($one_result['Status'])] = array( + 'total_time' => $one_result['Duration'], + 'calls' => 1, + ); + } + $profiling_stats['total_time'] += $one_result['Duration']; + + $profiling_table .= ' ' . "\n"; + $profiling_table .= '' . "\n"; + $profiling_table .= '' . "\n"; $profiling_table .= '' . "\n"; + . 's' . "\n"; if (isset($chart_json[ucwords($one_result['Status'])])) { $chart_json[ucwords($one_result['Status'])] += $one_result['Duration']; @@ -519,8 +536,56 @@ function PMA_getHtmlForProfilingChart($url_query, $pma_token, $profiling_results } } - $profiling_table .= '
' . __('Order') + . '
' . __('State') . PMA_Util::showMySQLDocu( 'general-thread-states', 'general-thread-states' ) - . '' . __('Time') . '
' . __('Time') + . '
' . ucwords($one_result['Status']) . '
' . $i++ . '' . ucwords($one_result['Status']) . '' . (PMA_Util::formatNumber($one_result['Duration'], 3, 1)) - . 's
' . "\n"; + $profiling_table .= '
' . "\n"; $profiling_table .= '
'; + + $profiling_table .= '
'; + $profiling_table .= '

' . __('Summary by state') . '

'; + $profiling_table .= '' . "\n"; + $profiling_table .= ' ' . "\n"; + $profiling_table .= ' ' . "\n"; + $profiling_table .= ' ' . "\n"; + $profiling_table .= ' ' . "\n"; + $profiling_table .= ' ' . "\n"; + $profiling_table .= ' ' . "\n"; + $profiling_table .= ' ' . "\n"; + foreach ($profiling_stats['states'] as $name => $stats) { + $profiling_table .= ' ' . "\n"; + $profiling_table .= '' . "\n"; + $profiling_table .= '' . "\n"; + $profiling_table .= '' . "\n"; + $profiling_table .= '' . "\n"; + $profiling_table .= '' . "\n"; + $profiling_table .= ' ' . "\n"; + } + + $profiling_table .= '
' . __('State') + . PMA_Util::showMySQLDocu( + 'general-thread-states', 'general-thread-states' + ) + . '
' . __('Total Time') + . '
' . __('% Time') + . '
' . __('Calls') + . '
' . __('ΓΈ Time') + . '
' . $name . '' + . PMA_Util::formatNumber($stats['total_time'], 3, 1) + . 's' + . PMA_Util::formatNumber(100 * ($stats['total_time'] / $profiling_stats['total_time']), 0, 2) + . '%' . $stats['calls'] . '' + . PMA_Util::formatNumber($stats['total_time'] / $stats['calls'], 3, 1) + . 's
' . "\n"; + + $profiling_table .= << + pma_token = '$pma_token'; + url_query = '$url_query'; + +EOT; + $profiling_table .= "
"; + //require_once 'libraries/chart.lib.php'; $profiling_table .= '