} } $tmp_error_create = false; if ($create) { $create_query = PMA_getSQLToCreateForeignKey($table, $master_field, $foreign_db, $foreign_table, $foreign_field, $_REQUEST['constraint_name'][$master_field_md5], $options_array[$_REQUEST['on_delete'][$master_field_md5]], $options_array[$_REQUEST['on_update'][$master_field_md5]]); $display_query .= $create_query . "\n"; PMA_DBI_try_query($create_query); $tmp_error_create = PMA_DBI_getError(); if (!empty($tmp_error_create)) { $seen_error = true; if (substr($tmp_error_create, 1, 4) == '1005') { $message = PMA_Message::error(__('Error creating foreign key on %1$s (check data types)')); $message->addParam($master_field); $message->display(); } else { $html_output .= PMA_Util::mysqlDie($tmp_error_create, $create_query, false, '', false); } $html_output .= PMA_Util::showMySQLDocu('manual_Table_types', 'InnoDB_foreign_key_constraints') . "\n"; } // this is an alteration and the old constraint has been dropped // without creation of a new one if ($drop && $create && empty($tmp_error_drop) && !empty($tmp_error_create)) { // a rollback may be better here $sql_query_recreate = '# Restoring the dropped constraint...' . "\n"; $sql_query_recreate .= PMA_getSQLToCreateForeignKey($table, $master_field, PMA_Util::backquote($existrel_foreign[$master_field]['foreign_db']), PMA_Util::backquote($existrel_foreign[$master_field]['foreign_table']), PMA_Util::backquote($existrel_foreign[$master_field]['foreign_field']), $existrel_foreign[$master_field]['constraint'], $options_array[$existrel_foreign[$master_field]['on_delete']], $options_array[$existrel_foreign[$master_field]['on_update']]); $display_query .= $sql_query_recreate . "\n"; PMA_DBI_try_query($sql_query_recreate); } } } // end foreach
// Now we can check the parameters PMA_Util::checkParameters(array('sql_query')); } /** * Parse and analyze the query */ require_once 'libraries/parse_analyze.inc.php'; /** * Check rights in case of DROP DATABASE * * This test may be bypassed if $is_js_confirmed = 1 (already checked with js) * but since a malicious user may pass this variable by url/form, we don't take * into account this case. */ if (PMA_hasNoRightsToDropDatabase($analyzed_sql_results, $cfg['AllowUserDropDatabase'], $is_superuser)) { PMA_Util::mysqlDie(__('"DROP DATABASE" statements are disabled.'), '', '', $err_url); } // end if /** * Need to find the real end of rows? */ if (isset($find_real_end) && $find_real_end) { $unlim_num_rows = PMA_findRealEndOfRows($db, $table); } /** * Bookmark add */ if (isset($_POST['store_bkm'])) { PMA_addBookmark($cfg['PmaAbsoluteUri'], $goto); // script has exited at this point }
/** * Function to handle update for a foreign key * * @param array $multi_edit_columns_name multu edit columns name * @param string $master_field_md5 master field md5 * @param string $destination_foreign_table destination foreign table * @param string $destination_foreign_column destination foreign column * @param array $options_array options array * @param array $existrel_foreign db, table, column * @param string $table current table * @param bool &$seen_error whether seen error * @param string &$display_query display query * @param string $foreign_db foreign database * * @return string */ function PMA_handleUpdateForForeignKey($multi_edit_columns_name, $master_field_md5, $destination_foreign_table, $destination_foreign_column, $options_array, $existrel_foreign, $table, &$seen_error, &$display_query, $foreign_db) { $html_output = ''; $create = false; $drop = false; // Map the fieldname's md5 back to its real name $master_field = $multi_edit_columns_name[$master_field_md5]; $foreign_table = $destination_foreign_table[$master_field_md5]; $foreign_field = $destination_foreign_column[$master_field_md5]; if (!empty($foreign_db) && !empty($foreign_table) && !empty($foreign_field)) { if (isset($existrel_foreign[$master_field])) { $constraint_name = $existrel_foreign[$master_field]['constraint']; $on_delete = !empty($existrel_foreign[$master_field]['on_delete']) ? $existrel_foreign[$master_field]['on_delete'] : 'RESTRICT'; $on_update = !empty($existrel_foreign[$master_field]['on_update']) ? $existrel_foreign[$master_field]['on_update'] : 'RESTRICT'; } if (!isset($existrel_foreign[$master_field])) { // no key defined for this field $create = true; } elseif ($existrel_foreign[$master_field]['foreign_db'] != $foreign_db || $existrel_foreign[$master_field]['foreign_table'] != $foreign_table || $existrel_foreign[$master_field]['foreign_field'] != $foreign_field || $_REQUEST['constraint_name'][$master_field_md5] != $constraint_name || $_REQUEST['on_delete'][$master_field_md5] != $on_delete || $_REQUEST['on_update'][$master_field_md5] != $on_update) { // another foreign key is already defined for this field // or an option has been changed for ON DELETE or ON UPDATE $drop = true; $create = true; } // end if... else.... } elseif (isset($existrel_foreign[$master_field])) { $drop = true; } // end if... else.... $tmp_error_drop = false; if ($drop) { $drop_query = PMA_getSQLToDropForeignKey($table, $existrel_foreign[$master_field]['constraint']); $display_query .= $drop_query . "\n"; $GLOBALS['dbi']->tryQuery($drop_query); $tmp_error_drop = $GLOBALS['dbi']->getError(); if (!empty($tmp_error_drop)) { $seen_error = true; $html_output .= PMA_Util::mysqlDie($tmp_error_drop, $drop_query, false, '', false); return $html_output; } } $tmp_error_create = false; if ($create) { $create_query = PMA_getSQLToCreateForeignKey($table, $master_field, $foreign_db, $foreign_table, $foreign_field, $_REQUEST['constraint_name'][$master_field_md5], $options_array[$_REQUEST['on_delete'][$master_field_md5]], $options_array[$_REQUEST['on_update'][$master_field_md5]]); $display_query .= $create_query . "\n"; $GLOBALS['dbi']->tryQuery($create_query); $tmp_error_create = $GLOBALS['dbi']->getError(); if (!empty($tmp_error_create)) { $seen_error = true; if (substr($tmp_error_create, 1, 4) == '1005') { $message = PMA_Message::error(__('Error creating foreign key on %1$s (check data types)')); $message->addParam($master_field); $html_output .= $message->getDisplay(); } else { $html_output .= PMA_Util::mysqlDie($tmp_error_create, $create_query, false, '', false); } $html_output .= PMA_Util::showMySQLDocu('InnoDB_foreign_key_constraints') . "\n"; } // this is an alteration and the old constraint has been dropped // without creation of a new one if ($drop && $create && empty($tmp_error_drop) && !empty($tmp_error_create)) { // a rollback may be better here $sql_query_recreate = '# Restoring the dropped constraint...' . "\n"; $sql_query_recreate .= PMA_getSQLToCreateForeignKey($table, $master_field, $existrel_foreign[$master_field]['foreign_db'], $existrel_foreign[$master_field]['foreign_table'], $existrel_foreign[$master_field]['foreign_field'], $existrel_foreign[$master_field]['constraint'], $options_array[$existrel_foreign[$master_field]['on_delete']], $options_array[$existrel_foreign[$master_field]['on_update']]); $display_query .= $sql_query_recreate . "\n"; $GLOBALS['dbi']->tryQuery($sql_query_recreate); } } return $html_output; }
/** * Update password and get message for password updating * * @param string $err_url error url * @param string $username username * @param string $hostname hostname * * @return string $message success or error message after updating password */ function PMA_getMessageForUpdatePassword($err_url, $username, $hostname) { // similar logic in user_password.php $message = ''; if (empty($_REQUEST['nopass']) && isset($_POST['pma_pw']) && isset($_POST['pma_pw2'])) { if ($_POST['pma_pw'] != $_POST['pma_pw2']) { $message = PMA_Message::error(__('The passwords aren\'t the same!')); } elseif (empty($_POST['pma_pw']) || empty($_POST['pma_pw2'])) { $message = PMA_Message::error(__('The password is empty!')); } } // here $nopass could be == 1 if (empty($message)) { $hashing_function = (!empty($_REQUEST['pw_hash']) && $_REQUEST['pw_hash'] == 'old' ? 'OLD_' : '') . 'PASSWORD'; // in $sql_query which will be displayed, hide the password $sql_query = 'SET PASSWORD FOR \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = ' . ($_POST['pma_pw'] == '' ? '\'\'' : $hashing_function . '(\'' . preg_replace('@.@s', '*', $_POST['pma_pw']) . '\')'); $local_query = 'SET PASSWORD FOR \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = ' . ($_POST['pma_pw'] == '' ? '\'\'' : $hashing_function . '(\'' . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . '\')'); PMA_DBI_try_query($local_query) or PMA_Util::mysqlDie(PMA_DBI_getError(), $sql_query, false, $err_url); $message = PMA_Message::success(__('The password for %s was changed successfully.')); $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\''); } return $message; }
/** * Responds an error when an error happens when executing the query * * @param boolean $is_gotofile whether goto file or not * @param String $error error after executing the query * @param String $full_sql_query full sql query * * @return void */ function PMA_handleQueryExecuteError($is_gotofile, $error, $full_sql_query) { if ($is_gotofile) { $message = PMA_Message::rawError($error); $response = PMA_Response::getInstance(); $response->isSuccess(false); $response->addJSON('message', $message); } else { PMA_Util::mysqlDie($error, $full_sql_query, '', ''); } exit; }
} } } // Go back to the structure sub-page $message = PMA_Message::success(__('Table %1$s has been altered successfully')); $message->addParam($table); if ($GLOBALS['is_ajax_request'] == true) { $response->addJSON('message', $message); $response->addJSON('sql_query', PMA_Util::getMessage(null, $sql_query)); exit; } $active_page = 'tbl_structure.php'; $abort = true; include 'tbl_structure.php'; } else { $error_message_html = PMA_Util::mysqlDie('', '', '', $err_url, false); $response->addHTML($error_message_html); if ($GLOBALS['is_ajax_request'] == true) { exit; } // An error happened while inserting/updating a table definition. // to prevent total loss of that data, we embed the form once again. // The variable $regenerate will be used to restore data in libraries/tbl_columns_definition_form.inc.php $num_fields = $_REQUEST['orig_num_fields']; if (isset($_REQUEST['orig_after_field'])) { $_REQUEST['after_field'] = $_REQUEST['orig_after_field']; } if (isset($_REQUEST['orig_field_where'])) { $_REQUEST['field_where'] = $_REQUEST['orig_field_where']; } $regenerate = true;
/** * Update the table's structure based on $_REQUEST * * @param string $db database name * @param string $table table name * * @return boolean $regenerate true if error occurred * */ function PMA_updateColumns($db, $table) { $err_url = 'tbl_structure.php?' . PMA_URL_getCommon($db, $table); $regenerate = false; $field_cnt = count($_REQUEST['field_name']); $key_fields = array(); $changes = array(); for ($i = 0; $i < $field_cnt; $i++) { if (PMA_columnNeedsAlterTable($i)) { $changes[] = 'CHANGE ' . PMA_Table::generateAlter(isset($_REQUEST['field_orig'][$i]) ? $_REQUEST['field_orig'][$i] : '', $_REQUEST['field_name'][$i], $_REQUEST['field_type'][$i], $_REQUEST['field_length'][$i], $_REQUEST['field_attribute'][$i], isset($_REQUEST['field_collation'][$i]) ? $_REQUEST['field_collation'][$i] : '', isset($_REQUEST['field_null'][$i]) ? $_REQUEST['field_null'][$i] : 'NOT NULL', $_REQUEST['field_default_type'][$i], $_REQUEST['field_default_value'][$i], isset($_REQUEST['field_extra'][$i]) ? $_REQUEST['field_extra'][$i] : false, isset($_REQUEST['field_comments'][$i]) ? $_REQUEST['field_comments'][$i] : '', $key_fields, $i, isset($_REQUEST['field_move_to'][$i]) ? $_REQUEST['field_move_to'][$i] : ''); } } // end for $response = PMA_Response::getInstance(); if (count($changes) > 0) { // Builds the primary keys statements and updates the table $key_query = ''; /** * this is a little bit more complex * * @todo if someone selects A_I when altering a column we need to check: * - no other column with A_I * - the column has an index, if not create one * */ // To allow replication, we first select the db to use // and then run queries on this db. if (!$GLOBALS['dbi']->selectDb($db)) { PMA_Util::mysqlDie($GLOBALS['dbi']->getError(), 'USE ' . PMA_Util::backquote($db) . ';', '', $err_url); } $sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' '; $sql_query .= implode(', ', $changes) . $key_query; $sql_query .= ';'; $result = $GLOBALS['dbi']->tryQuery($sql_query); if ($result !== false) { $message = PMA_Message::success(__('Table %1$s has been altered successfully.')); $message->addParam($table); $response->addHTML(PMA_Util::getMessage($message, $sql_query, 'success')); } else { // An error happened while inserting/updating a table definition $response->isSuccess(false); $response->addJSON('message', PMA_Message::rawError(__('Query error') . ':<br />' . $GLOBALS['dbi']->getError())); $regenerate = true; } } include_once 'libraries/transformations.lib.php'; // update field names in relation if (isset($_REQUEST['field_orig']) && is_array($_REQUEST['field_orig'])) { foreach ($_REQUEST['field_orig'] as $fieldindex => $fieldcontent) { if ($_REQUEST['field_name'][$fieldindex] != $fieldcontent) { PMA_REL_renameField($db, $table, $fieldcontent, $_REQUEST['field_name'][$fieldindex]); } } } // update mime types if (isset($_REQUEST['field_mimetype']) && is_array($_REQUEST['field_mimetype']) && $GLOBALS['cfg']['BrowseMIME']) { foreach ($_REQUEST['field_mimetype'] as $fieldindex => $mimetype) { if (isset($_REQUEST['field_name'][$fieldindex]) && strlen($_REQUEST['field_name'][$fieldindex])) { PMA_setMIME($db, $table, $_REQUEST['field_name'][$fieldindex], $mimetype, $_REQUEST['field_transformation'][$fieldindex], $_REQUEST['field_transformation_options'][$fieldindex]); } } } return $regenerate; }
if ($GLOBALS['is_ajax_request'] == true) { $response = PMA_Response::getInstance(); $response->isSuccess(false); $response->addJSON('message', $message); exit; } /** * Go to target path. */ include '' . PMA_securePath($goto); } else { $full_err_url = $err_url; if (preg_match('@^(db|tbl)_@', $err_url)) { $full_err_url .= '&show_query=1&sql_query=' . urlencode($sql_query); } PMA_Util::mysqlDie($error, $full_sql_query, '', $full_err_url); } exit; } unset($error); // If there are no errors and bookmarklabel was given, // store the query as a bookmark if (!empty($bkm_label) && !empty($import_text)) { include_once 'libraries/bookmark.lib.php'; $bfields = array('dbase' => $db, 'user' => $cfg['Bookmark']['user'], 'query' => urlencode($import_text), 'label' => $bkm_label); // Should we replace bookmark? if (isset($bkm_replace)) { $bookmarks = PMA_Bookmark_getList($db); foreach ($bookmarks as $key => $val) { if ($val == $bkm_label) { PMA_Bookmark_delete($db, $key);
PMA_Util::checkParameters(array('db')); /** @var PMA_String $pmaString */ $pmaString = $GLOBALS['PMA_String']; /* Check if database name is empty */ if (mb_strlen($db) == 0) { PMA_Util::mysqlDie(__('The database name is empty!'), '', false, 'index.php'); } /** * Selects the database to work with */ if (!$GLOBALS['dbi']->selectDb($db)) { PMA_Util::mysqlDie(sprintf(__('\'%s\' database does not exist.'), htmlspecialchars($db)), '', false, 'index.php'); } if ($GLOBALS['dbi']->getColumns($db, $table)) { // table exists already PMA_Util::mysqlDie(sprintf(__('Table %s already exists!'), htmlspecialchars($table)), '', false, 'db_structure.php' . PMA_URL_getCommon(array('db' => $db))); } // for libraries/tbl_columns_definition_form.inc.php // check number of fields to be created $num_fields = PMA_getNumberOfFieldsFromRequest(); $action = 'tbl_create.php'; /** * The form used to define the structure of the table has been submitted */ if (isset($_REQUEST['do_save_data'])) { $sql_query = PMA_getTableCreationQuery($db, $table); // If there is a request for SQL previewing. if (isset($_REQUEST['preview_sql'])) { PMA_previewSQL($sql_query); } // Executes the query
/** * Generate the error url and submit the query * * @param string $username Username * @param string $hostname Hostname * @param string $password Password * @param string $sql_query SQL query * @param string $hashing_function Hashing function * @param string $auth_plugin Authentication Plugin * * @return void */ function PMA_changePassUrlParamsAndSubmitQuery($username, $hostname, $password, $sql_query, $hashing_function, $auth_plugin) { $err_url = 'user_password.php' . PMA_URL_getCommon(); if (PMA_Util::getServerType() === 'MySQL' && PMA_MYSQL_INT_VERSION >= 50706) { $local_query = 'ALTER USER \'' . $username . '\'@\'' . $hostname . '\'' . ' IDENTIFIED with ' . $auth_plugin . ' BY ' . ($password == '' ? '\'\'' : '\'' . PMA_Util::sqlAddSlashes($password) . '\''); } else { $local_query = 'SET password = '******'' ? '\'\'' : $hashing_function . '(\'' . PMA_Util::sqlAddSlashes($password) . '\')'); } if (!@$GLOBALS['dbi']->tryQuery($local_query)) { PMA_Util::mysqlDie($GLOBALS['dbi']->getError(), $sql_query, false, $err_url); } }
/** * Generate the error url and submit the query * * @param string $username Username * @param string $hostname Hostname * @param string $password Password * @param string $sql_query SQL query * @param string $hashing_function Hashing function * @param string $orig_auth_plugin Original Authentication Plugin * * @return void */ function PMA_changePassUrlParamsAndSubmitQuery($username, $hostname, $password, $sql_query, $hashing_function, $orig_auth_plugin) { $err_url = 'user_password.php' . PMA_URL_getCommon(); $serverType = PMA_Util::getServerType(); if ($serverType == 'MySQL' && PMA_MYSQL_INT_VERSION >= 50706) { $local_query = 'ALTER USER \'' . $username . '\'@\'' . $hostname . '\'' . ' IDENTIFIED with ' . $orig_auth_plugin . ' BY ' . ($password == '' ? '\'\'' : '\'' . PMA_Util::sqlAddSlashes($password) . '\''); } else { if ($serverType == 'MariaDB' && PMA_MYSQL_INT_VERSION >= 50200) { if ($orig_auth_plugin == 'mysql_native_password') { // Set the hashing method used by PASSWORD() // to be 'mysql_native_password' type $GLOBALS['dbi']->tryQuery('SET old_passwords = 0;'); } else { if ($orig_auth_plugin == 'sha256_password') { // Set the hashing method used by PASSWORD() // to be 'sha256_password' type $GLOBALS['dbi']->tryQuery('SET `old_passwords` = 2;'); } } $hashedPassword = PMA_getHashedPassword($_POST['pma_pw']); $local_query = "UPDATE `mysql`.`user` SET" . " `authentication_string` = '" . $hashedPassword . "', `Password` = '', " . " `plugin` = '" . $orig_auth_plugin . "'" . " WHERE `User` = '" . $username . "' AND Host = '" . $hostname . "';"; $GLOBALS['dbi']->tryQuery("FLUSH PRIVILEGES;"); } else { $local_query = 'SET password = '******'' ? '\'\'' : $hashing_function . '(\'' . PMA_Util::sqlAddSlashes($password) . '\')'); } } if (!@$GLOBALS['dbi']->tryQuery($local_query)) { PMA_Util::mysqlDie($GLOBALS['dbi']->getError(), $sql_query, false, $err_url); } }
/** * Generate the error url and submit the query * * @param string $password * @param array $_url_params * @param string $sql_query * @param string $hashing_function * * @return void */ function PMA_ChangePassUrlParamsAndSubmitQuery( $password, $_url_params, $sql_query, $hashing_function ) { $err_url = 'user_password.php' . PMA_generate_common_url($_url_params); $local_query = 'SET password = '******'') ? '\'\'' : $hashing_function . '(\'' . PMA_Util::sqlAddSlashes($password) . '\')'); $result = @PMA_DBI_try_query($local_query) or PMA_Util::mysqlDie( PMA_DBI_getError(), $sql_query, false, $err_url ); }
/** * Update password and get message for password updating * * @param string $err_url error url * @param string $username username * @param string $hostname hostname * * @return string $message success or error message after updating password */ function PMA_updatePassword($err_url, $username, $hostname) { // similar logic in user_password.php $message = ''; if (empty($_REQUEST['nopass']) && isset($_POST['pma_pw']) && isset($_POST['pma_pw2'])) { if ($_POST['pma_pw'] != $_POST['pma_pw2']) { $message = PMA_Message::error(__('The passwords aren\'t the same!')); } elseif (empty($_POST['pma_pw']) || empty($_POST['pma_pw2'])) { $message = PMA_Message::error(__('The password is empty!')); } } // here $nopass could be == 1 if (empty($message)) { if (PMA_Util::getServerType() == 'MySQL' && PMA_MYSQL_INT_VERSION >= 50706) { if (!empty($_REQUEST['pw_hash']) && $_REQUEST['pw_hash'] != 'old') { $query_prefix = "ALTER USER '" . PMA_Util::sqlAddSlashes($username) . "'@'" . PMA_Util::sqlAddSlashes($hostname) . "'" . " IDENTIFIED WITH " . $_REQUEST['pw_hash'] . " BY '"; } else { $query_prefix = "ALTER USER '" . PMA_Util::sqlAddSlashes($username) . "'@'" . PMA_Util::sqlAddSlashes($hostname) . "'" . " IDENTIFIED BY '"; } // in $sql_query which will be displayed, hide the password $sql_query = $query_prefix . "*'"; $local_query = $query_prefix . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . "'"; } else { if (!empty($_REQUEST['pw_hash']) && $_REQUEST['pw_hash'] == 'old') { $hashing_function = 'OLD_PASSWORD'; } elseif (!empty($_REQUEST['pw_hash']) && $_REQUEST['pw_hash'] == 'sha256_password') { $hashing_function = 'PASSWORD'; // Backup the old value, to be reset later $row = $GLOBALS['dbi']->fetchSingleRow('SHOW VARIABLES like \'old_passwords\';'); $orig_value = $row['Value']; // Set the hashing method used by PASSWORD() // to be 'sha256_password' type $GLOBALS['dbi']->tryQuery('SET old_passwords = 2;'); } else { $hashing_function = 'PASSWORD'; } $sql_query = 'SET PASSWORD FOR \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = ' . ($_POST['pma_pw'] == '' ? '\'\'' : $hashing_function . '(\'' . preg_replace('@.@s', '*', $_POST['pma_pw']) . '\')'); $local_query = 'SET PASSWORD FOR \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = ' . ($_POST['pma_pw'] == '' ? '\'\'' : $hashing_function . '(\'' . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . '\')'); } $GLOBALS['dbi']->tryQuery($local_query) or PMA_Util::mysqlDie($GLOBALS['dbi']->getError(), $sql_query, false, $err_url); $message = PMA_Message::success(__('The password for %s was changed successfully.')); $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\''); if (isset($orig_value)) { $GLOBALS['dbi']->tryQuery('SET `old_passwords` = ' . $orig_value . ';'); } } return $message; }
/** * returns array with databases containing extended infos about them * * @param string $database database * @param boolean $force_stats retrieve stats also for MySQL < 5 * @param object $link mysql link * @param string $sort_by column to order by * @param string $sort_order ASC or DESC * @param integer $limit_offset starting offset for LIMIT * @param bool|int $limit_count row count for LIMIT or true * for $GLOBALS['cfg']['MaxDbList'] * * @todo move into PMA_List_Database? * * @return array $databases */ public function getDatabasesFull($database = null, $force_stats = false, $link = null, $sort_by = 'SCHEMA_NAME', $sort_order = 'ASC', $limit_offset = 0, $limit_count = false) { $sort_order = strtoupper($sort_order); if (true === $limit_count) { $limit_count = $GLOBALS['cfg']['MaxDbList']; } $apply_limit_and_order_manual = true; if (!$GLOBALS['cfg']['Server']['DisableIS']) { /** * if $GLOBALS['cfg']['NaturalOrder'] is enabled, we cannot use LIMIT * cause MySQL does not support natural ordering, * we have to do it afterward */ $limit = ''; if (!$GLOBALS['cfg']['NaturalOrder']) { if ($limit_count) { $limit = ' LIMIT ' . $limit_count . ' OFFSET ' . $limit_offset; } $apply_limit_and_order_manual = false; } // get table information from information_schema if (!empty($database)) { $sql_where_schema = 'WHERE `SCHEMA_NAME` LIKE \'' . PMA_Util::sqlAddSlashes($database) . '\''; } else { $sql_where_schema = ''; } $sql = 'SELECT *, CAST(BIN_NAME AS CHAR CHARACTER SET utf8) AS SCHEMA_NAME FROM ('; $sql .= 'SELECT BINARY s.SCHEMA_NAME AS BIN_NAME, s.DEFAULT_COLLATION_NAME'; if ($force_stats) { $sql .= ', COUNT(t.TABLE_SCHEMA) AS SCHEMA_TABLES, SUM(t.TABLE_ROWS) AS SCHEMA_TABLE_ROWS, SUM(t.DATA_LENGTH) AS SCHEMA_DATA_LENGTH, SUM(t.MAX_DATA_LENGTH) AS SCHEMA_MAX_DATA_LENGTH, SUM(t.INDEX_LENGTH) AS SCHEMA_INDEX_LENGTH, SUM(t.DATA_LENGTH + t.INDEX_LENGTH) AS SCHEMA_LENGTH, SUM(t.DATA_FREE) AS SCHEMA_DATA_FREE'; } $sql .= ' FROM `information_schema`.SCHEMATA s'; if ($force_stats) { $sql .= ' LEFT JOIN `information_schema`.TABLES t ON BINARY t.TABLE_SCHEMA = BINARY s.SCHEMA_NAME'; } $sql .= $sql_where_schema . ' GROUP BY BINARY s.SCHEMA_NAME, s.DEFAULT_COLLATION_NAME ORDER BY '; if ($sort_by == 'SCHEMA_NAME' || $sort_by == 'DEFAULT_COLLATION_NAME') { $sql .= 'BINARY '; } $sql .= PMA_Util::backquote($sort_by) . ' ' . $sort_order . $limit; $sql .= ') a'; $databases = $this->fetchResult($sql, 'SCHEMA_NAME', null, $link); $mysql_error = $this->getError($link); if (!count($databases) && $GLOBALS['errno']) { PMA_Util::mysqlDie($mysql_error, $sql); } // display only databases also in official database list // f.e. to apply hide_db and only_db $drops = array_diff(array_keys($databases), (array) $GLOBALS['pma']->databases); foreach ($drops as $drop) { unset($databases[$drop]); } } else { $databases = array(); foreach ($GLOBALS['pma']->databases as $database_name) { // MySQL forward compatibility // so pma could use this array as if every server is of version >5.0 // todo : remove and check the rest of the code for usage, // MySQL 5.0 or higher is required for current PMA version $databases[$database_name]['SCHEMA_NAME'] = $database_name; include_once './libraries/mysql_charsets.inc.php'; $databases[$database_name]['DEFAULT_COLLATION_NAME'] = PMA_getDbCollation($database_name); if (!$force_stats) { continue; } // get additional info about tables $databases[$database_name]['SCHEMA_TABLES'] = 0; $databases[$database_name]['SCHEMA_TABLE_ROWS'] = 0; $databases[$database_name]['SCHEMA_DATA_LENGTH'] = 0; $databases[$database_name]['SCHEMA_MAX_DATA_LENGTH'] = 0; $databases[$database_name]['SCHEMA_INDEX_LENGTH'] = 0; $databases[$database_name]['SCHEMA_LENGTH'] = 0; $databases[$database_name]['SCHEMA_DATA_FREE'] = 0; $res = $this->query('SHOW TABLE STATUS FROM ' . PMA_Util::backquote($database_name) . ';'); if ($res === false) { unset($res); continue; } while ($row = $this->fetchAssoc($res)) { $databases[$database_name]['SCHEMA_TABLES']++; $databases[$database_name]['SCHEMA_TABLE_ROWS'] += $row['Rows']; $databases[$database_name]['SCHEMA_DATA_LENGTH'] += $row['Data_length']; $databases[$database_name]['SCHEMA_MAX_DATA_LENGTH'] += $row['Max_data_length']; $databases[$database_name]['SCHEMA_INDEX_LENGTH'] += $row['Index_length']; // for InnoDB, this does not contain the number of // overhead bytes but the total free space if ('InnoDB' != $row['Engine']) { $databases[$database_name]['SCHEMA_DATA_FREE'] += $row['Data_free']; } $databases[$database_name]['SCHEMA_LENGTH'] += $row['Data_length'] + $row['Index_length']; } $this->freeResult($res); unset($res); } } /** * apply limit and order manually now * (caused by older MySQL < 5 or $GLOBALS['cfg']['NaturalOrder']) */ if ($apply_limit_and_order_manual) { $GLOBALS['callback_sort_order'] = $sort_order; $GLOBALS['callback_sort_by'] = $sort_by; usort($databases, array('PMA_DatabaseInterface', '_usortComparisonCallback')); unset($GLOBALS['callback_sort_order'], $GLOBALS['callback_sort_by']); /** * now apply limit */ if ($limit_count) { $databases = array_slice($databases, $limit_offset, $limit_count); } } return $databases; }
/** * Function to execute the column creation statement * * @param string $db current database * @param string $table current table * @param string $err_url error page url * * @return array */ function PMA_tryColumnCreationQuery($db, $table, $err_url) { // get column addition statements $sql_statement = PMA_getColumnCreationStatements(false); // To allow replication, we first select the db to use and then run queries // on this db. $GLOBALS['dbi']->selectDb($db) or PMA_Util::mysqlDie($GLOBALS['dbi']->getError(), 'USE ' . PMA_Util::backquote($db), false, $err_url); $sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ' . $sql_statement . ';'; // If there is a request for SQL previewing. if (isset($_REQUEST['preview_sql'])) { PMA_previewSQL($sql_query); } return array($GLOBALS['dbi']->tryQuery($sql_query), $sql_query); }
/** * Handles the whole import logic * * @return void */ public function doImport() { global $db, $table, $csv_terminated, $csv_enclosed, $csv_escaped, $csv_new_line, $csv_columns, $err_url; // $csv_replace and $csv_ignore should have been here, // but we use directly from $_POST global $error, $timeout_passed, $finished, $message; $replacements = array('\\n' => "\n", '\\t' => "\t", '\\r' => "\r"); $csv_terminated = strtr($csv_terminated, $replacements); $csv_enclosed = strtr($csv_enclosed, $replacements); $csv_escaped = strtr($csv_escaped, $replacements); $csv_new_line = strtr($csv_new_line, $replacements); $param_error = false; if (mb_strlen($csv_terminated) < 1) { $message = PMA_Message::error(__('Invalid parameter for CSV import: %s')); $message->addParam(__('Columns terminated with'), false); $error = true; $param_error = true; // The default dialog of MS Excel when generating a CSV produces a // semi-colon-separated file with no chance of specifying the // enclosing character. Thus, users who want to import this file // tend to remove the enclosing character on the Import dialog. // I could not find a test case where having no enclosing characters // confuses this script. // But the parser won't work correctly with strings so we allow just // one character. } elseif (mb_strlen($csv_enclosed) > 1) { $message = PMA_Message::error(__('Invalid parameter for CSV import: %s')); $message->addParam(__('Columns enclosed with'), false); $error = true; $param_error = true; } elseif (mb_strlen($csv_escaped) != 1) { $message = PMA_Message::error(__('Invalid parameter for CSV import: %s')); $message->addParam(__('Columns escaped with'), false); $error = true; $param_error = true; } elseif (mb_strlen($csv_new_line) != 1 && $csv_new_line != 'auto') { $message = PMA_Message::error(__('Invalid parameter for CSV import: %s')); $message->addParam(__('Lines terminated with'), false); $error = true; $param_error = true; } // If there is an error in the parameters entered, // indicate that immediately. if ($param_error) { PMA_Util::mysqlDie($message->getMessage(), '', false, $err_url); } $buffer = ''; $required_fields = 0; if (!$this->_getAnalyze()) { $sql_template = 'INSERT'; if (isset($_POST['csv_ignore'])) { $sql_template .= ' IGNORE'; } $sql_template .= ' INTO ' . PMA_Util::backquote($table); $tmp_fields = $GLOBALS['dbi']->getColumns($db, $table); if (empty($csv_columns)) { $fields = $tmp_fields; } else { $sql_template .= ' ('; $fields = array(); $tmp = preg_split('/,( ?)/', $csv_columns); foreach ($tmp as $key => $val) { if (count($fields) > 0) { $sql_template .= ', '; } /* Trim also `, if user already included backquoted fields */ $val = trim($val, " \t\r\n\v`"); $found = false; foreach ($tmp_fields as $field) { if ($field['Field'] == $val) { $found = true; break; } } if (!$found) { $message = PMA_Message::error(__('Invalid column (%s) specified! Ensure that columns' . ' names are spelled correctly, separated by commas' . ', and not enclosed in quotes.')); $message->addParam($val); $error = true; break; } $fields[] = $field; $sql_template .= PMA_Util::backquote($val); } $sql_template .= ') '; } $required_fields = count($fields); $sql_template .= ' VALUES ('; } // Defaults for parser $i = 0; $len = 0; $lastlen = null; $line = 1; $lasti = -1; $values = array(); $csv_finish = false; $tempRow = array(); $rows = array(); $col_names = array(); $tables = array(); $col_count = 0; $max_cols = 0; $csv_terminated_len = mb_strlen($csv_terminated); while (!($finished && $i >= $len) && !$error && !$timeout_passed) { $data = PMA_importGetNextChunk(); if ($data === false) { // subtract data we didn't handle yet and stop processing $GLOBALS['offset'] -= strlen($buffer); break; } elseif ($data === true) { // Handle rest of buffer } else { // Append new data to buffer $buffer .= $data; unset($data); // Force a trailing new line at EOF to prevent parsing problems if ($finished && $buffer) { $finalch = mb_substr($buffer, -1); if ($csv_new_line == 'auto' && $finalch != "\r" && $finalch != "\n") { $buffer .= "\n"; } elseif ($csv_new_line != 'auto' && $finalch != $csv_new_line) { $buffer .= $csv_new_line; } } // Do not parse string when we're not at the end // and don't have new line inside if ($csv_new_line == 'auto' && mb_strpos($buffer, "\r") === false && mb_strpos($buffer, "\n") === false || $csv_new_line != 'auto' && mb_strpos($buffer, $csv_new_line) === false) { continue; } } // Current length of our buffer $len = mb_strlen($buffer); // Currently parsed char $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } while ($i < $len) { // Deadlock protection if ($lasti == $i && $lastlen == $len) { $message = PMA_Message::error(__('Invalid format of CSV input on line %d.')); $message->addParam($line); $error = true; break; } $lasti = $i; $lastlen = $len; // This can happen with auto EOL and \r at the end of buffer if (!$csv_finish) { // Grab empty field if ($ch == $csv_terminated) { if ($i == $len - 1) { break; } $values[] = ''; $i++; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } continue; } // Grab one field $fallbacki = $i; if ($ch == $csv_enclosed) { if ($i == $len - 1) { break; } $need_end = true; $i++; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } } else { $need_end = false; } $fail = false; $value = ''; while ($need_end && ($ch != $csv_enclosed || $csv_enclosed == $csv_escaped) || !$need_end && !($ch == $csv_terminated || $ch == $csv_new_line || $csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n"))) { if ($ch == $csv_escaped) { if ($i == $len - 1) { $fail = true; break; } $i++; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } if ($csv_enclosed == $csv_escaped && ($ch == $csv_terminated || $ch == $csv_new_line || $csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n"))) { break; } } $value .= $ch; if ($i == $len - 1) { if (!$finished) { $fail = true; } break; } $i++; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } } // unquoted NULL string if (false === $need_end && $value === 'NULL') { $value = null; } if ($fail) { $i = $fallbacki; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $i += $csv_terminated_len - 1; } break; } // Need to strip trailing enclosing char? if ($need_end && $ch == $csv_enclosed) { if ($finished && $i == $len - 1) { $ch = null; } elseif ($i == $len - 1) { $i = $fallbacki; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $i += $csv_terminated_len - 1; } break; } else { $i++; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } } } // Are we at the end? if ($ch == $csv_new_line || $csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n") || $finished && $i == $len - 1) { $csv_finish = true; } // Go to next char if ($ch == $csv_terminated) { if ($i == $len - 1) { $i = $fallbacki; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $i += $csv_terminated_len - 1; } break; } $i++; $ch = mb_substr($buffer, $i, 1); if ($csv_terminated_len > 1 && $ch == $csv_terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csv_terminated_len); $i += $csv_terminated_len - 1; } } // If everything went okay, store value $values[] = $value; } // End of line if ($csv_finish || $ch == $csv_new_line || $csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n")) { if ($csv_new_line == 'auto' && $ch == "\r") { // Handle "\r\n" if ($i >= $len - 2 && !$finished) { break; // We need more data to decide new line } if (mb_substr($buffer, $i + 1, 1) == "\n") { $i++; } } // We didn't parse value till the end of line, so there was // empty one if (!$csv_finish) { $values[] = ''; } if ($this->_getAnalyze()) { foreach ($values as $val) { $tempRow[] = $val; ++$col_count; } if ($col_count > $max_cols) { $max_cols = $col_count; } $col_count = 0; $rows[] = $tempRow; $tempRow = array(); } else { // Do we have correct count of values? if (count($values) != $required_fields) { // Hack for excel if ($values[count($values) - 1] == ';') { unset($values[count($values) - 1]); } else { $message = PMA_Message::error(__('Invalid column count in CSV input' . ' on line %d.')); $message->addParam($line); $error = true; break; } } $first = true; $sql = $sql_template; foreach ($values as $key => $val) { if (!$first) { $sql .= ', '; } if ($val === null) { $sql .= 'NULL'; } else { $sql .= '\'' . PMA_Util::sqlAddSlashes($val) . '\''; } $first = false; } $sql .= ')'; if (isset($_POST['csv_replace'])) { $sql .= " ON DUPLICATE KEY UPDATE "; foreach ($fields as $field) { $fieldName = PMA_Util::backquote($field['Field']); $sql .= $fieldName . " = VALUES(" . $fieldName . "), "; } $sql = rtrim($sql, ', '); } /** * @todo maybe we could add original line to verbose * SQL in comment */ PMA_importRunQuery($sql, $sql); } $line++; $csv_finish = false; $values = array(); $buffer = mb_substr($buffer, $i + 1); $len = mb_strlen($buffer); $i = 0; $lasti = -1; $ch = mb_substr($buffer, 0, 1); } } // End of parser loop } // End of import loop if ($this->_getAnalyze()) { /* Fill out all rows */ $num_rows = count($rows); for ($i = 0; $i < $num_rows; ++$i) { for ($j = count($rows[$i]); $j < $max_cols; ++$j) { $rows[$i][] = 'NULL'; } } if (isset($_REQUEST['csv_col_names'])) { $col_names = array_splice($rows, 0, 1); $col_names = $col_names[0]; // MySQL column names can't end with a space character. foreach ($col_names as $key => $col_name) { $col_names[$key] = rtrim($col_name); } } if (isset($col_names) && count($col_names) != $max_cols || !isset($col_names)) { // Fill out column names for ($i = 0; $i < $max_cols; ++$i) { $col_names[] = 'COL ' . ($i + 1); } } if (mb_strlen($db)) { $result = $GLOBALS['dbi']->fetchResult('SHOW TABLES'); $tbl_name = 'TABLE ' . (count($result) + 1); } else { $tbl_name = 'TBL_NAME'; } $tables[] = array($tbl_name, $col_names, $rows); /* Obtain the best-fit MySQL types for each column */ $analyses = array(); $analyses[] = PMA_analyzeTable($tables[0]); /** * string $db_name (no backquotes) * * array $table = array(table_name, array() column_names, array()() rows) * array $tables = array of "$table"s * * array $analysis = array(array() column_types, array() column_sizes) * array $analyses = array of "$analysis"s * * array $create = array of SQL strings * * array $options = an associative array of options */ /* Set database name to the currently selected one, if applicable */ list($db_name, $options) = $this->getDbnameAndOptions($db, 'CSV_DB'); /* Non-applicable parameters */ $create = null; /* Created and execute necessary SQL statements from data */ PMA_buildSQL($db_name, $tables, $analyses, $create, $options); unset($tables); unset($analyses); } // Commit any possible data in buffers PMA_importRunQuery(); if (count($values) != 0 && !$error) { $message = PMA_Message::error(__('Invalid format of CSV input on line %d.')); $message->addParam($line); $error = true; } }
/** * returns array with databases containing extended infos about them * * @param string $database database * @param boolean $force_stats retrieve stats also for MySQL < 5 * @param resource $link mysql link * @param string $sort_by column to order by * @param string $sort_order ASC or DESC * @param integer $limit_offset starting offset for LIMIT * @param bool|int $limit_count row count for LIMIT or true * for $GLOBALS['cfg']['MaxDbList'] * * @todo move into PMA_List_Database? * * @return array $databases */ function PMA_DBI_get_databases_full($database = null, $force_stats = false, $link = null, $sort_by = 'SCHEMA_NAME', $sort_order = 'ASC', $limit_offset = 0, $limit_count = false) { $sort_order = strtoupper($sort_order); if (true === $limit_count) { $limit_count = $GLOBALS['cfg']['MaxDbList']; } // initialize to avoid errors when there are no databases $databases = array(); $apply_limit_and_order_manual = true; if (!$GLOBALS['cfg']['Server']['DisableIS']) { /** * if $GLOBALS['cfg']['NaturalOrder'] is enabled, we cannot use LIMIT * cause MySQL does not support natural ordering, we have to do it afterward */ $limit = ''; if (!$GLOBALS['cfg']['NaturalOrder']) { if ($limit_count) { $limit = ' LIMIT ' . $limit_count . ' OFFSET ' . $limit_offset; } $apply_limit_and_order_manual = false; } // get table information from information_schema if ($database) { $sql_where_schema = 'WHERE `SCHEMA_NAME` LIKE \'' . PMA_Util::sqlAddSlashes($database) . '\''; } else { $sql_where_schema = ''; } if (PMA_DRIZZLE) { // data_dictionary.table_cache may not contain any data for some // tables, it's just a table cache $sql = 'SELECT s.SCHEMA_NAME, s.DEFAULT_COLLATION_NAME'; if ($force_stats) { // no TABLE_CACHE data, stable results are better than // constantly changing $sql .= ', COUNT(t.TABLE_SCHEMA) AS SCHEMA_TABLES, SUM(stat.NUM_ROWS) AS SCHEMA_TABLE_ROWS'; } $sql .= ' FROM data_dictionary.SCHEMAS s'; if ($force_stats) { $engine_info = PMA_Util::cacheGet('drizzle_engines', true); $stats_join = "LEFT JOIN (SELECT 0 NUM_ROWS) AS stat ON false"; if (isset($engine_info['InnoDB']) && $engine_info['InnoDB']['module_library'] == 'innobase') { $stats_join = "LEFT JOIN data_dictionary.INNODB_SYS_TABLESTATS" . " stat ON (t.ENGINE = 'InnoDB' AND stat.NAME" . " = (t.TABLE_SCHEMA || '/') || t.TABLE_NAME)"; } $sql .= "\n LEFT JOIN data_dictionary.TABLES t\n ON t.TABLE_SCHEMA = s.SCHEMA_NAME\n {$stats_join}"; } $sql .= $sql_where_schema . ' GROUP BY s.SCHEMA_NAME ORDER BY ' . PMA_Util::backquote($sort_by) . ' ' . $sort_order . $limit; } else { $sql = 'SELECT s.SCHEMA_NAME, s.DEFAULT_COLLATION_NAME'; if ($force_stats) { $sql .= ', COUNT(t.TABLE_SCHEMA) AS SCHEMA_TABLES, SUM(t.TABLE_ROWS) AS SCHEMA_TABLE_ROWS, SUM(t.DATA_LENGTH) AS SCHEMA_DATA_LENGTH, SUM(t.MAX_DATA_LENGTH) AS SCHEMA_MAX_DATA_LENGTH, SUM(t.INDEX_LENGTH) AS SCHEMA_INDEX_LENGTH, SUM(t.DATA_LENGTH + t.INDEX_LENGTH) AS SCHEMA_LENGTH, SUM(t.DATA_FREE) AS SCHEMA_DATA_FREE'; } $sql .= ' FROM `information_schema`.SCHEMATA s'; if ($force_stats) { $sql .= ' LEFT JOIN `information_schema`.TABLES t ON BINARY t.TABLE_SCHEMA = BINARY s.SCHEMA_NAME'; } $sql .= $sql_where_schema . ' GROUP BY BINARY s.SCHEMA_NAME ORDER BY BINARY ' . PMA_Util::backquote($sort_by) . ' ' . $sort_order . $limit; } $databases = PMA_DBI_fetch_result($sql, 'SCHEMA_NAME', null, $link); $mysql_error = PMA_DBI_getError($link); if (!count($databases) && $GLOBALS['errno']) { PMA_Util::mysqlDie($mysql_error, $sql); } // display only databases also in official database list // f.e. to apply hide_db and only_db $drops = array_diff(array_keys($databases), (array) $GLOBALS['pma']->databases); if (count($drops)) { foreach ($drops as $drop) { unset($databases[$drop]); } unset($drop); } unset($sql_where_schema, $sql, $drops); } else { foreach ($GLOBALS['pma']->databases as $database_name) { // MySQL forward compatibility // so pma could use this array as if every server is of version >5.0 // todo : remove and check the rest of the code for usage, // MySQL 5.0 or higher is required for current PMA version $databases[$database_name]['SCHEMA_NAME'] = $database_name; if ($force_stats) { include_once './libraries/mysql_charsets.lib.php'; $databases[$database_name]['DEFAULT_COLLATION_NAME'] = PMA_getDbCollation($database_name); // get additional info about tables $databases[$database_name]['SCHEMA_TABLES'] = 0; $databases[$database_name]['SCHEMA_TABLE_ROWS'] = 0; $databases[$database_name]['SCHEMA_DATA_LENGTH'] = 0; $databases[$database_name]['SCHEMA_MAX_DATA_LENGTH'] = 0; $databases[$database_name]['SCHEMA_INDEX_LENGTH'] = 0; $databases[$database_name]['SCHEMA_LENGTH'] = 0; $databases[$database_name]['SCHEMA_DATA_FREE'] = 0; $res = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_Util::backquote($database_name) . ';'); while ($row = PMA_DBI_fetch_assoc($res)) { $databases[$database_name]['SCHEMA_TABLES']++; $databases[$database_name]['SCHEMA_TABLE_ROWS'] += $row['Rows']; $databases[$database_name]['SCHEMA_DATA_LENGTH'] += $row['Data_length']; $databases[$database_name]['SCHEMA_MAX_DATA_LENGTH'] += $row['Max_data_length']; $databases[$database_name]['SCHEMA_INDEX_LENGTH'] += $row['Index_length']; // for InnoDB, this does not contain the number of // overhead bytes but the total free space if ('InnoDB' != $row['Engine']) { $databases[$database_name]['SCHEMA_DATA_FREE'] += $row['Data_free']; } $databases[$database_name]['SCHEMA_LENGTH'] += $row['Data_length'] + $row['Index_length']; } PMA_DBI_free_result($res); unset($res); } } } /** * apply limit and order manually now * (caused by older MySQL < 5 or $GLOBALS['cfg']['NaturalOrder']) */ if ($apply_limit_and_order_manual) { $GLOBALS['callback_sort_order'] = $sort_order; $GLOBALS['callback_sort_by'] = $sort_by; usort($databases, 'PMA_usort_comparison_callback'); unset($GLOBALS['callback_sort_order'], $GLOBALS['callback_sort_by']); /** * now apply limit */ if ($limit_count) { $databases = array_slice($databases, $limit_offset, $limit_count); } } return $databases; }
/** * Function to handle foreign key updates * * @param array $destination_foreign_db destination foreign database * @param array $multi_edit_columns_name multi edit column names * @param array $destination_foreign_table destination foreign table * @param array $destination_foreign_column destination foreign column * @param array $options_array options array * @param string $table current table * @param array $existrel_foreign db, table, column * * @return array */ public function updateForeignKeys($destination_foreign_db, $multi_edit_columns_name, $destination_foreign_table, $destination_foreign_column, $options_array, $table, $existrel_foreign) { $html_output = ''; $preview_sql_data = ''; $display_query = ''; $seen_error = false; foreach ($destination_foreign_db as $master_field_md5 => $foreign_db) { $create = false; $drop = false; // Map the fieldname's md5 back to its real name $master_field = $multi_edit_columns_name[$master_field_md5]; $foreign_table = $destination_foreign_table[$master_field_md5]; $foreign_field = $destination_foreign_column[$master_field_md5]; if (isset($existrel_foreign[$master_field_md5]['ref_db_name'])) { $ref_db_name = $existrel_foreign[$master_field_md5]['ref_db_name']; } else { $ref_db_name = $GLOBALS['db']; } $empty_fields = false; foreach ($master_field as $key => $one_field) { if (!empty($one_field) && empty($foreign_field[$key]) || empty($one_field) && !empty($foreign_field[$key])) { $empty_fields = true; } if (empty($one_field) && empty($foreign_field[$key])) { unset($master_field[$key]); unset($foreign_field[$key]); } } if (!empty($foreign_db) && !empty($foreign_table) && !$empty_fields) { if (isset($existrel_foreign[$master_field_md5])) { $constraint_name = $existrel_foreign[$master_field_md5]['constraint']; $on_delete = !empty($existrel_foreign[$master_field_md5]['on_delete']) ? $existrel_foreign[$master_field_md5]['on_delete'] : 'RESTRICT'; $on_update = !empty($existrel_foreign[$master_field_md5]['on_update']) ? $existrel_foreign[$master_field_md5]['on_update'] : 'RESTRICT'; if ($ref_db_name != $foreign_db || $existrel_foreign[$master_field_md5]['ref_table_name'] != $foreign_table || $existrel_foreign[$master_field_md5]['ref_index_list'] != $foreign_field || $existrel_foreign[$master_field_md5]['index_list'] != $master_field || $_REQUEST['constraint_name'][$master_field_md5] != $constraint_name || $_REQUEST['on_delete'][$master_field_md5] != $on_delete || $_REQUEST['on_update'][$master_field_md5] != $on_update) { // another foreign key is already defined for this field // or an option has been changed for ON DELETE or ON UPDATE $drop = true; $create = true; } // end if... else.... } else { // no key defined for this field(s) $create = true; } } elseif (isset($existrel_foreign[$master_field_md5])) { $drop = true; } // end if... else.... $tmp_error_drop = false; if ($drop) { $drop_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' DROP FOREIGN KEY ' . PMA_Util::backquote($existrel_foreign[$master_field_md5]['constraint']) . ';'; if (!isset($_REQUEST['preview_sql'])) { $display_query .= $drop_query . "\n"; $this->_dbi->tryQuery($drop_query); $tmp_error_drop = $this->_dbi->getError(); if (!empty($tmp_error_drop)) { $seen_error = true; $html_output .= PMA_Util::mysqlDie($tmp_error_drop, $drop_query, false, '', false); continue; } } else { $preview_sql_data .= $drop_query . "\n"; } } $tmp_error_create = false; if (!$create) { continue; } $create_query = $this->_getSQLToCreateForeignKey($table, $master_field, $foreign_db, $foreign_table, $foreign_field, $_REQUEST['constraint_name'][$master_field_md5], $options_array[$_REQUEST['on_delete'][$master_field_md5]], $options_array[$_REQUEST['on_update'][$master_field_md5]]); if (!isset($_REQUEST['preview_sql'])) { $display_query .= $create_query . "\n"; $this->_dbi->tryQuery($create_query); $tmp_error_create = $this->_dbi->getError(); if (!empty($tmp_error_create)) { $seen_error = true; if (substr($tmp_error_create, 1, 4) == '1005') { $message = PMA_Message::error(__('Error creating foreign key on %1$s (check data ' . 'types)')); $message->addParam(implode(', ', $master_field)); $html_output .= $message->getDisplay(); } else { $html_output .= PMA_Util::mysqlDie($tmp_error_create, $create_query, false, '', false); } $html_output .= PMA_Util::showMySQLDocu('InnoDB_foreign_key_constraints') . "\n"; } } else { $preview_sql_data .= $create_query . "\n"; } // this is an alteration and the old constraint has been dropped // without creation of a new one if ($drop && $create && empty($tmp_error_drop) && !empty($tmp_error_create)) { // a rollback may be better here $sql_query_recreate = '# Restoring the dropped constraint...' . "\n"; $sql_query_recreate .= $this->_getSQLToCreateForeignKey($table, $master_field, $existrel_foreign[$master_field_md5]['ref_db_name'], $existrel_foreign[$master_field_md5]['ref_table_name'], $existrel_foreign[$master_field_md5]['ref_index_list'], $existrel_foreign[$master_field_md5]['constraint'], $options_array[$existrel_foreign[$master_field_md5]['on_delete']], $options_array[$existrel_foreign[$master_field_md5]['on_update']]); if (!isset($_REQUEST['preview_sql'])) { $display_query .= $sql_query_recreate . "\n"; $this->_dbi->tryQuery($sql_query_recreate); } else { $preview_sql_data .= $sql_query_recreate; } } } // end foreach return array($html_output, $preview_sql_data, $display_query, $seen_error); }
/** * returns array with databases containing extended infos about them * * @param string $database database * @param boolean $force_stats retrieve stats also for MySQL < 5 * @param resource $link mysql link * @param string $sort_by column to order by * @param string $sort_order ASC or DESC * @param integer $limit_offset starting offset for LIMIT * @param bool|int $limit_count row count for LIMIT or true * for $GLOBALS['cfg']['MaxDbList'] * * @todo move into PMA_List_Database? * * @return array $databases */ public function getDatabasesFull($database = null, $force_stats = false, $link = null, $sort_by = 'SCHEMA_NAME', $sort_order = 'ASC', $limit_offset = 0, $limit_count = false) { $sort_order = strtoupper($sort_order); if (true === $limit_count) { $limit_count = $GLOBALS['cfg']['MaxDbList']; } // initialize to avoid errors when there are no databases $databases = array(); $apply_limit_and_order_manual = true; /** * if $GLOBALS['cfg']['NaturalOrder'] is enabled, we cannot use LIMIT * cause MySQL does not support natural ordering, * we have to do it afterward */ $limit = ''; if (!$GLOBALS['cfg']['NaturalOrder']) { if ($limit_count) { $limit = ' LIMIT ' . $limit_count . ' OFFSET ' . $limit_offset; } $apply_limit_and_order_manual = false; } // get table information from information_schema if ($database) { $sql_where_schema = 'WHERE `SCHEMA_NAME` LIKE \'' . PMA_Util::sqlAddSlashes($database) . '\''; } else { $sql_where_schema = ''; } if (PMA_DRIZZLE) { // data_dictionary.table_cache may not contain any data for some // tables, it's just a table cache $sql = 'SELECT s.SCHEMA_NAME, s.DEFAULT_COLLATION_NAME'; if ($force_stats) { // no TABLE_CACHE data, stable results are better than // constantly changing $sql .= ', COUNT(t.TABLE_SCHEMA) AS SCHEMA_TABLES, SUM(stat.NUM_ROWS) AS SCHEMA_TABLE_ROWS'; } $sql .= ' FROM data_dictionary.SCHEMAS s'; if ($force_stats) { $engine_info = PMA_Util::cacheGet('drizzle_engines', true); $stats_join = "LEFT JOIN (SELECT 0 NUM_ROWS) AS stat ON false"; if (isset($engine_info['InnoDB']) && $engine_info['InnoDB']['module_library'] == 'innobase') { $stats_join = "LEFT JOIN data_dictionary.INNODB_SYS_TABLESTATS stat" . " ON (t.ENGINE = 'InnoDB' AND stat.NAME" . " = (t.TABLE_SCHEMA || '/') || t.TABLE_NAME)"; } $sql .= "\n LEFT JOIN data_dictionary.TABLES t\n ON t.TABLE_SCHEMA = s.SCHEMA_NAME\n {$stats_join}"; } $sql .= $sql_where_schema . ' GROUP BY s.SCHEMA_NAME ORDER BY ' . PMA_Util::backquote($sort_by) . ' ' . $sort_order . $limit; } else { $sql = 'SELECT s.SCHEMA_NAME, s.DEFAULT_COLLATION_NAME'; if ($force_stats) { $sql .= ', COUNT(t.TABLE_SCHEMA) AS SCHEMA_TABLES, SUM(t.TABLE_ROWS) AS SCHEMA_TABLE_ROWS, SUM(t.DATA_LENGTH) AS SCHEMA_DATA_LENGTH, SUM(t.MAX_DATA_LENGTH) AS SCHEMA_MAX_DATA_LENGTH, SUM(t.INDEX_LENGTH) AS SCHEMA_INDEX_LENGTH, SUM(t.DATA_LENGTH + t.INDEX_LENGTH) AS SCHEMA_LENGTH, SUM(t.DATA_FREE) AS SCHEMA_DATA_FREE'; } $sql .= ' FROM `information_schema`.SCHEMATA s'; if ($force_stats) { $sql .= ' LEFT JOIN `information_schema`.TABLES t ON BINARY t.TABLE_SCHEMA = BINARY s.SCHEMA_NAME'; } $sql .= $sql_where_schema . ' GROUP BY BINARY s.SCHEMA_NAME ORDER BY BINARY ' . PMA_Util::backquote($sort_by) . ' ' . $sort_order . $limit; } $databases = $this->fetchResult($sql, 'SCHEMA_NAME', null, $link); $mysql_error = $this->getError($link); if (!count($databases) && $GLOBALS['errno']) { PMA_Util::mysqlDie($mysql_error, $sql); } // display only databases also in official database list // f.e. to apply hide_db and only_db $drops = array_diff(array_keys($databases), (array) $GLOBALS['pma']->databases); if (count($drops)) { foreach ($drops as $drop) { unset($databases[$drop]); } unset($drop); } unset($sql_where_schema, $sql, $drops); /** * apply limit and order manually now * (caused by older MySQL < 5 or $GLOBALS['cfg']['NaturalOrder']) */ if ($apply_limit_and_order_manual) { $GLOBALS['callback_sort_order'] = $sort_order; $GLOBALS['callback_sort_by'] = $sort_by; usort($databases, array('PMA_DatabaseInterface', '_usortComparisonCallback')); unset($GLOBALS['callback_sort_order'], $GLOBALS['callback_sort_by']); /** * now apply limit */ if ($limit_count) { $databases = array_slice($databases, $limit_offset, $limit_count); } } return $databases; }
if ($_REQUEST['ajax_request'] == true) { $response = PMA_Response::getInstance(); $response->isSuccess($message->isSuccess()); $response->addJSON('message', $message); $response->addJSON( 'sql_query', PMA_Util::getMessage(null, $sql_query) ); exit; } $active_page = 'tbl_structure.php'; include 'tbl_structure.php'; } else { PMA_Util::mysqlDie('', '', '', $err_url, false); // An error happened while inserting/updating a table definition. // to prevent total loss of that data, we embed the form once again. // The variable $regenerate will be used to restore data in libraries/tbl_properties.inc.php if (isset($_REQUEST['orig_field'])) { $_REQUEST['field'] = $_REQUEST['orig_field']; } $regenerate = true; } } /** * No modifications yet required -> displays the table fields * * $selected comes from multi_submits.inc.php
// if there is any message, copy it into $_SESSION as well, // so we can obtain it by AJAX call if (isset($message)) { $_SESSION['Import_message']['message'] = $message->getDisplay(); } // Parse and analyze the query, for correct db and table name // in case of a query typed in the query window // (but if the query is too large, in case of an imported file, the parser // can choke on it so avoid parsing) if (strlen($sql_query) <= $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) { include_once 'libraries/parse_analyze.inc.php'; } // There was an error? if (isset($my_die)) { foreach ($my_die as $key => $die) { PMA_Util::mysqlDie($die['error'], $die['sql'], false, $err_url, $error); } } if ($go_sql) { // parse sql query include_once 'libraries/parse_analyze.inc.php'; if (isset($ajax_reload) && $ajax_reload['reload'] === true) { $response = PMA_Response::getInstance(); $response->addJSON('ajax_reload', $ajax_reload); } PMA_executeQueryAndSendQueryResponse($analyzed_sql_results, false, $db, $table, null, $import_text, null, $analyzed_sql_results['is_affected'], null, null, null, null, $goto, $pmaThemeImage, null, null, null, $sql_query, null, null); } else { if ($result) { // Save a Bookmark with more than one queries (if Bookmark label given). if (!empty($_POST['bkm_label']) && !empty($import_text)) { PMA_storeTheQueryAsBookmark($db, $GLOBALS['cfg']['Bookmark']['user'], $import_text, $_POST['bkm_label'], isset($_POST['bkm_replace']) ? $_POST['bkm_replace'] : null);
/** * Update password and get message for password updating * * @param string $err_url error url * @param string $username username * @param string $hostname hostname * * @return string $message success or error message after updating password */ function PMA_updatePassword($err_url, $username, $hostname) { // similar logic in user_password.php $message = ''; $is_superuser = $GLOBALS['dbi']->isSuperuser(); if (empty($_REQUEST['nopass']) && isset($_POST['pma_pw']) && isset($_POST['pma_pw2'])) { if ($_POST['pma_pw'] != $_POST['pma_pw2']) { $message = PMA_Message::error(__('The passwords aren\'t the same!')); } elseif (empty($_POST['pma_pw']) || empty($_POST['pma_pw2'])) { $message = PMA_Message::error(__('The password is empty!')); } } // here $nopass could be == 1 if (empty($message)) { $hashing_function = 'PASSWORD'; $serverType = PMA_Util::getServerType(); $authentication_plugin = isset($_REQUEST['authentication_plugin']) ? $_REQUEST['authentication_plugin'] : PMA_getCurrentAuthenticationPlugin('change', $username, $hostname); // Use 'ALTER USER ...' syntax for MySQL 5.7.6+ if ($serverType == 'MySQL' && PMA_MYSQL_INT_VERSION >= 50706) { if ($authentication_plugin != 'mysql_old_password') { $query_prefix = "ALTER USER '" . PMA_Util::sqlAddSlashes($username) . "'@'" . PMA_Util::sqlAddSlashes($hostname) . "'" . " IDENTIFIED WITH " . $authentication_plugin . " BY '"; } else { $query_prefix = "ALTER USER '" . PMA_Util::sqlAddSlashes($username) . "'@'" . PMA_Util::sqlAddSlashes($hostname) . "'" . " IDENTIFIED BY '"; } // in $sql_query which will be displayed, hide the password $sql_query = $query_prefix . "*'"; $local_query = $query_prefix . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . "'"; } else { if ($serverType == 'MariaDB' && PMA_MYSQL_INT_VERSION >= 50200 && $is_superuser) { // Use 'UPDATE `mysql`.`user` ...' Syntax for MariaDB 5.2+ if ($authentication_plugin == 'mysql_native_password') { // Set the hashing method used by PASSWORD() // to be 'mysql_native_password' type $GLOBALS['dbi']->tryQuery('SET old_passwords = 0;'); } else { if ($authentication_plugin == 'sha256_password') { // Set the hashing method used by PASSWORD() // to be 'sha256_password' type $GLOBALS['dbi']->tryQuery('SET `old_passwords` = 2;'); } } $hashedPassword = PMA_getHashedPassword($_POST['pma_pw']); $sql_query = 'SET PASSWORD FOR \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = ' . ($_POST['pma_pw'] == '' ? '\'\'' : $hashing_function . '(\'' . preg_replace('@.@s', '*', $_POST['pma_pw']) . '\')'); $local_query = "UPDATE `mysql`.`user` SET " . " `authentication_string` = '" . $hashedPassword . "', `Password` = '', " . " `plugin` = '" . $authentication_plugin . "'" . " WHERE `User` = '" . $username . "' AND Host = '" . $hostname . "';"; $GLOBALS['dbi']->tryQuery("FLUSH PRIVILEGES;"); } else { // USE 'SET PASSWORD ...' syntax for rest of the versions // Backup the old value, to be reset later $row = $GLOBALS['dbi']->fetchSingleRow('SELECT @@old_passwords;'); $orig_value = $row['@@old_passwords']; $update_plugin_query = "UPDATE `mysql`.`user` SET" . " `plugin` = '" . $authentication_plugin . "'" . " WHERE `User` = '" . $username . "' AND Host = '" . $hostname . "';"; // Update the plugin for the user $GLOBALS['dbi']->tryQuery($update_plugin_query) or PMA_Util::mysqlDie($GLOBALS['dbi']->getError(), $update_plugin_query, false, $err_url); $GLOBALS['dbi']->tryQuery("FLUSH PRIVILEGES;"); if ($authentication_plugin == 'mysql_native_password') { // Set the hashing method used by PASSWORD() // to be 'mysql_native_password' type $GLOBALS['dbi']->tryQuery('SET old_passwords = 0;'); } else { if ($authentication_plugin == 'sha256_password') { // Set the hashing method used by PASSWORD() // to be 'sha256_password' type $GLOBALS['dbi']->tryQuery('SET `old_passwords` = 2;'); } } $sql_query = 'SET PASSWORD FOR \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = ' . ($_POST['pma_pw'] == '' ? '\'\'' : $hashing_function . '(\'' . preg_replace('@.@s', '*', $_POST['pma_pw']) . '\')'); $local_query = 'SET PASSWORD FOR \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = ' . ($_POST['pma_pw'] == '' ? '\'\'' : $hashing_function . '(\'' . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . '\')'); } } $GLOBALS['dbi']->tryQuery($local_query) or PMA_Util::mysqlDie($GLOBALS['dbi']->getError(), $sql_query, false, $err_url); $message = PMA_Message::success(__('The password for %s was changed successfully.')); $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\''); if (isset($orig_value)) { $GLOBALS['dbi']->tryQuery('SET `old_passwords` = ' . $orig_value . ';'); } } return $message; }
/** * Gets some core libraries */ require_once 'libraries/common.inc.php'; require_once 'libraries/DbSearch.class.php'; $response = PMA_Response::getInstance(); $header = $response->getHeader(); $scripts = $header->getScripts(); $scripts->addFile('db_search.js'); $scripts->addFile('sql.js'); $scripts->addFile('makegrid.js'); $scripts->addFile('jquery/jquery-ui-timepicker-addon.js'); require 'libraries/db_common.inc.php'; // If config variable $GLOBALS['cfg']['Usedbsearch'] is on false : exit. if (!$GLOBALS['cfg']['UseDbSearch']) { PMA_Util::mysqlDie(__('Access denied!'), '', false, $err_url); } // end if $url_query .= '&goto=db_search.php'; $url_params['goto'] = 'db_search.php'; // Create a database search instance $db_search = new PMA_DbSearch($GLOBALS['db']); // Display top links if we are not in an Ajax request if ($GLOBALS['is_ajax_request'] != true) { include 'libraries/db_info.inc.php'; } // Main search form has been submitted, get results if (isset($_REQUEST['submit_search'])) { $response->addHTML($db_search->getSearchResults()); } else { $response->addHTML('<div id="searchresults"></div>');
/** * Function to execute the column creation statement * * @param string $db current database * @param string $table current table * @param string $err_url error page url * * @return array */ function PMA_tryColumnCreationQuery($db, $table, $err_url) { // get column addition statements $sql_statement = PMA_getColumnCreationStatements(false); // To allow replication, we first select the db to use and then run queries // on this db. $GLOBALS['dbi']->selectDb($db) or PMA_Util::mysqlDie($GLOBALS['dbi']->getError(), 'USE ' . PMA_Util::backquote($db), false, $err_url); $sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ' . $sql_statement . ';'; return array($GLOBALS['dbi']->tryQuery($sql_query), $sql_query); }
* * @package PhpMyAdmin */ /** * Common functions. */ // we don't want the usual PMA_Response-generated HTML above the column's data define('PMA_BYPASS_GET_INSTANCE', 1); require_once 'libraries/common.inc.php'; require_once 'libraries/mime.lib.php'; /* Check parameters */ PMA_Util::checkParameters(array('db', 'table')); /* Select database */ if (!$GLOBALS['dbi']->selectDb($db)) { PMA_Util::mysqlDie(sprintf(__('\'%s\' database does not exist.'), htmlspecialchars($db)), '', ''); } /* Check if table exists */ if (!$GLOBALS['dbi']->getColumns($db, $table)) { PMA_Util::mysqlDie(__('Invalid table name')); } /* Grab data */ $sql = 'SELECT ' . PMA_Util::backquote($_GET['transform_key']) . ' FROM ' . PMA_Util::backquote($table) . ' WHERE ' . $_GET['where_clause'] . ';'; $result = $GLOBALS['dbi']->fetchValue($sql); /* Check return code */ if ($result === false) { PMA_Util::mysqlDie(__('MySQL returned an empty result set (i.e. zero rows).'), $sql); } /* Avoid corrupting data */ @ini_set('url_rewriter.tags', ''); PMA_downloadHeader($table . '-' . $_GET['transform_key'] . '.bin', PMA_detectMIME($result), strlen($result)); echo $result;
/** * Generate the error url and submit the query * * @param string $password Password * @param array $_url_params URL parameters * @param string $sql_query SQL query * @param string $hashing_function Hashing function * * @return void */ function PMA_changePassUrlParamsAndSubmitQuery($password, $_url_params, $sql_query, $hashing_function) { $err_url = 'user_password.php' . PMA_URL_getCommon($_url_params); $local_query = 'SET password = '******'' ? '\'\'' : $hashing_function . '(\'' . PMA_Util::sqlAddSlashes($password) . '\')'); if (!@$GLOBALS['dbi']->tryQuery($local_query)) { PMA_Util::mysqlDie($GLOBALS['dbi']->getError(), $sql_query, false, $err_url); } }
/** * User is not allowed to login to MySQL -> authentication failed * * @global string the MySQL error message PHP returns * @global string the connection type (persistent or not) * @global string the MySQL server port to use * @global string the MySQL socket port to use * @global array the current server settings * @global string the font face to use in case of failure * @global string the default font size to use in case of failure * @global string the big font size to use in case of failure * @global boolean tell the "PMA_mysqlDie()" function headers have been * sent * * @return boolean always true (no return indeed) */ public function authFails() { $conn_error = $GLOBALS['dbi']->getError(); if (!$conn_error) { $conn_error = __('Cannot connect: invalid settings.'); } /* HTML header */ $response = PMA_Response::getInstance(); $response->getFooter()->setMinimal(); $header = $response->getHeader(); $header->setBodyId('loginform'); $header->setTitle(__('Access denied!')); $header->disableMenuAndConsole(); echo '<br /><br /> <center> <h1>'; echo sprintf(__('Welcome to %s'), ' phpMyAdmin '); echo '</h1> </center> <br /> <table cellpadding="0" cellspacing="3" style="margin: 0 auto" width="80%"> <tr> <td>'; if (isset($GLOBALS['allowDeny_forbidden']) && $GLOBALS['allowDeny_forbidden']) { trigger_error(__('Access denied!'), E_USER_NOTICE); } else { // Check whether user has configured something if ($GLOBALS['PMA_Config']->source_mtime == 0) { echo '<p>' . sprintf(__('You probably did not create a configuration file.' . ' You might want to use the %1$ssetup script%2$s to' . ' create one.'), '<a href="setup/">', '</a>') . '</p>' . "\n"; } elseif (!isset($GLOBALS['errno']) || isset($GLOBALS['errno']) && $GLOBALS['errno'] != 2002 && $GLOBALS['errno'] != 2003) { // if we display the "Server not responding" error, do not confuse // users by telling them they have a settings problem // (note: it's true that they could have a badly typed host name, // but anyway the current message tells that the server // rejected the connection, which is not really what happened) // 2002 is the error given by mysqli // 2003 is the error given by mysql trigger_error(__('phpMyAdmin tried to connect to the MySQL server, and the' . ' server rejected the connection. You should check the' . ' host, username and password in your configuration and' . ' make sure that they correspond to the information given' . ' by the administrator of the MySQL server.'), E_USER_WARNING); } echo PMA_Util::mysqlDie($conn_error, '', true, '', false); } $GLOBALS['error_handler']->dispUserErrors(); echo '</td> </tr> <tr> <td>' . "\n"; echo '<a href="' . PMA_Util::getScriptNameForOption($GLOBALS['cfg']['DefaultTabServer'], 'server') . PMA_URL_getCommon(array()) . '" class="button disableAjax">' . __('Retry to connect') . '</a>' . "\n"; echo '</td> </tr>' . "\n"; if (count($GLOBALS['cfg']['Servers']) > 1) { // offer a chance to login to other servers if the current one failed include_once './libraries/select_server.lib.php'; echo '<tr>' . "\n"; echo ' <td>' . "\n"; echo PMA_selectServer(true, true); echo ' </td>' . "\n"; echo '</tr>' . "\n"; } echo '</table>' . "\n"; if (!defined('TESTSUITE')) { exit; } return true; }
/** * Update the table's structure based on $_REQUEST * * @param string $db database name * @param string $table table name * * @return boolean $regenerate true if error occurred * */ function PMA_updateColumns($db, $table) { $err_url = 'tbl_structure.php' . PMA_URL_getCommon(array('db' => $db, 'table' => $table)); $regenerate = false; $field_cnt = count($_REQUEST['field_name']); $changes = array(); $pmatable = new PMA_Table($table, $db); $adjust_privileges = array(); for ($i = 0; $i < $field_cnt; $i++) { if (PMA_columnNeedsAlterTable($i)) { $changes[] = 'CHANGE ' . PMA_Table::generateAlter(isset($_REQUEST['field_orig'][$i]) ? $_REQUEST['field_orig'][$i] : '', $_REQUEST['field_name'][$i], $_REQUEST['field_type'][$i], $_REQUEST['field_length'][$i], $_REQUEST['field_attribute'][$i], isset($_REQUEST['field_collation'][$i]) ? $_REQUEST['field_collation'][$i] : '', isset($_REQUEST['field_null'][$i]) ? $_REQUEST['field_null'][$i] : 'NOT NULL', $_REQUEST['field_default_type'][$i], $_REQUEST['field_default_value'][$i], isset($_REQUEST['field_extra'][$i]) ? $_REQUEST['field_extra'][$i] : false, isset($_REQUEST['field_comments'][$i]) ? $_REQUEST['field_comments'][$i] : '', isset($_REQUEST['field_virtuality'][$i]) ? $_REQUEST['field_virtuality'][$i] : '', isset($_REQUEST['field_expression'][$i]) ? $_REQUEST['field_expression'][$i] : '', isset($_REQUEST['field_move_to'][$i]) ? $_REQUEST['field_move_to'][$i] : ''); // find the remembered sort expression $sorted_col = $pmatable->getUiProp(PMA_Table::PROP_SORTED_COLUMN); // if the old column name is part of the remembered sort expression if (mb_strpos($sorted_col, PMA_Util::backquote($_REQUEST['field_orig'][$i])) !== false) { // delete the whole remembered sort expression $pmatable->removeUiProp(PMA_Table::PROP_SORTED_COLUMN); } if (isset($_REQUEST['field_adjust_privileges'][$i]) && !empty($_REQUEST['field_adjust_privileges'][$i]) && $_REQUEST['field_orig'][$i] != $_REQUEST['field_name'][$i]) { $adjust_privileges[$_REQUEST['field_orig'][$i]] = $_REQUEST['field_name'][$i]; } } } // end for $response = PMA_Response::getInstance(); if (count($changes) > 0 || isset($_REQUEST['preview_sql'])) { // Builds the primary keys statements and updates the table $key_query = ''; /** * this is a little bit more complex * * @todo if someone selects A_I when altering a column we need to check: * - no other column with A_I * - the column has an index, if not create one * */ // To allow replication, we first select the db to use // and then run queries on this db. if (!$GLOBALS['dbi']->selectDb($db)) { PMA_Util::mysqlDie($GLOBALS['dbi']->getError(), 'USE ' . PMA_Util::backquote($db) . ';', false, $err_url); } $sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' '; $sql_query .= implode(', ', $changes) . $key_query; $sql_query .= ';'; // If there is a request for SQL previewing. if (isset($_REQUEST['preview_sql'])) { PMA_previewSQL(count($changes) > 0 ? $sql_query : ''); } $changedToBlob = array(); // While changing the Column Collation // First change to BLOB for ($i = 0; $i < $field_cnt; $i++) { if (isset($_REQUEST['field_collation'][$i]) && isset($_REQUEST['field_collation_orig'][$i]) && $_REQUEST['field_collation'][$i] !== $_REQUEST['field_collation_orig'][$i]) { $secondary_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' CHANGE ' . PMA_Util::backquote($_REQUEST['field_orig'][$i]) . ' ' . PMA_Util::backquote($_REQUEST['field_orig'][$i]) . ' BLOB;'; $GLOBALS['dbi']->query($secondary_query); $changedToBlob[$i] = true; } else { $changedToBlob[$i] = false; } } // Then make the requested changes $result = $GLOBALS['dbi']->tryQuery($sql_query); if ($result !== false) { $changed_privileges = PMA_adjustColumnPrivileges($db, $table, $adjust_privileges); if ($changed_privileges) { $message = PMA_Message::success(__('Table %1$s has been altered successfully. Privileges ' . 'have been adjusted.')); } else { $message = PMA_Message::success(__('Table %1$s has been altered successfully.')); } $message->addParam($table); $response->addHTML(PMA_Util::getMessage($message, $sql_query, 'success')); } else { // An error happened while inserting/updating a table definition // Save the Original Error $orig_error = $GLOBALS['dbi']->getError(); $changes_revert = array(); // Change back to Orignal Collation and data type for ($i = 0; $i < $field_cnt; $i++) { if ($changedToBlob[$i]) { $changes_revert[] = 'CHANGE ' . PMA_Table::generateAlter(isset($_REQUEST['field_orig'][$i]) ? $_REQUEST['field_orig'][$i] : '', $_REQUEST['field_name'][$i], $_REQUEST['field_type_orig'][$i], $_REQUEST['field_length_orig'][$i], $_REQUEST['field_attribute_orig'][$i], isset($_REQUEST['field_collation_orig'][$i]) ? $_REQUEST['field_collation_orig'][$i] : '', isset($_REQUEST['field_null_orig'][$i]) ? $_REQUEST['field_null_orig'][$i] : 'NOT NULL', $_REQUEST['field_default_type_orig'][$i], $_REQUEST['field_default_value_orig'][$i], isset($_REQUEST['field_extra_orig'][$i]) ? $_REQUEST['field_extra_orig'][$i] : false, isset($_REQUEST['field_comments_orig'][$i]) ? $_REQUEST['field_comments_orig'][$i] : '', isset($_REQUEST['field_move_to_orig'][$i]) ? $_REQUEST['field_move_to_orig'][$i] : ''); } } $revert_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' '; $revert_query .= implode(', ', $changes_revert) . ''; $revert_query .= ';'; // Column reverted back to original $GLOBALS['dbi']->query($revert_query); $response->isSuccess(false); $response->addJSON('message', PMA_Message::rawError(__('Query error') . ':<br />' . $orig_error)); $regenerate = true; } } include_once 'libraries/transformations.lib.php'; // update field names in relation if (isset($_REQUEST['field_orig']) && is_array($_REQUEST['field_orig'])) { foreach ($_REQUEST['field_orig'] as $fieldindex => $fieldcontent) { if ($_REQUEST['field_name'][$fieldindex] != $fieldcontent) { PMA_REL_renameField($db, $table, $fieldcontent, $_REQUEST['field_name'][$fieldindex]); } } } // update mime types if (isset($_REQUEST['field_mimetype']) && is_array($_REQUEST['field_mimetype']) && $GLOBALS['cfg']['BrowseMIME']) { foreach ($_REQUEST['field_mimetype'] as $fieldindex => $mimetype) { if (isset($_REQUEST['field_name'][$fieldindex]) && mb_strlen($_REQUEST['field_name'][$fieldindex])) { PMA_setMIME($db, $table, $_REQUEST['field_name'][$fieldindex], $mimetype, $_REQUEST['field_transformation'][$fieldindex], $_REQUEST['field_transformation_options'][$fieldindex], $_REQUEST['field_input_transformation'][$fieldindex], $_REQUEST['field_input_transformation_options'][$fieldindex]); } } } return $regenerate; }
/** * Update password and get message for password updating * * @param string $err_url error url * @param string $username username * @param string $hostname hostname * * @return string $message success or error message after updating password */ function PMA_updatePassword($err_url, $username, $hostname) { // similar logic in user_password.php $message = ''; if (empty($_REQUEST['nopass']) && isset($_POST['pma_pw']) && isset($_POST['pma_pw2'])) { if ($_POST['pma_pw'] != $_POST['pma_pw2']) { $message = PMA_Message::error(__('The passwords aren\'t the same!')); } elseif (empty($_POST['pma_pw']) || empty($_POST['pma_pw2'])) { $message = PMA_Message::error(__('The password is empty!')); } } // here $nopass could be == 1 if (empty($message)) { if (PMA_Util::getServerType() == 'MySQL' && PMA_MYSQL_INT_VERSION >= 50706) { $query_prefix = "ALTER USER '" . PMA_Util::sqlAddSlashes($username) . "'@'" . PMA_Util::sqlAddSlashes($hostname) . "'" . " IDENTIFIED BY '"; // in $sql_query which will be displayed, hide the password $sql_query = $query_prefix . "*'"; $local_query = $query_prefix . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . "'"; } else { if (!empty($_REQUEST['pw_hash']) && $_REQUEST['pw_hash'] == 'old') { $hashing_function = 'OLD_PASSWORD'; } else { $hashing_function = 'PASSWORD'; } $sql_query = 'SET PASSWORD FOR \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = ' . ($_POST['pma_pw'] == '' ? '\'\'' : $hashing_function . '(\'' . preg_replace('@.@s', '*', $_POST['pma_pw']) . '\')'); $local_query = 'SET PASSWORD FOR \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\' = ' . ($_POST['pma_pw'] == '' ? '\'\'' : $hashing_function . '(\'' . PMA_Util::sqlAddSlashes($_POST['pma_pw']) . '\')'); } $GLOBALS['dbi']->tryQuery($local_query) or PMA_Util::mysqlDie($GLOBALS['dbi']->getError(), $sql_query, false, $err_url); $message = PMA_Message::success(__('The password for %s was changed successfully.')); $message->addParam('\'' . htmlspecialchars($username) . '\'@\'' . htmlspecialchars($hostname) . '\''); } return $message; }
. ' DROP FOREIGN KEY ' . PMA_Util::backquote($existrel_foreign[$master_field]['constraint']); $sql_query .= ';'; $display_query .= $sql_query . "\n"; } // end if... else.... if (! empty($sql_query)) { PMA_DBI_try_query($sql_query); $tmp_error = PMA_DBI_getError(); if (! empty($tmp_error)) { $seen_error = true; } if (substr($tmp_error, 1, 4) == '1216' || substr($tmp_error, 1, 4) == '1452' ) { PMA_Util::mysqlDie($tmp_error, $sql_query, false, '', false); echo PMA_Util::showMySQLDocu('manual_Table_types', 'InnoDB_foreign_key_constraints') . "\n"; } if (substr($tmp_error, 1, 4) == '1005') { $message = PMA_Message::error(__('Error creating foreign key on %1$s (check data types)')); $message->addParam($master_field); $message->display(); echo PMA_Util::showMySQLDocu('manual_Table_types', 'InnoDB_foreign_key_constraints') . "\n"; } unset($tmp_error); $sql_query = ''; } } // end foreach if (!empty($display_query)) { if ($seen_error) { echo PMA_Util::getMessage(__('Error'), null, 'error');