/**
  * @depends test_parseOneParameter
  * @dataProvider query_provider
  */
 public function test_parseAllParameters($query, $type, $target)
 {
     PMA_RTN_setGlobals();
     $this->assertEquals($target, PMA_RTN_parseAllParameters(PMA_SQP_parse($query), $type));
 }
Esempio n. 2
0
/**
 * This function will generate the values that are required to complete
 * the "Edit routine" form given the name of a routine.
 *
 * @param string $name The name of the routine.
 * @param string $type Type of routine (ROUTINE|PROCEDURE)
 * @param bool   $all  Whether to return all data or just
 *                     the info about parameters.
 *
 * @return array    Data necessary to create the routine editor.
 */
function PMA_RTN_getDataFromName($name, $type, $all = true)
{
    global $db;
    $retval = array();
    // Build and execute the query
    $fields = "SPECIFIC_NAME, ROUTINE_TYPE, DTD_IDENTIFIER, " . "ROUTINE_DEFINITION, IS_DETERMINISTIC, SQL_DATA_ACCESS, " . "ROUTINE_COMMENT, SECURITY_TYPE";
    $where = "ROUTINE_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "' " . "AND SPECIFIC_NAME='" . PMA_Util::sqlAddSlashes($name) . "'" . "AND ROUTINE_TYPE='" . PMA_Util::sqlAddSlashes($type) . "'";
    $query = "SELECT {$fields} FROM INFORMATION_SCHEMA.ROUTINES WHERE {$where};";
    $routine = PMA_DBI_fetch_single_row($query);
    if (!$routine) {
        return false;
    }
    // Get required data
    $retval['item_name'] = $routine['SPECIFIC_NAME'];
    $retval['item_type'] = $routine['ROUTINE_TYPE'];
    $parsed_query = PMA_SQP_parse(PMA_DBI_get_definition($db, $routine['ROUTINE_TYPE'], $routine['SPECIFIC_NAME']));
    $params = PMA_RTN_parseAllParameters($parsed_query, $routine['ROUTINE_TYPE']);
    $retval['item_num_params'] = $params['num'];
    $retval['item_param_dir'] = $params['dir'];
    $retval['item_param_name'] = $params['name'];
    $retval['item_param_type'] = $params['type'];
    $retval['item_param_length'] = $params['length'];
    $retval['item_param_opts_num'] = $params['opts'];
    $retval['item_param_opts_text'] = $params['opts'];
    // Get extra data
    if ($all) {
        if ($retval['item_type'] == 'FUNCTION') {
            $retval['item_type_toggle'] = 'PROCEDURE';
        } else {
            $retval['item_type_toggle'] = 'FUNCTION';
        }
        $retval['item_returntype'] = '';
        $retval['item_returnlength'] = '';
        $retval['item_returnopts_num'] = '';
        $retval['item_returnopts_text'] = '';
        if (!empty($routine['DTD_IDENTIFIER'])) {
            if (strlen($routine['DTD_IDENTIFIER']) > 63) {
                // If the DTD_IDENTIFIER string from INFORMATION_SCHEMA is
                // at least 64 characters, then it may actually have been
                // chopped because that column is a varchar(64), so we will
                // parse the output of SHOW CREATE query to get accurate
                // information about the return variable.
                $dtd = '';
                $fetching = false;
                for ($i = 0; $i < $parsed_query['len']; $i++) {
                    if ($parsed_query[$i]['type'] == 'alpha_reservedWord' && strtoupper($parsed_query[$i]['data']) == 'RETURNS') {
                        $fetching = true;
                    } else {
                        if ($fetching == true && $parsed_query[$i]['type'] == 'alpha_reservedWord') {
                            // We will not be looking for options such as UNSIGNED
                            // or ZEROFILL because there is no way that a numeric
                            // field's DTD_IDENTIFIER can be longer than 64
                            // characters. We can safely assume that the return
                            // datatype is either ENUM or SET, so we only look
                            // for CHARSET.
                            $word = strtoupper($parsed_query[$i]['data']);
                            if ($word == 'CHARSET' && ($parsed_query[$i + 1]['type'] == 'alpha_charset' || $parsed_query[$i + 1]['type'] == 'alpha_identifier')) {
                                $dtd .= $word . ' ' . $parsed_query[$i + 1]['data'];
                            }
                            break;
                        } else {
                            if ($fetching == true) {
                                $dtd .= $parsed_query[$i]['data'] . ' ';
                            }
                        }
                    }
                }
                $routine['DTD_IDENTIFIER'] = $dtd;
            }
            $returnparam = PMA_RTN_parseOneParameter($routine['DTD_IDENTIFIER']);
            $retval['item_returntype'] = $returnparam[2];
            $retval['item_returnlength'] = $returnparam[3];
            $retval['item_returnopts_num'] = $returnparam[4];
            $retval['item_returnopts_text'] = $returnparam[4];
        }
        $retval['item_definer'] = PMA_RTN_parseRoutineDefiner($parsed_query);
        $retval['item_definition'] = $routine['ROUTINE_DEFINITION'];
        $retval['item_isdeterministic'] = '';
        if ($routine['IS_DETERMINISTIC'] == 'YES') {
            $retval['item_isdeterministic'] = " checked='checked'";
        }
        $retval['item_securitytype_definer'] = '';
        $retval['item_securitytype_invoker'] = '';
        if ($routine['SECURITY_TYPE'] == 'DEFINER') {
            $retval['item_securitytype_definer'] = " selected='selected'";
        } else {
            if ($routine['SECURITY_TYPE'] == 'INVOKER') {
                $retval['item_securitytype_invoker'] = " selected='selected'";
            }
        }
        $retval['item_sqldataaccess'] = $routine['SQL_DATA_ACCESS'];
        $retval['item_comment'] = $routine['ROUTINE_COMMENT'];
    }
    return $retval;
}
Esempio n. 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['type'], PMA_Util::backquote($routine['name']));
    $type_link = "item_type={$routine['type']}";
    $retval = "        <tr class='{$rowclass}'>\n";
    $retval .= "            <td>\n";
    $retval .= '                <input type="checkbox"' . ' class="checkall" name="item_name[]"' . ' value="' . htmlspecialchars($routine['name']) . '" />';
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    $retval .= "                <span class='drop_sql hide'>" . htmlspecialchars($sql_drop) . "</span>\n";
    $retval .= "                <strong>\n";
    $retval .= "                    " . htmlspecialchars($routine['name']) . "\n";
    $retval .= "                </strong>\n";
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    // Since editing a procedure involved dropping and recreating, check also for
    // CREATE ROUTINE privilege to avoid lost procedures.
    if (PMA_Util::currentUserHasPrivilege('CREATE ROUTINE', $db)) {
        $retval .= '                <a ' . $ajax_class['edit'] . ' href="db_routines.php' . $url_query . '&amp;edit_item=1' . '&amp;item_name=' . urlencode($routine['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 the 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.
    $params = PMA_RTN_parseAllParameters(PMA_SQP_parse($GLOBALS['dbi']->getDefinition($db, $routine['type'], $routine['name'])), $routine['type']);
    if ($routine !== false) {
        if (PMA_Util::currentUserHasPrivilege('EXECUTE', $db)) {
            $execute_action = 'execute_routine';
            for ($i = 0; $i < $params['num']; $i++) {
                if ($routine['type'] == 'PROCEDURE' && $params['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['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['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['type']}\n";
    $retval .= "            </td>\n";
    $retval .= "            <td>\n";
    $retval .= "                " . htmlspecialchars($routine['returns']) . "\n";
    $retval .= "            </td>\n";
    $retval .= "        </tr>\n";
    return $retval;
}