/** * Handles actions related to multiple tables * * @return void */ public function multiSubmitAction() { $action = 'db_structure.php'; $err_url = 'db_structure.php' . PMA_URL_getCommon(array('db' => $this->db)); // see bug #2794840; in this case, code path is: // db_structure.php -> libraries/mult_submits.inc.php -> sql.php // -> db_structure.php and if we got an error on the multi submit, // we must display it here and not call again mult_submits.inc.php if (!isset($_POST['error']) || false === $_POST['error']) { include 'libraries/mult_submits.inc.php'; } if (empty($_POST['message'])) { $_POST['message'] = Message::success(); } }
} elseif (!$run_parts) { $GLOBALS['dbi']->selectDb($db); $result = $GLOBALS['dbi']->tryQuery($sql_query); if ($result && !empty($sql_query_views)) { $sql_query .= ' ' . $sql_query_views . ';'; $result = $GLOBALS['dbi']->tryQuery($sql_query_views); unset($sql_query_views); } if (!$result) { $message = Message::error($GLOBALS['dbi']->getError()); } } if ($query_type == 'drop_tbl' || $query_type == 'empty_tbl' || $query_type == 'row_delete') { PMA\libraries\Util::handleDisableFKCheckCleanup($default_fk_check_value); } if ($rebuild_database_list) { // avoid a problem with the database list navigator // when dropping a db from server_databases $GLOBALS['pma']->databases->build(); } } else { if (isset($submit_mult) && ($submit_mult == 'sync_unique_columns_central_list' || $submit_mult == 'delete_unique_columns_central_list' || $submit_mult == 'add_to_central_columns' || $submit_mult == 'remove_from_central_columns' || $submit_mult == 'make_consistent_with_central_list')) { if (isset($centralColsError) && $centralColsError !== true) { $message = $centralColsError; } else { $message = Message::success(__('Success!')); } } else { $message = Message::success(__('No change')); } }
/** * Prepares queries for adding users and * also create database and return query and message * * @param boolean $_error whether user create or not * @param string $real_sql_query SQL query for add a user * @param string $sql_query SQL query to be displayed * @param string $username username * @param string $hostname host name * @param string $dbname database name * * @return array $sql_query, $message */ function PMA_addUserAndCreateDatabase($_error, $real_sql_query, $sql_query, $username, $hostname, $dbname) { if ($_error || !empty($real_sql_query) && !$GLOBALS['dbi']->tryQuery($real_sql_query)) { $_REQUEST['createdb-1'] = $_REQUEST['createdb-2'] = $_REQUEST['createdb-3'] = null; $message = Message::rawError($GLOBALS['dbi']->getError()); } else { $message = Message::success(__('You have added a new user.')); } if (isset($_REQUEST['createdb-1'])) { // Create database with same name and grant all privileges $q = 'CREATE DATABASE IF NOT EXISTS ' . Util::backquote(Util::sqlAddSlashes($username)) . ';'; $sql_query .= $q; if (!$GLOBALS['dbi']->tryQuery($q)) { $message = Message::rawError($GLOBALS['dbi']->getError()); } /** * Reload the navigation */ $GLOBALS['reload'] = true; $GLOBALS['db'] = $username; $q = 'GRANT ALL PRIVILEGES ON ' . Util::backquote(Util::escapeMysqlWildcards(Util::sqlAddSlashes($username))) . '.* TO \'' . Util::sqlAddSlashes($username) . '\'@\'' . Util::sqlAddSlashes($hostname) . '\';'; $sql_query .= $q; if (!$GLOBALS['dbi']->tryQuery($q)) { $message = Message::rawError($GLOBALS['dbi']->getError()); } } if (isset($_REQUEST['createdb-2'])) { // Grant all privileges on wildcard name (username\_%) $q = 'GRANT ALL PRIVILEGES ON ' . Util::backquote(Util::sqlAddSlashes($username) . '\\_%') . '.* TO \'' . Util::sqlAddSlashes($username) . '\'@\'' . Util::sqlAddSlashes($hostname) . '\';'; $sql_query .= $q; if (!$GLOBALS['dbi']->tryQuery($q)) { $message = Message::rawError($GLOBALS['dbi']->getError()); } } if (isset($_REQUEST['createdb-3'])) { // Grant all privileges on the specified database to the new user $q = 'GRANT ALL PRIVILEGES ON ' . Util::backquote(Util::sqlAddSlashes($dbname)) . '.* TO \'' . Util::sqlAddSlashes($username) . '\'@\'' . Util::sqlAddSlashes($hostname) . '\';'; $sql_query .= $q; if (!$GLOBALS['dbi']->tryQuery($q)) { $message = Message::rawError($GLOBALS['dbi']->getError()); } } return array($sql_query, $message); }
$response->addJSON('message', Message::error(__('No databases selected.'))); } else { PMA_sendHeaderLocation($uri); } exit; } } // end if (ensures db exists) /** * Changes database charset if requested by the user */ if (isset($_REQUEST['submitcollation']) && isset($_REQUEST['db_collation']) && !empty($_REQUEST['db_collation'])) { list($db_charset) = explode('_', $_REQUEST['db_collation']); $sql_query = 'ALTER DATABASE ' . PMA\libraries\Util::backquote($db) . ' DEFAULT' . PMA_generateCharsetQueryPart($_REQUEST['db_collation']); $result = $GLOBALS['dbi']->query($sql_query); $message = Message::success(); unset($db_charset); /** * If we are in an Ajax request, let us stop the execution here. Necessary for * db charset change action on db_operations.php. If this causes a bug on * other pages, we might have to move this to a different location. */ if ($GLOBALS['is_ajax_request'] == true) { $response = PMA\libraries\Response::getInstance(); $response->setRequestStatus($message->isSuccess()); $response->addJSON('message', $message); exit; } } /** * Set parameters for links
/** * Deal with Drops multiple databases * * @return null */ function PMA_dropMultiDatabases() { if (!isset($_REQUEST['selected_dbs']) && !isset($_REQUEST['query_type'])) { $message = Message::error(__('No databases selected.')); } else { $action = 'server_databases.php'; $submit_mult = 'drop_db'; $err_url = 'server_databases.php' . PMA_URL_getCommon(); if (isset($_REQUEST['selected_dbs']) && !isset($_REQUEST['is_js_confirmed'])) { $selected_db = $_REQUEST['selected_dbs']; } if (isset($_REQUEST['is_js_confirmed'])) { $_REQUEST = array('query_type' => $submit_mult, 'selected' => $_REQUEST['selected_dbs'], 'mult_btn' => __('Yes'), 'db' => $GLOBALS['db'], 'table' => $GLOBALS['table']); } //the following variables will be used on mult_submits.inc.php global $query_type, $selected, $mult_btn; include 'libraries/mult_submits.inc.php'; unset($action, $submit_mult, $err_url, $selected_db, $GLOBALS['db']); if (empty($message)) { if ($mult_btn == __('Yes')) { $number_of_databases = count($selected); } else { $number_of_databases = 0; } $message = Message::success(_ngettext('%1$d database has been dropped successfully.', '%1$d databases have been dropped successfully.', $number_of_databases)); $message->addParam($number_of_databases); } } if ($GLOBALS['is_ajax_request'] && $message instanceof PMA\libraries\Message) { $response = PMA\libraries\Response::getInstance(); $response->setRequestStatus($message->isSuccess()); $response->addJSON('message', $message); exit; } }
/** * Function to display results when the executed query returns non empty results * * @param object $result executed query results * @param array $analyzed_sql_results analysed sql results * @param string $db current database * @param string $table current table * @param string $message message to show * @param array $sql_data sql data * @param DisplayResults $displayResultsObject Instance of DisplayResults * @param string $pmaThemeImage uri of the theme image * @param int $unlim_num_rows unlimited number of rows * @param int $num_rows number of rows * @param string $disp_query display query * @param string $disp_message display message * @param array $profiling_results profiling results * @param string $query_type query type * @param array|null $selectedTables array of table names selected * from the database structure page, for * an action like check table, * optimize table, analyze table or * repair table * @param string $sql_query sql query * @param string $complete_query complete sql query * * @return string html */ function PMA_getQueryResponseForResultsReturned($result, $analyzed_sql_results, $db, $table, $message, $sql_data, $displayResultsObject, $pmaThemeImage, $unlim_num_rows, $num_rows, $disp_query, $disp_message, $profiling_results, $query_type, $selectedTables, $sql_query, $complete_query) { // If we are retrieving the full value of a truncated field or the original // value of a transformed field, show it here if (isset($_REQUEST['grid_edit']) && $_REQUEST['grid_edit'] == true) { PMA_sendResponseForGridEdit($result); // script has exited at this point } // Gets the list of fields properties if (isset($result) && $result) { $fields_meta = $GLOBALS['dbi']->getFieldsMeta($result); } // Should be initialized these parameters before parsing $showtable = isset($showtable) ? $showtable : null; $url_query = isset($url_query) ? $url_query : null; $response = PMA\libraries\Response::getInstance(); $header = $response->getHeader(); $scripts = $header->getScripts(); // hide edit and delete links: // - for information_schema // - if the result set does not contain all the columns of a unique key // (unless this is an updatable view) $updatableView = false; $statement = $analyzed_sql_results['statement']; if ($statement instanceof SqlParser\Statements\SelectStatement) { if (!empty($statement->expr)) { if ($statement->expr[0]->expr === '*') { $_table = new Table($table, $db); $updatableView = $_table->isUpdatableView(); } } } $has_unique = PMA_resultSetContainsUniqueKey($db, $table, $fields_meta); $just_one_table = PMA_resultSetHasJustOneTable($fields_meta); $editable = ($has_unique || $GLOBALS['cfg']['RowActionLinksWithoutUnique'] || $updatableView) && $just_one_table; $displayParts = array('edit_lnk' => $displayResultsObject::UPDATE_ROW, 'del_lnk' => $displayResultsObject::DELETE_ROW, 'sort_lnk' => '1', 'nav_bar' => '1', 'bkm_form' => '1', 'text_btn' => '0', 'pview_lnk' => '1'); if (!empty($table) && ($GLOBALS['dbi']->isSystemSchema($db) || !$editable)) { $displayParts = array('edit_lnk' => $displayResultsObject::NO_EDIT_OR_DELETE, 'del_lnk' => $displayResultsObject::NO_EDIT_OR_DELETE, 'sort_lnk' => '1', 'nav_bar' => '1', 'bkm_form' => '1', 'text_btn' => '1', 'pview_lnk' => '1'); } if (isset($_REQUEST['printview']) && $_REQUEST['printview'] == '1') { $displayParts = array('edit_lnk' => $displayResultsObject::NO_EDIT_OR_DELETE, 'del_lnk' => $displayResultsObject::NO_EDIT_OR_DELETE, 'sort_lnk' => '0', 'nav_bar' => '0', 'bkm_form' => '0', 'text_btn' => '0', 'pview_lnk' => '0'); } if (isset($_REQUEST['table_maintenance'])) { $scripts->addFile('makegrid.js'); $scripts->addFile('sql.js'); $table_maintenance_html = ''; if (isset($message)) { $message = Message::success($message); $table_maintenance_html = PMA\libraries\Util::getMessage($message, $GLOBALS['sql_query'], 'success'); } $table_maintenance_html .= PMA_getHtmlForSqlQueryResultsTable($displayResultsObject, $pmaThemeImage, $url_query, $displayParts, false, $unlim_num_rows, $num_rows, $showtable, $result, $analyzed_sql_results); if (empty($sql_data) || ($sql_data['valid_queries'] = 1)) { $response->addHTML($table_maintenance_html); exit; } } if (!isset($_REQUEST['printview']) || $_REQUEST['printview'] != '1') { $scripts->addFile('makegrid.js'); $scripts->addFile('sql.js'); unset($GLOBALS['message']); //we don't need to buffer the output in getMessage here. //set a global variable and check against it in the function $GLOBALS['buffer_message'] = false; } $previous_update_query_html = PMA_getHtmlForPreviousUpdateQuery(isset($disp_query) ? $disp_query : null, $GLOBALS['cfg']['ShowSQL'], isset($sql_data) ? $sql_data : null, isset($disp_message) ? $disp_message : null); $profiling_chart_html = PMA_getHtmlForProfilingChart($url_query, $db, isset($profiling_results) ? $profiling_results : array()); $missing_unique_column_msg = PMA_getMessageIfMissingColumnIndex($table, $db, $editable, $has_unique); $bookmark_created_msg = PMA_getBookmarkCreatedMessage(); $table_html = PMA_getHtmlForSqlQueryResultsTable($displayResultsObject, $pmaThemeImage, $url_query, $displayParts, $editable, $unlim_num_rows, $num_rows, $showtable, $result, $analyzed_sql_results); $indexes_problems_html = PMA_getHtmlForIndexesProblems(isset($query_type) ? $query_type : null, isset($selectedTables) ? $selectedTables : null, $db); $cfgBookmark = PMA_Bookmark_getParams(); if ($cfgBookmark) { $bookmark_support_html = PMA_getHtmlForBookmark($displayParts, $cfgBookmark, $sql_query, $db, $table, isset($complete_query) ? $complete_query : $sql_query, $cfgBookmark['user']); } else { $bookmark_support_html = ''; } $html_output = isset($table_maintenance_html) ? $table_maintenance_html : ''; $html_output .= PMA_getHtmlForSqlQueryResults($previous_update_query_html, $profiling_chart_html, $missing_unique_column_msg, $bookmark_created_msg, $table_html, $indexes_problems_html, $bookmark_support_html); return $html_output; }
/** * Update the table's structure based on $_REQUEST * * @return boolean $regenerate true if error occurred * */ protected function updateColumns() { $err_url = 'tbl_structure.php' . PMA_URL_getCommon(array('db' => $this->db, 'table' => $this->table)); $regenerate = false; $field_cnt = count($_REQUEST['field_name']); $changes = array(); $adjust_privileges = array(); for ($i = 0; $i < $field_cnt; $i++) { if (!$this->columnNeedsAlterTable($i)) { continue; } $changes[] = 'CHANGE ' . Table::generateAlter(Util_lib\get($_REQUEST, "field_orig.{$i}", ''), $_REQUEST['field_name'][$i], $_REQUEST['field_type'][$i], $_REQUEST['field_length'][$i], $_REQUEST['field_attribute'][$i], Util_lib\get($_REQUEST, "field_collation.{$i}", ''), Util_lib\get($_REQUEST, "field_null.{$i}", 'NOT NULL'), $_REQUEST['field_default_type'][$i], $_REQUEST['field_default_value'][$i], Util_lib\get($_REQUEST, "field_extra.{$i}", false), Util_lib\get($_REQUEST, "field_comments.{$i}", ''), Util_lib\get($_REQUEST, "field_virtuality.{$i}", ''), Util_lib\get($_REQUEST, "field_expression.{$i}", ''), Util_lib\get($_REQUEST, "field_move_to.{$i}", '')); // find the remembered sort expression $sorted_col = $this->table_obj->getUiProp(Table::PROP_SORTED_COLUMN); // if the old column name is part of the remembered sort expression if (mb_strpos($sorted_col, Util::backquote($_REQUEST['field_orig'][$i])) !== false) { // delete the whole remembered sort expression $this->table_obj->removeUiProp(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 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 (!$this->dbi->selectDb($this->db)) { Util::mysqlDie($this->dbi->getError(), 'USE ' . Util::backquote($this->db) . ';', false, $err_url); } $sql_query = 'ALTER TABLE ' . Util::backquote($this->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 : ''); } $columns_with_index = $this->dbi->getTable($this->db, $this->table)->getColumnsWithIndex(PMA_Index::PRIMARY | PMA_Index::UNIQUE | PMA_Index::INDEX | PMA_Index::SPATIAL | PMA_Index::FULLTEXT); $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] && !in_array($_REQUEST['field_orig'][$i], $columns_with_index)) { $secondary_query = 'ALTER TABLE ' . Util::backquote($this->table) . ' CHANGE ' . Util::backquote($_REQUEST['field_orig'][$i]) . ' ' . Util::backquote($_REQUEST['field_orig'][$i]) . ' BLOB;'; $this->dbi->query($secondary_query); $changedToBlob[$i] = true; } else { $changedToBlob[$i] = false; } } // Then make the requested changes $result = $this->dbi->tryQuery($sql_query); if ($result !== false) { $changed_privileges = $this->adjustColumnPrivileges($adjust_privileges); if ($changed_privileges) { $message = Message::success(__('Table %1$s has been altered successfully. Privileges ' . 'have been adjusted.')); } else { $message = Message::success(__('Table %1$s has been altered successfully.')); } $message->addParam($this->table); $this->response->addHTML(Util::getMessage($message, $sql_query, 'success')); } else { // An error happened while inserting/updating a table definition // Save the Original Error $orig_error = $this->dbi->getError(); $changes_revert = array(); // Change back to Original Collation and data type for ($i = 0; $i < $field_cnt; $i++) { if ($changedToBlob[$i]) { $changes_revert[] = 'CHANGE ' . Table::generateAlter(Util_lib\get($_REQUEST, "field_orig.{$i}", ''), $_REQUEST['field_name'][$i], $_REQUEST['field_type_orig'][$i], $_REQUEST['field_length_orig'][$i], $_REQUEST['field_attribute_orig'][$i], Util_lib\get($_REQUEST, "field_collation_orig.{$i}", ''), Util_lib\get($_REQUEST, "field_null_orig.{$i}", 'NOT NULL'), $_REQUEST['field_default_type_orig'][$i], $_REQUEST['field_default_value_orig'][$i], Util_lib\get($_REQUEST, "field_extra_orig.{$i}", false), Util_lib\get($_REQUEST, "field_comments_orig.{$i}", ''), Util_lib\get($_REQUEST, "field_virtuality_orig.{$i}", ''), Util_lib\get($_REQUEST, "field_expression_orig.{$i}", ''), Util_lib\get($_REQUEST, "field_move_to_orig.{$i}", '')); } } $revert_query = 'ALTER TABLE ' . Util::backquote($this->table) . ' '; $revert_query .= implode(', ', $changes_revert) . ''; $revert_query .= ';'; // Column reverted back to original $this->dbi->query($revert_query); $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::rawError(__('Query error') . ':<br />' . $orig_error)); $regenerate = true; } } // 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($this->db, $this->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($this->db, $this->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; }
/** * Flush privileges and get message * * @param bool $flushPrivileges Flush privileges * * @return PMA\libraries\Message */ function PMA_RTN_flushPrivileges($flushPrivileges) { if ($flushPrivileges) { // Flush the Privileges $flushPrivQuery = 'FLUSH PRIVILEGES;'; $GLOBALS['dbi']->query($flushPrivQuery); $message = PMA\libraries\Message::success(__('Routine %1$s has been modified. Privileges have been adjusted.')); } else { $message = PMA\libraries\Message::success(__('Routine %1$s has been modified.')); } $message->addParam(PMA\libraries\Util::backquote($_REQUEST['item_name'])); return $message; }
/** * move the repeating group of columns to a new table * * @param string $repeatingColumns comma separated list of repeating group columns * @param string $primary_columns comma separated list of column in primary key * of $table * @param string $newTable name of the new table to be created * @param string $newColumn name of the new column in the new table * @param string $table current table * @param string $db current database * * @return array */ function PMA_moveRepeatingGroup($repeatingColumns, $primary_columns, $newTable, $newColumn, $table, $db) { $repeatingColumnsArr = (array) Util::backquote(explode(', ', $repeatingColumns)); $primary_columns = implode(',', Util::backquote(explode(',', $primary_columns))); $query1 = 'CREATE TABLE ' . Util::backquote($newTable); $query2 = 'ALTER TABLE ' . Util::backquote($table); $message = Message::success(sprintf(__('Selected repeating group has been moved to the table \'%s\''), htmlspecialchars($table))); $first = true; $error = false; foreach ($repeatingColumnsArr as $repeatingColumn) { if (!$first) { $query1 .= ' UNION '; } $first = false; $query1 .= ' SELECT ' . $primary_columns . ',' . $repeatingColumn . ' as ' . Util::backquote($newColumn) . ' FROM ' . Util::backquote($table); $query2 .= ' DROP ' . $repeatingColumn . ','; } $query2 = trim($query2, ','); $queries = array($query1, $query2); $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']); foreach ($queries as $query) { if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['userlink'])) { $message = Message::error(__('Error in processing!')); $message->addMessage('<br /><br />'); $message->addMessage(Message::rawError($GLOBALS['dbi']->getError($GLOBALS['userlink']))); $error = true; break; } } return array('queryError' => $error, 'message' => $message); }
/** * Function to create the tracking version * * @return string HTML of the success message */ function PMA_createTrackingVersion() { $html = ''; $tracking_set = PMA_getTrackingSet(); $versionCreated = Tracker::createVersion($GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version'], $tracking_set, $GLOBALS['dbi']->getTable($GLOBALS['db'], $GLOBALS['table'])->isView()); if ($versionCreated) { $msg = Message::success(sprintf(__('Version %1$s was created, tracking for %2$s is active.'), htmlspecialchars($_REQUEST['version']), htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']))); $html .= $msg->getDisplay(); } return $html; }
/** * Handles dropping multiple databases * * @return void */ public function dropDatabasesAction() { if (!isset($_REQUEST['selected_dbs'])) { $message = Message::error(__('No databases selected.')); } else { $action = 'server_databases.php'; $err_url = $action . PMA_URL_getCommon(); $GLOBALS['submit_mult'] = 'drop_db'; $GLOBALS['mult_btn'] = __('Yes'); include 'libraries/mult_submits.inc.php'; if (empty($message)) { // no error message $number_of_databases = count($selected); $message = Message::success(_ngettext('%1$d database has been dropped successfully.', '%1$d databases have been dropped successfully.', $number_of_databases)); $message->addParam($number_of_databases); } } if ($message instanceof Message) { $this->response->setRequestStatus($message->isSuccess()); $this->response->addJSON('message', $message); } }
/** * Index action * * @return void */ public function indexAction() { // Add/Remove favorite tables using Ajax request. if ($GLOBALS['is_ajax_request'] && !empty($_REQUEST['favorite_table'])) { $this->addRemoveFavoriteTablesAction(); return; } $this->response->getHeader()->getScripts()->addFiles(array('db_structure.js', 'tbl_change.js', 'jquery/jquery-ui-timepicker-addon.js')); // Drops/deletes/etc. multiple tables if required if (!empty($_POST['submit_mult']) && isset($_POST['selected_tbl']) || isset($_POST['mult_btn'])) { $action = 'db_structure.php'; $err_url = 'db_structure.php' . PMA_URL_getCommon(array('db' => $this->db)); // see bug #2794840; in this case, code path is: // db_structure.php -> libraries/mult_submits.inc.php -> sql.php // -> db_structure.php and if we got an error on the multi submit, // we must display it here and not call again mult_submits.inc.php if (!isset($_POST['error']) || false === $_POST['error']) { include 'libraries/mult_submits.inc.php'; } if (empty($_POST['message'])) { $_POST['message'] = Message::success(); } } $this->_url_query .= '&goto=db_structure.php'; // Gets the database structure $sub_part = '_structure'; list($tables, $num_tables, $total_num_tables, , $is_show_stats, $db_is_system_schema, $tooltip_truename, $tooltip_aliasname, $pos) = Util::getDbInfo($GLOBALS['db'], isset($sub_part) ? $sub_part : ''); $this->_tables = $tables; // updating $tables seems enough for #11376, but updating other // variables too in case they may cause some other problem. $this->_num_tables = $num_tables; $this->_pos = $pos; $this->_db_is_system_schema = $db_is_system_schema; $this->_total_num_tables = $total_num_tables; $this->_is_show_stats = $is_show_stats; // If there is an Ajax request for real row count of a table. if ($GLOBALS['is_ajax_request'] && isset($_REQUEST['real_row_count']) && $_REQUEST['real_row_count'] == true) { $this->handleRealRowCountRequestAction(); return; } include_once 'libraries/replication.inc.php'; PageSettings::showGroup('DbStructure'); $db_collation = PMA_getDbCollation($this->db); $titles = Util::buildActionTitles(); // 1. No tables if ($this->_num_tables == 0) { $this->response->addHTML(Message::notice(__('No tables found in database.'))); if (empty($db_is_system_schema)) { $this->response->addHTML(PMA_getHtmlForCreateTable($this->db)); } return; } // else // 2. Shows table information /** * Displays the tables list */ $this->response->addHTML('<div id="tableslistcontainer">'); $_url_params = array('pos' => $this->_pos, 'db' => $this->db); // Add the sort options if they exists if (isset($_REQUEST['sort'])) { $_url_params['sort'] = $_REQUEST['sort']; } if (isset($_REQUEST['sort_order'])) { $_url_params['sort_order'] = $_REQUEST['sort_order']; } $this->response->addHTML(Util::getListNavigator($this->_total_num_tables, $this->_pos, $_url_params, 'db_structure.php', 'frame_content', $GLOBALS['cfg']['MaxTableList'])); // table form $this->response->addHTML(Template::get('database/structure/table_header')->render(array('db' => $this->db, 'db_is_system_schema' => $this->_db_is_system_schema, 'replication' => $GLOBALS['replication_info']['slave']['status']))); $i = $sum_entries = 0; $overhead_check = ''; $create_time_all = ''; $update_time_all = ''; $check_time_all = ''; $num_columns = $GLOBALS['cfg']['PropertiesNumColumns'] > 1 ? ceil($this->_num_tables / $GLOBALS['cfg']['PropertiesNumColumns']) + 1 : 0; $row_count = 0; $sum_size = (double) 0; $overhead_size = (double) 0; $hidden_fields = array(); $odd_row = true; $overall_approx_rows = false; // Instance of RecentFavoriteTable class. $fav_instance = RecentFavoriteTable::getInstance('favorite'); foreach ($this->_tables as $keyname => $current_table) { // Get valid statistics whatever is the table type $drop_query = ''; $drop_message = ''; $overhead = ''; $table_is_view = false; $table_encoded = urlencode($current_table['TABLE_NAME']); // Sets parameters for links $tbl_url_query = $this->_url_query . '&table=' . $table_encoded; // do not list the previous table's size info for a view list($current_table, $formatted_size, $unit, $formatted_overhead, $overhead_unit, $overhead_size, $table_is_view, $sum_size) = $this->getStuffForEngineTypeTable($current_table, $sum_size, $overhead_size); $curTable = $this->dbi->getTable($this->db, $current_table['TABLE_NAME']); if (!$curTable->isMerge()) { $sum_entries += $current_table['TABLE_ROWS']; } if (isset($current_table['Collation'])) { $collation = '<dfn title="' . PMA_getCollationDescr($current_table['Collation']) . '">' . $current_table['Collation'] . '</dfn>'; } else { $collation = '---'; } if ($this->_is_show_stats) { if ($formatted_overhead != '') { $overhead = '<a href="tbl_structure.php' . $tbl_url_query . '#showusage">' . '<span>' . $formatted_overhead . '</span> ' . '<span class="unit">' . $overhead_unit . '</span>' . '</a>' . "\n"; $overhead_check .= "markAllRows('row_tbl_" . ($i + 1) . "');"; } else { $overhead = '-'; } } // end if $showtable = $this->dbi->getTable($this->db, $current_table['TABLE_NAME'])->getStatusInfo(null, true); if ($GLOBALS['cfg']['ShowDbStructureCreation']) { $create_time = isset($showtable['Create_time']) ? $showtable['Create_time'] : ''; if ($create_time && (!$create_time_all || $create_time < $create_time_all)) { $create_time_all = $create_time; } } if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) { // $showtable might already be set from ShowDbStructureCreation, // see above $update_time = isset($showtable['Update_time']) ? $showtable['Update_time'] : ''; if ($update_time && (!$update_time_all || $update_time < $update_time_all)) { $update_time_all = $update_time; } } if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) { // $showtable might already be set from ShowDbStructureCreation, // see above $check_time = isset($showtable['Check_time']) ? $showtable['Check_time'] : ''; if ($check_time && (!$check_time_all || $check_time < $check_time_all)) { $check_time_all = $check_time; } } $truename = htmlspecialchars(!empty($tooltip_truename) && isset($tooltip_truename[$current_table['TABLE_NAME']]) ? $tooltip_truename[$current_table['TABLE_NAME']] : $current_table['TABLE_NAME']); $truename = str_replace(' ', ' ', $truename); $i++; $row_count++; if ($table_is_view) { $hidden_fields[] = '<input type="hidden" name="views[]" value="' . htmlspecialchars($current_table['TABLE_NAME']) . '" />'; } /* * Always activate links for Browse, Search and Empty, even if * the icons are greyed, because * 1. for views, we don't know the number of rows at this point * 2. for tables, another source could have populated them since the * page was generated * * I could have used the PHP ternary conditional operator but I find * the code easier to read without this operator. */ $may_have_rows = $current_table['TABLE_ROWS'] > 0 || $table_is_view; $browse_table = Template::get('database/structure/browse_table')->render(array('tbl_url_query' => $tbl_url_query, 'title' => $may_have_rows ? $titles['Browse'] : $titles['NoBrowse'])); $search_table = Template::get('database/structure/search_table')->render(array('tbl_url_query' => $tbl_url_query, 'title' => $may_have_rows ? $titles['Search'] : $titles['NoSearch'])); $browse_table_label = Template::get('database/structure/browse_table_label')->render(array('tbl_url_query' => $tbl_url_query, 'title' => htmlspecialchars($current_table['TABLE_COMMENT']), 'truename' => $truename)); $empty_table = ''; if (!$this->_db_is_system_schema) { $empty_table = ' '; if (!$table_is_view) { $empty_table = Template::get('database/structure/empty_table')->render(array('tbl_url_query' => $tbl_url_query, 'sql_query' => urlencode('TRUNCATE ' . Util::backquote($current_table['TABLE_NAME'])), 'message_to_show' => urlencode(sprintf(__('Table %s has been emptied.'), htmlspecialchars($current_table['TABLE_NAME']))), 'title' => $may_have_rows ? $titles['Empty'] : $titles['NoEmpty'])); } $drop_query = sprintf('DROP %s %s', $table_is_view || $current_table['ENGINE'] == null ? 'VIEW' : 'TABLE', Util::backquote($current_table['TABLE_NAME'])); $drop_message = sprintf($table_is_view || $current_table['ENGINE'] == null ? __('View %s has been dropped.') : __('Table %s has been dropped.'), str_replace(' ', ' ', htmlspecialchars($current_table['TABLE_NAME']))); } $tracking_icon = ''; if (Tracker::isActive()) { $is_tracked = Tracker::isTracked($GLOBALS["db"], $truename); if ($is_tracked || Tracker::getVersion($GLOBALS["db"], $truename) > 0) { $tracking_icon = Template::get('database/structure/tracking_icon')->render(array('url_query' => $this->_url_query, 'truename' => $truename, 'is_tracked' => $is_tracked)); } } if ($num_columns > 0 && $this->_num_tables > $num_columns && $row_count % $num_columns == 0) { $row_count = 1; $odd_row = true; $this->response->addHTML('</tr></tbody></table>'); $this->response->addHTML(Template::get('database/structure/table_header')->render(array('db' => $this->db, 'db_is_system_schema' => $this->_db_is_system_schema, 'replication' => $GLOBALS['replication_info']['slave']['status']))); } $do = $ignored = false; if ($GLOBALS['replication_info']['slave']['status']) { $nbServSlaveDoDb = count($GLOBALS['replication_info']['slave']['Do_DB']); $nbServSlaveIgnoreDb = count($GLOBALS['replication_info']['slave']['Ignore_DB']); $searchDoDBInTruename = array_search($truename, $GLOBALS['replication_info']['slave']['Do_DB']); $searchDoDBInDB = array_search($this->db, $GLOBALS['replication_info']['slave']['Do_DB']); $do = strlen($searchDoDBInTruename) > 0 || strlen($searchDoDBInDB) > 0 || $nbServSlaveDoDb == 1 && $nbServSlaveIgnoreDb == 1 || $this->hasTable($GLOBALS['replication_info']['slave']['Wild_Do_Table'], $truename); $searchDb = array_search($this->db, $GLOBALS['replication_info']['slave']['Ignore_DB']); $searchTable = array_search($truename, $GLOBALS['replication_info']['slave']['Ignore_Table']); $ignored = strlen($searchTable) > 0 || strlen($searchDb) > 0 || $this->hasTable($GLOBALS['replication_info']['slave']['Wild_Ignore_Table'], $truename); } // Handle favorite table list. ----START---- $already_favorite = $this->checkFavoriteTable($current_table['TABLE_NAME']); if (isset($_REQUEST['remove_favorite'])) { if ($already_favorite) { // If already in favorite list, remove it. $favorite_table = $_REQUEST['favorite_table']; $fav_instance->remove($this->db, $favorite_table); } } if (isset($_REQUEST['add_favorite'])) { if (!$already_favorite) { // Otherwise add to favorite list. $favorite_table = $_REQUEST['favorite_table']; $fav_instance->add($this->db, $favorite_table); } } // Handle favorite table list. ----ENDS---- $show_superscript = ''; // there is a null value in the ENGINE // - when the table needs to be repaired, or // - when it's a view // so ensure that we'll display "in use" below for a table // that needs to be repaired $approx_rows = false; if (isset($current_table['TABLE_ROWS']) && ($current_table['ENGINE'] != null || $table_is_view)) { // InnoDB table: we did not get an accurate row count $approx_rows = !$table_is_view && $current_table['ENGINE'] == 'InnoDB' && !$current_table['COUNTED']; } $this->response->addHTML(Template::get('database/structure/structure_table_row')->render(array('db' => $this->db, 'curr' => $i, 'odd_row' => $odd_row, 'table_is_view' => $table_is_view, 'current_table' => $current_table, 'browse_table_label' => $browse_table_label, 'tracking_icon' => $tracking_icon, 'server_slave_status' => $GLOBALS['replication_info']['slave']['status'], 'browse_table' => $browse_table, 'tbl_url_query' => $tbl_url_query, 'search_table' => $search_table, 'db_is_system_schema' => $this->_db_is_system_schema, 'titles' => $titles, 'empty_table' => $empty_table, 'drop_query' => $drop_query, 'drop_message' => $drop_message, 'collation' => $collation, 'formatted_size' => $formatted_size, 'unit' => $unit, 'overhead' => $overhead, 'create_time' => isset($create_time) ? $create_time : '', 'update_time' => isset($update_time) ? $update_time : '', 'check_time' => isset($check_time) ? $check_time : '', 'is_show_stats' => $this->_is_show_stats, 'ignored' => $ignored, 'do' => $do, 'colspan_for_structure' => $GLOBALS['colspan_for_structure'], 'approx_rows' => $approx_rows, 'show_superscript' => $show_superscript, 'already_favorite' => $this->checkFavoriteTable($current_table['TABLE_NAME'])))); $odd_row = !$odd_row; $overall_approx_rows = $overall_approx_rows || $approx_rows; } // end foreach // Show Summary $this->response->addHTML('</tbody>'); $this->response->addHTML(Template::get('database/structure/body_for_table_summary')->render(array('num_tables' => $this->_num_tables, 'server_slave_status' => $GLOBALS['replication_info']['slave']['status'], 'db_is_system_schema' => $this->_db_is_system_schema, 'sum_entries' => $sum_entries, 'db_collation' => $db_collation, 'is_show_stats' => $this->_is_show_stats, 'sum_size' => $sum_size, 'overhead_size' => $overhead_size, 'create_time_all' => $create_time_all, 'update_time_all' => $update_time_all, 'check_time_all' => $check_time_all, 'approx_rows' => $overall_approx_rows))); $this->response->addHTML('</table>'); //check all $this->response->addHTML(Template::get('database/structure/check_all_tables')->render(array('pmaThemeImage' => $GLOBALS['pmaThemeImage'], 'text_dir' => $GLOBALS['text_dir'], 'overhead_check' => $overhead_check, 'db_is_system_schema' => $this->_db_is_system_schema, 'hidden_fields' => $hidden_fields))); $this->response->addHTML('</form>'); //end of form // display again the table list navigator $this->response->addHTML(Util::getListNavigator($this->_total_num_tables, $this->_pos, $_url_params, 'db_structure.php', 'frame_content', $GLOBALS['cfg']['MaxTableList'])); $this->response->addHTML('</div><hr />'); /** * Work on the database */ /* DATABASE WORK */ /* Printable view of a table */ $this->response->addHTML(Template::get('database/structure/print_view_data_dictionary_link')->render(array('url_query' => $this->_url_query))); if (empty($db_is_system_schema)) { $this->response->addHTML(PMA_getHtmlForCreateTable($this->db)); } }
/** * handle control requests * * @return NULL */ function PMA_handleControlRequest() { if (isset($_REQUEST['sr_take_action'])) { $refresh = false; $result = false; $messageSuccess = null; $messageError = null; if (isset($_REQUEST['slave_changemaster'])) { $result = PMA_handleRequestForSlaveChangeMaster(); } elseif (isset($_REQUEST['sr_slave_server_control'])) { $result = PMA_handleRequestForSlaveServerControl(); $refresh = true; switch ($_REQUEST['sr_slave_action']) { case 'start': $messageSuccess = __('Replication started successfully.'); $messageError = __('Error starting replication.'); break; case 'stop': $messageSuccess = __('Replication stopped successfully.'); $messageError = __('Error stopping replication.'); break; case 'reset': $messageSuccess = __('Replication resetting successfully.'); $messageError = __('Error resetting replication.'); break; default: $messageSuccess = __('Success.'); $messageError = __('Error.'); break; } } elseif (isset($_REQUEST['sr_slave_skip_error'])) { $result = PMA_handleRequestForSlaveSkipError(); } if ($refresh) { $response = PMA\libraries\Response::getInstance(); if ($response->isAjax()) { $response->setRequestStatus($result); $response->addJSON('message', $result ? Message::success($messageSuccess) : Message::error($messageError)); } else { PMA_sendHeaderLocation($GLOBALS['cfg']['PmaAbsoluteUri'] . 'server_replication.php' . PMA_URL_getCommon($GLOBALS['url_params'], 'text')); } } unset($refresh); } }
/** * Set the content that needs to be shown in message * * @param string $sorted_column_message the message for sorted column * @param array $analyzed_sql_results the analyzed query * @param integer $total the total number of rows returned by * the SQL query without any * programmatically appended LIMIT clause * @param integer $pos_next the offset for next page * @param string $pre_count the string renders before row count * @param string $after_count the string renders after row count * * @return Message $message an object of Message * * @access private * * @see getTable() */ private function _setMessageInformation($sorted_column_message, $analyzed_sql_results, $total, $pos_next, $pre_count, $after_count) { $unlim_num_rows = $this->__get('unlim_num_rows'); // To use in isset() if (!empty($analyzed_sql_results['statement']->limit)) { $first_shown_rec = $analyzed_sql_results['statement']->limit->offset; $row_count = $analyzed_sql_results['statement']->limit->rowCount; if ($row_count < $total) { $last_shown_rec = $first_shown_rec + $row_count - 1; } else { $last_shown_rec = $first_shown_rec + $total - 1; } } elseif ($_SESSION['tmpval']['max_rows'] == self::ALL_ROWS || $pos_next > $total) { $first_shown_rec = $_SESSION['tmpval']['pos']; $last_shown_rec = $total - 1; } else { $first_shown_rec = $_SESSION['tmpval']['pos']; $last_shown_rec = $pos_next - 1; } $table = new Table($this->__get('table'), $this->__get('db')); if ($table->isView() && $total == $GLOBALS['cfg']['MaxExactCountViews']) { $message = Message::notice(__('This view has at least this number of rows. ' . 'Please refer to %sdocumentation%s.')); $message->addParam('[doc@cfg_MaxExactCount]'); $message->addParam('[/doc]'); $message_view_warning = Util::showHint($message); } else { $message_view_warning = false; } $message = Message::success(__('Showing rows %1s - %2s')); $message->addParam($first_shown_rec); if ($message_view_warning !== false) { $message->addParam('... ' . $message_view_warning, false); } else { $message->addParam($last_shown_rec); } $message->addMessage('('); if ($message_view_warning === false) { if (isset($unlim_num_rows) && $unlim_num_rows != $total) { $message_total = Message::notice($pre_count . __('%1$d total, %2$d in query')); $message_total->addParam($total); $message_total->addParam($unlim_num_rows); } else { $message_total = Message::notice($pre_count . __('%d total')); $message_total->addParam($total); } if (!empty($after_count)) { $message_total->addMessage($after_count); } $message->addMessage($message_total, ''); $message->addMessage(', ', ''); } $message_qt = Message::notice(__('Query took %01.4f seconds.') . ')'); $message_qt->addParam($this->__get('querytime')); $message->addMessage($message_qt, ''); if (!is_null($sorted_column_message)) { $message->addMessage($sorted_column_message, ''); } return $message; }
/** * get Message for number of inserted rows * * shorthand for getting a customized message * * @param integer $rows Number of rows * * @return Message * @static */ public static function getMessageForInsertedRows($rows) { $message = Message::success(_ngettext('%1$d row inserted.', '%1$d rows inserted.', $rows)); $message->addParam($rows); return $message; }
/** * Move or copy a table * * @param string $db current database name * @param string $table current table name * * @return void */ function PMA_moveOrCopyTable($db, $table) { /** * Selects the database to work with */ $GLOBALS['dbi']->selectDb($db); /** * $_REQUEST['target_db'] could be empty in case we came from an input field * (when there are many databases, no drop-down) */ if (empty($_REQUEST['target_db'])) { $_REQUEST['target_db'] = $db; } /** * A target table name has been sent to this script -> do the work */ if (PMA_isValid($_REQUEST['new_name'])) { if ($db == $_REQUEST['target_db'] && $table == $_REQUEST['new_name']) { if (isset($_REQUEST['submit_move'])) { $message = Message::error(__('Can\'t move table to same one!')); } else { $message = Message::error(__('Can\'t copy table to same one!')); } } else { Table::moveCopy($db, $table, $_REQUEST['target_db'], $_REQUEST['new_name'], $_REQUEST['what'], isset($_REQUEST['submit_move']), 'one_table'); if (isset($_REQUEST['adjust_privileges']) && !empty($_REQUEST['adjust_privileges'])) { if (isset($_REQUEST['submit_move'])) { PMA_AdjustPrivileges_renameOrMoveTable($db, $table, $_REQUEST['target_db'], $_REQUEST['new_name']); } else { PMA_AdjustPrivileges_copyTable($db, $table, $_REQUEST['target_db'], $_REQUEST['new_name']); } if (isset($_REQUEST['submit_move'])) { $message = Message::success(__('Table %s has been moved to %s. Privileges have been ' . 'adjusted.')); } else { $message = Message::success(__('Table %s has been copied to %s. Privileges have been ' . 'adjusted.')); } } else { if (isset($_REQUEST['submit_move'])) { $message = Message::success(__('Table %s has been moved to %s.')); } else { $message = Message::success(__('Table %s has been copied to %s.')); } } $old = PMA\libraries\Util::backquote($db) . '.' . PMA\libraries\Util::backquote($table); $message->addParam($old); $new = PMA\libraries\Util::backquote($_REQUEST['target_db']) . '.' . PMA\libraries\Util::backquote($_REQUEST['new_name']); $message->addParam($new); /* Check: Work on new table or on old table? */ if (isset($_REQUEST['submit_move']) || PMA_isValid($_REQUEST['switch_to_new'])) { } } } else { /** * No new name for the table! */ $message = Message::error(__('The table name is empty!')); } if ($GLOBALS['is_ajax_request'] == true) { $response = PMA\libraries\Response::getInstance(); $response->addJSON('message', $message); if ($message->isSuccess()) { $response->addJSON('db', $GLOBALS['db']); } else { $response->setRequestStatus(false); } exit; } }
/** * Returns the html for binary log information. * * @param Array $url_params links parameters * * @return string */ function PMA_getLogInfo($url_params) { /** * Need to find the real end of rows? */ if (!isset($_REQUEST['pos'])) { $pos = 0; } else { /* We need this to be a integer */ $pos = (int) $_REQUEST['pos']; } $sql_query = 'SHOW BINLOG EVENTS'; if (!empty($_REQUEST['log'])) { $sql_query .= ' IN \'' . $_REQUEST['log'] . '\''; } $sql_query .= ' LIMIT ' . $pos . ', ' . (int) $GLOBALS['cfg']['MaxRows']; /** * Sends the query */ $result = $GLOBALS['dbi']->query($sql_query); /** * prepare some vars for displaying the result table */ // Gets the list of fields properties if (isset($result) && $result) { $num_rows = $GLOBALS['dbi']->numRows($result); } else { $num_rows = 0; } if (empty($_REQUEST['dontlimitchars'])) { $dontlimitchars = false; } else { $dontlimitchars = true; $url_params['dontlimitchars'] = 1; } //html output $html = Util::getMessage(Message::success(), $sql_query); $html .= '<table id="binlogTable">' . '<thead>' . '<tr>' . '<td colspan="6" class="center">'; $html .= PMA_getNavigationRow($url_params, $pos, $num_rows, $dontlimitchars); $html .= '</td>' . '</tr>' . '<tr>' . '<th>' . __('Log name') . '</th>' . '<th>' . __('Position') . '</th>' . '<th>' . __('Event type') . '</th>' . '<th>' . __('Server ID') . '</th>' . '<th>' . __('Original position') . '</th>' . '<th>' . __('Information') . '</th>' . '</tr>' . '</thead>' . '<tbody>'; $html .= PMA_getAllLogItemInfo($result, $dontlimitchars); $html .= '</tbody>' . '</table>'; return $html; }
/** * Handles requests for executing a routine * * @return void */ function PMA_RTN_handleExecute() { global $_GET, $_POST, $_REQUEST, $GLOBALS, $db; /** * Handle all user requests other than the default of listing routines */ if (!empty($_REQUEST['execute_routine']) && !empty($_REQUEST['item_name'])) { // Build the queries $routine = PMA_RTN_getDataFromName($_REQUEST['item_name'], $_REQUEST['item_type'], false, true); if ($routine === false) { $message = __('Error in processing request:') . ' '; $message .= sprintf(PMA_RTE_getWord('not_found'), htmlspecialchars(PMA\libraries\Util::backquote($_REQUEST['item_name'])), htmlspecialchars(PMA\libraries\Util::backquote($db))); $message = Message::error($message); if ($GLOBALS['is_ajax_request']) { $response = PMA\libraries\Response::getInstance(); $response->setRequestStatus(false); $response->addJSON('message', $message); exit; } else { echo $message->getDisplay(); unset($_POST); } } $queries = array(); $end_query = array(); $args = array(); $all_functions = $GLOBALS['PMA_Types']->getAllFunctions(); for ($i = 0; $i < $routine['item_num_params']; $i++) { if (isset($_REQUEST['params'][$routine['item_param_name'][$i]])) { $value = $_REQUEST['params'][$routine['item_param_name'][$i]]; if (is_array($value)) { // is SET type $value = implode(',', $value); } $value = $GLOBALS['dbi']->escapeString($value); if (!empty($_REQUEST['funcs'][$routine['item_param_name'][$i]]) && in_array($_REQUEST['funcs'][$routine['item_param_name'][$i]], $all_functions)) { $queries[] = "SET @p{$i}=" . $_REQUEST['funcs'][$routine['item_param_name'][$i]] . "('{$value}');\n"; } else { $queries[] = "SET @p{$i}='{$value}';\n"; } $args[] = "@p{$i}"; } else { $args[] = "@p{$i}"; } if ($routine['item_type'] == 'PROCEDURE') { if ($routine['item_param_dir'][$i] == 'OUT' || $routine['item_param_dir'][$i] == 'INOUT') { $end_query[] = "@p{$i} AS " . PMA\libraries\Util::backquote($routine['item_param_name'][$i]); } } } if ($routine['item_type'] == 'PROCEDURE') { $queries[] = "CALL " . PMA\libraries\Util::backquote($routine['item_name']) . "(" . implode(', ', $args) . ");\n"; if (count($end_query)) { $queries[] = "SELECT " . implode(', ', $end_query) . ";\n"; } } else { $queries[] = "SELECT " . PMA\libraries\Util::backquote($routine['item_name']) . "(" . implode(', ', $args) . ") " . "AS " . PMA\libraries\Util::backquote($routine['item_name']) . ";\n"; } // Get all the queries as one SQL statement $multiple_query = implode("", $queries); $outcome = true; $affected = 0; // Execute query if (!$GLOBALS['dbi']->tryMultiQuery($multiple_query)) { $outcome = false; } // Generate output if ($outcome) { // Pass the SQL queries through the "pretty printer" $output = PMA\libraries\Util::formatSql(implode($queries, "\n")); // Display results $output .= "<fieldset><legend>"; $output .= sprintf(__('Execution results of routine %s'), PMA\libraries\Util::backquote(htmlspecialchars($routine['item_name']))); $output .= "</legend>"; $nbResultsetToDisplay = 0; do { $result = $GLOBALS['dbi']->storeResult(); $num_rows = $GLOBALS['dbi']->numRows($result); if ($result !== false && $num_rows > 0) { $output .= "<table><tr>"; foreach ($GLOBALS['dbi']->getFieldsMeta($result) as $field) { $output .= "<th>"; $output .= htmlspecialchars($field->name); $output .= "</th>"; } $output .= "</tr>"; $color_class = 'odd'; while ($row = $GLOBALS['dbi']->fetchAssoc($result)) { $output .= "<tr>" . browseRow($row, $color_class) . "</tr>"; $color_class = $color_class == 'odd' ? 'even' : 'odd'; } $output .= "</table>"; $nbResultsetToDisplay++; $affected = $num_rows; } if (!$GLOBALS['dbi']->moreResults()) { break; } $output .= "<br/>"; $GLOBALS['dbi']->freeResult($result); } while ($GLOBALS['dbi']->nextResult()); $output .= "</fieldset>"; $message = __('Your SQL query has been executed successfully.'); if ($routine['item_type'] == 'PROCEDURE') { $message .= '<br />'; // TODO : message need to be modified according to the // output from the routine $message .= sprintf(_ngettext('%d row affected by the last statement inside the ' . 'procedure.', '%d rows affected by the last statement inside the ' . 'procedure.', $affected), $affected); } $message = Message::success($message); if ($nbResultsetToDisplay == 0) { $notice = __('MySQL returned an empty result set (i.e. zero rows).'); $output .= Message::notice($notice)->getDisplay(); } } else { $output = ''; $message = Message::error(sprintf(__('The following query has failed: "%s"'), htmlspecialchars($multiple_query)) . '<br /><br />' . __('MySQL said: ') . $GLOBALS['dbi']->getError(null)); } // Print/send output if ($GLOBALS['is_ajax_request']) { $response = PMA\libraries\Response::getInstance(); $response->setRequestStatus($message->isSuccess()); $response->addJSON('message', $message->getDisplay() . $output); $response->addJSON('dialog', false); exit; } else { echo $message->getDisplay(), $output; if ($message->isError()) { // At least one query has failed, so shouldn't // execute any more queries, so we quit. exit; } unset($_POST); // Now deliberately fall through to displaying the routines list } return; } else { if (!empty($_GET['execute_dialog']) && !empty($_GET['item_name'])) { /** * Display the execute form for a routine. */ $routine = PMA_RTN_getDataFromName($_GET['item_name'], $_GET['item_type'], true, true); if ($routine !== false) { $form = PMA_RTN_getExecuteForm($routine); if ($GLOBALS['is_ajax_request'] == true) { $title = __("Execute routine") . " " . PMA\libraries\Util::backquote(htmlentities($_GET['item_name'], ENT_QUOTES)); $response = PMA\libraries\Response::getInstance(); $response->addJSON('message', $form); $response->addJSON('title', $title); $response->addJSON('dialog', true); } else { echo "\n\n<h2>" . __("Execute routine") . "</h2>\n\n"; echo $form; } exit; } else { if ($GLOBALS['is_ajax_request'] == true) { $message = __('Error in processing request:') . ' '; $message .= sprintf(PMA_RTE_getWord('not_found'), htmlspecialchars(PMA\libraries\Util::backquote($_REQUEST['item_name'])), htmlspecialchars(PMA\libraries\Util::backquote($db))); $message = Message::error($message); $response = PMA\libraries\Response::getInstance(); $response->setRequestStatus(false); $response->addJSON('message', $message); exit; } } } } }
/** * Process the data from the edit/create index form, * run the query to build the new index * and moves back to "tbl_sql.php" * * @return void */ public function doSaveDataAction() { $error = false; $sql_query = $this->dbi->getTable($this->db, $this->table)->getSqlQueryForIndexCreateOrEdit($this->index, $error); // If there is a request for SQL previewing. if (isset($_REQUEST['preview_sql'])) { $this->response->addJSON('sql_data', Template::get('preview_sql')->render(array('query_data' => $sql_query))); } elseif (!$error) { $this->dbi->query($sql_query); if ($GLOBALS['is_ajax_request'] == true) { $message = Message::success(__('Table %1$s has been altered successfully.')); $message->addParam($this->table); $this->response->addJSON('message', Util::getMessage($message, $sql_query, 'success')); $this->response->addJSON('index_table', Index::getHtmlForIndexes($this->table, $this->db)); } else { include 'tbl_structure.php'; } } else { $this->response->setRequestStatus(false); $this->response->addJSON('message', $error); } }