/** * Send table columns for foreign table dropdown * * @return void * */ public function getDropdownValueForTableAction() { $foreignTable = $_REQUEST['foreignTable']; $table_obj = $this->dbi->getTable($_REQUEST['foreignDb'], $foreignTable); // Since views do not have keys defined on them provide the full list of // columns if ($table_obj->isView()) { $columnList = $table_obj->getColumns(false, false); } else { $columnList = $table_obj->getIndexedColumns(false, false); } $columns = array(); foreach ($columnList as $column) { $columns[] = htmlspecialchars($column); } $this->response->addJSON('columns', $columns); // @todo should be: $server->db($db)->table($table)->primary() $primary = Index::getPrimary($foreignTable, $_REQUEST['foreignDb']); if (false === $primary) { return; } $this->response->addJSON('primary', array_keys($primary->getColumns())); }
/** * Index action * * @return void */ public function indexAction() { PageSettings::showGroup('TableStructure'); /** * Function implementations for this script */ include_once 'libraries/check_user_privileges.lib.php'; include_once 'libraries/index.lib.php'; include_once 'libraries/sql.lib.php'; include_once 'libraries/bookmark.lib.php'; $this->response->getHeader()->getScripts()->addFiles(array('tbl_structure.js', 'indexes.js')); /** * Handle column moving */ if (isset($_REQUEST['move_columns']) && is_array($_REQUEST['move_columns']) && $this->response->isAjax()) { $this->moveColumns(); return; } /** * handle MySQL reserved words columns check */ if (isset($_REQUEST['reserved_word_check'])) { if ($GLOBALS['cfg']['ReservedWordDisableWarning'] === false) { $columns_names = $_REQUEST['field_name']; $reserved_keywords_names = array(); foreach ($columns_names as $column) { if (SqlParser\Context::isKeyword(trim($column), true)) { $reserved_keywords_names[] = trim($column); } } if (SqlParser\Context::isKeyword(trim($this->table), true)) { $reserved_keywords_names[] = trim($this->table); } if (count($reserved_keywords_names) == 0) { $this->response->setRequestStatus(false); } $this->response->addJSON('message', sprintf(_ngettext('The name \'%s\' is a MySQL reserved keyword.', 'The names \'%s\' are MySQL reserved keywords.', count($reserved_keywords_names)), implode(',', $reserved_keywords_names))); } else { $this->response->setRequestStatus(false); } return; } /** * A click on Change has been made for one column */ if (isset($_REQUEST['change_column'])) { $this->displayHtmlForColumnChange(null, 'tbl_structure.php'); return; } /** * Adding or editing partitioning of the table */ if (isset($_REQUEST['edit_partitioning']) && !isset($_REQUEST['save_partitioning'])) { $this->displayHtmlForPartitionChange(); return; } /** * handle multiple field commands if required * * submit_mult_*_x comes from IE if <input type="img" ...> is used */ $submit_mult = $this->getMultipleFieldCommandType(); if (!empty($submit_mult)) { if (isset($_REQUEST['selected_fld'])) { if ($submit_mult == 'browse') { // browsing the table displaying only selected columns $this->displayTableBrowseForSelectedColumns($GLOBALS['goto'], $GLOBALS['pmaThemeImage']); } else { // handle multiple field commands // handle confirmation of deleting multiple columns $action = 'tbl_structure.php'; $GLOBALS['selected'] = $_REQUEST['selected_fld']; list($what_ret, $query_type_ret, $is_unset_submit_mult, $mult_btn_ret, $centralColsError) = $this->getDataForSubmitMult($submit_mult, $_REQUEST['selected_fld'], $action); //update the existing variables // todo: refactor mult_submits.inc.php such as // below globals are not needed anymore if (isset($what_ret)) { $GLOBALS['what'] = $what_ret; global $what; } if (isset($query_type_ret)) { $GLOBALS['query_type'] = $query_type_ret; global $query_type; } if ($is_unset_submit_mult) { unset($submit_mult); } if (isset($mult_btn_ret)) { $GLOBALS['mult_btn'] = $mult_btn_ret; global $mult_btn; } include 'libraries/mult_submits.inc.php'; /** * if $submit_mult == 'change', execution will have stopped * at this point */ if (empty($message)) { $message = Message::success(); } $this->response->addHTML(Util::getMessage($message, $sql_query)); } } else { $this->response->setRequestStatus(false); $this->response->addJSON('message', __('No column selected.')); } } // display secondary level tabs if necessary $engine = $this->table_obj->getStatusInfo('ENGINE'); $this->response->addHTML(Template::get('table/secondary_tabs')->render(array('url_params' => array('db' => $this->db, 'table' => $this->table), 'engine' => $engine))); $this->response->addHTML('<div id="structure_content">'); /** * Modifications have been submitted -> updates the table */ if (isset($_REQUEST['do_save_data'])) { $regenerate = $this->updateColumns(); if ($regenerate) { // This happens when updating failed // @todo: do something appropriate } else { // continue to show the table's structure unset($_REQUEST['selected']); } } /** * Modifications to the partitioning have been submitted -> updates the table */ if (isset($_REQUEST['save_partitioning'])) { $this->updatePartitioning(); } /** * Adding indexes */ if (isset($_REQUEST['add_key']) || isset($_REQUEST['partition_maintenance'])) { //todo: set some variables for sql.php include, to be eliminated //after refactoring sql.php $db = $this->db; $table = $this->table; $cfg = $GLOBALS['cfg']; $is_superuser = $GLOBALS['dbi']->isSuperuser(); $pmaThemeImage = $GLOBALS['pmaThemeImage']; include 'sql.php'; $GLOBALS['reload'] = true; } /** * Gets the relation settings */ $cfgRelation = PMA_getRelationsParam(); /** * Runs common work */ // set db, table references, for require_once that follows // got to be eliminated in long run $db =& $this->db; $table =& $this->table; include_once 'libraries/tbl_common.inc.php'; $this->_db_is_system_schema = $db_is_system_schema; $this->_url_query = $url_query . '&goto=tbl_structure.php&back=tbl_structure.php'; $url_params['goto'] = 'tbl_structure.php'; $url_params['back'] = 'tbl_structure.php'; /** * Gets tables information */ include_once 'libraries/tbl_info.inc.php'; // 2. Gets table keys and retains them // @todo should be: $server->db($db)->table($table)->primary() $primary = Index::getPrimary($this->table, $this->db); $columns_with_index = $this->dbi->getTable($this->db, $this->table)->getColumnsWithIndex(Index::UNIQUE | Index::INDEX | Index::SPATIAL | Index::FULLTEXT); $columns_with_unique_index = $this->dbi->getTable($this->db, $this->table)->getColumnsWithIndex(Index::UNIQUE); // 3. Get fields $fields = (array) $this->dbi->getColumns($this->db, $this->table, null, true); // Get more complete field information // For now, this is done just for MySQL 4.1.2+ new TIMESTAMP options // but later, if the analyser returns more information, it // could be executed for any MySQL version and replace // the info given by SHOW FULL COLUMNS FROM. // // We also need this to correctly learn if a TIMESTAMP is NOT NULL, since // SHOW FULL COLUMNS or INFORMATION_SCHEMA incorrectly says NULL // and SHOW CREATE TABLE says NOT NULL (tested // in MySQL 4.0.25 and 5.0.21, http://bugs.mysql.com/20910). $show_create_table = $this->table_obj->showCreate(); $parser = new SqlParser\Parser($show_create_table); /** * @var CreateStatement $stmt */ $stmt = $parser->statements[0]; $create_table_fields = SqlTable::getFields($stmt); //display table structure $this->response->addHTML($this->displayStructure($cfgRelation, $columns_with_unique_index, $url_params, $primary, $fields, $columns_with_index, $create_table_fields)); $this->response->addHTML('</div>'); }
/** * Returns HTML for the index choice selector * * @param boolean $edit_table whether this is table editing * * @return string HTML for the index choice selector */ public function generateIndexChoiceSelector($edit_table) { $html_options = '<select name="index[Index_choice]"' . ' id="select_index_choice" ' . ($edit_table ? 'disabled="disabled"' : '') . '>'; foreach (Index::getIndexChoices() as $each_index_choice) { if ($each_index_choice === 'PRIMARY' && $this->_choice !== 'PRIMARY' && Index::getPrimary($this->_table, $this->_schema)) { // skip PRIMARY if there is already one in the table continue; } $html_options .= '<option value="' . $each_index_choice . '"' . ($this->_choice == $each_index_choice ? ' selected="selected"' : '') . '>' . $each_index_choice . '</option>' . "\n"; } $html_options .= '</select>'; return $html_options; }