Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2014-06-24 16:29:21 +02:00
commit 13f9f86d92
15 changed files with 1023 additions and 385 deletions

View File

@ -18,6 +18,7 @@ phpMyAdmin - ChangeLog
+ rfe #755 Export with table/column name changes
+ rfe #869 Run SQL query: Allow rollback for InnoDB tables
+ rfe #654 Range Search Capability
+ rfe #1490 Dynamic process list
4.2.5.0 (not yet released)
- bug #4467 shell_exec() has been disabled for security reasons

View File

@ -132,6 +132,8 @@ $js_messages['strAddOneSeriesWarning'] = __('Please add at least one variable to
$js_messages['strNone'] = __('None');
$js_messages['strResumeMonitor'] = __('Resume monitor');
$js_messages['strPauseMonitor'] = __('Pause monitor');
$js_messages['strStartRefresh'] = __('Start auto refresh');
$js_messages['strStopRefresh'] = __('Stop auto refresh');
/* Monitor: Instructions Dialog */
$js_messages['strBothLogOn'] = __('general_log and slow_query_log are enabled.');
$js_messages['strGenLogOn'] = __('general_log is enabled.');

View File

@ -670,9 +670,9 @@ AJAX.registerOnload('server_status_monitor.js', function () {
event.preventDefault();
runtime.redrawCharts = ! runtime.redrawCharts;
if (! runtime.redrawCharts) {
$(this).html(PMA_getImage('play.png') + ' ' + PMA_messages.strResumeMonitor);
$(this).html(PMA_getImage('play.png') + PMA_messages.strResumeMonitor);
} else {
$(this).html(PMA_getImage('pause.png') + ' ' + PMA_messages.strPauseMonitor);
$(this).html(PMA_getImage('pause.png') + PMA_messages.strPauseMonitor);
if (! runtime.charts) {
initGrid();
$('a[href="#settingsPopup"]').show();

View File

@ -0,0 +1,171 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Server Status Processes
*
* @package PhpMyAdmin
*/
// object to store process list state information
var processList = {
// denotes whether auto refresh is on or off
autoRefresh: false,
// stores the GET request which refresh process list
refreshRequest: null,
// stores the timeout id returned by setTimeout
refreshTimeout: null,
// the refresh interval in seconds
refreshInterval: null,
// the refresh URL (required to save last used option)
// i.e. full or sorting url
refreshUrl: null,
/**
* Handles killing of a process
*
* @return void
*/
init: function() {
processList.setRefreshLabel();
if (processList.refreshUrl === null) {
processList.refreshUrl = 'server_status_processes.php?' +
PMA_commonParams.get('common_query');
}
if (processList.refreshInterval === null) {
processList.refreshInterval = $('#id_refreshRate').val();
} else {
$('#id_refreshRate').val(processList.refreshInterval);
}
},
/**
* Handles killing of a process
*
* @param object the event object
*
* @return void
*/
killProcessHandler: function(event) {
event.preventDefault();
var url = $(this).attr('href');
// Get row element of the process to be killed.
var $tr = $(this).closest('tr');
$.getJSON(url, function(data) {
// Check if process was killed or not.
if (data.hasOwnProperty('success') && data.success) {
// remove the row of killed process.
$tr.remove();
// As we just removed a row, reapply odd-even classes
// to keep table stripes consistent
$('#tableprocesslist > tbody > tr').filter(':even')
.removeClass('odd').addClass('even');
$('#tableprocesslist > tbody > tr').filter(':odd')
.removeClass('even').addClass('odd');
// Show process killed message
PMA_ajaxShowMessage(data.message, false);
} else {
// Show process error message
PMA_ajaxShowMessage(data.error, false);
}
});
},
/**
* Handles Auto Refreshing
*
* @param object the event object
*
* @return void
*/
refresh: function(event) {
// abort any previous pending requests
// this is necessary, it may go into
// multiple loops causing unnecessary
// requests even after leaving the page.
processList.abortRefresh();
// if auto refresh is enabled
if (processList.autoRefresh) {
var interval = parseInt(processList.refreshInterval, 10) * 1000;
processList.refreshRequest = $.get(processList.refreshUrl, {
'ajax_request': true,
'refresh': true
}, function(data) {
if (data.hasOwnProperty('success') && data.success) {
$newTable = $(data.message);
$('#tableprocesslist').html($newTable.html());
}
processList.refreshTimeout = setTimeout(
processList.refresh,
interval
);
});
}
},
/**
* Stop current request and clears timeout
*
* @return void
*/
abortRefresh: function() {
if (processList.refreshRequest !== null) {
processList.refreshRequest.abort();
processList.refreshRequest = null;
}
clearTimeout(processList.refreshTimeout);
},
/**
* Set label of refresh button
* change between play & pause
*
* @return void
*/
setRefreshLabel: function() {
var img = 'play.png';
var label = PMA_messages.strStartRefresh;
if (processList.autoRefresh) {
img = 'pause.png';
label = PMA_messages.strStopRefresh;
processList.refresh();
}
$('a#toggleRefresh').html(PMA_getImage(img) + escapeHtml(label));
}
};
AJAX.registerOnload('server_status_processes.js', function() {
processList.init();
// Bind event handler for kill_process
$('#tableprocesslist').on(
'click',
'a.kill_process',
processList.killProcessHandler
);
// Bind event handler for toggling refresh of process list
$('a#toggleRefresh').on('click', function(event) {
event.preventDefault();
processList.autoRefresh = !processList.autoRefresh;
processList.setRefreshLabel();
});
// Bind event handler for change in refresh rate
$('#id_refreshRate').on('change', function(event) {
processList.refreshInterval = $(this).val();
});
// Bind event handler for table header links
$('#tableprocesslist').on('click', 'thead a', function() {
processList.refreshUrl = $(this).attr('href');
});
});
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('server_status_processes.js', function() {
$('#tableprocesslist').off('click', 'a.kill_process');
$('a#toggleRefresh').off('click');
$('#id_refreshRate').off('change');
$('#tableprocesslist').off('click', 'thead a');
// stop refreshing further
processList.abortRefresh();
});

View File

@ -365,6 +365,10 @@ class PMA_ServerStatusData
'name' => __('Server'),
'url' => 'server_status.php'
),
array(
'name' => __('Processes'),
'url' => 'server_status_processes.php'
),
array(
'name' => __('Query statistics'),
'url' => 'server_status_queries.php'
@ -401,6 +405,40 @@ class PMA_ServerStatusData
return $retval;
}
/**
* Builds a <select> list for refresh rates
*
* @param string $name Name of select
* @param int $defaultRate Currently chosen rate
* @param array $refreshRates List of refresh rates
*
* @return string
*/
public static function getHtmlForRefreshList($name,
$defaultRate = 5,
$refreshRates = Array(1, 2, 5, 10, 20, 40, 60, 120, 300, 600)
) {
$return = '<select name="' . $name . '" id="id_' . $name
. '" class="refreshRate">';
foreach ($refreshRates as $rate) {
$selected = ($rate == $defaultRate)?' selected="selected"':'';
$return .= '<option value="' . $rate . '"' . $selected . '>';
if ($rate < 60) {
$return .= sprintf(
_ngettext('%d second', '%d seconds', $rate), $rate
);
} else {
$rate = $rate / 60;
$return .= sprintf(
_ngettext('%d minute', '%d minutes', $rate), $rate
);
}
$return .= '</option>';
}
$return .= '</select>';
return $return;
}
}
?>

View File

@ -30,9 +30,6 @@ function PMA_getHtmlForServerStatus($ServerStatusData)
//display the server state connection information
$retval .= PMA_getHtmlForServerStateConnections($ServerStatusData);
//display the server Process List information
$retval .= PMA_getHtmlForServerProcesslist($ServerStatusData);
return $retval;
}
@ -309,236 +306,4 @@ function PMA_getHtmlForServerStateConnections($ServerStatusData)
return $retval;
}
/**
* Prints Server Process list
*
* @return string
*/
function PMA_getHtmlForServerProcesslist()
{
$url_params = array();
$show_full_sql = ! empty($_REQUEST['full']);
if ($show_full_sql) {
$url_params['full'] = 1;
$full_text_link = 'server_status.php' . PMA_URL_getCommon(
array(), 'html', '?'
);
} else {
$full_text_link = 'server_status.php' . PMA_URL_getCommon(
array('full' => 1)
);
}
// This array contains display name and real column name of each
// sortable column in the table
$sortable_columns = array(
array(
'column_name' => __('ID'),
'order_by_field' => 'Id'
),
array(
'column_name' => __('User'),
'order_by_field' => 'User'
),
array(
'column_name' => __('Host'),
'order_by_field' => 'Host'
),
array(
'column_name' => __('Database'),
'order_by_field' => 'db'
),
array(
'column_name' => __('Command'),
'order_by_field' => 'Command'
),
array(
'column_name' => __('Time'),
'order_by_field' => 'Time'
),
array(
'column_name' => __('Status'),
'order_by_field' => 'State'
),
array(
'column_name' => __('SQL query'),
'order_by_field' => 'Info'
)
);
$sortableColCount = count($sortable_columns);
if (PMA_DRIZZLE) {
$left_str = 'left(p.info, '
. (int)$GLOBALS['cfg']['MaxCharactersInDisplayedSQL'] . ')';
$sql_query = "SELECT
p.id AS Id,
p.username AS User,
p.host AS Host,
p.db AS db,
p.command AS Command,
p.time AS Time,
p.state AS State,"
. ($show_full_sql ? 's.query' : $left_str )
. " AS Info FROM data_dictionary.PROCESSLIST p "
. ($show_full_sql
? 'LEFT JOIN data_dictionary.SESSIONS s ON s.session_id = p.id'
: '');
if (! empty($_REQUEST['order_by_field'])
&& ! empty($_REQUEST['sort_order'])
) {
$sql_query .= ' ORDER BY p.' . $_REQUEST['order_by_field'] . ' '
. $_REQUEST['sort_order'];
}
} else {
$sql_query = $show_full_sql
? 'SHOW FULL PROCESSLIST'
: 'SHOW PROCESSLIST';
if (! empty($_REQUEST['order_by_field'])
&& ! empty($_REQUEST['sort_order'])
) {
$sql_query = 'SELECT * FROM `INFORMATION_SCHEMA`.`PROCESSLIST` '
. 'ORDER BY `'
. $_REQUEST['order_by_field'] . '` ' . $_REQUEST['sort_order'];
}
}
$result = $GLOBALS['dbi']->query($sql_query);
$retval = '<table id="tableprocesslist" '
. 'class="data clearfloat noclick sortable">';
$retval .= '<thead>';
$retval .= '<tr>';
$retval .= '<th>' . __('Processes') . '</th>';
foreach ($sortable_columns as $column) {
$is_sorted = ! empty($_REQUEST['order_by_field'])
&& ! empty($_REQUEST['sort_order'])
&& ($_REQUEST['order_by_field'] == $column['order_by_field']);
$column['sort_order'] = 'ASC';
if ($is_sorted && $_REQUEST['sort_order'] === 'ASC') {
$column['sort_order'] = 'DESC';
}
if ($is_sorted) {
if ($_REQUEST['sort_order'] == 'ASC') {
$asc_display_style = 'inline';
$desc_display_style = 'none';
} elseif ($_REQUEST['sort_order'] == 'DESC') {
$desc_display_style = 'inline';
$asc_display_style = 'none';
}
}
$retval .= '<th>';
$columnUrl = PMA_URL_getCommon($column);
$retval .= '<a href="server_status.php' . $columnUrl . '" ';
if ($is_sorted) {
$retval .= 'onmouseout="$(\'.soimg\').toggle()" '
. 'onmouseover="$(\'.soimg\').toggle()"';
}
$retval .= '>';
$retval .= $column['column_name'];
if ($is_sorted) {
$retval .= '<img class="icon ic_s_desc soimg" alt="'
. __('Descending') . '" title="" src="themes/dot.gif" '
. 'style="display: ' . $desc_display_style . '" />';
$retval .= '<img class="icon ic_s_asc soimg hide" alt="'
. __('Ascending') . '" title="" src="themes/dot.gif" '
. 'style="display: ' . $asc_display_style . '" />';
}
$retval .= '</a>';
if (! PMA_DRIZZLE && (0 === --$sortableColCount)) {
$retval .= '<a href="' . $full_text_link . '">';
if ($show_full_sql) {
$retval .= PMA_Util::getImage(
's_partialtext.png',
__('Truncate Shown Queries')
);
} else {
$retval .= PMA_Util::getImage(
's_fulltext.png',
__('Show Full Queries')
);
}
$retval .= '</a>';
}
$retval .= '</th>';
}
$retval .= '</tr>';
$retval .= '</thead>';
$retval .= '<tbody>';
$odd_row = true;
while ($process = $GLOBALS['dbi']->fetchAssoc($result)) {
$retval .= PMA_getHtmlForServerProcessItem(
$process,
$odd_row,
$show_full_sql
);
$odd_row = ! $odd_row;
}
$retval .= '</tbody>';
$retval .= '</table>';
return $retval;
}
/**
* Prints Every Item of Server Process
*
* @param Array $process data of Every Item of Server Process
* @param bool $odd_row display odd row or not
* @param bool $show_full_sql show full sql or not
*
* @return string
*/
function PMA_getHtmlForServerProcessItem($process, $odd_row, $show_full_sql)
{
// Array keys need to modify due to the way it has used
// to display column values
if (! empty($_REQUEST['order_by_field']) && ! empty($_REQUEST['sort_order']) ) {
foreach (array_keys($process) as $key) {
$new_key = ucfirst(strtolower($key));
$process[$new_key] = $process[$key];
unset($process[$key]);
}
}
$url_params = array(
'kill' => $process['Id']
);
$kill_process = 'server_status.php' . PMA_URL_getCommon($url_params);
$retval = '<tr class="' . ($odd_row ? 'odd' : 'even') . '">';
$retval .= '<td><a href="' . $kill_process . '">' . __('Kill') . '</a></td>';
$retval .= '<td class="value">' . $process['Id'] . '</td>';
$retval .= '<td>' . htmlspecialchars($process['User']) . '</td>';
$retval .= '<td>' . htmlspecialchars($process['Host']) . '</td>';
$retval .= '<td>' . ((! isset($process['db']) || ! strlen($process['db']))
? '<i>' . __('None') . '</i>'
: htmlspecialchars($process['db'])) . '</td>';
$retval .= '<td>' . htmlspecialchars($process['Command']) . '</td>';
$retval .= '<td class="value">' . $process['Time'] . '</td>';
$processStatusStr = empty($process['State']) ? '---' : $process['State'];
$retval .= '<td>' . $processStatusStr . '</td>';
$retval .= '<td>';
if (empty($process['Info'])) {
$retval .= '---';
} else {
$retval .= PMA_Util::formatSql($process['Info'], ! $show_full_sql);
}
$retval .= '</td>';
$retval .= '</tr>';
return $retval;
}
?>

View File

@ -55,36 +55,6 @@ function PMA_getHtmlForMonitor($ServerStatusData)
return $retval;
}
/**
* Builds a <select> list for refresh rates
*
* @param string $name Name of select
* @param int $defaultRate Currently chosen rate
* @param array $refreshRates List of refresh rates
*
* @return string
*/
function PMA_getHtmlForRefreshList($name,
$defaultRate = 5,
$refreshRates = Array(1, 2, 5, 10, 20, 40, 60, 120, 300, 600)
) {
$return = '<select name="' . $name . '" id="id_' . $name
. '" class="refreshRate">';
foreach ($refreshRates as $rate) {
$selected = ($rate == $defaultRate)?' selected="selected"':'';
$return .= '<option value="' . $rate . '"' . $selected . '>';
if ($rate < 60) {
$return .= sprintf(_ngettext('%d second', '%d seconds', $rate), $rate);
} else {
$rate = $rate / 60;
$return .= sprintf(_ngettext('%d minute', '%d minutes', $rate), $rate);
}
$return .= '</option>';
}
$return .= '</select>';
return $return;
}
/**
* Returns html for Analyse Dialog
*
@ -328,7 +298,7 @@ function PMA_getHtmlForSettingsDialog()
$retval .= '<div class="clearfloat paddingtop"></div>';
$retval .= '<div class="floatleft">';
$retval .= __('Refresh rate') . '<br />';
$retval .= PMA_getHtmlForRefreshList(
$retval .= PMA_ServerStatusData::getHtmlForRefreshList(
'gridChartRefresh',
5,
Array(2, 3, 4, 5, 10, 20, 40, 60, 120, 300, 600, 1200)

View File

@ -0,0 +1,280 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* functions for displaying processes list
*
* @usedby server_status_processes.php
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
* Prints html for server status processes
*
* @return string
*/
function PMA_getHtmlForServerProcesses()
{
$notice = PMA_Message::notice(
__(
'Note: Enabling the auto refresh here might cause '
. 'heavy traffic between the web server and the MySQL server.'
)
)->getDisplay();
$retval = $notice . '<div class="tabLinks">';
$retval .= '<label>' . __('Refresh rate') . ': ';
$retval .= PMA_ServerStatusData::getHtmlForRefreshList(
'refreshRate',
5,
Array(2, 3, 4, 5, 10, 20, 40, 60, 120, 300, 600, 1200)
);
$retval .= '</label>';
$retval .= '<a id="toggleRefresh" href="#">';
$retval .= PMA_Util::getImage('play.png') . __('Start auto refresh');
$retval .= '</a>';
$retval .= '</div>';
$retval .= PMA_getHtmlForServerProcesslist();
return $retval;
}
/**
* Prints Server Process list
*
* @return string
*/
function PMA_getHtmlForServerProcesslist()
{
$url_params = array();
$show_full_sql = ! empty($_REQUEST['full']);
if ($show_full_sql) {
$url_params['full'] = 1;
$full_text_link = 'server_status_processes.php' . PMA_URL_getCommon(
array(), 'html', '?'
);
} else {
$full_text_link = 'server_status_processes.php' . PMA_URL_getCommon(
array('full' => 1)
);
}
// This array contains display name and real column name of each
// sortable column in the table
$sortable_columns = array(
array(
'column_name' => __('ID'),
'order_by_field' => 'Id'
),
array(
'column_name' => __('User'),
'order_by_field' => 'User'
),
array(
'column_name' => __('Host'),
'order_by_field' => 'Host'
),
array(
'column_name' => __('Database'),
'order_by_field' => 'db'
),
array(
'column_name' => __('Command'),
'order_by_field' => 'Command'
),
array(
'column_name' => __('Time'),
'order_by_field' => 'Time'
),
array(
'column_name' => __('Status'),
'order_by_field' => 'State'
),
array(
'column_name' => __('SQL query'),
'order_by_field' => 'Info'
)
);
$sortableColCount = count($sortable_columns);
if (PMA_DRIZZLE) {
$left_str = 'left(p.info, '
. (int)$GLOBALS['cfg']['MaxCharactersInDisplayedSQL'] . ')';
$sql_query = "SELECT
p.id AS Id,
p.username AS User,
p.host AS Host,
p.db AS db,
p.command AS Command,
p.time AS Time,
p.state AS State,"
. ($show_full_sql ? 's.query' : $left_str )
. " AS Info FROM data_dictionary.PROCESSLIST p "
. ($show_full_sql
? 'LEFT JOIN data_dictionary.SESSIONS s ON s.session_id = p.id'
: '');
if (! empty($_REQUEST['order_by_field'])
&& ! empty($_REQUEST['sort_order'])
) {
$sql_query .= ' ORDER BY p.' . $_REQUEST['order_by_field'] . ' '
. $_REQUEST['sort_order'];
}
} else {
$sql_query = $show_full_sql
? 'SHOW FULL PROCESSLIST'
: 'SHOW PROCESSLIST';
if (! empty($_REQUEST['order_by_field'])
&& ! empty($_REQUEST['sort_order'])
) {
$sql_query = 'SELECT * FROM `INFORMATION_SCHEMA`.`PROCESSLIST` '
. 'ORDER BY `'
. $_REQUEST['order_by_field'] . '` ' . $_REQUEST['sort_order'];
}
}
$result = $GLOBALS['dbi']->query($sql_query);
$retval = '<table id="tableprocesslist" '
. 'class="data clearfloat noclick sortable">';
$retval .= '<thead>';
$retval .= '<tr>';
$retval .= '<th>' . __('Processes') . '</th>';
foreach ($sortable_columns as $column) {
$is_sorted = ! empty($_REQUEST['order_by_field'])
&& ! empty($_REQUEST['sort_order'])
&& ($_REQUEST['order_by_field'] == $column['order_by_field']);
$column['sort_order'] = 'ASC';
if ($is_sorted && $_REQUEST['sort_order'] === 'ASC') {
$column['sort_order'] = 'DESC';
}
if ($is_sorted) {
if ($_REQUEST['sort_order'] == 'ASC') {
$asc_display_style = 'inline';
$desc_display_style = 'none';
} elseif ($_REQUEST['sort_order'] == 'DESC') {
$desc_display_style = 'inline';
$asc_display_style = 'none';
}
}
$retval .= '<th>';
$columnUrl = PMA_URL_getCommon($column);
$retval .= '<a href="server_status_processes.php' . $columnUrl . '" ';
if ($is_sorted) {
$retval .= 'onmouseout="$(\'.soimg\').toggle()" '
. 'onmouseover="$(\'.soimg\').toggle()"';
}
$retval .= '>';
$retval .= $column['column_name'];
if ($is_sorted) {
$retval .= '<img class="icon ic_s_desc soimg" alt="'
. __('Descending') . '" title="" src="themes/dot.gif" '
. 'style="display: ' . $desc_display_style . '" />';
$retval .= '<img class="icon ic_s_asc soimg hide" alt="'
. __('Ascending') . '" title="" src="themes/dot.gif" '
. 'style="display: ' . $asc_display_style . '" />';
}
$retval .= '</a>';
if (! PMA_DRIZZLE && (0 === --$sortableColCount)) {
$retval .= '<a href="' . $full_text_link . '">';
if ($show_full_sql) {
$retval .= PMA_Util::getImage(
's_partialtext.png',
__('Truncate Shown Queries')
);
} else {
$retval .= PMA_Util::getImage(
's_fulltext.png',
__('Show Full Queries')
);
}
$retval .= '</a>';
}
$retval .= '</th>';
}
$retval .= '</tr>';
$retval .= '</thead>';
$retval .= '<tbody>';
$odd_row = true;
while ($process = $GLOBALS['dbi']->fetchAssoc($result)) {
$retval .= PMA_getHtmlForServerProcessItem(
$process,
$odd_row,
$show_full_sql
);
$odd_row = ! $odd_row;
}
$retval .= '</tbody>';
$retval .= '</table>';
return $retval;
}
/**
* Prints Every Item of Server Process
*
* @param Array $process data of Every Item of Server Process
* @param bool $odd_row display odd row or not
* @param bool $show_full_sql show full sql or not
*
* @return string
*/
function PMA_getHtmlForServerProcessItem($process, $odd_row, $show_full_sql)
{
// Array keys need to modify due to the way it has used
// to display column values
if (! empty($_REQUEST['order_by_field']) && ! empty($_REQUEST['sort_order']) ) {
foreach (array_keys($process) as $key) {
$new_key = ucfirst(strtolower($key));
if ($new_key !== $key) {
$process[$new_key] = $process[$key];
unset($process[$key]);
}
}
}
$url_params = array(
'kill' => $process['Id'],
'ajax_request' => true
);
$kill_process = 'server_status_processes.php' . PMA_URL_getCommon($url_params);
$retval = '<tr class="' . ($odd_row ? 'odd' : 'even') . '">';
$retval .= '<td><a class="ajax kill_process" href="' . $kill_process . '">'
. __('Kill') . '</a></td>';
$retval .= '<td class="value">' . $process['Id'] . '</td>';
$retval .= '<td>' . htmlspecialchars($process['User']) . '</td>';
$retval .= '<td>' . htmlspecialchars($process['Host']) . '</td>';
$retval .= '<td>' . ((! isset($process['db']) || ! strlen($process['db']))
? '<i>' . __('None') . '</i>'
: htmlspecialchars($process['db'])) . '</td>';
$retval .= '<td>' . htmlspecialchars($process['Command']) . '</td>';
$retval .= '<td class="value">' . $process['Time'] . '</td>';
$processStatusStr = empty($process['State']) ? '---' : $process['State'];
$retval .= '<td>' . $processStatusStr . '</td>';
$retval .= '<td>';
if (empty($process['Info'])) {
$retval .= '---';
} else {
$retval .= PMA_Util::formatSql($process['Info'], ! $show_full_sql);
}
$retval .= '</td>';
$retval .= '</tr>';
return $retval;
}
?>

View File

@ -24,24 +24,6 @@ if (PMA_DRIZZLE) {
$ServerStatusData = new PMA_ServerStatusData();
/**
* Kills a selected process
*/
if (! empty($_REQUEST['kill'])) {
$query = $GLOBALS['dbi']->getKillQuery((int)$_REQUEST['kill']);
if ($GLOBALS['dbi']->tryQuery($query)) {
$message = PMA_Message::success(__('Thread %s was successfully killed.'));
} else {
$message = PMA_Message::error(
__(
'phpMyAdmin was unable to kill thread %s.'
. ' It probably has already been closed.'
)
);
}
$message->addParam($_REQUEST['kill']);
}
/**
* start output
*/

View File

@ -0,0 +1,62 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* displays the server status > processes list
*
* @package PhpMyAdmin
*/
require_once 'libraries/common.inc.php';
require_once 'libraries/server_common.inc.php';
require_once 'libraries/ServerStatusData.class.php';
require_once 'libraries/server_status_processes.lib.php';
/**
* Replication library
*/
if (PMA_DRIZZLE) {
$server_master_status = false;
$server_slave_status = false;
} else {
include_once 'libraries/replication.inc.php';
include_once 'libraries/replication_gui.lib.php';
}
$ServerStatusData = new PMA_ServerStatusData();
$response = PMA_Response::getInstance();
/**
* Kills a selected process
* on ajax request
*/
if ($response->isAjax() && !empty($_REQUEST['kill'])) {
$query = $GLOBALS['dbi']->getKillQuery((int)$_REQUEST['kill']);
if ($GLOBALS['dbi']->tryQuery($query)) {
$message = PMA_Message::success(__('Thread %s was successfully killed.'));
$response->isSuccess(true);
} else {
$message = PMA_Message::error(
__(
'phpMyAdmin was unable to kill thread %s.'
. ' It probably has already been closed.'
)
);
$response->isSuccess(false);
}
$message->addParam($_REQUEST['kill']);
$response->addJSON('message', $message);
} elseif ($response->isAjax() && !empty($_REQUEST['refresh'])) {
// Only sends the process list table
$response->addHTML(PMA_getHtmlForServerProcessList());
} else {
// Load the full page
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('server_status_processes.js');
$response->addHTML('<div>');
$response->addHTML($ServerStatusData->getMenuHtml());
$response->addHTML(PMA_getHtmlForServerProcesses());
$response->addHTML('</div>');
}
exit;
?>

View File

@ -0,0 +1,136 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Test for PMA_ServerStatusData class
*
* @package PhpMyAdmin-test
*/
/*
* Include to test.
*/
require_once 'libraries/Util.class.php';
require_once 'libraries/php-gettext/gettext.inc';
require_once 'libraries/url_generating.lib.php';
require_once 'libraries/ServerStatusData.class.php';
require_once 'libraries/database_interface.inc.php';
/**
* Test for PMA_ServerStatusData class
*
* @package PhpMyAdmin-test
*/
class PMA_ServerStatusData_Test extends PHPUnit_Framework_TestCase
{
/**
* @access protected
*/
protected $object;
/**
* Configures global environment.
*
* @return void
*/
function setup()
{
$GLOBALS['PMA_PHP_SELF'] = PMA_getenv('PHP_SELF');
$GLOBALS['cfg']['Server']['host'] = "::1";
$GLOBALS['server_master_status'] = true;
$GLOBALS['server_slave_status'] = true;
$GLOBALS['replication_types'] = array();
//Mock DBI
$dbi = $this->getMockBuilder('PMA_DatabaseInterface')
->disableOriginalConstructor()
->getMock();
//this data is needed when PMA_ServerStatusData constructs
$server_status = array(
"Aborted_clients" => "0",
"Aborted_connects" => "0",
"Com_delete_multi" => "0",
"Com_create_function" => "0",
"Com_empty_query" => 3,
"Key_blocks_used" => 2,
"Key_writes" => true,
"Key_reads" => true,
"Key_write_requests" => 5,
"Key_read_requests" => 1,
"Threads_created" => true,
"Connections" => 2,
);
$server_variables= array(
"auto_increment_increment" => "1",
"auto_increment_offset" => "1",
"automatic_sp_privileges" => "ON",
"back_log" => "50",
"big_tables" => "OFF",
"key_buffer_size" => 10,
);
$fetchResult = array(
array(
"SHOW GLOBAL STATUS",
0,
1,
null,
0,
$server_status
),
array(
"SHOW GLOBAL VARIABLES",
0,
1,
null,
0,
$server_variables
),
array(
"SELECT concat('Com_', variable_name), variable_value "
. "FROM data_dictionary.GLOBAL_STATEMENTS",
0,
1,
null,
0,
$server_status
),
);
$dbi->expects($this->any())->method('fetchResult')
->will($this->returnValueMap($fetchResult));
$GLOBALS['dbi'] = $dbi;
$this->object = new PMA_ServerStatusData();
}
/**
* tests getMenuHtml()
*
* @return void
*/
function testGetMenuHtml()
{
$html = $this->object->getMenuHtml();
$this->assertContains('Server', $html);
$this->assertContains('server_status.php', $html);
$this->assertContains('Processes', $html);
$this->assertContains('server_status_processes.php', $html);
$this->assertContains('Query statistics', $html);
$this->assertContains('server_status_queries.php', $html);
$this->assertContains('All status variables', $html);
$this->assertContains('server_status_variables.php', $html);
$this->assertContains('Monitor', $html);
$this->assertContains('server_status_monitor.php', $html);
$this->assertContains('Advisor', $html);
$this->assertContains('server_status_advisor.php', $html);
}
}

View File

@ -0,0 +1,279 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* tests for server_status_processes.lib.php
*
* @package PhpMyAdmin-test
*/
/*
* Include to test.
*/
require_once 'libraries/Util.class.php';
require_once 'libraries/php-gettext/gettext.inc';
require_once 'libraries/url_generating.lib.php';
require_once 'libraries/server_status_processes.lib.php';
require_once 'libraries/database_interface.inc.php';
require_once 'libraries/ServerStatusData.class.php';
require_once 'libraries/Message.class.php';
require_once 'libraries/Theme.class.php';
require_once 'libraries/sanitizing.lib.php';
/**
* class PMA_ServerStatusProcesses_Test
*
* this class is for testing server_status_processes.lib.php functions
*
* @package PhpMyAdmin-test
*/
class PMA_ServerStatusProcesses_Test extends PHPUnit_Framework_TestCase
{
/**
* Test for setUp
*
* @return void
*/
public function setUp()
{
$GLOBALS['cfg']['Server']['host'] = "localhost";
$GLOBALS['PMA_PHP_SELF'] = PMA_getenv('PHP_SELF');
$GLOBALS['server_master_status'] = true;
$GLOBALS['server_slave_status'] = false;
$GLOBALS['replication_types'] = array();
$GLOBALS['pmaThemeImage'] = 'image';
//$_SESSION
$_SESSION['PMA_Theme'] = PMA_Theme::load('./themes/pmahomme');
$_SESSION['PMA_Theme'] = new PMA_Theme();
//Mock DBI
$dbi = $this->getMockBuilder('PMA_DatabaseInterface')
->disableOriginalConstructor()
->getMock();
$GLOBALS['dbi'] = $dbi;
}
/**
* Test for PMA_getHtmlForServerProcesses
*
* @return void
* @group medium
*/
public function testPMAGetHtmlForServerProcesses()
{
$html = PMA_getHtmlForServerProcesses();
// Test Notice
$this->assertContains(
'Note: Enabling the auto refresh here might cause '
. 'heavy traffic between the web server and the MySQL server.',
$html
);
// Test tab links
$this->assertContains(
'<div class="tabLinks">',
$html
);
$this->assertContains(
'<a id="toggleRefresh" href="#">',
$html
);
$this->assertContains(
'play',
$html
);
$this->assertContains(
'Start auto refresh</a>',
$html
);
$this->assertContains(
'<label>Refresh rate: <select',
$html
);
$this->assertContains(
'<option value="5" selected="selected">5 seconds</option>',
$html
);
}
/**
* Test for PMA_getHtmlForServerProcesslist
*
* @return void
* @group medium
*/
public function testPMAGetHtmlForServerProcessList()
{
$process = array(
"User" => "User1",
"Host" => "Host1",
"Id" => "Id1",
"db" => "db1",
"Command" => "Command1",
"State" => "State1",
"Info" => "Info1",
"State" => "State1",
"Time" => "Time1"
);
$GLOBALS['cfg']['MaxCharactersInDisplayedSQL'] = 12;
$GLOBALS['dbi']->expects($this->any())->method('fetchAssoc')
->will($this->onConsecutiveCalls($process));
$html = PMA_getHtmlForServerProcesslist();
// Test process table
$this->assertContains(
'<table id="tableprocesslist" '
. 'class="data clearfloat noclick sortable">',
$html
);
$this->assertContains(
'<th>Processes</th>',
$html
);
$this->assertContains(
'Show Full Queries',
$html
);
$this->assertContains(
'server_status_processes.php',
$html
);
$_REQUEST['full'] = true;
$_REQUEST['sort_order'] = 'ASC';
$_REQUEST['order_by_field'] = 'db';
$_REQUEST['column_name'] = 'Database';
$html = PMA_getHtmlForServerProcesslist();
$this->assertContains(
'Truncate Shown Queries',
$html
);
$this->assertContains(
'Database',
$html
);
$this->assertContains(
'DESC',
$html
);
$_REQUEST['sort_order'] = 'DESC';
$_REQUEST['order_by_field'] = 'Host';
$_REQUEST['column_name'] = 'Host';
$html = PMA_getHtmlForServerProcesslist();
$this->assertContains(
'Host',
$html
);
$this->assertContains(
'ASC',
$html
);
}
/**
* Test for PMA_getHtmlForServerProcessItem
*
* @return void
*/
public function testPMAGetHtmlForServerProcessItem()
{
//parameters
$process = array(
"user" => "User1",
"host" => "Host1",
"id" => "Id1",
"db" => "db1",
"command" => "Command1",
"state" => "State1",
"info" => "Info1",
"state" => "State1",
"time" => "Time1",
);
$odd_row = true;
$show_full_sql = true;
$_REQUEST['sort_order'] = "desc";
$_REQUEST['order_by_field'] = "process";
$GLOBALS['cfg']['MaxCharactersInDisplayedSQL'] = 12;
//Call the test function
$html = PMA_getHtmlForServerProcessItem($process, $odd_row, $show_full_sql);
//validate 1: $kill_process
$url_params = array(
'kill' => $process['id'],
'ajax_request' => true
);
$kill_process = 'server_status_processes.php'
. PMA_URL_getCommon($url_params);
$this->assertContains(
$kill_process,
$html
);
$this->assertContains(
'ajax kill_process',
$html
);
$this->assertContains(
__('Kill'),
$html
);
//validate 2: $process['User']
$this->assertContains(
htmlspecialchars($process['user']),
$html
);
//validate 3: $process['Host']
$this->assertContains(
htmlspecialchars($process['host']),
$html
);
//validate 4: $process['db']
$this->assertContains(
__('None'),
$html
);
//validate 5: $process['Command']
$this->assertContains(
htmlspecialchars($process['command']),
$html
);
//validate 6: $process['Time']
$this->assertContains(
$process['time'],
$html
);
//validate 7: $process['state']
$this->assertContains(
$process['state'],
$html
);
//validate 8: $process['info']
$this->assertContains(
$process['info'],
$html
);
unset($process['info']);
$html = PMA_getHtmlForServerProcessItem($process, $odd_row, $show_full_sql);
$this->assertContains(
'---',
$html
);
}
}
?>

View File

@ -10,20 +10,15 @@
* Include to test.
*/
require_once 'libraries/Util.class.php';
require_once 'libraries/Advisor.class.php';
require_once 'libraries/php-gettext/gettext.inc';
require_once 'libraries/url_generating.lib.php';
require_once 'libraries/ServerStatusData.class.php';
require_once 'libraries/server_status.lib.php';
require_once 'libraries/Theme.class.php';
require_once 'libraries/database_interface.inc.php';
require_once 'libraries/Message.class.php';
require_once 'libraries/sanitizing.lib.php';
require_once 'libraries/sqlparser.lib.php';
require_once 'libraries/js_escape.lib.php';
/**
* class PMA_ServerStatusAdvisor_Test
* class PMA_ServerStatus_Test
*
* this class is for testing server_status.lib.php functions
*
@ -45,20 +40,6 @@ class PMA_ServerStatus_Test extends PHPUnit_Framework_TestCase
*/
public function setUp()
{
//$_REQUEST
$_REQUEST['log'] = "index1";
$_REQUEST['pos'] = 3;
//$GLOBALS
$GLOBALS['cfg']['MaxRows'] = 10;
$GLOBALS['cfg']['ServerDefault'] = "server";
$GLOBALS['cfg']['RememberSorting'] = true;
$GLOBALS['cfg']['SQP'] = array();
$GLOBALS['cfg']['MaxCharactersInDisplayedSQL'] = 1000;
$GLOBALS['cfg']['ShowSQL'] = true;
$GLOBALS['cfg']['TableNavigationLinksMode'] = 'icons';
$GLOBALS['cfg']['LimitChars'] = 100;
$GLOBALS['cfg']['DBG']['sql'] = false;
$GLOBALS['cfg']['Server']['host'] = "localhost";
$GLOBALS['cfg']['ShowHint'] = true;
$GLOBALS['cfg']['ActionLinksMode'] = 'icons';
@ -86,6 +67,8 @@ class PMA_ServerStatus_Test extends PHPUnit_Framework_TestCase
"Com_delete_multi" => "0",
"Com_create_function" => "0",
"Com_empty_query" => "0",
"Com_execute_sql" => 2,
"Com_stmt_execute" => 2,
);
$server_variables= array(
@ -203,6 +186,14 @@ class PMA_ServerStatus_Test extends PHPUnit_Framework_TestCase
);
//validate 3: PMA_getHtmlForServerStateConnections
$this->assertContains(
'<th colspan="2">Connections</th>',
$html
);
$this->assertContains(
'<th>&oslash; per hour</th>',
$html
);
$this->assertContains(
'<table id="serverstatusconnections" class="data noclick">',
$html
@ -216,95 +207,38 @@ class PMA_ServerStatus_Test extends PHPUnit_Framework_TestCase
'<td class="value">' . $max_used_conn,
$html
);
$this->assertContains(
'<th class="name">Failed attempts</th>',
$html
);
//Aborted_connects
$this->assertContains(
'<td class="value">' . $aborted_conn,
$html
);
}
/**
* Test for PMA_getHtmlForServerProcessItem
*
* @return void
*/
public function testPMAGetHtmlForServerProcessItem()
{
//parameters
$process = array(
"user" => "User1",
"host" => "Host1",
"id" => "Id1",
"db" => "db1",
"command" => "Command1",
"state" => "State1",
"info" => "Info1",
"state" => "State1",
"time" => "Time1",
);
$odd_row = true;
$show_full_sql = "show_full_sql";
$_REQUEST['sort_order'] = "desc";
$_REQUEST['order_by_field'] = "process";
$GLOBALS['cfg']['MaxCharactersInDisplayedSQL'] = 12;
//Call the test function
$html = PMA_getHtmlForServerProcessItem($process, $odd_row, $show_full_sql);
//validate 1: $kill_process
$url_params = array();
$url_params['kill'] = $process['id'];
$kill_process = 'server_status.php' . PMA_URL_getCommon($url_params);
$this->assertContains(
$kill_process,
$html
);
$this->assertContains(
__('Kill'),
'<th class="name">Aborted</th>',
$html
);
//validate 2: $process['User']
$GLOBALS['server_master_status'] = true;
$GLOBALS['server_slave_status'] = true;
$this->ServerStatusData->status['Connections'] = 0;
$html = PMA_getHtmlForServerStatus($this->ServerStatusData);
$this->assertContains(
htmlspecialchars($process['user']),
'This MySQL server works as <b>master</b> and <b>slave</b>',
$html
);
//validate 3: $process['Host']
$this->assertContains(
htmlspecialchars($process['host']),
$html
);
$GLOBALS['server_master_status'] = false;
$GLOBALS['server_slave_status'] = true;
$html = PMA_getHtmlForServerStatus($this->ServerStatusData);
//validate 4: $process['db']
$this->assertContains(
__('None'),
$html
);
//validate 5: $process['Command']
$this->assertContains(
htmlspecialchars($process['command']),
$html
);
//validate 6: $process['Time']
$this->assertContains(
$process['time'],
$html
);
//validate 7: $process['state']
$this->assertContains(
$process['state'],
$html
);
//validate 8: $process['info']
$this->assertContains(
$process['info'],
'This MySQL server works as <b>slave</b>',
$html
);
}
}
?>

View File

@ -1057,9 +1057,18 @@ table#chartGrid div.monitorChart {
border: none;
}
div#serverstatus div.tabLinks {
float:<?php echo $left; ?>;
padding-bottom: 10px;
div.tabLinks {
margin-left: 0.3em;
float: <?php echo $left; ?>;
padding: 5px 0px;
}
div.tabLinks a, div.tabLinks label {
margin-right: 7px;
}
div.tabLinks .icon {
margin: -0.2em 0.3em 0px 0px;
}
.popupContent {

View File

@ -720,7 +720,7 @@ div.error h1 {
div.success,
div.notice,
div.error {
margin: .5em 0 1.3em;
margin: .5em 0 0.5em;
border: 1px solid;
background-repeat: no-repeat;
<?php if ($GLOBALS['text_dir'] === 'ltr') { ?>
@ -1365,9 +1365,18 @@ table#chartGrid div.monitorChart {
border: none;
}
div#serverstatus div.tabLinks {
div.tabLinks {
margin-left: 0.3em;
float: <?php echo $left; ?>;
padding-bottom: 10px;
padding: 5px 0px;
}
div.tabLinks a, div.tabLinks label {
margin-right: 7px;
}
div.tabLinks .icon {
margin: -0.2em 0.3em 0px 0px;
}
.popupContent {