Multiple results support for SQL executions
This commit is contained in:
parent
10fb6df3d8
commit
d5acfed0e8
@ -430,6 +430,10 @@ if (! $error && isset($skip)) {
|
||||
unset($skip);
|
||||
}
|
||||
|
||||
// This array contain the data like numberof valid sql queries in the statement
|
||||
// and complete valid sql statement (which affected for rows)
|
||||
$sql_data = array('valid_sql' => array(), 'valid_queries' => 0);
|
||||
|
||||
if (! $error) {
|
||||
// Check for file existance
|
||||
require_once("libraries/plugin_interface.lib.php");
|
||||
@ -445,7 +449,7 @@ if (! $error) {
|
||||
);
|
||||
} else {
|
||||
// Do the real import
|
||||
$import_plugin->doImport();
|
||||
$import_plugin->doImport($sql_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -177,6 +177,29 @@ function PMA_DBI_try_query($query, $link = null, $options = 0,
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run multi query statement and return results
|
||||
*
|
||||
* @param string $multi_query multi query statement to execute
|
||||
* @param mysqli $link mysqli object
|
||||
*
|
||||
* @return mysqli_result collection | boolean(false)
|
||||
*/
|
||||
function PMA_DBI_try_multi_query($multi_query = '', $link = null)
|
||||
{
|
||||
|
||||
if (empty($link)) {
|
||||
if (isset($GLOBALS['userlink'])) {
|
||||
$link = $GLOBALS['userlink'];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return mysqli_multi_query($link, $multi_query);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* converts charset of a mysql message, usually coming from mysql_error(),
|
||||
* into PMA charset, usally UTF-8
|
||||
|
||||
@ -253,6 +253,19 @@ function PMA_DBI_real_query($query, $link, $options)
|
||||
return mysqli_query($link, $query, $method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the multi query and output the results
|
||||
*
|
||||
* @param mysqli $link mysqli object
|
||||
* @param string $query multi query statement to execute
|
||||
*
|
||||
* @return mysqli_result collection | boolean(false)
|
||||
*/
|
||||
function PMA_DBI_real_muli_query($link, $query)
|
||||
{
|
||||
return mysqli_multi_query($link, $query);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns array of rows with associative and numeric keys from $result
|
||||
*
|
||||
|
||||
@ -81,7 +81,7 @@ function PMA_detectCompression($filepath)
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function PMA_importRunQuery($sql = '', $full = '', $controluser = false)
|
||||
function PMA_importRunQuery($sql = '', $full = '', $controluser = false, &$sql_data = array())
|
||||
{
|
||||
global $import_run_buffer, $go_sql, $complete_query, $display_query,
|
||||
$sql_query, $my_die, $error, $reload,
|
||||
@ -108,7 +108,17 @@ function PMA_importRunQuery($sql = '', $full = '', $controluser = false)
|
||||
$GLOBALS['message'] = PMA_Message::error(__('"DROP DATABASE" statements are disabled.'));
|
||||
$error = true;
|
||||
} else {
|
||||
|
||||
$executed_queries++;
|
||||
|
||||
if ($controluser) {
|
||||
$result = PMA_queryAsControlUser(
|
||||
$import_run_buffer['sql']
|
||||
);
|
||||
} else {
|
||||
$result = PMA_DBI_try_query($import_run_buffer['sql']);
|
||||
}
|
||||
|
||||
if ($run_query
|
||||
&& $GLOBALS['finished']
|
||||
&& empty($sql)
|
||||
@ -126,6 +136,12 @@ function PMA_importRunQuery($sql = '', $full = '', $controluser = false)
|
||||
$display_query = '';
|
||||
}
|
||||
$sql_query = $import_run_buffer['sql'];
|
||||
|
||||
if ($result !== false) {
|
||||
$sql_data['valid_sql'][] = $import_run_buffer['full'];
|
||||
$sql_data['valid_queries']++;
|
||||
}
|
||||
|
||||
// If a 'USE <db>' SQL-clause was found,
|
||||
// set our current $db to the new one
|
||||
list($db, $reload) = PMA_lookForUse(
|
||||
@ -134,13 +150,7 @@ function PMA_importRunQuery($sql = '', $full = '', $controluser = false)
|
||||
$reload
|
||||
);
|
||||
} elseif ($run_query) {
|
||||
if ($controluser) {
|
||||
$result = PMA_queryAsControlUser(
|
||||
$import_run_buffer['sql']
|
||||
);
|
||||
} else {
|
||||
$result = PMA_DBI_try_query($import_run_buffer['sql']);
|
||||
}
|
||||
|
||||
$msg = '# ';
|
||||
if ($result === false) { // execution failed
|
||||
if (! isset($my_die)) {
|
||||
@ -163,6 +173,8 @@ function PMA_importRunQuery($sql = '', $full = '', $controluser = false)
|
||||
if ($a_num_rows > 0) {
|
||||
$msg .= __('Rows'). ': ' . $a_num_rows;
|
||||
$last_query_with_results = $import_run_buffer['sql'];
|
||||
$sql_data['valid_sql'][] = $import_run_buffer['sql'];
|
||||
$sql_data['valid_queries']++;
|
||||
} elseif ($a_aff_rows > 0) {
|
||||
$message = PMA_Message::affected_rows($a_aff_rows);
|
||||
$msg .= $message->getMessage();
|
||||
|
||||
@ -93,10 +93,12 @@ class ImportSql extends ImportPlugin
|
||||
|
||||
/**
|
||||
* Handles the whole import logic
|
||||
*
|
||||
* @param &$sql_data array 2-element array with sql data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function doImport()
|
||||
public function doImport(&$sql_data = array())
|
||||
{
|
||||
global $error, $timeout_passed;
|
||||
|
||||
@ -384,7 +386,9 @@ class ImportSql extends ImportPlugin
|
||||
$sql = $tmp_sql;
|
||||
PMA_importRunQuery(
|
||||
$sql,
|
||||
substr($buffer, 0, $i + strlen($sql_delimiter))
|
||||
substr($buffer, 0, $i + strlen($sql_delimiter)),
|
||||
false,
|
||||
$sql_data
|
||||
);
|
||||
$buffer = substr($buffer, $i + strlen($sql_delimiter));
|
||||
// Reset parser:
|
||||
@ -408,7 +412,7 @@ class ImportSql extends ImportPlugin
|
||||
} // End of parser loop
|
||||
} // End of import loop
|
||||
// Commit any possible data in buffers
|
||||
PMA_importRunQuery('', substr($buffer, 0, $len));
|
||||
PMA_importRunQuery();
|
||||
PMA_importRunQuery('', substr($buffer, 0, $len), false, $sql_data);
|
||||
PMA_importRunQuery('', '', false, $sql_data);
|
||||
}
|
||||
}
|
||||
248
sql.php
248
sql.php
@ -464,32 +464,11 @@ if (empty($reload)
|
||||
* @todo detect all this with the parser, to avoid problems finding
|
||||
* those strings in comments or backquoted identifiers
|
||||
*/
|
||||
|
||||
$is_explain = $is_count = $is_export = $is_delete = $is_insert = $is_affected = $is_show = $is_maint = $is_analyse = $is_group = $is_func = $is_replace = false;
|
||||
if ($is_select) { // see line 141
|
||||
$is_group = preg_match('@(GROUP[[:space:]]+BY|HAVING|SELECT[[:space:]]+DISTINCT)[[:space:]]+@i', $sql_query);
|
||||
$is_func = ! $is_group && (preg_match('@[[:space:]]+(SUM|AVG|STD|STDDEV|MIN|MAX|BIT_OR|BIT_AND)\s*\(@i', $sql_query));
|
||||
$is_count = ! $is_group && (preg_match('@^SELECT[[:space:]]+COUNT\((.*\.+)?.*\)@i', $sql_query));
|
||||
$is_export = (preg_match('@[[:space:]]+INTO[[:space:]]+OUTFILE[[:space:]]+@i', $sql_query));
|
||||
$is_analyse = (preg_match('@[[:space:]]+PROCEDURE[[:space:]]+ANALYSE@i', $sql_query));
|
||||
} elseif (preg_match('@^EXPLAIN[[:space:]]+@i', $sql_query)) {
|
||||
$is_explain = true;
|
||||
} elseif (preg_match('@^DELETE[[:space:]]+@i', $sql_query)) {
|
||||
$is_delete = true;
|
||||
$is_affected = true;
|
||||
} elseif (preg_match('@^(INSERT|LOAD[[:space:]]+DATA|REPLACE)[[:space:]]+@i', $sql_query)) {
|
||||
$is_insert = true;
|
||||
$is_affected = true;
|
||||
if (preg_match('@^(REPLACE)[[:space:]]+@i', $sql_query)) {
|
||||
$is_replace = true;
|
||||
}
|
||||
} elseif (preg_match('@^UPDATE[[:space:]]+@i', $sql_query)) {
|
||||
$is_affected = true;
|
||||
} elseif (preg_match('@^[[:space:]]*SHOW[[:space:]]+@i', $sql_query)) {
|
||||
$is_show = true;
|
||||
} elseif (preg_match('@^(CHECK|ANALYZE|REPAIR|OPTIMIZE)[[:space:]]+TABLE[[:space:]]+@i', $sql_query)) {
|
||||
$is_maint = true;
|
||||
}
|
||||
list($is_group, $is_func, $is_count, $is_export, $is_analyse, $is_explain,
|
||||
$is_delete, $is_affected, $is_insert, $is_replace, $is_show, $is_maint)
|
||||
= PMA_getDisplayPropertyParams(
|
||||
$sql_query, $is_select
|
||||
);
|
||||
|
||||
// assign default full_sql_query
|
||||
$full_sql_query = $sql_query;
|
||||
@ -937,13 +916,24 @@ if ((0 == $num_rows && 0 == $unlim_num_rows) || $is_affected) {
|
||||
$printview = isset($printview) ? $printview : null;
|
||||
$url_query = isset($url_query) ? $url_query : null;
|
||||
|
||||
$displayResultsObject->setProperties(
|
||||
$unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func,
|
||||
$is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage, $text_dir,
|
||||
$is_maint, $is_explain, $is_show, $showtable, $printview, $url_query
|
||||
);
|
||||
echo $displayResultsObject->getTable($result, $disp_mode, $analyzed_sql);
|
||||
exit();
|
||||
if (!empty($sql_data) && ($sql_data['valid_queries'] > 1)) {
|
||||
|
||||
echo getTableHtmlForMultipleQueries(
|
||||
$displayResultsObject, $db, $sql_data, $goto,
|
||||
$pmaThemeImage, $text_dir, $printview, $url_query, $disp_mode
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
$displayResultsObject->setProperties(
|
||||
$unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func,
|
||||
$is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage, $text_dir,
|
||||
$is_maint, $is_explain, $is_show, $showtable, $printview, $url_query
|
||||
);
|
||||
|
||||
echo $displayResultsObject->getTable($result, $disp_mode, $analyzed_sql);
|
||||
exit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1032,7 +1022,7 @@ if ((0 == $num_rows && 0 == $unlim_num_rows) || $is_affected) {
|
||||
}
|
||||
|
||||
// Display previous update query (from tbl_replace)
|
||||
if (isset($disp_query) && $cfg['ShowSQL'] == true) {
|
||||
if (isset($disp_query) && ($cfg['ShowSQL'] == true) && empty($sql_data)) {
|
||||
echo $common_functions->getMessage($disp_message, $disp_query, 'success');
|
||||
}
|
||||
|
||||
@ -1097,13 +1087,24 @@ $(makeProfilingChart);
|
||||
$printview = isset($printview) ? $printview : null;
|
||||
$url_query = isset($url_query) ? $url_query : null;
|
||||
|
||||
$displayResultsObject->setProperties(
|
||||
$unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func,
|
||||
$is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage, $text_dir,
|
||||
$is_maint, $is_explain, $is_show, $showtable, $printview, $url_query
|
||||
);
|
||||
echo $displayResultsObject->getTable($result, $disp_mode, $analyzed_sql);
|
||||
PMA_DBI_free_result($result);
|
||||
if (!empty($sql_data) && ($sql_data['valid_queries'] > 1)) {
|
||||
|
||||
echo getTableHtmlForMultipleQueries(
|
||||
$displayResultsObject, $db, $sql_data, $goto,
|
||||
$pmaThemeImage, $text_dir, $printview, $url_query, $disp_mode
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
$displayResultsObject->setProperties(
|
||||
$unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func,
|
||||
$is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage, $text_dir,
|
||||
$is_maint, $is_explain, $is_show, $showtable, $printview, $url_query
|
||||
);
|
||||
|
||||
echo $displayResultsObject->getTable($result, $disp_mode, $analyzed_sql);
|
||||
PMA_DBI_free_result($result);
|
||||
}
|
||||
|
||||
// BEGIN INDEX CHECK See if indexes should be checked.
|
||||
if (isset($query_type) && $query_type == 'check_tbl' && isset($selected) && is_array($selected)) {
|
||||
@ -1176,4 +1177,169 @@ $(makeProfilingChart);
|
||||
if (! isset($_REQUEST['table_maintenance'])) {
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
// These functions will need for use set the required parameters for display results
|
||||
|
||||
/**
|
||||
* Initialize some parameters needed to display results
|
||||
*
|
||||
* @param string $sql_query SQL statement
|
||||
* @param boolean $is_select select query or not
|
||||
*
|
||||
* @return array set of parameters
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function PMA_getDisplayPropertyParams($sql_query, $is_select)
|
||||
{
|
||||
|
||||
$is_explain = $is_count = $is_export = $is_delete = $is_insert = $is_affected = $is_show = $is_maint = $is_analyse = $is_group = $is_func = $is_replace = false;
|
||||
|
||||
if ($is_select) {
|
||||
$is_group = preg_match('@(GROUP[[:space:]]+BY|HAVING|SELECT[[:space:]]+DISTINCT)[[:space:]]+@i', $sql_query);
|
||||
$is_func = ! $is_group && (preg_match('@[[:space:]]+(SUM|AVG|STD|STDDEV|MIN|MAX|BIT_OR|BIT_AND)\s*\(@i', $sql_query));
|
||||
$is_count = ! $is_group && (preg_match('@^SELECT[[:space:]]+COUNT\((.*\.+)?.*\)@i', $sql_query));
|
||||
$is_export = (preg_match('@[[:space:]]+INTO[[:space:]]+OUTFILE[[:space:]]+@i', $sql_query));
|
||||
$is_analyse = (preg_match('@[[:space:]]+PROCEDURE[[:space:]]+ANALYSE@i', $sql_query));
|
||||
} elseif (preg_match('@^EXPLAIN[[:space:]]+@i', $sql_query)) {
|
||||
$is_explain = true;
|
||||
} elseif (preg_match('@^DELETE[[:space:]]+@i', $sql_query)) {
|
||||
$is_delete = true;
|
||||
$is_affected = true;
|
||||
} elseif (preg_match('@^(INSERT|LOAD[[:space:]]+DATA|REPLACE)[[:space:]]+@i', $sql_query)) {
|
||||
$is_insert = true;
|
||||
$is_affected = true;
|
||||
if (preg_match('@^(REPLACE)[[:space:]]+@i', $sql_query)) {
|
||||
$is_replace = true;
|
||||
}
|
||||
} elseif (preg_match('@^UPDATE[[:space:]]+@i', $sql_query)) {
|
||||
$is_affected = true;
|
||||
} elseif (preg_match('@^[[:space:]]*SHOW[[:space:]]+@i', $sql_query)) {
|
||||
$is_show = true;
|
||||
} elseif (preg_match('@^(CHECK|ANALYZE|REPAIR|OPTIMIZE)[[:space:]]+TABLE[[:space:]]+@i', $sql_query)) {
|
||||
$is_maint = true;
|
||||
}
|
||||
|
||||
return array(
|
||||
$is_group, $is_func, $is_count, $is_export, $is_analyse, $is_explain,
|
||||
$is_delete, $is_affected, $is_insert, $is_replace,$is_show, $is_maint
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table name in a sql query
|
||||
* If there are several tables in the SQL query,
|
||||
* first table wil lreturn
|
||||
*
|
||||
* @param string $sql SQL query
|
||||
* @param array $tables array of names in current database
|
||||
*
|
||||
* @return string $table table name
|
||||
*/
|
||||
function PMA_getTableNameBySQL($sql, $tables)
|
||||
{
|
||||
|
||||
$table = '';
|
||||
|
||||
// loop through all the tables in the database
|
||||
foreach($tables as $tbl){
|
||||
if(strpos($sql,$tbl)){
|
||||
$table .= ' ' . $tbl;
|
||||
}
|
||||
}
|
||||
|
||||
if (count(explode(' ', trim($table))) > 1) {
|
||||
$tmp_array = explode(' ', trim($table));
|
||||
return $tmp_array[0];
|
||||
}
|
||||
|
||||
return trim($table);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate table html when SQL statement have multiple queries
|
||||
* which return displayable results
|
||||
*
|
||||
* @param PMA_DisplayResults $displayResultsObject object
|
||||
* @param string $db database name
|
||||
* @param array $sql_data information about SQL statement
|
||||
* @param string $goto the URL to go back in case of errors
|
||||
* @param string $pmaThemeImage path for theme images directory
|
||||
* @param string $text_dir
|
||||
* @param string $printview
|
||||
* @param string $url_query URL query
|
||||
* @param array $disp_mode the display mode
|
||||
*
|
||||
* @return string $table_html html content
|
||||
*/
|
||||
function getTableHtmlForMultipleQueries(
|
||||
$displayResultsObject, $db, $sql_data, $goto, $pmaThemeImage,
|
||||
$text_dir, $printview, $url_query, $disp_mode
|
||||
) {
|
||||
|
||||
$table_html = '';
|
||||
|
||||
$tables_array = PMA_DBI_get_tables($db);
|
||||
$multi_sql = implode(";", $sql_data['valid_sql']);
|
||||
|
||||
$querytime_before = array_sum(explode(' ', microtime()));
|
||||
|
||||
$multiple_results = @PMA_DBI_try_multi_query($multi_sql);
|
||||
|
||||
$querytime_after = array_sum(explode(' ', microtime()));
|
||||
$querytime = $querytime_after - $querytime_before;
|
||||
$sql_no = 0;
|
||||
|
||||
do {
|
||||
|
||||
$table = PMA_getTableNameBySQL($sql_data['valid_sql'][$sql_no], $tables_array);
|
||||
$result = mysqli_store_result($GLOBALS['userlink']);
|
||||
$fields_meta = PMA_DBI_get_fields_meta($result);
|
||||
$fields_cnt = count($fields_meta);
|
||||
$parsed_sql = PMA_SQP_parse($sql_query);
|
||||
$analyzed_sql = PMA_SQP_analyze($parsed_sql);
|
||||
$is_select = isset($analyzed_sql[0]['queryflags']['select_from']);
|
||||
$unlim_num_rows = PMA_Table::countRecords($db, $table, $force_exact = true);
|
||||
$showtable = PMA_Table::sGetStatusInfo($db, $table, null, true);
|
||||
$url_query = PMA_generate_common_url($db, $table);
|
||||
|
||||
list($is_group, $is_func, $is_count, $is_export, $is_analyse,
|
||||
$is_explain, $is_delete, $is_affected, $is_insert, $is_replace,
|
||||
$is_show, $is_maint)
|
||||
= PMA_getDisplayPropertyParams(
|
||||
$sql_data['valid_sql'][$sql_no], $is_select
|
||||
);
|
||||
|
||||
if (! $is_affected) {
|
||||
$num_rows = ($result) ? @PMA_DBI_num_rows($result) : 0;
|
||||
} elseif (! isset($num_rows)) {
|
||||
$num_rows = @PMA_DBI_affected_rows();
|
||||
}
|
||||
|
||||
$displayResultsObject->__set('_db', $db);
|
||||
$displayResultsObject->__set('_table', $table);
|
||||
$displayResultsObject->__set('_goto', $goto);
|
||||
$displayResultsObject->__set('_sql_query', $sql_data['valid_sql'][$sql_no]);
|
||||
|
||||
$displayResultsObject->setProperties(
|
||||
$unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func,
|
||||
$is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage, $text_dir,
|
||||
$is_maint, $is_explain, $is_show, $showtable, $printview, $url_query
|
||||
);
|
||||
|
||||
$table_html .= $displayResultsObject->getTable($result, $disp_mode, $analyzed_sql);
|
||||
unset($result);
|
||||
$sql_no++;
|
||||
|
||||
} while (mysqli_next_result($GLOBALS['userlink']));
|
||||
|
||||
return $table_html;
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user