Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
547a594e2f
@ -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
|
||||
|
||||
@ -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'
|
||||
|
||||
42
js/sql.js
42
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();
|
||||
});
|
||||
@ -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 .= '<script type="text/javascript">';
|
||||
$profiling_table .= 'pma_token = \'' . $pma_token . '\';';
|
||||
$profiling_table .= 'url_query = \'' . $url_query . '\';';
|
||||
$profiling_table .= 'AJAX.registerOnload(\'sql.js\',makeProfilingChart);';
|
||||
$profiling_table .= '</script>';
|
||||
|
||||
$profiling_table .= '<fieldset><legend>' . __('Profiling') . '</legend>' . "\n";
|
||||
$profiling_table .= '<div style="float: left;">';
|
||||
$profiling_table .= '<table>' . "\n";
|
||||
$profiling_table .= ' <tr>' . "\n";
|
||||
$profiling_table .= ' <th>' . __('Status')
|
||||
$profiling_table .= '<h3>' . __('Detailed profile') . '</h3>';
|
||||
$profiling_table .= '<table id="profiletable"><thead>' . "\n";
|
||||
$profiling_table .= ' <tr>' . "\n";
|
||||
$profiling_table .= ' <th>' . __('Order')
|
||||
. '<div class="sorticon"></div></th>' . "\n";
|
||||
$profiling_table .= ' <th>' . __('State')
|
||||
. PMA_Util::showMySQLDocu(
|
||||
'general-thread-states', 'general-thread-states'
|
||||
)
|
||||
. '</th>' . "\n";
|
||||
$profiling_table .= ' <th>' . __('Time') . '</th>' . "\n";
|
||||
$profiling_table .= ' </tr>' . "\n";
|
||||
. '<div class="sorticon"></div></th>' . "\n";
|
||||
$profiling_table .= ' <th>' . __('Time')
|
||||
. '<div class="sorticon"></div></th>' . "\n";
|
||||
$profiling_table .= ' </tr></thead><tbody>' . "\n";
|
||||
|
||||
$chart_json = Array();
|
||||
$i = 1;
|
||||
foreach ($profiling_results as $one_result) {
|
||||
$profiling_table .= ' <tr>' . "\n";
|
||||
$profiling_table .= '<td>' . ucwords($one_result['Status']) . '</td>' . "\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 .= ' <tr>' . "\n";
|
||||
$profiling_table .= '<td>' . $i++ . '</td>' . "\n";
|
||||
$profiling_table .= '<td>' . ucwords($one_result['Status']) . '</td>' . "\n";
|
||||
$profiling_table .= '<td class="right">'
|
||||
. (PMA_Util::formatNumber($one_result['Duration'], 3, 1))
|
||||
. 's</td>' . "\n";
|
||||
. 's<span style="display:none;" class="rawvalue">'
|
||||
. $one_result['Duration'] . '</span></td>' . "\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 .= '</table>' . "\n";
|
||||
$profiling_table .= '</tbody></table>' . "\n";
|
||||
$profiling_table .= '</div>';
|
||||
|
||||
$profiling_table .= '<div style="float: left; margin-left:10px;">';
|
||||
$profiling_table .= '<h3>' . __('Summary by state') . '</h3>';
|
||||
$profiling_table .= '<table id="profilesummarytable"><thead>' . "\n";
|
||||
$profiling_table .= ' <tr>' . "\n";
|
||||
$profiling_table .= ' <th>' . __('State')
|
||||
. PMA_Util::showMySQLDocu(
|
||||
'general-thread-states', 'general-thread-states'
|
||||
)
|
||||
. '<div class="sorticon"></div></th>' . "\n";
|
||||
$profiling_table .= ' <th>' . __('Total Time')
|
||||
. '<div class="sorticon"></div></th>' . "\n";
|
||||
$profiling_table .= ' <th>' . __('% Time')
|
||||
. '<div class="sorticon"></div></th>' . "\n";
|
||||
$profiling_table .= ' <th>' . __('Calls')
|
||||
. '<div class="sorticon"></div></th>' . "\n";
|
||||
$profiling_table .= ' <th>' . __('ø Time')
|
||||
. '<div class="sorticon"></div></th>' . "\n";
|
||||
$profiling_table .= ' </tr></thead><tbody>' . "\n";
|
||||
foreach ($profiling_stats['states'] as $name => $stats) {
|
||||
$profiling_table .= ' <tr>' . "\n";
|
||||
$profiling_table .= '<td>' . $name . '</td>' . "\n";
|
||||
$profiling_table .= '<td align="right">'
|
||||
. PMA_Util::formatNumber($stats['total_time'], 3, 1)
|
||||
. 's<span style="display:none;" class="rawvalue">'
|
||||
. $stats['total_time'] . '</span></td>' . "\n";
|
||||
$profiling_table .= '<td align="right">'
|
||||
. PMA_Util::formatNumber(100 * ($stats['total_time'] / $profiling_stats['total_time']), 0, 2)
|
||||
. '%</td>' . "\n";
|
||||
$profiling_table .= '<td align="right">' . $stats['calls'] . '</td>' . "\n";
|
||||
$profiling_table .= '<td align="right">'
|
||||
. PMA_Util::formatNumber($stats['total_time'] / $stats['calls'], 3, 1)
|
||||
. 's<span style="display:none;" class="rawvalue">'
|
||||
. number_format($stats['total_time'] / $stats['calls'], 8, '.', '')
|
||||
. '</span></td>' . "\n";
|
||||
$profiling_table .= ' </tr>' . "\n";
|
||||
}
|
||||
|
||||
$profiling_table .= '</tbody></table>' . "\n";
|
||||
|
||||
$profiling_table .= <<<EOT
|
||||
<script type="text/javascript">
|
||||
pma_token = '$pma_token';
|
||||
url_query = '$url_query';
|
||||
</script>
|
||||
EOT;
|
||||
$profiling_table .= "</div>";
|
||||
|
||||
//require_once 'libraries/chart.lib.php';
|
||||
$profiling_table .= '<div id="profilingChartData" style="display:none;">';
|
||||
$profiling_table .= json_encode($chart_json);
|
||||
|
||||
15
sql.php
15
sql.php
@ -68,6 +68,21 @@ if (isset($_REQUEST['printview'])) {
|
||||
$GLOBALS['printview'] = $_REQUEST['printview'];
|
||||
}
|
||||
|
||||
if (isset($_SESSION['profiling'])) {
|
||||
$response = PMA_Response::getInstance();
|
||||
$header = $response->getHeader();
|
||||
$scripts = $header->getScripts();
|
||||
/* < IE 9 doesn't support canvas natively */
|
||||
if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 9) {
|
||||
$scripts->addFile('canvg/flashcanvas.js');
|
||||
}
|
||||
$scripts->addFile('jqplot/jquery.jqplot.js');
|
||||
$scripts->addFile('jqplot/plugins/jqplot.pieRenderer.js');
|
||||
$scripts->addFile('jqplot/plugins/jqplot.highlighter.js');
|
||||
$scripts->addFile('canvg/canvg.js');
|
||||
$scripts->addFile('jquery/jquery.tablesorter.js');
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['is_multi_query'])) {
|
||||
$_SESSION['is_multi_query'] = false;
|
||||
}
|
||||
|
||||
@ -1187,6 +1187,34 @@ div#profilingchart {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#profilingchart .jqplot-highlighter-tooltip{
|
||||
top: auto !important;
|
||||
left: 11px;
|
||||
bottom:24px;
|
||||
}
|
||||
|
||||
#profilesummarytable th.header, #profiletable th.header{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#profilesummarytable th.header .sorticon, #profiletable th.header .sorticon{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: right center;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#profilesummarytable th.headerSortUp .sorticon, #profiletable th.headerSortUp .sorticon{
|
||||
background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('s_desc.png');?>);
|
||||
}
|
||||
|
||||
#profilesummarytable th.headerSortDown .sorticon, #profiletable th.headerSortDown .sorticon{
|
||||
background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('s_asc.png');?>);
|
||||
}
|
||||
|
||||
/* END profiling */
|
||||
|
||||
/* querybox */
|
||||
@ -1248,7 +1276,7 @@ div#queryboxcontainer div#bookmarkoptions {
|
||||
/* iconic view for ul items */
|
||||
|
||||
li.no_bullets {
|
||||
list-style-type:none !important;
|
||||
list-style-type:none !important;
|
||||
margin-left: -25px !important; //align with other list items which have bullets
|
||||
}
|
||||
|
||||
|
||||
@ -729,7 +729,7 @@ div.error {
|
||||
|
||||
h1.success,
|
||||
div.success {
|
||||
border-color: #a2d246;
|
||||
border-color: #a2d246;
|
||||
}
|
||||
.success h1 {
|
||||
border-color: #00FF00;
|
||||
@ -757,7 +757,7 @@ div.notice {
|
||||
|
||||
h1.error,
|
||||
div.error {
|
||||
border-color: #333;
|
||||
border-color: #333;
|
||||
}
|
||||
|
||||
div.error h1 {
|
||||
@ -1491,6 +1491,34 @@ div#profilingchart {
|
||||
float: <?php echo $left; ?>;
|
||||
}
|
||||
|
||||
#profilingchart .jqplot-highlighter-tooltip{
|
||||
top: auto !important;
|
||||
left: 11px;
|
||||
bottom:24px;
|
||||
}
|
||||
|
||||
#profilesummarytable th.header, #profiletable th.header{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#profilesummarytable th.header .sorticon, #profiletable th.header .sorticon{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: right center;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#profilesummarytable th.headerSortUp .sorticon, #profiletable th.headerSortUp .sorticon{
|
||||
background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('s_desc.png');?>);
|
||||
}
|
||||
|
||||
#profilesummarytable th.headerSortDown .sorticon, #profiletable th.headerSortDown .sorticon{
|
||||
background-image: url(<?php echo $_SESSION['PMA_Theme']->getImgPath('s_asc.png');?>);
|
||||
}
|
||||
|
||||
/* END profiling */
|
||||
|
||||
/* table charting */
|
||||
@ -1624,7 +1652,7 @@ div#queryboxcontainer div#bookmarkoptions {
|
||||
/* iconic view for ul items */
|
||||
|
||||
li.no_bullets {
|
||||
list-style-type:none !important;
|
||||
list-style-type:none !important;
|
||||
margin-left: -25px !important; //align with other list items which have bullets
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user