示例#1
0
/**
 * Handles requests for executing a routine
 *
 * @return void
 */
function PMA_RTN_handleExecute()
{
    global $_GET, $_POST, $_REQUEST, $GLOBALS, $db;
    /**
     * Handle all user requests other than the default of listing routines
     */
    if (!empty($_REQUEST['execute_routine']) && !empty($_REQUEST['item_name'])) {
        // Build the queries
        $routine = PMA_RTN_getDataFromName($_REQUEST['item_name'], $_REQUEST['item_type'], false, true);
        if ($routine === false) {
            $message = __('Error in processing request:') . ' ';
            $message .= sprintf(PMA_RTE_getWord('not_found'), htmlspecialchars(PMA\libraries\Util::backquote($_REQUEST['item_name'])), htmlspecialchars(PMA\libraries\Util::backquote($db)));
            $message = Message::error($message);
            if ($GLOBALS['is_ajax_request']) {
                $response = PMA\libraries\Response::getInstance();
                $response->setRequestStatus(false);
                $response->addJSON('message', $message);
                exit;
            } else {
                echo $message->getDisplay();
                unset($_POST);
            }
        }
        $queries = array();
        $end_query = array();
        $args = array();
        $all_functions = $GLOBALS['PMA_Types']->getAllFunctions();
        for ($i = 0; $i < $routine['item_num_params']; $i++) {
            if (isset($_REQUEST['params'][$routine['item_param_name'][$i]])) {
                $value = $_REQUEST['params'][$routine['item_param_name'][$i]];
                if (is_array($value)) {
                    // is SET type
                    $value = implode(',', $value);
                }
                $value = $GLOBALS['dbi']->escapeString($value);
                if (!empty($_REQUEST['funcs'][$routine['item_param_name'][$i]]) && in_array($_REQUEST['funcs'][$routine['item_param_name'][$i]], $all_functions)) {
                    $queries[] = "SET @p{$i}=" . $_REQUEST['funcs'][$routine['item_param_name'][$i]] . "('{$value}');\n";
                } else {
                    $queries[] = "SET @p{$i}='{$value}';\n";
                }
                $args[] = "@p{$i}";
            } else {
                $args[] = "@p{$i}";
            }
            if ($routine['item_type'] == 'PROCEDURE') {
                if ($routine['item_param_dir'][$i] == 'OUT' || $routine['item_param_dir'][$i] == 'INOUT') {
                    $end_query[] = "@p{$i} AS " . PMA\libraries\Util::backquote($routine['item_param_name'][$i]);
                }
            }
        }
        if ($routine['item_type'] == 'PROCEDURE') {
            $queries[] = "CALL " . PMA\libraries\Util::backquote($routine['item_name']) . "(" . implode(', ', $args) . ");\n";
            if (count($end_query)) {
                $queries[] = "SELECT " . implode(', ', $end_query) . ";\n";
            }
        } else {
            $queries[] = "SELECT " . PMA\libraries\Util::backquote($routine['item_name']) . "(" . implode(', ', $args) . ") " . "AS " . PMA\libraries\Util::backquote($routine['item_name']) . ";\n";
        }
        // Get all the queries as one SQL statement
        $multiple_query = implode("", $queries);
        $outcome = true;
        $affected = 0;
        // Execute query
        if (!$GLOBALS['dbi']->tryMultiQuery($multiple_query)) {
            $outcome = false;
        }
        // Generate output
        if ($outcome) {
            // Pass the SQL queries through the "pretty printer"
            $output = PMA\libraries\Util::formatSql(implode($queries, "\n"));
            // Display results
            $output .= "<fieldset><legend>";
            $output .= sprintf(__('Execution results of routine %s'), PMA\libraries\Util::backquote(htmlspecialchars($routine['item_name'])));
            $output .= "</legend>";
            $nbResultsetToDisplay = 0;
            do {
                $result = $GLOBALS['dbi']->storeResult();
                $num_rows = $GLOBALS['dbi']->numRows($result);
                if ($result !== false && $num_rows > 0) {
                    $output .= "<table><tr>";
                    foreach ($GLOBALS['dbi']->getFieldsMeta($result) as $field) {
                        $output .= "<th>";
                        $output .= htmlspecialchars($field->name);
                        $output .= "</th>";
                    }
                    $output .= "</tr>";
                    $color_class = 'odd';
                    while ($row = $GLOBALS['dbi']->fetchAssoc($result)) {
                        $output .= "<tr>" . browseRow($row, $color_class) . "</tr>";
                        $color_class = $color_class == 'odd' ? 'even' : 'odd';
                    }
                    $output .= "</table>";
                    $nbResultsetToDisplay++;
                    $affected = $num_rows;
                }
                if (!$GLOBALS['dbi']->moreResults()) {
                    break;
                }
                $output .= "<br/>";
                $GLOBALS['dbi']->freeResult($result);
            } while ($GLOBALS['dbi']->nextResult());
            $output .= "</fieldset>";
            $message = __('Your SQL query has been executed successfully.');
            if ($routine['item_type'] == 'PROCEDURE') {
                $message .= '<br />';
                // TODO : message need to be modified according to the
                // output from the routine
                $message .= sprintf(_ngettext('%d row affected by the last statement inside the ' . 'procedure.', '%d rows affected by the last statement inside the ' . 'procedure.', $affected), $affected);
            }
            $message = Message::success($message);
            if ($nbResultsetToDisplay == 0) {
                $notice = __('MySQL returned an empty result set (i.e. zero rows).');
                $output .= Message::notice($notice)->getDisplay();
            }
        } else {
            $output = '';
            $message = Message::error(sprintf(__('The following query has failed: "%s"'), htmlspecialchars($multiple_query)) . '<br /><br />' . __('MySQL said: ') . $GLOBALS['dbi']->getError(null));
        }
        // Print/send output
        if ($GLOBALS['is_ajax_request']) {
            $response = PMA\libraries\Response::getInstance();
            $response->setRequestStatus($message->isSuccess());
            $response->addJSON('message', $message->getDisplay() . $output);
            $response->addJSON('dialog', false);
            exit;
        } else {
            echo $message->getDisplay(), $output;
            if ($message->isError()) {
                // At least one query has failed, so shouldn't
                // execute any more queries, so we quit.
                exit;
            }
            unset($_POST);
            // Now deliberately fall through to displaying the routines list
        }
        return;
    } else {
        if (!empty($_GET['execute_dialog']) && !empty($_GET['item_name'])) {
            /**
             * Display the execute form for a routine.
             */
            $routine = PMA_RTN_getDataFromName($_GET['item_name'], $_GET['item_type'], true, true);
            if ($routine !== false) {
                $form = PMA_RTN_getExecuteForm($routine);
                if ($GLOBALS['is_ajax_request'] == true) {
                    $title = __("Execute routine") . " " . PMA\libraries\Util::backquote(htmlentities($_GET['item_name'], ENT_QUOTES));
                    $response = PMA\libraries\Response::getInstance();
                    $response->addJSON('message', $form);
                    $response->addJSON('title', $title);
                    $response->addJSON('dialog', true);
                } else {
                    echo "\n\n<h2>" . __("Execute routine") . "</h2>\n\n";
                    echo $form;
                }
                exit;
            } else {
                if ($GLOBALS['is_ajax_request'] == true) {
                    $message = __('Error in processing request:') . ' ';
                    $message .= sprintf(PMA_RTE_getWord('not_found'), htmlspecialchars(PMA\libraries\Util::backquote($_REQUEST['item_name'])), htmlspecialchars(PMA\libraries\Util::backquote($db)));
                    $message = Message::error($message);
                    $response = PMA\libraries\Response::getInstance();
                    $response->setRequestStatus(false);
                    $response->addJSON('message', $message);
                    exit;
                }
            }
        }
    }
}
示例#2
0
/**
 * Handles requests for executing a routine
 */
function PMA_RTN_handleExecute()
{
    global $_GET, $_POST, $_REQUEST, $GLOBALS, $db, $cfg;
    /**
     * Handle all user requests other than the default of listing routines
     */
    if (!empty($_REQUEST['execute_routine']) && !empty($_REQUEST['item_name'])) {
        // Build the queries
        $routine = PMA_RTN_getDataFromName($_REQUEST['item_name'], $_REQUEST['item_type'], false);
        if ($routine !== false) {
            $queries = array();
            $end_query = array();
            $args = array();
            for ($i = 0; $i < $routine['item_num_params']; $i++) {
                if (isset($_REQUEST['params'][$routine['item_param_name'][$i]])) {
                    $value = $_REQUEST['params'][$routine['item_param_name'][$i]];
                    if (is_array($value)) {
                        // is SET type
                        $value = implode(',', $value);
                    }
                    $value = PMA_sqlAddSlashes($value);
                    if (!empty($_REQUEST['funcs'][$routine['item_param_name'][$i]]) && in_array($_REQUEST['funcs'][$routine['item_param_name'][$i]], $cfg['Functions'])) {
                        $queries[] = "SET @p{$i}={$_REQUEST['funcs'][$routine['item_param_name'][$i]]}('{$value}');\n";
                    } else {
                        $queries[] = "SET @p{$i}='{$value}';\n";
                    }
                    $args[] = "@p{$i}";
                } else {
                    $args[] = "@p{$i}";
                }
                if ($routine['item_type'] == 'PROCEDURE') {
                    if ($routine['item_param_dir'][$i] == 'OUT' || $routine['item_param_dir'][$i] == 'INOUT') {
                        $end_query[] = "@p{$i} AS " . PMA_backquote($routine['item_param_name'][$i]);
                    }
                }
            }
            if ($routine['item_type'] == 'PROCEDURE') {
                $queries[] = "CALL " . PMA_backquote($routine['item_name']) . "(" . implode(', ', $args) . ");\n";
                if (count($end_query)) {
                    $queries[] = "SELECT " . implode(', ', $end_query) . ";\n";
                }
            } else {
                $queries[] = "SELECT " . PMA_backquote($routine['item_name']) . "(" . implode(', ', $args) . ") " . "AS " . PMA_backquote($routine['item_name']) . ";\n";
            }
            // Execute the queries
            $affected = 0;
            $result = null;
            $outcome = true;
            foreach ($queries as $query) {
                $resource = PMA_DBI_try_query($query);
                if ($resource === false) {
                    $outcome = false;
                    break;
                }
                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') {
                        $result = $resource ? $resource : $result;
                        $affected = PMA_DBI_affected_rows() - PMA_DBI_num_rows($resource);
                    }
                }
            }
            // Generate output
            if ($outcome) {
                $message = __('Your SQL query has been executed successfully');
                if ($routine['item_type'] == 'PROCEDURE') {
                    $message .= '<br />';
                    $message .= sprintf(_ngettext('%d row affected by the last statement inside the procedure', '%d rows affected by the last statement inside the procedure', $affected), $affected);
                }
                $message = PMA_message::success($message);
                // Pass the SQL queries through the "pretty printer"
                $output = '<code class="sql" style="margin-bottom: 1em;">';
                $output .= PMA_SQP_formatHtml(PMA_SQP_parse(implode($queries)));
                $output .= '</code>';
                // Display results
                if ($result) {
                    $output .= "<fieldset><legend>";
                    $output .= sprintf(__('Execution results of routine %s'), PMA_backquote(htmlspecialchars($routine['item_name'])));
                    $output .= "</legend>";
                    $output .= "<table><tr>";
                    foreach (PMA_DBI_get_fields_meta($result) as $key => $field) {
                        $output .= "<th>";
                        $output .= htmlspecialchars($field->name);
                        $output .= "</th>";
                    }
                    $output .= "</tr>";
                    // Stored routines can only ever return ONE ROW.
                    $data = PMA_DBI_fetch_single_row($result);
                    foreach ($data as $key => $value) {
                        if ($value === null) {
                            $value = '<i>NULL</i>';
                        } else {
                            $value = htmlspecialchars($value);
                        }
                        $output .= "<td class='odd'>" . $value . "</td>";
                    }
                    $output .= "</table></fieldset>";
                } else {
                    $notice = __('MySQL returned an empty result set (i.e. zero rows).');
                    $output .= PMA_message::notice($notice)->getDisplay();
                }
            } else {
                $output = '';
                $message = PMA_message::error(sprintf(__('The following query has failed: "%s"'), $query) . '<br /><br />' . __('MySQL said: ') . PMA_DBI_getError(null));
            }
            // Print/send output
            if ($GLOBALS['is_ajax_request']) {
                $extra_data = array('dialog' => false);
                PMA_ajaxResponse($message->getDisplay() . $output, $message->isSuccess(), $extra_data);
            } else {
                echo $message->getDisplay() . $output;
                if ($message->isError()) {
                    // At least one query has failed, so shouldn't
                    // execute any more queries, so we quit.
                    exit;
                }
                unset($_POST);
                // Now deliberately fall through to displaying the routines list
            }
        } else {
            $message = __('Error in processing request') . ' : ';
            $message .= sprintf(PMA_RTE_getWord('not_found'), htmlspecialchars(PMA_backquote($_REQUEST['item_name'])), htmlspecialchars(PMA_backquote($db)));
            $message = PMA_message::error($message);
            if ($GLOBALS['is_ajax_request']) {
                PMA_ajaxResponse($message, $message->isSuccess());
            } else {
                echo $message->getDisplay();
                unset($_POST);
            }
        }
    } else {
        if (!empty($_GET['execute_dialog']) && !empty($_GET['item_name'])) {
            /**
             * Display the execute form for a routine.
             */
            $routine = PMA_RTN_getDataFromName($_GET['item_name'], $_GET['item_type'], true);
            if ($routine !== false) {
                $form = PMA_RTN_getExecuteForm($routine);
                if ($GLOBALS['is_ajax_request'] == true) {
                    $extra_data = array();
                    $extra_data['dialog'] = true;
                    $extra_data['title'] = __("Execute routine") . " ";
                    $extra_data['title'] .= PMA_backquote(htmlentities($_GET['item_name'], ENT_QUOTES));
                    PMA_ajaxResponse($form, true, $extra_data);
                } else {
                    echo "\n\n<h2>" . __("Execute routine") . "</h2>\n\n";
                    echo $form;
                    include './libraries/footer.inc.php';
                    // exit;
                }
            } else {
                if ($GLOBALS['is_ajax_request'] == true) {
                    $message = __('Error in processing request') . ' : ';
                    $message .= sprintf(PMA_RTE_getWord('not_found'), htmlspecialchars(PMA_backquote($_REQUEST['item_name'])), htmlspecialchars(PMA_backquote($db)));
                    $message = PMA_message::error($message);
                    PMA_ajaxResponse($message, false);
                }
            }
        }
    }
}
示例#3
0
/**
 * Creates the contents for a row in the list of routines
 *
 * @param    array    $routine    An array of routine data
 * @param    string   $rowclass   Empty or one of ['even'|'odd']
 *
 * @return   string   HTML code of a row for the list of routines
 */
function PMA_RTN_getRowForList($routine, $rowclass = '')
{
    global $ajax_class, $url_query, $db, $titles;
    $sql_drop = sprintf('DROP %s IF EXISTS %s', $routine['ROUTINE_TYPE'], PMA_backquote($routine['SPECIFIC_NAME']));
    $type_link = "item_type={$routine['ROUTINE_TYPE']}";
    $retval = "        <tr class='noclick {$rowclass}'>\n";
    $retval .= "            <td>\n";
    $retval .= "                <span class='drop_sql hide'>{$sql_drop}</span>\n";
    $retval .= "                <strong>\n";
    $retval .= "                    " . htmlspecialchars($routine['SPECIFIC_NAME']) . "\n";
    $retval .= "                </strong>\n";
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    if ($routine['ROUTINE_DEFINITION'] !== null && PMA_currentUserHasPrivilege('ALTER ROUTINE', $db) && PMA_currentUserHasPrivilege('CREATE ROUTINE', $db)) {
        $retval .= '                <a ' . $ajax_class['edit'] . ' href="db_routines.php?' . $url_query . '&amp;edit_item=1' . '&amp;item_name=' . urlencode($routine['SPECIFIC_NAME']) . '&amp;' . $type_link . '">' . $titles['Edit'] . "</a>\n";
    } else {
        $retval .= "                {$titles['NoEdit']}\n";
    }
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    if ($routine['ROUTINE_DEFINITION'] !== null && PMA_currentUserHasPrivilege('EXECUTE', $db)) {
        // Check if he routine has any input parameters. If it does,
        // we will show a dialog to get values for these parameters,
        // otherwise we can execute it directly.
        $routine_details = PMA_RTN_getDataFromName($routine['SPECIFIC_NAME'], $routine['ROUTINE_TYPE'], false);
        if ($routine !== false) {
            $execute_action = 'execute_routine';
            for ($i = 0; $i < $routine_details['item_num_params']; $i++) {
                if ($routine_details['item_type'] == 'PROCEDURE' && $routine_details['item_param_dir'][$i] == 'OUT') {
                    continue;
                }
                $execute_action = 'execute_dialog';
                break;
            }
            $retval .= '                <a ' . $ajax_class['exec'] . ' href="db_routines.php?' . $url_query . '&amp;' . $execute_action . '=1' . '&amp;item_name=' . urlencode($routine['SPECIFIC_NAME']) . '&amp;' . $type_link . '">' . $titles['Execute'] . "</a>\n";
        }
    } else {
        $retval .= "                {$titles['NoExecute']}\n";
    }
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    $retval .= '                <a ' . $ajax_class['export'] . ' href="db_routines.php?' . $url_query . '&amp;export_item=1' . '&amp;item_name=' . urlencode($routine['SPECIFIC_NAME']) . '&amp;' . $type_link . '">' . $titles['Export'] . "</a>\n";
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    if (PMA_currentUserHasPrivilege('ALTER ROUTINE', $db)) {
        $retval .= '                <a ' . $ajax_class['drop'] . ' href="sql.php?' . $url_query . '&amp;sql_query=' . urlencode($sql_drop) . '&amp;goto=db_routines.php' . urlencode("?db={$db}") . '" >' . $titles['Drop'] . "</a>\n";
    } else {
        $retval .= "                {$titles['NoDrop']}\n";
    }
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    $retval .= "                 {$routine['ROUTINE_TYPE']}\n";
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    $retval .= "                " . htmlspecialchars($routine['DTD_IDENTIFIER']) . "\n";
    $retval .= "            </td>\n";
    $retval .= "        </tr>\n";
    return $retval;
}
示例#4
0
/**
 * Creates the contents for a row in the list of routines
 *
 * @param array  $routine  An array of routine data
 * @param string $rowclass Empty or one of ['even'|'odd']
 *
 * @return string HTML code of a row for the list of routines
 */
function PMA_RTN_getRowForList($routine, $rowclass = '')
{
    global $ajax_class, $url_query, $db, $titles;
    $sql_drop = sprintf('DROP %s IF EXISTS %s', $routine['ROUTINE_TYPE'], PMA_Util::backquote($routine['SPECIFIC_NAME']));
    $type_link = "item_type={$routine['ROUTINE_TYPE']}";
    $retval = "        <tr class='noclick {$rowclass}'>\n";
    $retval .= "            <td>\n";
    $retval .= "                <span class='drop_sql hide'>" . htmlspecialchars($sql_drop) . "</span>\n";
    $retval .= "                <strong>\n";
    $retval .= "                    " . htmlspecialchars($routine['SPECIFIC_NAME']) . "\n";
    $retval .= "                </strong>\n";
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    if ($routine['ROUTINE_DEFINITION'] !== null) {
        $retval .= '                <a ' . $ajax_class['edit'] . ' href="db_routines.php?' . $url_query . '&amp;edit_item=1' . '&amp;item_name=' . urlencode($routine['SPECIFIC_NAME']) . '&amp;' . $type_link . '">' . $titles['Edit'] . "</a>\n";
    } else {
        $retval .= "                {$titles['NoEdit']}\n";
    }
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    // There is a problem with PMA_Util::currentUserHasPrivilege():
    // it does not detect all kinds of privileges, for example
    // a direct privilege on a specific routine. So, at this point,
    // we show the Execute link, hoping that the user has the correct rights.
    // Also, information_schema might be hiding the ROUTINE_DEFINITION
    // but a routine with no input parameters can be nonetheless executed.
    // Check if he routine has any input parameters. If it does,
    // we will show a dialog to get values for these parameters,
    // otherwise we can execute it directly.
    $routine_details = PMA_RTN_getDataFromName($routine['SPECIFIC_NAME'], $routine['ROUTINE_TYPE'], false);
    if ($routine !== false) {
        $execute_action = 'execute_routine';
        for ($i = 0; $i < $routine_details['item_num_params']; $i++) {
            if ($routine_details['item_type'] == 'PROCEDURE' && $routine_details['item_param_dir'][$i] == 'OUT') {
                continue;
            }
            $execute_action = 'execute_dialog';
            break;
        }
        $retval .= '                <a ' . $ajax_class['exec'] . ' href="db_routines.php?' . $url_query . '&amp;' . $execute_action . '=1' . '&amp;item_name=' . urlencode($routine['SPECIFIC_NAME']) . '&amp;' . $type_link . '">' . $titles['Execute'] . "</a>\n";
    }
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    $retval .= '                <a ' . $ajax_class['export'] . ' href="db_routines.php?' . $url_query . '&amp;export_item=1' . '&amp;item_name=' . urlencode($routine['SPECIFIC_NAME']) . '&amp;' . $type_link . '">' . $titles['Export'] . "</a>\n";
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    $retval .= '                <a ' . $ajax_class['drop'] . ' href="sql.php?' . $url_query . '&amp;sql_query=' . urlencode($sql_drop) . '&amp;goto=db_routines.php' . urlencode("?db={$db}") . '" >' . $titles['Drop'] . "</a>\n";
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    $retval .= "                 {$routine['ROUTINE_TYPE']}\n";
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    $retval .= "                " . htmlspecialchars($routine['DTD_IDENTIFIER']) . "\n";
    $retval .= "            </td>\n";
    $retval .= "        </tr>\n";
    return $retval;
}