From e0f4b36c73faa9d9eae1888fbd5fc0d1d623242e Mon Sep 17 00:00:00 2001 From: Rouslan Placella Date: Fri, 10 Jun 2011 14:19:20 +0100 Subject: [PATCH] Fail safely when a requested routine is not found in the db. --- libraries/db_routines.inc.php | 495 +++++++++++++++++----------------- 1 file changed, 250 insertions(+), 245 deletions(-) diff --git a/libraries/db_routines.inc.php b/libraries/db_routines.inc.php index a80afc4235..19c88b12b5 100644 --- a/libraries/db_routines.inc.php +++ b/libraries/db_routines.inc.php @@ -374,6 +374,10 @@ function getFormInputFromRoutineName($db, $name, $all = true) $query = "SELECT $fields FROM INFORMATION_SCHEMA.ROUTINES WHERE $where;"; $routine = PMA_DBI_fetch_single_row($query); + if (! $routine) { + return false; + } + // Get required data $retval['name'] = $routine['SPECIFIC_NAME']; $retval['type'] = $routine['ROUTINE_TYPE']; @@ -1021,18 +1025,20 @@ function routineMakeRowForList($routine, $ct = 0) { // we will show a dialog to get values for these parameters, // otherwise we can execute it directly. $routine_details = getFormInputFromRoutineName($db, $routine['SPECIFIC_NAME'], false); - $execute_action = 'execute_routine'; - for ($i=0; $i<$routine_details['num_params']; $i++) { - if ($routine_details['type'] == 'PROCEDURE' && $routine_details['param_dir'][$i] == 'OUT') { - continue; + if ($routine !== false) { + $execute_action = 'execute_routine'; + for ($i=0; $i<$routine_details['num_params']; $i++) { + if ($routine_details['type'] == 'PROCEDURE' && $routine_details['param_dir'][$i] == 'OUT') { + continue; + } + $execute_action = 'execute_dialog'; + break; } - $execute_action = 'execute_dialog'; - break; + $execlink = '' . $titles['Execute'] . ''; } - $execlink = '' . $titles['Execute'] . ''; } if ($routine['ROUTINE_DEFINITION'] !== NULL) { $exprlink = ' $query) { + $resource = PMA_DBI_query($query); + while (true) { + if(! PMA_DBI_more_results()) { + break; + } + PMA_DBI_next_result(); + } + if (substr($query, 0, 6) == 'SELECT') { + $result = $resource; + } else if (substr($query, 0, 4) == 'CALL') { + $affected = PMA_DBI_affected_rows() - PMA_DBI_num_rows($resource); } } - } - if ($routine['type'] == 'PROCEDURE') { - $queries[] = "CALL " . PMA_backquote($routine['name']) - . "(" . implode(', ', $args) . ");\n"; - if (count($end_query)) { - $queries[] = "SELECT " . implode(', ', $end_query) . ";\n"; + + // If any of the queries failed, we wouldn't have gotten + // this far, so we simply show a success message. + $message = __('Your SQL query has been executed successfully'); + if ($routine['type'] == 'PROCEDURE') { + $message .= '
'; + $message .= sprintf(__('%s row(s) affected by the last statement inside the procedure'), $affected); } - } else { - $queries[] = "SELECT " . PMA_backquote($routine['name']) - . "(" . implode(', ', $args) . ") " - . "AS " . PMA_backquote($routine['name']) . ";\n"; - } - // Execute the queries - $affected = 0; - $result = null; - foreach ($queries as $num => $query) { - $resource = PMA_DBI_query($query); - while (true) { - if(! PMA_DBI_more_results()) { - break; + $message = PMA_message::success($message); + + // Pass the sql query through the "pretty printer" + // and display it. + $output = ''; + $output .= PMA_SQP_formatHtml(PMA_SQP_parse(implode($queries))); + $output .= ''; + + // Display results + if ($result) { + $output .= "
"; + $output .= sprintf(__('Execution Results of Routine %s'), + PMA_backquote(htmlspecialchars($routine['name']))); + $output .= ""; + $output .= ""; + foreach (PMA_DBI_get_fields_meta($result) as $key => $field) { + $output .= ""; } - PMA_DBI_next_result(); - } - if (substr($query, 0, 6) == 'SELECT') { - $result = $resource; - } else if (substr($query, 0, 4) == 'CALL') { - $affected = PMA_DBI_affected_rows() - PMA_DBI_num_rows($resource); - } - } - - // If any of the queries failed, we wouldn't have gotten - // this far, so we simply show a success message. - $message = __('Your SQL query has been executed successfully'); - if ($routine['type'] == 'PROCEDURE') { - $message .= '
'; - $message .= sprintf(__('%s row(s) affected by the last statement inside the procedure'), $affected); - } - $message = PMA_message::success($message); - - // Pass the sql query through the "pretty printer" - // and display it. - $output = ''; - $output .= PMA_SQP_formatHtml(PMA_SQP_parse(implode($queries))); - $output .= ''; - - // Display results - if ($result) { - $output .= "
"; - $output .= sprintf(__('Execution Results of Routine %s'), - PMA_backquote(htmlspecialchars($routine['name']))); - $output .= ""; - $output .= "
{$field->name}
"; - foreach (PMA_DBI_get_fields_meta($result) as $key => $field) { - $output .= ""; - } - $output .= ""; - // Stored routines can only ever return ONE ROW. - $data = PMA_DBI_fetch_single_row($result); - foreach ($data as $key => $value) { - if ($value === null) { - $value = 'NULL'; + $output .= ""; + // Stored routines can only ever return ONE ROW. + $data = PMA_DBI_fetch_single_row($result); + foreach ($data as $key => $value) { + if ($value === null) { + $value = 'NULL'; + } + $output .= ""; } - $output .= ""; + $output .= "
{$field->name}
$value$value
"; + } else { + $notice = __('MySQL returned an empty result set (i.e. zero rows).'); + $output .= PMA_message::notice($notice)->getDisplay(); + } + if ($GLOBALS['is_ajax_request']) { + // FIXME: STUB + } else { + echo $message->getDisplay() . $output; + unset($_POST); + // Now deliberately fall through to displaying the routines list } - $output .= ""; - } else { - $notice = __('MySQL returned an empty result set (i.e. zero rows).'); - $output .= PMA_message::notice($notice)->getDisplay(); - } - if ($GLOBALS['is_ajax_request']) { - // FIXME: STUB - } else { - echo $message->getDisplay() . $output; - unset($_POST); - // Now deliberately fall through to displaying the routines list } } else if (! empty($_GET['execute_dialog']) && ! empty($_GET['routine_name'])) { /** @@ -1187,120 +1195,113 @@ if (! empty($_REQUEST['execute_routine']) && ! empty($_REQUEST['routine_name'])) echo "\n\n

" . __("Execute Routine") . "

\n\n"; } $routine = getFormInputFromRoutineName($db, $_GET['routine_name'], false); - echo "
\n" - . "\n" - . PMA_generate_common_hidden_inputs($db, $table) . "\n"; - echo '
' . "\n" - . "{$routine['name']}\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - if ($cfg['ShowFunctionFields']) { - echo "\n"; - } - echo "\n"; - echo "\n\n"; - $ct = 0; - for ($i=0; $i<$routine['num_params']; $i++) { - $rowclass = ($ct % 2 == 0) ? 'even' : 'odd'; - if ($routine['type'] == 'PROCEDURE' && $routine['param_dir'][$i] == 'OUT') { - continue; - } - echo "\n\n"; - echo "\n"; - echo "\n"; + if ($routine !== false) { + echo "\n" + . "\n" + . PMA_generate_common_hidden_inputs($db, $table) . "\n"; + echo '
' . "\n" + . "{$routine['name']}\n"; + echo "
\n"; - echo __('Routine Parameters'); - echo "
" . __('Name') . "" . __('Type') . "" . __('Function') . "" . __('Value') . "
{$routine['param_name'][$i]}{$routine['param_type'][$i]}
\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; if ($cfg['ShowFunctionFields']) { - echo "\n"; + } + echo "\n"; + echo "\n\n"; + $ct = 0; + for ($i=0; $i<$routine['num_params']; $i++) { + $rowclass = ($ct % 2 == 0) ? 'even' : 'odd'; + if ($routine['type'] == 'PROCEDURE' && $routine['param_dir'][$i] == 'OUT') { + continue; + } + echo "\n\n"; + echo "\n"; + echo "\n"; + if ($cfg['ShowFunctionFields']) { + echo "\n"; + } + // Append a class to date/time fields so that jQuery can attach a datepicker to them + $class = ''; + if (in_array($routine['param_type'][$i], array('DATETIME', 'TIMESTAMP'))) { + $class = 'datetimefield'; + } else if ($routine['param_type'][$i] == 'DATE') { + $class = 'datefield'; + } + echo "\n"; + echo "\n"; + $ct++; } - // Append a class to date/time fields so that jQuery can attach a datepicker to them - $class = ''; - if (in_array($routine['param_type'][$i], array('DATETIME', 'TIMESTAMP'))) { - $class = 'datetimefield'; - } else if ($routine['param_type'][$i] == 'DATE') { - $class = 'datefield'; - } - echo "\n"; - echo "\n"; - $ct++; } - echo "\n
\n"; + echo __('Routine Parameters'); + echo "
" . __('Name') . "" . __('Type') . "\n"; - // Get a list of data types that are not yet supported. - $no_support_types = PMA_unsupportedDatatypes(); - if (stristr($routine['param_type'][$i], 'enum') - || stristr($routine['param_type'][$i], 'set') - || in_array(strtolower($routine['param_type'][$i]), $no_support_types)) { - echo "--\n"; - } else { - $dropdown_built = array(); - $op_spacing_needed = false; - // Find the current type in the RestrictColumnTypes. Will result in 'FUNC_CHAR' - // or something similar. Then directly look up the entry in the RestrictFunctions array, - // which will then reveal the available dropdown options - if (isset($cfg['RestrictColumnTypes'][strtoupper($routine['param_type'][$i])]) - && isset($cfg['RestrictFunctions'][$cfg['RestrictColumnTypes'][strtoupper($routine['param_type'][$i])]])) { - $current_func_type = $cfg['RestrictColumnTypes'][strtoupper($routine['param_type'][$i])]; - $dropdown = $cfg['RestrictFunctions'][$current_func_type]; + echo "" . __('Function') . "" . __('Value') . "
{$routine['param_name'][$i]}{$routine['param_type'][$i]}\n"; + // Get a list of data types that are not yet supported. + $no_support_types = PMA_unsupportedDatatypes(); + if (stristr($routine['param_type'][$i], 'enum') + || stristr($routine['param_type'][$i], 'set') + || in_array(strtolower($routine['param_type'][$i]), $no_support_types)) { + echo "--\n"; } else { - $dropdown = array(); - } - // loop on the dropdown array and print all available options for that field. - echo ""; + // loop on the dropdown array and print all available options for that field. + echo ""; + } + echo "\n"; + if (in_array($routine['param_type'][$i], array('ENUM', 'SET'))) { + $tokens = PMA_SQP_parse(html_entity_decode($routine['param_length'][$i], ENT_QUOTES)); + if ($routine['param_type'][$i] == 'ENUM') { + $input_type = 'radio'; + } else { + $input_type = 'checkbox'; + } + for ($j=0; $j<$tokens['len']; $j++) { + if ($tokens[$j]['type'] != 'punct_listsep') { + $tokens[$j]['data'] = htmlentities(PMA_unquote($tokens[$j]['data']), ENT_QUOTES); + echo "" + . "{$tokens[$j]['data']}
\n"; + } + } + } else if (in_array(strtolower($routine['param_type'][$i]), $no_support_types)) { + echo "\n"; + } else { + echo "\n"; } echo "
\n"; - if (in_array($routine['param_type'][$i], array('ENUM', 'SET'))) { - $tokens = PMA_SQP_parse(html_entity_decode($routine['param_length'][$i], ENT_QUOTES)); - if ($routine['param_type'][$i] == 'ENUM') { - $input_type = 'radio'; - } else { - $input_type = 'checkbox'; - } - for ($j=0; $j<$tokens['len']; $j++) { - if ($tokens[$j]['type'] != 'punct_listsep') { - $tokens[$j]['data'] = htmlentities(PMA_unquote($tokens[$j]['data']), ENT_QUOTES); - echo "" - . "{$tokens[$j]['data']}
\n"; - } - } - } else if (in_array(strtolower($routine['param_type'][$i]), $no_support_types)) { - echo "\n"; - } else { - echo "\n"; - } - echo "
\n"; - echo "
\n\n"; - echo "
\n" - . " \n" - . "
\n" - . "
\n\n"; - require './libraries/footer.inc.php'; - // exit; } else if (! empty($_GET['exportroutine']) && ! empty($_GET['routine_name'])) { /** * Display the export for a routine. @@ -1445,51 +1446,55 @@ if (count($routine_errors) || ( empty($_REQUEST['routine_process_addroutine']) & } if (! $operation && ! empty($_REQUEST['routine_name']) && empty($_REQUEST['routine_process_editroutine'])) { $routine = getFormInputFromRoutineName($db, $_REQUEST['routine_name']); - $routine['original_name'] = $routine['name']; - $routine['original_type'] = $routine['type']; + if ($routine !== false) { + $routine['original_name'] = $routine['name']; + $routine['original_type'] = $routine['type']; + } } else { $routine = getFormInputFromRequest(); } $mode = 'edit'; } - // Show form - $editor = displayRoutineEditor($mode, $operation, $routine, $routine_errors); - if (! empty($_REQUEST['ajax_request'])) { - $template = " \n"; - $template .= " \n"; + foreach ($param_directions as $key => $value) { + $template .= " \n"; + } + $template .= " \n"; + $template .= " $value) { + $template .= " \n"; + } + $template .= "\n \n"; + $template .= " \n"; + $template .= "
\n"; + $template .= " {$titles['Drop']}\n"; + $template .= " \n"; + $template .= " \n"; + $template .= " \n"; + $extra_data = array('title' => $title, 'param_template' => $template, 'type' => $routine['type']); + PMA_ajaxResponse($editor, true, $extra_data); } - $template .= " \n"; - $template .= " $value) { - $template .= " \n"; - } - $template .= "\n \n"; - $template .= " \n"; - $template .= " \n"; - $template .= " {$titles['Drop']}\n"; - $template .= " \n"; - $template .= " \n"; - $template .= " \n"; - $extra_data = array('title' => $title, 'param_template' => $template, 'type' => $routine['type']); - PMA_ajaxResponse($editor, true, $extra_data); + echo $editor; + require './libraries/footer.inc.php'; + // exit; } - echo $editor; - require './libraries/footer.inc.php'; - // exit; } /**