/** * Loads user preferences * * Returns an array: * * config_data - path => value pairs * * mtime - last modification time * * type - 'db' (config read from pmadb) or 'session' (read from user session) * * @return array */ function PMA_load_userprefs() { $cfgRelation = PMA_getRelationsParam(); if (! $cfgRelation['userconfigwork']) { // no pmadb table, use session storage if (! isset($_SESSION['userconfig'])) { $_SESSION['userconfig'] = array( 'db' => array(), 'ts' => time()); } return array( 'config_data' => $_SESSION['userconfig']['db'], 'mtime' => $_SESSION['userconfig']['ts'], 'type' => 'session'); } // load configuration from pmadb $query_table = PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['userconfig']); $query = ' SELECT `config_data`, UNIX_TIMESTAMP(`timevalue`) ts FROM ' . $query_table . ' WHERE `username` = \'' . PMA_sqlAddSlashes($cfgRelation['user']) . '\''; $row = PMA_DBI_fetch_single_row($query, 'ASSOC', $GLOBALS['controllink']); return array( 'config_data' => $row ? (array)json_decode($row['config_data']) : array(), 'mtime' => $row ? $row['ts'] : time(), 'type' => 'db'); }
/** * Counts and returns (or displays) the number of records in a table * * Revision 13 July 2001: Patch for limiting dump size from * vinay@sanisoft.com & girish@sanisoft.com * * @param string the current database name * @param string the current table name * @param boolean whether to retain or to displays the result * @param boolean whether to force an exact count * * @return mixed the number of records if "retain" param is true, * otherwise true * * @access public */ public static function countRecords($db, $table, $ret = false, $force_exact = false, $is_view = null) { if (isset(PMA_Table::$cache[$db][$table]['ExactRows'])) { $row_count = PMA_Table::$cache[$db][$table]['ExactRows']; } else { $row_count = false; if (null === $is_view) { $is_view = PMA_Table::isView($db, $table); } if (!$force_exact) { if (!isset(PMA_Table::$cache[$db][$table]['Rows']) && !$is_view) { PMA_Table::$cache[$db][$table] = PMA_DBI_fetch_single_row('SHOW TABLE STATUS FROM ' . PMA_backquote($db) . ' LIKE \'' . PMA_sqlAddslashes($table, true) . '\''); } $row_count = PMA_Table::$cache[$db][$table]['Rows']; } // for a VIEW, $row_count is always false at this point if (false === $row_count || $row_count < $GLOBALS['cfg']['MaxExactCount']) { if (!$is_view) { $row_count = PMA_DBI_fetch_value('SELECT COUNT(*) FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table)); } else { // For complex views, even trying to get a partial record // count could bring down a server, so we offer an // alternative: setting MaxExactCountViews to 0 will bypass // completely the record counting for views if ($GLOBALS['cfg']['MaxExactCountViews'] == 0) { $row_count = 0; } else { // Counting all rows of a VIEW could be too long, so use // a LIMIT clause. // Use try_query because it can fail (a VIEW is based on // a table that no longer exists) $result = PMA_DBI_try_query('SELECT 1 FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table) . ' LIMIT ' . $GLOBALS['cfg']['MaxExactCountViews'], null, PMA_DBI_QUERY_STORE); if (!PMA_DBI_getError()) { $row_count = PMA_DBI_num_rows($result); PMA_DBI_free_result($result); } } } PMA_Table::$cache[$db][$table]['ExactRows'] = $row_count; } } if ($ret) { return $row_count; } /** * @deprecated at the moment nowhere is $return = false used */ // Note: as of PMA 2.8.0, we no longer seem to be using // PMA_Table::countRecords() in display mode. echo PMA_formatNumber($row_count, 0); if ($is_view) { echo ' ' . sprintf($GLOBALS['strViewHasAtLeast'], $GLOBALS['cfg']['MaxExactCount'], '[a@./Documentation.html#cfg_MaxExactCount@_blank]', '[/a]'); } }
/** * Displays the privileges form table * * @param string $db the database * @param string $table the table * @param boolean $submit wheather to display the submit button or not * * @global array $cfg the phpMyAdmin configuration * @global ressource $user_link the database connection * * @return string html snippet */ function PMA_getHtmlToDisplayPrivilegesTable($db = '*', $table = '*', $submit = true) { $html_output = ''; if ($db == '*') { $table = '*'; } if (isset($GLOBALS['username'])) { $username = $GLOBALS['username']; $hostname = $GLOBALS['hostname']; $sql_query = PMA_getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname); $row = PMA_DBI_fetch_single_row($sql_query); } if (empty($row)) { if ($table == '*') { if ($db == '*') { $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;'; } elseif ($table == '*') { $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;'; } $res = PMA_DBI_query($sql_query); while ($row1 = PMA_DBI_fetch_row($res)) { if (substr($row1[0], 0, 4) == 'max_') { $row[$row1[0]] = 0; } else { $row[$row1[0]] = 'N'; } } PMA_DBI_free_result($res); } else { $row = array('Table_priv' => ''); } } if (isset($row['Table_priv'])) { $row1 = PMA_DBI_fetch_single_row('SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';', 'ASSOC', $GLOBALS['userlink']); // note: in MySQL 5.0.3 we get "Create View', 'Show view'; // the View for Create is spelled with uppercase V // the view for Show is spelled with lowercase v // and there is a space between the words $av_grants = explode('\',\'', substr($row1['Type'], strpos($row1['Type'], '(') + 2, strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3)); unset($row1); $users_grants = explode(',', $row['Table_priv']); foreach ($av_grants as $current_grant) { $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ? 'Y' : 'N'; } unset($row['Table_priv'], $current_grant, $av_grants, $users_grants); // get columns $res = PMA_DBI_try_query('SHOW COLUMNS FROM ' . PMA_Util::backquote(PMA_Util::unescapeMysqlWildcards($db)) . '.' . PMA_Util::backquote($table) . ';'); $columns = array(); if ($res) { while ($row1 = PMA_DBI_fetch_row($res)) { $columns[$row1[0]] = array('Select' => false, 'Insert' => false, 'Update' => false, 'References' => false); } PMA_DBI_free_result($res); } unset($res, $row1); } // t a b l e - s p e c i f i c p r i v i l e g e s if (!empty($columns)) { $html_output .= PMA_getHtmlForTableSpecificPrivileges($username, $hostname, $db, $table, $columns, $row); } else { // g l o b a l o r d b - s p e c i f i c $html_output .= PMA_getHtmlForGlobalOrDbSpecificPrivs($db, $table, $row); } $html_output .= '</fieldset>' . "\n"; if ($submit) { $html_output .= '<fieldset id="fieldset_user_privtable_footer" ' . 'class="tblFooters">' . "\n" . '<input type="submit" name="update_privs" ' . 'value="' . __('Go') . '" />' . "\n" . '</fieldset>' . "\n"; } return $html_output; }
/** * 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); } } } } }
/** * Function called just after a connection to the MySQL database server has * been established. It sets the connection collation, and determins the * version of MySQL which is running. * * @param mixed $link mysql link resource|object * @param boolean $is_controluser whether link is for control user * * @return void */ function PMA_DBI_postConnect($link, $is_controluser = false) { $common_functions = PMA_CommonFunctions::getInstance(); if (!defined('PMA_MYSQL_INT_VERSION')) { if ($common_functions->cacheExists('PMA_MYSQL_INT_VERSION', true)) { define('PMA_MYSQL_INT_VERSION', $common_functions->cacheGet('PMA_MYSQL_INT_VERSION', true)); define('PMA_MYSQL_MAJOR_VERSION', $common_functions->cacheGet('PMA_MYSQL_MAJOR_VERSION', true)); define('PMA_MYSQL_STR_VERSION', $common_functions->cacheGet('PMA_MYSQL_STR_VERSION', true)); define('PMA_MYSQL_VERSION_COMMENT', $common_functions->cacheGet('PMA_MYSQL_VERSION_COMMENT', true)); } else { $version = PMA_DBI_fetch_single_row('SELECT @@version, @@version_comment', 'ASSOC', $link); if ($version) { $match = explode('.', $version['@@version']); define('PMA_MYSQL_MAJOR_VERSION', (int) $match[0]); define('PMA_MYSQL_INT_VERSION', (int) sprintf('%d%02d%02d', $match[0], $match[1], intval($match[2]))); define('PMA_MYSQL_STR_VERSION', $version['@@version']); define('PMA_MYSQL_VERSION_COMMENT', $version['@@version_comment']); } else { define('PMA_MYSQL_INT_VERSION', 50015); define('PMA_MYSQL_MAJOR_VERSION', 5); define('PMA_MYSQL_STR_VERSION', '5.00.15'); define('PMA_MYSQL_VERSION_COMMENT', ''); } $common_functions->cacheSet('PMA_MYSQL_INT_VERSION', PMA_MYSQL_INT_VERSION, true); $common_functions->cacheSet('PMA_MYSQL_MAJOR_VERSION', PMA_MYSQL_MAJOR_VERSION, true); $common_functions->cacheSet('PMA_MYSQL_STR_VERSION', PMA_MYSQL_STR_VERSION, true); $common_functions->cacheSet('PMA_MYSQL_VERSION_COMMENT', PMA_MYSQL_VERSION_COMMENT, true); } // detect Drizzle by version number: // <year>.<month>.<build number>(.<patch rev) define('PMA_DRIZZLE', PMA_MYSQL_MAJOR_VERSION >= 2009); } // Skip charsets for Drizzle if (!PMA_DRIZZLE) { if (!empty($GLOBALS['collation_connection'])) { PMA_DBI_query("SET CHARACTER SET 'utf8';", $link, PMA_DBI_QUERY_STORE); $set_collation_con_query = "SET collation_connection = '" . $common_functions->sqlAddSlashes($GLOBALS['collation_connection']) . "';"; PMA_DBI_query($set_collation_con_query, $link, PMA_DBI_QUERY_STORE); } else { PMA_DBI_query("SET NAMES 'utf8' COLLATE 'utf8_general_ci';", $link, PMA_DBI_QUERY_STORE); } } // Cache plugin list for Drizzle if (PMA_DRIZZLE && !$common_functions->cacheExists('drizzle_engines', true)) { $sql = "SELECT p.plugin_name, m.module_library\n FROM data_dictionary.plugins p\n JOIN data_dictionary.modules m USING (module_name)\n WHERE p.plugin_type = 'StorageEngine'\n AND p.plugin_name NOT IN ('FunctionEngine', 'schema')\n AND p.is_active = 'YES'"; $engines = PMA_DBI_fetch_result($sql, 'plugin_name', null, $link); $common_functions->cacheSet('drizzle_engines', $engines, true); } }
/** * Gets the display field of a table * * @param string $db the name of the db to check for * @param string $table the name of the table to check for * * @return string field name * * @access public */ function PMA_getDisplayField($db, $table) { $cfgRelation = PMA_getRelationsParam(); /** * Try to fetch the display field from DB. */ if ($cfgRelation['displaywork']) { $disp_query = ' SELECT `display_field` FROM ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['table_info']) . ' WHERE `db_name` = \'' . PMA_sqlAddSlashes($db) . '\' AND `table_name` = \'' . PMA_sqlAddSlashes($table) . '\''; $row = PMA_DBI_fetch_single_row($disp_query, 'ASSOC', $GLOBALS['controllink']); if (isset($row['display_field'])) { return $row['display_field']; } } /** * Emulating the display field for some information_schema tables. */ if ($db == 'information_schema') { switch ($table) { case 'CHARACTER_SETS': return 'DESCRIPTION'; case 'TABLES': return 'TABLE_COMMENT'; } } /** * No Luck... */ return false; }
$exp = array('kb' => 1, 'kib' => 1, 'mb' => 2, 'mib' => 2, 'gb' => 3, 'gib' => 3); $value = floatval($matches[1]) * pow(1024, $exp[strtolower($matches[3])]); } else { $value = PMA_sqlAddslashes($value); } if (! is_numeric($value)) { $value="'" . $value . "'"; } if (! preg_match("/[^a-zA-Z0-9_]+/", $_REQUEST['varName']) && PMA_DBI_query('SET GLOBAL ' . $_REQUEST['varName'] . ' = ' . $value) ) { // Some values are rounded down etc. $varValue = PMA_DBI_fetch_single_row( 'SHOW GLOBAL VARIABLES WHERE Variable_name="' . PMA_sqlAddslashes($_REQUEST['varName']) . '";', 'NUM' ); exit( json_encode( array( 'success' => true, 'variable' => formatVariable($_REQUEST['varName'], $varValue[1]) ) ) ); } exit( json_encode( array(
/** * Displays the privileges form table * * @param string $db the database * @param string $table the table * @param boolean $submit wheather to display the submit button or not * * @global array $cfg the phpMyAdmin configuration * @global ressource $user_link the database connection * * @return void */ function PMA_displayPrivTable($db = '*', $table = '*', $submit = true) { global $random_n; if ($db == '*') { $table = '*'; } if (isset($GLOBALS['username'])) { $username = $GLOBALS['username']; $hostname = $GLOBALS['hostname']; if ($db == '*') { $sql_query = "SELECT * FROM `mysql`.`user`" ." WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'" ." AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "';"; } elseif ($table == '*') { $sql_query = "SELECT * FROM `mysql`.`db`" ." WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'" ." AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "'" ." AND '" . PMA_unescape_mysql_wildcards($db) . "'" ." LIKE `Db`;"; } else { $sql_query = "SELECT `Table_priv`" ." FROM `mysql`.`tables_priv`" ." WHERE `User` = '" . PMA_sqlAddSlashes($username) . "'" ." AND `Host` = '" . PMA_sqlAddSlashes($hostname) . "'" ." AND `Db` = '" . PMA_unescape_mysql_wildcards($db) . "'" ." AND `Table_name` = '" . PMA_sqlAddSlashes($table) . "';"; } $row = PMA_DBI_fetch_single_row($sql_query); } if (empty($row)) { if ($table == '*') { if ($db == '*') { $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;'; } elseif ($table == '*') { $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;'; } $res = PMA_DBI_query($sql_query); while ($row1 = PMA_DBI_fetch_row($res)) { if (substr($row1[0], 0, 4) == 'max_') { $row[$row1[0]] = 0; } else { $row[$row1[0]] = 'N'; } } PMA_DBI_free_result($res); } else { $row = array('Table_priv' => ''); } } if (isset($row['Table_priv'])) { $row1 = PMA_DBI_fetch_single_row( 'SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';', 'ASSOC', $GLOBALS['userlink'] ); // note: in MySQL 5.0.3 we get "Create View', 'Show view'; // the View for Create is spelled with uppercase V // the view for Show is spelled with lowercase v // and there is a space between the words $av_grants = explode( '\',\'', substr( $row1['Type'], strpos($row1['Type'], '(') + 2, strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3 ) ); unset($row1); $users_grants = explode(',', $row['Table_priv']); foreach ($av_grants as $current_grant) { $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ? 'Y' : 'N'; } unset($row['Table_priv'], $current_grant, $av_grants, $users_grants); // get collumns $res = PMA_DBI_try_query( 'SHOW COLUMNS FROM ' . PMA_backquote(PMA_unescape_mysql_wildcards($db)) . '.' . PMA_backquote($table) . ';' ); $columns = array(); if ($res) { while ($row1 = PMA_DBI_fetch_row($res)) { $columns[$row1[0]] = array( 'Select' => false, 'Insert' => false, 'Update' => false, 'References' => false ); } PMA_DBI_free_result($res); } unset($res, $row1); } // t a b l e - s p e c i f i c p r i v i l e g e s if (! empty($columns)) { $res = PMA_DBI_query( 'SELECT `Column_name`, `Column_priv`' .' FROM `mysql`.`columns_priv`' .' WHERE `User`' .' = \'' . PMA_sqlAddSlashes($username) . "'" .' AND `Host`' .' = \'' . PMA_sqlAddSlashes($hostname) . "'" .' AND `Db`' .' = \'' . PMA_sqlAddSlashes(PMA_unescape_mysql_wildcards($db)) . "'" .' AND `Table_name`' .' = \'' . PMA_sqlAddSlashes($table) . '\';' ); while ($row1 = PMA_DBI_fetch_row($res)) { $row1[1] = explode(',', $row1[1]); foreach ($row1[1] as $current) { $columns[$row1[0]][$current] = true; } } PMA_DBI_free_result($res); unset($res, $row1, $current); echo '<input type="hidden" name="grant_count" value="' . count($row) . '" />' . "\n" . '<input type="hidden" name="column_count" value="' . count($columns) . '" />' . "\n" . '<fieldset id="fieldset_user_priv">' . "\n" . ' <legend>' . __('Table-specific privileges') . PMA_showHint(__('Note: MySQL privilege names are expressed in English')) . '</legend>' . "\n"; // privs that are attached to a specific column PMA_displayColumnPrivs( $columns, $row, 'Select_priv', 'SELECT', 'select', __('Allows reading data.'), 'Select' ); PMA_displayColumnPrivs( $columns, $row, 'Insert_priv', 'INSERT', 'insert', __('Allows inserting and replacing data.'), 'Insert' ); PMA_displayColumnPrivs( $columns, $row, 'Update_priv', 'UPDATE', 'update', __('Allows changing data.'), 'Update' ); PMA_displayColumnPrivs( $columns, $row, 'References_priv', 'REFERENCES', 'references', __('Has no effect in this MySQL version.'), 'References' ); // privs that are not attached to a specific column echo ' <div class="item">' . "\n"; foreach ($row as $current_grant => $current_grant_value) { $grant_type = substr($current_grant, 0, (strlen($current_grant) - 5)); if (in_array($grant_type, array('Select', 'Insert', 'Update', 'References'))) { continue; } // make a substitution to match the messages variables; // also we must substitute the grant we get, because we can't generate // a form variable containing blanks (those would get changed to // an underscore when receiving the POST) if ($current_grant == 'Create View_priv') { $tmp_current_grant = 'CreateView_priv'; $current_grant = 'Create_view_priv'; } elseif ($current_grant == 'Show view_priv') { $tmp_current_grant = 'ShowView_priv'; $current_grant = 'Show_view_priv'; } else { $tmp_current_grant = $current_grant; } echo ' <div class="item">' . "\n" . ' <input type="checkbox"' . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"') . ' name="' . $current_grant . '" id="checkbox_' . $current_grant . '" value="Y" ' . ($current_grant_value == 'Y' ? 'checked="checked" ' : '') . 'title="'; echo (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]) ? $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))] : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl']) . '"/>' . "\n"; echo ' <label for="checkbox_' . $current_grant . '"><code><dfn title="' . (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))]) ? $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5))] : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, (strlen($tmp_current_grant) - 5)) . 'Tbl']) . '">' . strtoupper(substr($current_grant, 0, strlen($current_grant) - 5)) . '</dfn></code></label>' . "\n" . ' </div>' . "\n"; } // end foreach () echo ' </div>' . "\n"; // for Safari 2.0.2 echo ' <div class="clearfloat"></div>' . "\n"; } else { // g l o b a l o r d b - s p e c i f i c // $privTable_names = array(0 => __('Data'), 1 => __('Structure'), 2 => __('Administration')); // d a t a $privTable[0] = array( array('Select', 'SELECT', __('Allows reading data.')), array('Insert', 'INSERT', __('Allows inserting and replacing data.')), array('Update', 'UPDATE', __('Allows changing data.')), array('Delete', 'DELETE', __('Allows deleting data.')) ); if ($db == '*') { $privTable[0][] = array('File', 'FILE', __('Allows importing data from and exporting data into files.')); } // s t r u c t u r e $privTable[1] = array( array('Create', 'CREATE', ($table == '*' ? __('Allows creating new databases and tables.') : __('Allows creating new tables.'))), array('Alter', 'ALTER', __('Allows altering the structure of existing tables.')), array('Index', 'INDEX', __('Allows creating and dropping indexes.')), array('Drop', 'DROP', ($table == '*' ? __('Allows dropping databases and tables.') : __('Allows dropping tables.'))), array('Create_tmp_table', 'CREATE TEMPORARY TABLES', __('Allows creating temporary tables.')), array('Show_view', 'SHOW VIEW', __('Allows performing SHOW CREATE VIEW queries.')), array('Create_routine', 'CREATE ROUTINE', __('Allows creating stored routines.')), array('Alter_routine', 'ALTER ROUTINE', __('Allows altering and dropping stored routines.')), array('Execute', 'EXECUTE', __('Allows executing stored routines.')), ); // this one is for a db-specific priv: Create_view_priv if (isset($row['Create_view_priv'])) { $privTable[1][] = array('Create_view', 'CREATE VIEW', __('Allows creating new views.')); } // this one is for a table-specific priv: Create View_priv if (isset($row['Create View_priv'])) { $privTable[1][] = array('Create View', 'CREATE VIEW', __('Allows creating new views.')); } if (isset($row['Event_priv'])) { // MySQL 5.1.6 $privTable[1][] = array('Event', 'EVENT', __('Allows to set up events for the event scheduler')); $privTable[1][] = array('Trigger', 'TRIGGER', __('Allows creating and dropping triggers')); } // a d m i n i s t r a t i o n $privTable[2] = array( array('Grant', 'GRANT', __('Allows adding users and privileges without reloading the privilege tables.')), ); if ($db == '*') { $privTable[2][] = array('Super', 'SUPER', __('Allows connecting, even if maximum number of connections is reached; required for most administrative operations like setting global variables or killing threads of other users.')); $privTable[2][] = array('Process', 'PROCESS', __('Allows viewing processes of all users')); $privTable[2][] = array('Reload', 'RELOAD', __('Allows reloading server settings and flushing the server\'s caches.')); $privTable[2][] = array('Shutdown', 'SHUTDOWN', __('Allows shutting down the server.')); $privTable[2][] = array('Show_db', 'SHOW DATABASES', __('Gives access to the complete list of databases.')); } $privTable[2][] = array('Lock_tables', 'LOCK TABLES', __('Allows locking tables for the current thread.')); $privTable[2][] = array('References', 'REFERENCES', __('Has no effect in this MySQL version.')); if ($db == '*') { $privTable[2][] = array('Repl_client', 'REPLICATION CLIENT', __('Allows the user to ask where the slaves / masters are.')); $privTable[2][] = array('Repl_slave', 'REPLICATION SLAVE', __('Needed for the replication slaves.')); $privTable[2][] = array('Create_user', 'CREATE USER', __('Allows creating, dropping and renaming user accounts.')); } echo '<input type="hidden" name="grant_count" value="' . (count($privTable[0]) + count($privTable[1]) + count($privTable[2]) - (isset($row['Grant_priv']) ? 1 : 0)) . '" />' . "\n" . '<fieldset id="fieldset_user_global_rights">' . "\n" . ' <legend>' . "\n" . ' ' . ($db == '*' ? __('Global privileges') : ($table == '*' ? __('Database-specific privileges') : __('Table-specific privileges'))) . "\n" . ' (<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&checkall=1" onclick="setCheckboxes(\'addUsersForm_' . $random_n . '\', true); return false;">' . __('Check All') . '</a> /' . "\n" . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '" onclick="setCheckboxes(\'addUsersForm_' . $random_n . '\', false); return false;">' . __('Uncheck All') . '</a>)' . "\n" . ' </legend>' . "\n" . ' <p><small><i>' . __('Note: MySQL privilege names are expressed in English') . '</i></small></p>' . "\n"; // Output the Global privilege tables with checkboxes foreach ($privTable as $i => $table) { echo ' <fieldset>' . "\n" . ' <legend>' . __($privTable_names[$i]) . '</legend>' . "\n"; foreach ($table as $priv) { echo ' <div class="item">' . "\n" . ' <input type="checkbox"' . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0] . '_priv"' . ' value="Y" title="' . $priv[2] . '"' . ((! empty($GLOBALS['checkall']) || $row[$priv[0] . '_priv'] == 'Y') ? ' checked="checked"' : '') . '/>' . "\n" . ' <label for="checkbox_' . $priv[0] . '_priv"><code><dfn title="' . $priv[2] . '">' . $priv[1] . '</dfn></code></label>' . "\n" . ' </div>' . "\n"; } echo ' </fieldset>' . "\n"; } // The "Resource limits" box is not displayed for db-specific privs if ($db == '*') { echo ' <fieldset>' . "\n" . ' <legend>' . __('Resource limits') . '</legend>' . "\n" . ' <p><small><i>' . __('Note: Setting these options to 0 (zero) removes the limit.') . '</i></small></p>' . "\n" . ' <div class="item">' . "\n" . ' <label for="text_max_questions"><code><dfn title="' . __('Limits the number of queries the user may send to the server per hour.') . '">MAX QUERIES PER HOUR</dfn></code></label>' . "\n" . ' <input type="text" name="max_questions" id="text_max_questions" value="' . $row['max_questions'] . '" size="11" maxlength="11" title="' . __('Limits the number of queries the user may send to the server per hour.') . '" />' . "\n" . ' </div>' . "\n" . ' <div class="item">' . "\n" . ' <label for="text_max_updates"><code><dfn title="' . __('Limits the number of commands that change any table or database the user may execute per hour.') . '">MAX UPDATES PER HOUR</dfn></code></label>' . "\n" . ' <input type="text" name="max_updates" id="text_max_updates" value="' . $row['max_updates'] . '" size="11" maxlength="11" title="' . __('Limits the number of commands that change any table or database the user may execute per hour.') . '" />' . "\n" . ' </div>' . "\n" . ' <div class="item">' . "\n" . ' <label for="text_max_connections"><code><dfn title="' . __('Limits the number of new connections the user may open per hour.') . '">MAX CONNECTIONS PER HOUR</dfn></code></label>' . "\n" . ' <input type="text" name="max_connections" id="text_max_connections" value="' . $row['max_connections'] . '" size="11" maxlength="11" title="' . __('Limits the number of new connections the user may open per hour.') . '" />' . "\n" . ' </div>' . "\n" . ' <div class="item">' . "\n" . ' <label for="text_max_user_connections"><code><dfn title="' . __('Limits the number of simultaneous connections the user may have.') . '">MAX USER_CONNECTIONS</dfn></code></label>' . "\n" . ' <input type="text" name="max_user_connections" id="text_max_user_connections" value="' . $row['max_user_connections'] . '" size="11" maxlength="11" title="' . __('Limits the number of simultaneous connections the user may have.') . '" />' . "\n" . ' </div>' . "\n" . ' </fieldset>' . "\n"; } // for Safari 2.0.2 echo ' <div class="clearfloat"></div>' . "\n"; } echo '</fieldset>' . "\n"; if ($submit) { echo '<fieldset id="fieldset_user_privtable_footer" class="tblFooters">' . "\n" . ' <input type="submit" name="update_privs" value="' . __('Go') . '" />' . "\n" . '</fieldset>' . "\n"; } } // end of the 'PMA_displayPrivTable()' function
/** * This function will generate the values that are required to complete * the "Edit event" form given the name of a event. * * @param string $name The name of the event. * * @return array Data necessary to create the editor. */ function PMA_EVN_getDataFromName($name) { global $db; $retval = array(); $columns = "`EVENT_NAME`, `STATUS`, `EVENT_TYPE`, `EXECUTE_AT`, " . "`INTERVAL_VALUE`, `INTERVAL_FIELD`, `STARTS`, `ENDS`, " . "`EVENT_DEFINITION`, `ON_COMPLETION`, `DEFINER`, `EVENT_COMMENT`"; $where = "EVENT_SCHEMA='" . PMA_sqlAddSlashes($db) . "' " . "AND EVENT_NAME='" . PMA_sqlAddSlashes($name) . "'"; $query = "SELECT {$columns} FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE {$where};"; $item = PMA_DBI_fetch_single_row($query); if (!$item) { return false; } $retval['item_name'] = $item['EVENT_NAME']; $retval['item_status'] = $item['STATUS']; $retval['item_type'] = $item['EVENT_TYPE']; if ($retval['item_type'] == 'RECURRING') { $retval['item_type_toggle'] = 'ONE TIME'; } else { $retval['item_type_toggle'] = 'RECURRING'; } $retval['item_execute_at'] = $item['EXECUTE_AT']; $retval['item_interval_value'] = $item['INTERVAL_VALUE']; $retval['item_interval_field'] = $item['INTERVAL_FIELD']; $retval['item_starts'] = $item['STARTS']; $retval['item_ends'] = $item['ENDS']; $retval['item_preserve'] = ''; if ($item['ON_COMPLETION'] == 'PRESERVE') { $retval['item_preserve'] = " checked='checked'"; } $retval['item_definition'] = $item['EVENT_DEFINITION']; $retval['item_definer'] = $item['DEFINER']; $retval['item_comment'] = $item['EVENT_COMMENT']; return $retval; }
/** * Get the current column value in the form for different data types * * @param string $possibly_uploaded_val uploaded file content * @param string $key an md5 of the column name * @param array $multi_edit_columns_type array of multi edit column types * @param string $current_value current column value in the form * @param array $multi_edit_auto_increment multi edit auto increment * @param string $rownumber index of where clause array * @param array $multi_edit_columns_name multi edit column names array * @param array $multi_edit_columns_null multi edit columns null array * @param array $multi_edit_columns_null_prev multi edit columns previous null * @param boolean $is_insert whether insert or not * @param boolean $using_key whether editing or new row * @param array $where_clause where clauses * @param string $table table name * * @return string $current_value current column value in the form */ function PMA_getCurrentValueForDifferentTypes($possibly_uploaded_val, $key, $multi_edit_columns_type, $current_value, $multi_edit_auto_increment, $rownumber, $multi_edit_columns_name, $multi_edit_columns_null, $multi_edit_columns_null_prev, $is_insert, $using_key, $where_clause, $table) { // Fetch the current values of a row to use in case we have a protected field if ($is_insert && $using_key && isset($multi_edit_columns_type) && is_array($multi_edit_columns_type) && isset($where_clause)) { $protected_row = PMA_DBI_fetch_single_row('SELECT * FROM ' . PMA_Util::backquote($table) . ' WHERE ' . $where_clause . ';'); } if (false !== $possibly_uploaded_val) { $current_value = $possibly_uploaded_val; } else { // c o l u m n v a l u e i n t h e f o r m if (isset($multi_edit_columns_type[$key])) { $type = $multi_edit_columns_type[$key]; } else { $type = ''; } if ($type != 'protected' && $type != 'set' && 0 === strlen($current_value)) { // best way to avoid problems in strict mode // (works also in non-strict mode) if (isset($multi_edit_auto_increment) && isset($multi_edit_auto_increment[$key])) { $current_value = 'NULL'; } else { $current_value = "''"; } } elseif ($type == 'set') { if (!empty($_REQUEST['fields']['multi_edit'][$rownumber][$key])) { $current_value = implode(',', $_REQUEST['fields']['multi_edit'][$rownumber][$key]); $current_value = "'" . PMA_Util::sqlAddSlashes($current_value) . "'"; } else { $current_value = "''"; } } elseif ($type == 'protected') { // here we are in protected mode (asked in the config) // so tbl_change has put this special value in the // coulmns array, so we do not change the column value // but we can still handle column upload // when in UPDATE mode, do not alter field's contents. When in INSERT // mode, insert empty field because no values were submitted. // If protected blobs where set, insert original fields content. if (!empty($protected_row[$multi_edit_columns_name[$key]])) { $current_value = '0x' . bin2hex($protected_row[$multi_edit_columns_name[$key]]); } else { $current_value = ''; } } elseif ($type == 'bit') { $current_value = preg_replace('/[^01]/', '0', $current_value); $current_value = "b'" . PMA_Util::sqlAddSlashes($current_value) . "'"; } elseif (!($type == 'datetime' || $type == 'timestamp') || $current_value != 'CURRENT_TIMESTAMP') { $current_value = "'" . PMA_Util::sqlAddSlashes($current_value) . "'"; } // Was the Null checkbox checked for this field? // (if there is a value, we ignore the Null checkbox: this could // be possible if Javascript is disabled in the browser) if (!empty($multi_edit_columns_null[$key]) && ($current_value == "''" || $current_value == '')) { $current_value = 'NULL'; } // The Null checkbox was unchecked for this field if (empty($current_value) && !empty($multi_edit_columns_null_prev[$key]) && !isset($multi_edit_columns_null[$key])) { $current_value = "''"; } } // end else (column value in the form) return $current_value; }
/** * Function called just after a connection to the MySQL database server has * been established. It sets the connection collation, and determins the * version of MySQL which is running. * * @param mixed $link mysql link resource|object * @param boolean $is_controluser whether link is for control user * * @return void */ function PMA_DBI_postConnect($link, $is_controluser = false) { if ($is_controluser) { return; } if (!defined('PMA_MYSQL_INT_VERSION')) { if (PMA_Util::cacheExists('PMA_MYSQL_INT_VERSION', true)) { define('PMA_MYSQL_INT_VERSION', PMA_Util::cacheGet('PMA_MYSQL_INT_VERSION', true)); define('PMA_MYSQL_MAJOR_VERSION', PMA_Util::cacheGet('PMA_MYSQL_MAJOR_VERSION', true)); define('PMA_MYSQL_STR_VERSION', PMA_Util::cacheGet('PMA_MYSQL_STR_VERSION', true)); define('PMA_MYSQL_VERSION_COMMENT', PMA_Util::cacheGet('PMA_MYSQL_VERSION_COMMENT', true)); define('PMA_DRIZZLE', PMA_Util::cacheGet('PMA_DRIZZLE', true)); } else { $version = PMA_DBI_fetch_single_row('SELECT @@version, @@version_comment', 'ASSOC', $link); if ($version) { $match = explode('.', $version['@@version']); define('PMA_MYSQL_MAJOR_VERSION', (int) $match[0]); define('PMA_MYSQL_INT_VERSION', (int) sprintf('%d%02d%02d', $match[0], $match[1], intval($match[2]))); define('PMA_MYSQL_STR_VERSION', $version['@@version']); define('PMA_MYSQL_VERSION_COMMENT', $version['@@version_comment']); } else { define('PMA_MYSQL_INT_VERSION', 50015); define('PMA_MYSQL_MAJOR_VERSION', 5); define('PMA_MYSQL_STR_VERSION', '5.00.15'); define('PMA_MYSQL_VERSION_COMMENT', ''); } PMA_Util::cacheSet('PMA_MYSQL_INT_VERSION', PMA_MYSQL_INT_VERSION, true); PMA_Util::cacheSet('PMA_MYSQL_MAJOR_VERSION', PMA_MYSQL_MAJOR_VERSION, true); PMA_Util::cacheSet('PMA_MYSQL_STR_VERSION', PMA_MYSQL_STR_VERSION, true); PMA_Util::cacheSet('PMA_MYSQL_VERSION_COMMENT', PMA_MYSQL_VERSION_COMMENT, true); // Detect Drizzle - it does not support character sets $charset_result = PMA_DBI_get_variable('character_set_results', PMA_DBI_GETVAR_GLOBAL, $link); if ($charset_result) { define('PMA_DRIZZLE', false); } else { define('PMA_DRIZZLE', true); } PMA_Util::cacheSet('PMA_DRIZZLE', PMA_DRIZZLE, true); } } // Skip charsets for Drizzle if (!PMA_DRIZZLE) { if (!empty($GLOBALS['collation_connection'])) { PMA_DBI_query("SET CHARACTER SET 'utf8';", $link, PMA_DBI_QUERY_STORE); $set_collation_con_query = "SET collation_connection = '" . PMA_Util::sqlAddSlashes($GLOBALS['collation_connection']) . "';"; PMA_DBI_query($set_collation_con_query, $link, PMA_DBI_QUERY_STORE); } else { PMA_DBI_query("SET NAMES 'utf8' COLLATE 'utf8_general_ci';", $link, PMA_DBI_QUERY_STORE); } } // Cache plugin list for Drizzle if (PMA_DRIZZLE && !PMA_Util::cacheExists('drizzle_engines', true)) { $sql = "SELECT p.plugin_name, m.module_library\n FROM data_dictionary.plugins p\n JOIN data_dictionary.modules m USING (module_name)\n WHERE p.plugin_type = 'StorageEngine'\n AND p.plugin_name NOT IN ('FunctionEngine', 'schema')\n AND p.is_active = 'YES'"; $engines = PMA_DBI_fetch_result($sql, 'plugin_name', null, $link); PMA_Util::cacheSet('drizzle_engines', $engines, true); } }
/** * Displays the privileges form table * * @param string $db the database * @param string $table the table * @param boolean $submit wheather to display the submit button or not * @global array $cfg the phpMyAdmin configuration * @global ressource $user_link the database connection * * @return void */ function PMA_displayPrivTable($db = '*', $table = '*', $submit = TRUE) { if ($db == '*') { $table = '*'; } if (isset($GLOBALS['username'])) { $username = $GLOBALS['username']; $hostname = $GLOBALS['hostname']; if ($db == '*') { $sql_query = "SELECT * FROM `mysql`.`user`" . " WHERE `User` = '" . PMA_sqlAddslashes($username) . "'" . " AND `Host` = '" . PMA_sqlAddslashes($hostname) . "';"; } elseif ($table == '*') { $sql_query = "SELECT * FROM `mysql`.`db`" . " WHERE `User` = '" . PMA_sqlAddslashes($username) . "'" . " AND `Host` = '" . PMA_sqlAddslashes($hostname) . "'" . " AND '" . PMA_unescape_mysql_wildcards($db) . "'" . " LIKE `Db`;"; } else { $sql_query = "SELECT `Table_priv`" . " FROM `mysql`.`tables_priv`" . " WHERE `User` = '" . PMA_sqlAddslashes($username) . "'" . " AND `Host` = '" . PMA_sqlAddslashes($hostname) . "'" . " AND `Db` = '" . PMA_unescape_mysql_wildcards($db) . "'" . " AND `Table_name` = '" . PMA_sqlAddslashes($table) . "';"; } $row = PMA_DBI_fetch_single_row($sql_query); } if (empty($row)) { if ($table == '*') { if ($db == '*') { $sql_query = 'SHOW COLUMNS FROM `mysql`.`user`;'; } elseif ($table == '*') { $sql_query = 'SHOW COLUMNS FROM `mysql`.`db`;'; } $res = PMA_DBI_query($sql_query); while ($row1 = PMA_DBI_fetch_row($res)) { if (substr($row1[0], 0, 4) == 'max_') { $row[$row1[0]] = 0; } else { $row[$row1[0]] = 'N'; } } PMA_DBI_free_result($res); } else { $row = array('Table_priv' => ''); } } if (isset($row['Table_priv'])) { $row1 = PMA_DBI_fetch_single_row('SHOW COLUMNS FROM `mysql`.`tables_priv` LIKE \'Table_priv\';', 'ASSOC', $GLOBALS['userlink']); // note: in MySQL 5.0.3 we get "Create View', 'Show view'; // the View for Create is spelled with uppercase V // the view for Show is spelled with lowercase v // and there is a space between the words $av_grants = explode('\',\'', substr($row1['Type'], strpos($row1['Type'], '(') + 2, strpos($row1['Type'], ')') - strpos($row1['Type'], '(') - 3)); unset($row1); $users_grants = explode(',', $row['Table_priv']); foreach ($av_grants as $current_grant) { $row[$current_grant . '_priv'] = in_array($current_grant, $users_grants) ? 'Y' : 'N'; } unset($row['Table_priv'], $current_grant, $av_grants, $users_grants); // get collumns $res = PMA_DBI_try_query('SHOW COLUMNS FROM ' . PMA_backquote(PMA_unescape_mysql_wildcards($db)) . '.' . PMA_backquote($table) . ';'); $columns = array(); if ($res) { while ($row1 = PMA_DBI_fetch_row($res)) { $columns[$row1[0]] = array('Select' => FALSE, 'Insert' => FALSE, 'Update' => FALSE, 'References' => FALSE); } PMA_DBI_free_result($res); } unset($res, $row1); } // t a b l e - s p e c i f i c p r i v i l e g e s if (!empty($columns)) { $res = PMA_DBI_query('SELECT `Column_name`, `Column_priv`' . ' FROM `mysql`.`columns_priv`' . ' WHERE `User`' . ' = \'' . PMA_sqlAddslashes($username) . "'" . ' AND `Host`' . ' = \'' . PMA_sqlAddslashes($hostname) . "'" . ' AND `Db`' . ' = \'' . PMA_sqlAddslashes(PMA_unescape_mysql_wildcards($db)) . "'" . ' AND `Table_name`' . ' = \'' . PMA_sqlAddslashes($table) . '\';'); while ($row1 = PMA_DBI_fetch_row($res)) { $row1[1] = explode(',', $row1[1]); foreach ($row1[1] as $current) { $columns[$row1[0]][$current] = TRUE; } } PMA_DBI_free_result($res); unset($res, $row1, $current); echo '<input type="hidden" name="grant_count" value="' . count($row) . '" />' . "\n" . '<input type="hidden" name="column_count" value="' . count($columns) . '" />' . "\n" . '<fieldset id="fieldset_user_priv">' . "\n" . ' <legend>' . $GLOBALS['strTblPrivileges'] . PMA_showHint($GLOBALS['strEnglishPrivileges']) . '</legend>' . "\n"; // privs that are attached to a specific column PMA_display_column_privs($columns, $row, 'Select_priv', 'SELECT', 'select', $GLOBALS['strPrivDescSelect'], 'Select'); PMA_display_column_privs($columns, $row, 'Insert_priv', 'INSERT', 'insert', $GLOBALS['strPrivDescInsert'], 'Insert'); PMA_display_column_privs($columns, $row, 'Update_priv', 'UPDATE', 'update', $GLOBALS['strPrivDescUpdate'], 'Update'); PMA_display_column_privs($columns, $row, 'References_priv', 'REFERENCES', 'references', $GLOBALS['strPrivDescReferences'], 'References'); // privs that are not attached to a specific column echo ' <div class="item">' . "\n"; foreach ($row as $current_grant => $current_grant_value) { if (in_array(substr($current_grant, 0, strlen($current_grant) - 5), array('Select', 'Insert', 'Update', 'References'))) { continue; } // make a substitution to match the messages variables; // also we must substitute the grant we get, because we can't generate // a form variable containing blanks (those would get changed to // an underscore when receiving the POST) if ($current_grant == 'Create View_priv') { $tmp_current_grant = 'CreateView_priv'; $current_grant = 'Create_view_priv'; } elseif ($current_grant == 'Show view_priv') { $tmp_current_grant = 'ShowView_priv'; $current_grant = 'Show_view_priv'; } else { $tmp_current_grant = $current_grant; } echo ' <div class="item">' . "\n" . ' <input type="checkbox"' . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"') . ' name="' . $current_grant . '" id="checkbox_' . $current_grant . '" value="Y" ' . ($current_grant_value == 'Y' ? 'checked="checked" ' : '') . 'title="'; echo (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, strlen($tmp_current_grant) - 5)]) ? $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, strlen($tmp_current_grant) - 5)] : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, strlen($tmp_current_grant) - 5) . 'Tbl']) . '"/>' . "\n"; echo ' <label for="checkbox_' . $current_grant . '"><tt><dfn title="' . (isset($GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, strlen($tmp_current_grant) - 5)]) ? $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, strlen($tmp_current_grant) - 5)] : $GLOBALS['strPrivDesc' . substr($tmp_current_grant, 0, strlen($tmp_current_grant) - 5) . 'Tbl']) . '">' . strtoupper(substr($current_grant, 0, strlen($current_grant) - 5)) . '</dfn></tt></label>' . "\n" . ' </div>' . "\n"; } // end foreach () echo ' </div>' . "\n"; // for Safari 2.0.2 echo ' <div class="clearfloat"></div>' . "\n"; } else { // g l o b a l o r d b - s p e c i f i c // // d a t a $privTable[0] = array(array('Select', 'SELECT', $GLOBALS['strPrivDescSelect']), array('Insert', 'INSERT', $GLOBALS['strPrivDescInsert']), array('Update', 'UPDATE', $GLOBALS['strPrivDescUpdate']), array('Delete', 'DELETE', $GLOBALS['strPrivDescDelete'])); if ($db == '*') { $privTable[0][] = array('File', 'FILE', $GLOBALS['strPrivDescFile']); } // s t r u c t u r e $privTable[1] = array(array('Create', 'CREATE', $table == '*' ? $GLOBALS['strPrivDescCreateDb'] : $GLOBALS['strPrivDescCreateTbl']), array('Alter', 'ALTER', $GLOBALS['strPrivDescAlter']), array('Index', 'INDEX', $GLOBALS['strPrivDescIndex']), array('Drop', 'DROP', $table == '*' ? $GLOBALS['strPrivDescDropDb'] : $GLOBALS['strPrivDescDropTbl']), array('Create_tmp_table', 'CREATE TEMPORARY TABLES', $GLOBALS['strPrivDescCreateTmpTable']), array('Show_view', 'SHOW VIEW', $GLOBALS['strPrivDescShowView']), array('Create_routine', 'CREATE ROUTINE', $GLOBALS['strPrivDescCreateRoutine']), array('Alter_routine', 'ALTER ROUTINE', $GLOBALS['strPrivDescAlterRoutine']), array('Execute', 'EXECUTE', $GLOBALS['strPrivDescExecute5'])); // this one is for a db-specific priv: Create_view_priv if (isset($row['Create_view_priv'])) { $privTable[1][] = array('Create_view', 'CREATE VIEW', $GLOBALS['strPrivDescCreateView']); } // this one is for a table-specific priv: Create View_priv if (isset($row['Create View_priv'])) { $privTable[1][] = array('Create View', 'CREATE VIEW', $GLOBALS['strPrivDescCreateView']); } if (isset($row['Event_priv'])) { // MySQL 5.1.6 $privTable[1][] = array('Event', 'EVENT', $GLOBALS['strPrivDescEvent']); $privTable[1][] = array('Trigger', 'TRIGGER', $GLOBALS['strPrivDescTrigger']); } // a d m i n i s t r a t i o n $privTable[2] = array(array('Grant', 'GRANT', $GLOBALS['strPrivDescGrant'])); if ($db == '*') { $privTable[2][] = array('Super', 'SUPER', $GLOBALS['strPrivDescSuper']); $privTable[2][] = array('Process', 'PROCESS', $GLOBALS['strPrivDescProcess']); $privTable[2][] = array('Reload', 'RELOAD', $GLOBALS['strPrivDescReload']); $privTable[2][] = array('Shutdown', 'SHUTDOWN', $GLOBALS['strPrivDescShutdown']); $privTable[2][] = array('Show_db', 'SHOW DATABASES', $GLOBALS['strPrivDescShowDb']); } $privTable[2][] = array('Lock_tables', 'LOCK TABLES', $GLOBALS['strPrivDescLockTables']); $privTable[2][] = array('References', 'REFERENCES', $GLOBALS['strPrivDescReferences']); if ($db == '*') { $privTable[2][] = array('Repl_client', 'REPLICATION CLIENT', $GLOBALS['strPrivDescReplClient']); $privTable[2][] = array('Repl_slave', 'REPLICATION SLAVE', $GLOBALS['strPrivDescReplSlave']); $privTable[2][] = array('Create_user', 'CREATE USER', $GLOBALS['strPrivDescCreateUser']); } echo '<input type="hidden" name="grant_count" value="' . (count($privTable[0]) + count($privTable[1]) + count($privTable[2]) - (isset($row['Grant_priv']) ? 1 : 0)) . '" />' . "\n" . '<fieldset id="fieldset_user_global_rights">' . "\n" . ' <legend>' . "\n" . ' ' . ($db == '*' ? $GLOBALS['strGlobalPrivileges'] : ($table == '*' ? $GLOBALS['strDbPrivileges'] : $GLOBALS['strTblPrivileges'])) . "\n" . ' (<a href="server_privileges.php?' . $GLOBALS['url_query'] . '&checkall=1" onclick="setCheckboxes(\'usersForm\', true); return false;">' . $GLOBALS['strCheckAll'] . '</a> /' . "\n" . ' <a href="server_privileges.php?' . $GLOBALS['url_query'] . '" onclick="setCheckboxes(\'usersForm\', false); return false;">' . $GLOBALS['strUncheckAll'] . '</a>)' . "\n" . ' </legend>' . "\n" . ' <p><small><i>' . $GLOBALS['strEnglishPrivileges'] . '</i></small></p>' . "\n" . ' <fieldset>' . "\n" . ' <legend>' . $GLOBALS['strData'] . '</legend>' . "\n"; foreach ($privTable[0] as $priv) { echo ' <div class="item">' . "\n" . ' <input type="checkbox"' . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"') . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0] . '_priv" value="Y" ' . ($row[$priv[0] . '_priv'] == 'Y' ? 'checked="checked" ' : '') . 'title="' . $priv[2] . '"/>' . "\n" . ' <label for="checkbox_' . $priv[0] . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1] . '</dfn></tt></label>' . "\n" . ' </div>' . "\n"; } echo ' </fieldset>' . "\n" . ' <fieldset>' . "\n" . ' <legend>' . $GLOBALS['strStructure'] . '</legend>' . "\n"; foreach ($privTable[1] as $priv) { echo ' <div class="item">' . "\n" . ' <input type="checkbox"' . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"') . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0] . '_priv" value="Y" ' . ($row[$priv[0] . '_priv'] == 'Y' ? 'checked="checked" ' : '') . 'title="' . $priv[2] . '"/>' . "\n" . ' <label for="checkbox_' . $priv[0] . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1] . '</dfn></tt></label>' . "\n" . ' </div>' . "\n"; } echo ' </fieldset>' . "\n" . ' <fieldset>' . "\n" . ' <legend>' . $GLOBALS['strAdministration'] . '</legend>' . "\n"; foreach ($privTable[2] as $priv) { echo ' <div class="item">' . "\n" . ' <input type="checkbox"' . (empty($GLOBALS['checkall']) ? '' : ' checked="checked"') . ' name="' . $priv[0] . '_priv" id="checkbox_' . $priv[0] . '_priv" value="Y" ' . ($row[$priv[0] . '_priv'] == 'Y' ? 'checked="checked" ' : '') . 'title="' . $priv[2] . '"/>' . "\n" . ' <label for="checkbox_' . $priv[0] . '_priv"><tt><dfn title="' . $priv[2] . '">' . $priv[1] . '</dfn></tt></label>' . "\n" . ' </div>' . "\n"; } echo ' </fieldset>' . "\n"; // The "Resource limits" box is not displayed for db-specific privs if ($db == '*') { echo ' <fieldset>' . "\n" . ' <legend>' . $GLOBALS['strResourceLimits'] . '</legend>' . "\n" . ' <p><small><i>' . $GLOBALS['strZeroRemovesTheLimit'] . '</i></small></p>' . "\n" . ' <div class="item">' . "\n" . ' <label for="text_max_questions"><tt><dfn title="' . $GLOBALS['strPrivDescMaxQuestions'] . '">MAX QUERIES PER HOUR</dfn></tt></label>' . "\n" . ' <input type="text" name="max_questions" id="text_max_questions" value="' . $row['max_questions'] . '" size="11" maxlength="11" title="' . $GLOBALS['strPrivDescMaxQuestions'] . '" />' . "\n" . ' </div>' . "\n" . ' <div class="item">' . "\n" . ' <label for="text_max_updates"><tt><dfn title="' . $GLOBALS['strPrivDescMaxUpdates'] . '">MAX UPDATES PER HOUR</dfn></tt></label>' . "\n" . ' <input type="text" name="max_updates" id="text_max_updates" value="' . $row['max_updates'] . '" size="11" maxlength="11" title="' . $GLOBALS['strPrivDescMaxUpdates'] . '" />' . "\n" . ' </div>' . "\n" . ' <div class="item">' . "\n" . ' <label for="text_max_connections"><tt><dfn title="' . $GLOBALS['strPrivDescMaxConnections'] . '">MAX CONNECTIONS PER HOUR</dfn></tt></label>' . "\n" . ' <input type="text" name="max_connections" id="text_max_connections" value="' . $row['max_connections'] . '" size="11" maxlength="11" title="' . $GLOBALS['strPrivDescMaxConnections'] . '" />' . "\n" . ' </div>' . "\n" . ' <div class="item">' . "\n" . ' <label for="text_max_user_connections"><tt><dfn title="' . $GLOBALS['strPrivDescMaxUserConnections'] . '">MAX USER_CONNECTIONS</dfn></tt></label>' . "\n" . ' <input type="text" name="max_user_connections" id="text_max_user_connections" value="' . $row['max_user_connections'] . '" size="11" maxlength="11" title="' . $GLOBALS['strPrivDescMaxUserConnections'] . '" />' . "\n" . ' </div>' . "\n" . ' </fieldset>' . "\n"; } // for Safari 2.0.2 echo ' <div class="clearfloat"></div>' . "\n"; } echo '</fieldset>' . "\n"; if ($submit) { echo '<fieldset id="fieldset_user_privtable_footer" class="tblFooters">' . "\n" . ' <input type="submit" name="update_privs" value="' . $GLOBALS['strGo'] . '" />' . "\n" . '</fieldset>' . "\n"; } }
} } /** * Checks if the user is allowed to do what he tries to... */ if (!$is_superuser) { $response->addHTML('<h2>' . "\n" . PMA_Util::getIcon('b_usrlist.png') . __('Privileges') . "\n" . '</h2>' . "\n"); $response->addHTML(PMA_Message::error(__('No Privileges'))->getDisplay()); exit; } /** * Changes / copies a user, part I */ if (isset($_REQUEST['change_copy'])) { $user_host_condition = ' WHERE `User` = ' . "'" . PMA_Util::sqlAddSlashes($_REQUEST['old_username']) . "'" . ' AND `Host` = ' . "'" . PMA_Util::sqlAddSlashes($_REQUEST['old_hostname']) . "';"; $row = PMA_DBI_fetch_single_row('SELECT * FROM `mysql`.`user` ' . $user_host_condition); if (!$row) { PMA_Message::notice(__('No user found.'))->display(); unset($_REQUEST['change_copy']); } else { extract($row, EXTR_OVERWRITE); // Recent MySQL versions have the field "Password" in mysql.user, // so the previous extract creates $Password but this script // uses $password if (!isset($password) && isset($Password)) { $password = $Password; } $queries = array(); } } /**
/** * Returns $table's CREATE definition * * @param string $db the database name * @param string $table the table name * @param string $crlf the end of line sequence * @param string $error_url the url to go back in case of error * @param bool $show_dates whether to include creation/update/check * dates * @param bool $add_semicolon whether to add semicolon and end-of-line at * the end * @param bool $view whether we're handling a view * * @return string resulting schema */ public function getTableDef($db, $table, $crlf, $error_url, $show_dates = false, $add_semicolon = true, $view = false) { global $sql_drop_table, $sql_backquotes, $sql_constraints, $sql_constraints_query, $sql_drop_foreign_keys; $schema_create = ''; $auto_increment = ''; $new_crlf = $crlf; if (isset($GLOBALS['sql_compatibility'])) { $compat = $GLOBALS['sql_compatibility']; } else { $compat = 'NONE'; } // need to use PMA_DBI_QUERY_STORE with PMA_DBI_num_rows() in mysqli $result = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db) . ' LIKE \'' . PMA_Util::sqlAddSlashes($table, true) . '\'', null, PMA_DBI_QUERY_STORE); if ($result != false) { if (PMA_DBI_num_rows($result) > 0) { $tmpres = PMA_DBI_fetch_assoc($result); if (PMA_DRIZZLE && $show_dates) { // Drizzle doesn't give Create_time and Update_time in // SHOW TABLE STATUS, add it $sql = "SELECT\n TABLE_CREATION_TIME AS Create_time,\n TABLE_UPDATE_TIME AS Update_time\n FROM data_dictionary.TABLES\n WHERE TABLE_SCHEMA = '" . PMA_Util::sqlAddSlashes($db) . "'\n AND TABLE_NAME = '" . PMA_Util::sqlAddSlashes($table) . "'"; $tmpres = array_merge(PMA_DBI_fetch_single_row($sql), $tmpres); } // Here we optionally add the AUTO_INCREMENT next value, // but starting with MySQL 5.0.24, the clause is already included // in SHOW CREATE TABLE so we'll remove it below // It's required for Drizzle because SHOW CREATE TABLE uses // the value from table's creation time if (isset($GLOBALS['sql_auto_increment']) && !empty($tmpres['Auto_increment'])) { $auto_increment .= ' AUTO_INCREMENT=' . $tmpres['Auto_increment'] . ' '; } if ($show_dates && isset($tmpres['Create_time']) && !empty($tmpres['Create_time'])) { $schema_create .= $this->_exportComment(__('Creation') . ': ' . PMA_Util::localisedDate(strtotime($tmpres['Create_time']))); $new_crlf = $this->_exportComment() . $crlf; } if ($show_dates && isset($tmpres['Update_time']) && !empty($tmpres['Update_time'])) { $schema_create .= $this->_exportComment(__('Last update') . ': ' . PMA_Util::localisedDate(strtotime($tmpres['Update_time']))); $new_crlf = $this->_exportComment() . $crlf; } if ($show_dates && isset($tmpres['Check_time']) && !empty($tmpres['Check_time'])) { $schema_create .= $this->_exportComment(__('Last check') . ': ' . PMA_Util::localisedDate(strtotime($tmpres['Check_time']))); $new_crlf = $this->_exportComment() . $crlf; } } PMA_DBI_free_result($result); } $schema_create .= $new_crlf; // no need to generate a DROP VIEW here, it was done earlier if (!empty($sql_drop_table) && !PMA_Table::isView($db, $table)) { $schema_create .= 'DROP TABLE IF EXISTS ' . PMA_Util::backquote($table, $sql_backquotes) . ';' . $crlf; } // Complete table dump, // Whether to quote table and column names or not // Drizzle always quotes names if (!PMA_DRIZZLE) { if ($sql_backquotes) { PMA_DBI_query('SET SQL_QUOTE_SHOW_CREATE = 1'); } else { PMA_DBI_query('SET SQL_QUOTE_SHOW_CREATE = 0'); } } // I don't see the reason why this unbuffered query could cause problems, // because SHOW CREATE TABLE returns only one row, and we free the // results below. Nonetheless, we got 2 user reports about this // (see bug 1562533) so I removed the unbuffered mode. // $result = PMA_DBI_query('SHOW CREATE TABLE ' . backquote($db) // . '.' . backquote($table), null, PMA_DBI_QUERY_UNBUFFERED); // // Note: SHOW CREATE TABLE, at least in MySQL 5.1.23, does not // produce a displayable result for the default value of a BIT // column, nor does the mysqldump command. See MySQL bug 35796 $result = PMA_DBI_try_query('SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table)); // an error can happen, for example the table is crashed $tmp_error = PMA_DBI_getError(); if ($tmp_error) { return $this->_exportComment(__('in use') . '(' . $tmp_error . ')'); } if ($result != false && ($row = PMA_DBI_fetch_row($result))) { $create_query = $row[1]; unset($row); // Convert end of line chars to one that we want (note that MySQL // doesn't return query it will accept in all cases) if (strpos($create_query, "(\r\n ")) { $create_query = str_replace("\r\n", $crlf, $create_query); } elseif (strpos($create_query, "(\n ")) { $create_query = str_replace("\n", $crlf, $create_query); } elseif (strpos($create_query, "(\r ")) { $create_query = str_replace("\r", $crlf, $create_query); } /* * Drop database name from VIEW creation. * * This is a bit tricky, but we need to issue SHOW CREATE TABLE with * database name, but we don't want name to show up in CREATE VIEW * statement. */ if ($view) { $create_query = preg_replace('/' . PMA_Util::backquote($db) . '\\./', '', $create_query); } // Should we use IF NOT EXISTS? // It always must be OFF for MSSQL compatibility mode if (isset($GLOBALS['sql_if_not_exists']) && $compat != 'MSSQL') { $create_query = preg_replace('/^CREATE TABLE/', 'CREATE TABLE IF NOT EXISTS', $create_query); } // In MSSQL // 1. DATE field doesn't exists, we will use DATETIME instead // 2. UNSIGNED attribute doesn't exist // 3. No length on INT, TINYINT, SMALLINT, BIGINT and no precision on // FLOAT fields // 4. No KEY and INDEX inside CREATE TABLE // 5. DOUBLE field doesn't exists, we will use FLOAT instead if ($compat == 'MSSQL') { // first we need to replace all lines ended with '" DATE ...,\n' // last preg_replace preserve us from situation with date text // inside DEFAULT field value $create_query = preg_replace("/\" date DEFAULT NULL(,)?\n/", '" datetime DEFAULT NULL$1' . "\n", $create_query); $create_query = preg_replace("/\" date NOT NULL(,)?\n/", '" datetime NOT NULL$1' . "\n", $create_query); $create_query = preg_replace('/" date NOT NULL DEFAULT \'([^\'])/', '" datetime NOT NULL DEFAULT \'$1', $create_query); // next we need to replace all lines ended with ') UNSIGNED ...,' // last preg_replace preserve us from situation with unsigned text // inside DEFAULT field value $create_query = preg_replace("/\\) unsigned NOT NULL(,)?\n/", ') NOT NULL$1' . "\n", $create_query); $create_query = preg_replace("/\\) unsigned DEFAULT NULL(,)?\n/", ') DEFAULT NULL$1' . "\n", $create_query); $create_query = preg_replace('/\\) unsigned NOT NULL DEFAULT \'([^\'])/', ') NOT NULL DEFAULT \'$1', $create_query); // we need to replace all lines ended with // '" INT|TINYINT([0-9]{1,}) ...,' last preg_replace preserve us // from situation with int([0-9]{1,}) text inside DEFAULT field // value $create_query = preg_replace('/" (int|tinyint|smallint|bigint)\\([0-9]+\\) DEFAULT NULL(,)?\\n/', '" $1 DEFAULT NULL$2' . "\n", $create_query); $create_query = preg_replace('/" (int|tinyint|smallint|bigint)\\([0-9]+\\) NOT NULL(,)?\\n/', '" $1 NOT NULL$2' . "\n", $create_query); $create_query = preg_replace('/" (int|tinyint|smallint|bigint)\\([0-9]+\\) NOT NULL DEFAULT \'([^\'])/', '" $1 NOT NULL DEFAULT \'$2', $create_query); // we need to replace all lines ended with // '" FLOAT|DOUBLE([0-9,]{1,}) ...,' // last preg_replace preserve us from situation with // float([0-9,]{1,}) text inside DEFAULT field value $create_query = preg_replace('/" (float|double)(\\([0-9]+,[0-9,]+\\))? DEFAULT NULL(,)?\\n/', '" float DEFAULT NULL$3' . "\n", $create_query); $create_query = preg_replace('/" (float|double)(\\([0-9,]+,[0-9,]+\\))? NOT NULL(,)?\\n/', '" float NOT NULL$3' . "\n", $create_query); $create_query = preg_replace('/" (float|double)(\\([0-9,]+,[0-9,]+\\))? NOT NULL DEFAULT \'([^\'])/', '" float NOT NULL DEFAULT \'$3', $create_query); // @todo remove indexes from CREATE TABLE } // Drizzle (checked on 2011.03.13) returns ROW_FORMAT surrounded // with quotes, which is not accepted by parser if (PMA_DRIZZLE) { $create_query = preg_replace('/ROW_FORMAT=\'(\\S+)\'/', 'ROW_FORMAT=$1', $create_query); } // are there any constraints to cut out? if (preg_match('@CONSTRAINT|FOREIGN[\\s]+KEY@', $create_query)) { // Split the query into lines, so we can easily handle it. // We know lines are separated by $crlf (done few lines above). $sql_lines = explode($crlf, $create_query); $sql_count = count($sql_lines); // lets find first line with constraints for ($i = 0; $i < $sql_count; $i++) { if (preg_match('@^[\\s]*(CONSTRAINT|FOREIGN[\\s]+KEY)@', $sql_lines[$i])) { break; } } // If we really found a constraint if ($i != $sql_count) { // remove, from the end of create statement $sql_lines[$i - 1] = preg_replace('@,$@', '', $sql_lines[$i - 1]); // prepare variable for constraints if (!isset($sql_constraints)) { if (isset($GLOBALS['no_constraints_comments'])) { $sql_constraints = ''; } else { $sql_constraints = $crlf . $this->_exportComment() . $this->_exportComment(__('Constraints for dumped tables')) . $this->_exportComment(); } } // comments for current table if (!isset($GLOBALS['no_constraints_comments'])) { $sql_constraints .= $crlf . $this->_exportComment() . $this->_exportComment(__('Constraints for table') . ' ' . PMA_Util::backquoteCompat($table, $compat)) . $this->_exportComment(); } // let's do the work $sql_constraints_query .= 'ALTER TABLE ' . PMA_Util::backquoteCompat($table, $compat) . $crlf; $sql_constraints .= 'ALTER TABLE ' . PMA_Util::backquoteCompat($table, $compat) . $crlf; $sql_drop_foreign_keys .= 'ALTER TABLE ' . PMA_Util::backquoteCompat($db, $compat) . '.' . PMA_Util::backquoteCompat($table, $compat) . $crlf; $first = true; for ($j = $i; $j < $sql_count; $j++) { if (preg_match('@CONSTRAINT|FOREIGN[\\s]+KEY@', $sql_lines[$j])) { if (!$first) { $sql_constraints .= $crlf; } if (strpos($sql_lines[$j], 'CONSTRAINT') === false) { $tmp_str = preg_replace('/(FOREIGN[\\s]+KEY)/', 'ADD \\1', $sql_lines[$j]); $sql_constraints_query .= $tmp_str; $sql_constraints .= $tmp_str; } else { $tmp_str = preg_replace('/(CONSTRAINT)/', 'ADD \\1', $sql_lines[$j]); $sql_constraints_query .= $tmp_str; $sql_constraints .= $tmp_str; preg_match('/(CONSTRAINT)([\\s])([\\S]*)([\\s])/', $sql_lines[$j], $matches); if (!$first) { $sql_drop_foreign_keys .= ', '; } $sql_drop_foreign_keys .= 'DROP FOREIGN KEY ' . $matches[3]; } $first = false; } else { break; } } $sql_constraints .= ';' . $crlf; $sql_constraints_query .= ';'; $create_query = implode($crlf, array_slice($sql_lines, 0, $i)) . $crlf . implode($crlf, array_slice($sql_lines, $j, $sql_count - 1)); unset($sql_lines); } } $schema_create .= $create_query; } // remove a possible "AUTO_INCREMENT = value" clause // that could be there starting with MySQL 5.0.24 // in Drizzle it's useless as it contains the value given at table // creation time $schema_create = preg_replace('/AUTO_INCREMENT\\s*=\\s*([0-9])+/', '', $schema_create); $schema_create .= $compat != 'MSSQL' ? $auto_increment : ''; PMA_DBI_free_result($result); return $schema_create . ($add_semicolon ? ';' . $crlf : ''); }
} // Defines the SET part of the sql query $query_values = array(); // Map multi-edit keys to single-level arrays, dependent on how we got the fields $me_fields = isset($_REQUEST['fields']['multi_edit'][$rownumber]) ? $_REQUEST['fields']['multi_edit'][$rownumber] : array(); $me_fields_name = isset($_REQUEST['fields_name']['multi_edit'][$rownumber]) ? $_REQUEST['fields_name']['multi_edit'][$rownumber] : null; $me_fields_prev = isset($_REQUEST['fields_prev']['multi_edit'][$rownumber]) ? $_REQUEST['fields_prev']['multi_edit'][$rownumber] : null; $me_funcs = isset($_REQUEST['funcs']['multi_edit'][$rownumber]) ? $_REQUEST['funcs']['multi_edit'][$rownumber] : null; $me_fields_type = isset($_REQUEST['fields_type']['multi_edit'][$rownumber]) ? $_REQUEST['fields_type']['multi_edit'][$rownumber] : null; $me_fields_null = isset($_REQUEST['fields_null']['multi_edit'][$rownumber]) ? $_REQUEST['fields_null']['multi_edit'][$rownumber] : null; $me_fields_null_prev = isset($_REQUEST['fields_null_prev']['multi_edit'][$rownumber]) ? $_REQUEST['fields_null_prev']['multi_edit'][$rownumber] : null; $me_auto_increment = isset($_REQUEST['auto_increment']['multi_edit'][$rownumber]) ? $_REQUEST['auto_increment']['multi_edit'][$rownumber] : null; // Fetch the current values of a row to use in case we have a protected field // @todo possibly move to ./libraries/tbl_replace_fields.inc.php if ($is_insert && $using_key && isset($me_fields_type) && is_array($me_fields_type) && isset($where_clause)) { $prot_row = PMA_DBI_fetch_single_row('SELECT * FROM ' . PMA_backquote($table) . ' WHERE ' . $where_clause . ';'); } // When a select field is nullified, it's not present in $_REQUEST // so initialize it; this way, the foreach($me_fields) will process it foreach ($me_fields_name as $key => $val) { if (!isset($me_fields[$key])) { $me_fields[$key] = ''; } } // Iterate in the order of $me_fields_name, not $me_fields, to avoid problems // when inserting multiple entries foreach ($me_fields_name as $key => $field_name) { $val = $me_fields[$key]; // Note: $key is an md5 of the fieldname. The actual fieldname is available in $me_fields_name[$key] include './libraries/tbl_replace_fields.inc.php'; // for blobstreaming
/** * Counts and returns (or displays) the number of records in a table * * Revision 13 July 2001: Patch for limiting dump size from * vinay@sanisoft.com & girish@sanisoft.com * * @param string the current database name * @param string the current table name * @param boolean whether to force an exact count * * @return mixed the number of records if "retain" param is true, * otherwise true * * @access public */ public static function countRecords($db, $table, $force_exact = false, $is_view = null) { if (isset(PMA_Table::$cache[$db][$table]['ExactRows'])) { $row_count = PMA_Table::$cache[$db][$table]['ExactRows']; } else { $row_count = false; if (null === $is_view) { $is_view = PMA_Table::isView($db, $table); } if (!$force_exact) { if (!isset(PMA_Table::$cache[$db][$table]['Rows']) && !$is_view) { PMA_Table::$cache[$db][$table] = PMA_DBI_fetch_single_row('SHOW TABLE STATUS FROM ' . PMA_backquote($db) . ' LIKE \'' . PMA_sqlAddslashes($table, true) . '\''); } $row_count = PMA_Table::$cache[$db][$table]['Rows']; } // for a VIEW, $row_count is always false at this point if (false === $row_count || $row_count < $GLOBALS['cfg']['MaxExactCount']) { if (!$is_view) { $row_count = PMA_DBI_fetch_value('SELECT COUNT(*) FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table)); } else { // For complex views, even trying to get a partial record // count could bring down a server, so we offer an // alternative: setting MaxExactCountViews to 0 will bypass // completely the record counting for views if ($GLOBALS['cfg']['MaxExactCountViews'] == 0) { $row_count = 0; } else { // Counting all rows of a VIEW could be too long, so use // a LIMIT clause. // Use try_query because it can fail (when a VIEW is // based on a table that no longer exists) $result = PMA_DBI_try_query('SELECT 1 FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table) . ' LIMIT ' . $GLOBALS['cfg']['MaxExactCountViews'], null, PMA_DBI_QUERY_STORE); if (!PMA_DBI_getError()) { $row_count = PMA_DBI_num_rows($result); PMA_DBI_free_result($result); } } } PMA_Table::$cache[$db][$table]['ExactRows'] = $row_count; } } return $row_count; }
/** * Returns $table's CREATE definition * * @param string $db the database name * @param string $table the table name * @param string $crlf the end of line sequence * @param string $error_url the url to go back in case of error * @param bool $show_dates whether to include creation/update/check dates * @param bool $add_semicolon whether to add semicolon and end-of-line at the end * @param bool $view whether we're handling a view * @return string resulting schema * * @access public */ function PMA_getTableDef($db, $table, $crlf, $error_url, $show_dates = false, $add_semicolon = true, $view = false) { global $sql_drop_table; global $sql_backquotes; global $sql_constraints; global $sql_constraints_query; // just the text of the query global $sql_drop_foreign_keys; $schema_create = ''; $auto_increment = ''; $new_crlf = $crlf; // need to use PMA_DBI_QUERY_STORE with PMA_DBI_num_rows() in mysqli $result = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_backquote($db) . ' LIKE \'' . PMA_sqlAddSlashes($table, true) . '\'', null, PMA_DBI_QUERY_STORE); if ($result != false) { if (PMA_DBI_num_rows($result) > 0) { $tmpres = PMA_DBI_fetch_assoc($result); if (PMA_DRIZZLE && $show_dates) { // Drizzle doesn't give Create_time and Update_time in SHOW TABLE STATUS, add it $sql = "SELECT\n TABLE_CREATION_TIME AS Create_time,\n TABLE_UPDATE_TIME AS Update_time\n FROM data_dictionary.TABLES\n WHERE TABLE_SCHEMA = '" . PMA_sqlAddSlashes($db) . "'\n AND TABLE_NAME = '" . PMA_sqlAddSlashes($table) . "'"; $tmpres = array_merge(PMA_DBI_fetch_single_row($sql), $tmpres); } // Here we optionally add the AUTO_INCREMENT next value, // but starting with MySQL 5.0.24, the clause is already included // in SHOW CREATE TABLE so we'll remove it below // It's required for Drizzle because SHOW CREATE TABLE uses // the value from table's creation time if (isset($GLOBALS['sql_auto_increment']) && !empty($tmpres['Auto_increment'])) { $auto_increment .= ' AUTO_INCREMENT=' . $tmpres['Auto_increment'] . ' '; } if ($show_dates && isset($tmpres['Create_time']) && !empty($tmpres['Create_time'])) { $schema_create .= PMA_exportComment(__('Creation') . ': ' . PMA_localisedDate(strtotime($tmpres['Create_time']))); $new_crlf = PMA_exportComment() . $crlf; } if ($show_dates && isset($tmpres['Update_time']) && !empty($tmpres['Update_time'])) { $schema_create .= PMA_exportComment(__('Last update') . ': ' . PMA_localisedDate(strtotime($tmpres['Update_time']))); $new_crlf = PMA_exportComment() . $crlf; } if ($show_dates && isset($tmpres['Check_time']) && !empty($tmpres['Check_time'])) { $schema_create .= PMA_exportComment(__('Last check') . ': ' . PMA_localisedDate(strtotime($tmpres['Check_time']))); $new_crlf = PMA_exportComment() . $crlf; } } PMA_DBI_free_result($result); } $schema_create .= $new_crlf; // no need to generate a DROP VIEW here, it was done earlier if (!empty($sql_drop_table) && !PMA_Table::isView($db, $table)) { $schema_create .= 'DROP TABLE IF EXISTS ' . PMA_backquote($table, $sql_backquotes) . ';' . $crlf; } // Complete table dump, // Whether to quote table and column names or not // Drizzle always quotes names if (!PMA_DRIZZLE) { if ($sql_backquotes) { PMA_DBI_query('SET SQL_QUOTE_SHOW_CREATE = 1'); } else { PMA_DBI_query('SET SQL_QUOTE_SHOW_CREATE = 0'); } } // I don't see the reason why this unbuffered query could cause problems, // because SHOW CREATE TABLE returns only one row, and we free the // results below. Nonetheless, we got 2 user reports about this // (see bug 1562533) so I remove the unbuffered mode. //$result = PMA_DBI_query('SHOW CREATE TABLE ' . PMA_backquote($db) . '.' . PMA_backquote($table), null, PMA_DBI_QUERY_UNBUFFERED); // // Note: SHOW CREATE TABLE, at least in MySQL 5.1.23, does not // produce a displayable result for the default value of a BIT // column, nor does the mysqldump command. See MySQL bug 35796 $result = PMA_DBI_try_query('SHOW CREATE TABLE ' . PMA_backquote($db) . '.' . PMA_backquote($table)); // an error can happen, for example the table is crashed $tmp_error = PMA_DBI_getError(); if ($tmp_error) { return PMA_exportComment(__('in use') . '(' . $tmp_error . ')'); } if ($result != false && ($row = PMA_DBI_fetch_row($result))) { $create_query = $row[1]; unset($row); // Convert end of line chars to one that we want (note that MySQL doesn't return query it will accept in all cases) if (strpos($create_query, "(\r\n ")) { $create_query = str_replace("\r\n", $crlf, $create_query); } elseif (strpos($create_query, "(\n ")) { $create_query = str_replace("\n", $crlf, $create_query); } elseif (strpos($create_query, "(\r ")) { $create_query = str_replace("\r", $crlf, $create_query); } /* * Drop database name from VIEW creation. * * This is a bit tricky, but we need to issue SHOW CREATE TABLE with * database name, but we don't want name to show up in CREATE VIEW * statement. */ if ($view) { $create_query = preg_replace('/' . PMA_backquote($db) . '\\./', '', $create_query); } // Should we use IF NOT EXISTS? if (isset($GLOBALS['sql_if_not_exists'])) { $create_query = preg_replace('/^CREATE TABLE/', 'CREATE TABLE IF NOT EXISTS', $create_query); } // Drizzle (checked on 2011.03.13) returns ROW_FORMAT surrounded with quotes, which is not accepted by parser if (PMA_DRIZZLE) { $create_query = preg_replace('/ROW_FORMAT=\'(\\S+)\'/', 'ROW_FORMAT=$1', $create_query); } // are there any constraints to cut out? if (preg_match('@CONSTRAINT|FOREIGN[\\s]+KEY@', $create_query)) { // Split the query into lines, so we can easily handle it. We know lines are separated by $crlf (done few lines above). $sql_lines = explode($crlf, $create_query); $sql_count = count($sql_lines); // lets find first line with constraints for ($i = 0; $i < $sql_count; $i++) { if (preg_match('@^[\\s]*(CONSTRAINT|FOREIGN[\\s]+KEY)@', $sql_lines[$i])) { break; } } // If we really found a constraint if ($i != $sql_count) { // remove , from the end of create statement $sql_lines[$i - 1] = preg_replace('@,$@', '', $sql_lines[$i - 1]); // prepare variable for constraints if (!isset($sql_constraints)) { if (isset($GLOBALS['no_constraints_comments'])) { $sql_constraints = ''; } else { $sql_constraints = $crlf . PMA_exportComment() . PMA_exportComment(__('Constraints for dumped tables')) . PMA_exportComment(); } } // comments for current table if (!isset($GLOBALS['no_constraints_comments'])) { $sql_constraints .= $crlf . PMA_exportComment() . PMA_exportComment(__('Constraints for table') . ' ' . PMA_backquote($table)) . PMA_exportComment(); } // let's do the work $sql_constraints_query .= 'ALTER TABLE ' . PMA_backquote($table) . $crlf; $sql_constraints .= 'ALTER TABLE ' . PMA_backquote($table) . $crlf; $sql_drop_foreign_keys .= 'ALTER TABLE ' . PMA_backquote($db) . '.' . PMA_backquote($table) . $crlf; $first = true; for ($j = $i; $j < $sql_count; $j++) { if (preg_match('@CONSTRAINT|FOREIGN[\\s]+KEY@', $sql_lines[$j])) { if (!$first) { $sql_constraints .= $crlf; } if (strpos($sql_lines[$j], 'CONSTRAINT') === false) { $tmp_str = preg_replace('/(FOREIGN[\\s]+KEY)/', 'ADD \\1', $sql_lines[$j]); $sql_constraints_query .= $tmp_str; $sql_constraints .= $tmp_str; } else { $tmp_str = preg_replace('/(CONSTRAINT)/', 'ADD \\1', $sql_lines[$j]); $sql_constraints_query .= $tmp_str; $sql_constraints .= $tmp_str; preg_match('/(CONSTRAINT)([\\s])([\\S]*)([\\s])/', $sql_lines[$j], $matches); if (!$first) { $sql_drop_foreign_keys .= ', '; } $sql_drop_foreign_keys .= 'DROP FOREIGN KEY ' . $matches[3]; } $first = false; } else { break; } } $sql_constraints .= ';' . $crlf; $sql_constraints_query .= ';'; $create_query = implode($crlf, array_slice($sql_lines, 0, $i)) . $crlf . implode($crlf, array_slice($sql_lines, $j, $sql_count - 1)); unset($sql_lines); } } $schema_create .= $create_query; } // remove a possible "AUTO_INCREMENT = value" clause // that could be there starting with MySQL 5.0.24 // in Drizzle it's useless as it contains the value given at table creation time $schema_create = preg_replace('/AUTO_INCREMENT\\s*=\\s*([0-9])+/', '', $schema_create); $schema_create .= $auto_increment; PMA_DBI_free_result($result); return $schema_create . ($add_semicolon ? ';' . $crlf : ''); }
/** * 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; }
$value = floatval($matches[1]) * $common_functions->pow(1024, $exp[strtolower($matches[3])]); } else { $value = $common_functions->sqlAddSlashes($value); } if (! is_numeric($value)) { $value="'" . $value . "'"; } $response = PMA_Response::getInstance(); if (! preg_match("/[^a-zA-Z0-9_]+/", $_REQUEST['varName']) && PMA_DBI_query('SET GLOBAL ' . $_REQUEST['varName'] . ' = ' . $value) ) { // Some values are rounded down etc. $varValue = PMA_DBI_fetch_single_row( 'SHOW GLOBAL VARIABLES WHERE Variable_name="' . $common_functions->sqlAddSlashes($_REQUEST['varName']) . '";', 'NUM' ); $response->addJSON( 'variable', formatVariable($_REQUEST['varName'], $varValue[1]) ); } else { $response->isSuccess(false); $response->addJSON( 'error', __('Setting variable failed') ); } exit; break; }