12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502 |
- <?php
- /* vim: set expandtab sw=4 ts=4 sts=4: */
- /**
- * Holds the PhpMyAdmin\Controllers\Table\TableStructureController
- *
- * @package PhpMyAdmin\Controllers
- */
- namespace PhpMyAdmin\Controllers\Table;
- use PhpMyAdmin\CentralColumns;
- use PhpMyAdmin\Config\PageSettings;
- use PhpMyAdmin\Controllers\TableController;
- use PhpMyAdmin\Core;
- use PhpMyAdmin\CreateAddField;
- use PhpMyAdmin\Index;
- use PhpMyAdmin\Message;
- use PhpMyAdmin\ParseAnalyze;
- use PhpMyAdmin\Partition;
- use PhpMyAdmin\Relation;
- use PhpMyAdmin\Sql;
- use PhpMyAdmin\SqlParser\Context;
- use PhpMyAdmin\SqlParser\Parser;
- use PhpMyAdmin\SqlParser\Statements\CreateStatement;
- use PhpMyAdmin\Table;
- use PhpMyAdmin\Template;
- use PhpMyAdmin\Tracker;
- use PhpMyAdmin\Transformations;
- use PhpMyAdmin\Url;
- use PhpMyAdmin\Util;
- /**
- * Handles table structure logic
- *
- * @package PhpMyAdmin\Controllers
- */
- class TableStructureController extends TableController
- {
- /**
- * @var Table The table object
- */
- protected $table_obj;
- /**
- * @var string The URL query string
- */
- protected $_url_query;
- /**
- * @var bool DB is information_schema
- */
- protected $_db_is_system_schema;
- /**
- * @var bool Table is a view
- */
- protected $_tbl_is_view;
- /**
- * @var string Table storage engine
- */
- protected $_tbl_storage_engine;
- /**
- * @var int Number of rows
- */
- protected $_table_info_num_rows;
- /**
- * @var string Table collation
- */
- protected $_tbl_collation;
- /**
- * @var array Show table info
- */
- protected $_showtable;
- /**
- * @var CreateAddField
- */
- private $createAddField;
- /**
- * @var Relation $relation
- */
- private $relation;
- /**
- * TableStructureController constructor
- *
- * @param string $db DB name
- * @param string $table Table name
- * @param string $type Indicate the db_structure or tbl_structure
- * @param int $num_tables Number of tables
- * @param int $pos Current position in the list
- * @param bool $db_is_system_schema DB is information_schema
- * @param int $total_num_tables Number of tables
- * @param array $tables Tables in the DB
- * @param bool $is_show_stats Whether stats show or not
- * @param bool $tbl_is_view Table is a view
- * @param string $tbl_storage_engine Table storage engine
- * @param int $table_info_num_rows Number of rows
- * @param string $tbl_collation Table collation
- * @param array $showtable Show table info
- */
- public function __construct(
- $response,
- $dbi,
- $db,
- $table,
- $type,
- $num_tables,
- $pos,
- $db_is_system_schema,
- $total_num_tables,
- $tables,
- $is_show_stats,
- $tbl_is_view,
- $tbl_storage_engine,
- $table_info_num_rows,
- $tbl_collation,
- $showtable
- ) {
- parent::__construct($response, $dbi, $db, $table);
- $this->_db_is_system_schema = $db_is_system_schema;
- $this->_url_query = Url::getCommonRaw(array('db' => $db, 'table' => $table));
- $this->_tbl_is_view = $tbl_is_view;
- $this->_tbl_storage_engine = $tbl_storage_engine;
- $this->_table_info_num_rows = $table_info_num_rows;
- $this->_tbl_collation = $tbl_collation;
- $this->_showtable = $showtable;
- $this->table_obj = $this->dbi->getTable($this->db, $this->table);
- $this->createAddField = new CreateAddField($dbi);
- $this->relation = new Relation();
- }
- /**
- * Index action
- *
- * @return void
- */
- public function indexAction()
- {
- PageSettings::showGroup('TableStructure');
- /**
- * Function implementations for this script
- */
- include_once 'libraries/check_user_privileges.inc.php';
- $this->response->getHeader()->getScripts()->addFiles(
- array(
- 'tbl_structure.js',
- 'indexes.js'
- )
- );
- /**
- * Handle column moving
- */
- if (isset($_POST['move_columns'])
- && is_array($_POST['move_columns'])
- && $this->response->isAjax()
- ) {
- $this->moveColumns();
- return;
- }
- /**
- * handle MySQL reserved words columns check
- */
- if (isset($_POST['reserved_word_check'])) {
- if ($GLOBALS['cfg']['ReservedWordDisableWarning'] === false) {
- $columns_names = $_POST['field_name'];
- $reserved_keywords_names = array();
- foreach ($columns_names as $column) {
- if (Context::isKeyword(trim($column), true)) {
- $reserved_keywords_names[] = trim($column);
- }
- }
- if (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($_GET['change_column'])) {
- $this->displayHtmlForColumnChange(null, 'tbl_structure.php');
- return;
- }
- /**
- * Adding or editing partitioning of the table
- */
- if (isset($_POST['edit_partitioning'])
- && ! isset($_POST['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($_POST['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'] = $_POST['selected_fld'];
- list(
- $what_ret, $query_type_ret, $is_unset_submit_mult,
- $mult_btn_ret, $centralColsError
- )
- = $this->getDataForSubmitMult(
- $submit_mult, $_POST['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->getStorageEngine();
- $this->response->addHTML(
- Template::get('table/secondary_tabs')->render(
- array(
- 'url_params' => array(
- 'db' => $this->db,
- 'table' => $this->table
- ),
- 'is_foreign_key_supported' => Util::isForeignKeySupported($engine),
- 'cfg_relation' => $this->relation->getRelationsParam(),
- )
- )
- );
- $this->response->addHTML('<div id="structure_content">');
- /**
- * Modifications have been submitted -> updates the table
- */
- if (isset($_POST['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($_POST['selected']);
- }
- }
- /**
- * Modifications to the partitioning have been submitted -> updates the table
- */
- if (isset($_POST['save_partitioning'])) {
- $this->updatePartitioning();
- }
- /**
- * Adding indexes
- */
- if (isset($_POST['add_key'])
- || isset($_POST['partition_maintenance'])
- ) {
- //todo: set some variables for sql.php include, to be eliminated
- //after refactoring sql.php
- $db = $this->db;
- $table = $this->table;
- $sql_query = $GLOBALS['sql_query'];
- $cfg = $GLOBALS['cfg'];
- $pmaThemeImage = $GLOBALS['pmaThemeImage'];
- include 'sql.php';
- $GLOBALS['reload'] = true;
- }
- /**
- * Gets the relation settings
- */
- $cfgRelation = $this->relation->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;
- $url_params = array();
- include_once 'libraries/tbl_common.inc.php';
- $this->_db_is_system_schema = $db_is_system_schema;
- $this->_url_query = Url::getCommonRaw(array(
- 'db' => $db,
- 'table' => $table,
- 'goto' => 'tbl_structure.php',
- 'back' => 'tbl_structure.php',
- ));
- /* The url_params array is initialized in above include */
- $url_params['goto'] = 'tbl_structure.php';
- $url_params['back'] = 'tbl_structure.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
- );
- foreach ($fields as $key => $row) {
- if ('text' === substr($row['Type'], -4)) {
- $fields[$key]['Default'] = stripcslashes(substr($row['Default'], 1, -1));
- }
- }
- //display table structure
- $this->response->addHTML(
- $this->displayStructure(
- $cfgRelation, $columns_with_unique_index, $url_params,
- $primary, $fields, $columns_with_index
- )
- );
- $this->response->addHTML('</div>');
- }
- /**
- * Moves columns in the table's structure based on $_REQUEST
- *
- * @return void
- */
- protected function moveColumns()
- {
- $this->dbi->selectDb($this->db);
- /*
- * load the definitions for all columns
- */
- $columns = $this->dbi->getColumnsFull($this->db, $this->table);
- $column_names = array_keys($columns);
- $changes = array();
- // @see https://mariadb.com/kb/en/library/changes-improvements-in-mariadb-102/#information-schema
- $usesLiteralNull = $this->dbi->isMariaDB() && $this->dbi->getVersion() >= 100200;
- $defaultNullValue = $usesLiteralNull ? 'NULL' : null;
- // move columns from first to last
- for ($i = 0, $l = count($_POST['move_columns']); $i < $l; $i++) {
- $column = $_POST['move_columns'][$i];
- // is this column already correctly placed?
- if ($column_names[$i] == $column) {
- continue;
- }
- // it is not, let's move it to index $i
- $data = $columns[$column];
- $extracted_columnspec = Util::extractColumnSpec($data['Type']);
- if (isset($data['Extra'])
- && $data['Extra'] == 'on update CURRENT_TIMESTAMP'
- ) {
- $extracted_columnspec['attribute'] = $data['Extra'];
- unset($data['Extra']);
- }
- $current_timestamp = ($data['Type'] == 'timestamp'
- || $data['Type'] == 'datetime' || $data['DATA_TYPE'] == 'int')
- && ($data['Default'] == 'CURRENT_TIMESTAMP'
- || $data['Default'] == 'current_timestamp()');
- // @see https://mariadb.com/kb/en/library/information-schema-columns-table/#examples
- if ($data['Null'] === 'YES' && in_array($data['Default'], [$defaultNullValue, null])) {
- $default_type = 'NULL';
- } elseif ($current_timestamp) {
- $default_type = 'CURRENT_TIMESTAMP';
- } elseif ($data['Default'] === null) {
- $default_type = 'NONE';
- } else {
- $default_type = 'USER_DEFINED';
- }
- $virtual = array(
- 'VIRTUAL', 'PERSISTENT', 'VIRTUAL GENERATED', 'STORED GENERATED'
- );
- $data['Virtuality'] = '';
- $data['Expression'] = '';
- if (isset($data['Extra']) && in_array($data['Extra'], $virtual)) {
- $data['Virtuality'] = str_replace(' GENERATED', '', $data['Extra']);
- $expressions = $this->table_obj->getColumnGenerationExpression($column);
- $data['Expression'] = $expressions[$column];
- }
- $changes[] = 'CHANGE ' . Table::generateAlter(
- $column,
- $column,
- mb_strtoupper($extracted_columnspec['type']),
- $extracted_columnspec['spec_in_brackets'],
- $extracted_columnspec['attribute'],
- isset($data['Collation']) ? $data['Collation'] : '',
- $data['Null'] === 'YES' ? 'YES' : 'NO',
- $default_type,
- $current_timestamp ? '' : $data['Default'],
- isset($data['Extra']) && $data['Extra'] !== '' ? $data['Extra']
- : false,
- isset($data['COLUMN_COMMENT']) && $data['COLUMN_COMMENT'] !== ''
- ? $data['COLUMN_COMMENT'] : false,
- $data['Virtuality'],
- $data['Expression'],
- $i === 0 ? '-first' : $column_names[$i - 1]
- );
- // update current column_names array, first delete old position
- for ($j = 0, $ll = count($column_names); $j < $ll; $j++) {
- if ($column_names[$j] == $column) {
- unset($column_names[$j]);
- }
- }
- // insert moved column
- array_splice($column_names, $i, 0, $column);
- }
- if (empty($changes)) { // should never happen
- $this->response->setRequestStatus(false);
- return;
- }
- // move columns
- $this->dbi->tryQuery(
- sprintf(
- 'ALTER TABLE %s %s',
- Util::backquote($this->table),
- implode(', ', $changes)
- )
- );
- $tmp_error = $this->dbi->getError();
- if ($tmp_error) {
- $this->response->setRequestStatus(false);
- $this->response->addJSON('message', Message::error($tmp_error));
- } else {
- $message = Message::success(
- __('The columns have been moved successfully.')
- );
- $this->response->addJSON('message', $message);
- $this->response->addJSON('columns', $column_names);
- }
- }
- /**
- * Displays HTML for changing one or more columns
- *
- * @param array $selected the selected columns
- * @param string $action target script to call
- *
- * @return boolean $regenerate true if error occurred
- *
- */
- protected function displayHtmlForColumnChange($selected, $action)
- {
- // $selected comes from mult_submits.inc.php
- if (empty($selected)) {
- $selected[] = $_REQUEST['field'];
- $selected_cnt = 1;
- } else { // from a multiple submit
- $selected_cnt = count($selected);
- }
- /**
- * @todo optimize in case of multiple fields to modify
- */
- $fields_meta = array();
- for ($i = 0; $i < $selected_cnt; $i++) {
- $value = $this->dbi->getColumns(
- $this->db, $this->table, $this->dbi->escapeString($selected[$i]), true
- );
- if (count($value) == 0) {
- $message = Message::error(
- __('Failed to get description of column %s!')
- );
- $message->addParam($selected[$i]);
- $this->response->addHTML($message);
- } else {
- $fields_meta[] = $value;
- }
- }
- $num_fields = count($fields_meta);
- // set these globals because tbl_columns_definition_form.inc.php
- // verifies them
- // @todo: refactor tbl_columns_definition_form.inc.php so that it uses
- // protected function params
- $GLOBALS['action'] = $action;
- $GLOBALS['num_fields'] = $num_fields;
- /**
- * Form for changing properties.
- */
- include_once 'libraries/check_user_privileges.inc.php';
- include 'libraries/tbl_columns_definition_form.inc.php';
- }
- /**
- * Displays HTML for partition change
- *
- * @return string HTML for partition change
- */
- protected function displayHtmlForPartitionChange()
- {
- $partitionDetails = null;
- if (! isset($_POST['partition_by'])) {
- $partitionDetails = $this->_extractPartitionDetails();
- }
- include 'libraries/tbl_partition_definition.inc.php';
- $this->response->addHTML(
- Template::get('table/structure/partition_definition_form')
- ->render(
- array(
- 'db' => $this->db,
- 'table' => $this->table,
- 'partition_details' => $partitionDetails,
- )
- )
- );
- }
- /**
- * Extracts partition details from CREATE TABLE statement
- *
- * @return array[] array of partition details
- */
- private function _extractPartitionDetails()
- {
- $createTable = (new Table($this->table, $this->db))->showCreate();
- if (! $createTable) {
- return null;
- }
- $parser = new Parser($createTable);
- /**
- * @var $stmt PhpMyAdmin\SqlParser\Statements\CreateStatement
- */
- $stmt = $parser->statements[0];
- $partitionDetails = array();
- $partitionDetails['partition_by'] = '';
- $partitionDetails['partition_expr'] = '';
- $partitionDetails['partition_count'] = '';
- if (! empty($stmt->partitionBy)) {
- $openPos = strpos($stmt->partitionBy, "(");
- $closePos = strrpos($stmt->partitionBy, ")");
- $partitionDetails['partition_by']
- = trim(substr($stmt->partitionBy, 0, $openPos));
- $partitionDetails['partition_expr']
- = trim(substr($stmt->partitionBy, $openPos + 1, $closePos - ($openPos + 1)));
- if (isset($stmt->partitionsNum)) {
- $count = $stmt->partitionsNum;
- } else {
- $count = count($stmt->partitions);
- }
- $partitionDetails['partition_count'] = $count;
- }
- $partitionDetails['subpartition_by'] = '';
- $partitionDetails['subpartition_expr'] = '';
- $partitionDetails['subpartition_count'] = '';
- if (! empty($stmt->subpartitionBy)) {
- $openPos = strpos($stmt->subpartitionBy, "(");
- $closePos = strrpos($stmt->subpartitionBy, ")");
- $partitionDetails['subpartition_by']
- = trim(substr($stmt->subpartitionBy, 0, $openPos));
- $partitionDetails['subpartition_expr']
- = trim(substr($stmt->subpartitionBy, $openPos + 1, $closePos - ($openPos + 1)));
- if (isset($stmt->subpartitionsNum)) {
- $count = $stmt->subpartitionsNum;
- } else {
- $count = count($stmt->partitions[0]->subpartitions);
- }
- $partitionDetails['subpartition_count'] = $count;
- }
- // Only LIST and RANGE type parameters allow subpartitioning
- $partitionDetails['can_have_subpartitions']
- = $partitionDetails['partition_count'] > 1
- && ($partitionDetails['partition_by'] == 'RANGE'
- || $partitionDetails['partition_by'] == 'RANGE COLUMNS'
- || $partitionDetails['partition_by'] == 'LIST'
- || $partitionDetails['partition_by'] == 'LIST COLUMNS');
- // Values are specified only for LIST and RANGE type partitions
- $partitionDetails['value_enabled'] = isset($partitionDetails['partition_by'])
- && ($partitionDetails['partition_by'] == 'RANGE'
- || $partitionDetails['partition_by'] == 'RANGE COLUMNS'
- || $partitionDetails['partition_by'] == 'LIST'
- || $partitionDetails['partition_by'] == 'LIST COLUMNS');
- $partitionDetails['partitions'] = array();
- for ($i = 0; $i < intval($partitionDetails['partition_count']); $i++) {
- if (! isset($stmt->partitions[$i])) {
- $partitionDetails['partitions'][$i] = array(
- 'name' => 'p' . $i,
- 'value_type' => '',
- 'value' => '',
- 'engine' => '',
- 'comment' => '',
- 'data_directory' => '',
- 'index_directory' => '',
- 'max_rows' => '',
- 'min_rows' => '',
- 'tablespace' => '',
- 'node_group' => '',
- );
- } else {
- $p = $stmt->partitions[$i];
- $type = $p->type;
- $expr = trim($p->expr, '()');
- if ($expr == 'MAXVALUE') {
- $type .= ' MAXVALUE';
- $expr = '';
- }
- $partitionDetails['partitions'][$i] = array(
- 'name' => $p->name,
- 'value_type' => $type,
- 'value' => $expr,
- 'engine' => $p->options->has('ENGINE', true),
- 'comment' => trim($p->options->has('COMMENT', true), "'"),
- 'data_directory' => trim($p->options->has('DATA DIRECTORY', true), "'"),
- 'index_directory' => trim($p->options->has('INDEX_DIRECTORY', true), "'"),
- 'max_rows' => $p->options->has('MAX_ROWS', true),
- 'min_rows' => $p->options->has('MIN_ROWS', true),
- 'tablespace' => $p->options->has('TABLESPACE', true),
- 'node_group' => $p->options->has('NODEGROUP', true),
- );
- }
- $partition =& $partitionDetails['partitions'][$i];
- $partition['prefix'] = 'partitions[' . $i . ']';
- if ($partitionDetails['subpartition_count'] > 1) {
- $partition['subpartition_count'] = $partitionDetails['subpartition_count'];
- $partition['subpartitions'] = array();
- for ($j = 0; $j < intval($partitionDetails['subpartition_count']); $j++) {
- if (! isset($stmt->partitions[$i]->subpartitions[$j])) {
- $partition['subpartitions'][$j] = array(
- 'name' => $partition['name'] . '_s' . $j,
- 'engine' => '',
- 'comment' => '',
- 'data_directory' => '',
- 'index_directory' => '',
- 'max_rows' => '',
- 'min_rows' => '',
- 'tablespace' => '',
- 'node_group' => '',
- );
- } else {
- $sp = $stmt->partitions[$i]->subpartitions[$j];
- $partition['subpartitions'][$j] = array(
- 'name' => $sp->name,
- 'engine' => $sp->options->has('ENGINE', true),
- 'comment' => trim($sp->options->has('COMMENT', true), "'"),
- 'data_directory' => trim($sp->options->has('DATA DIRECTORY', true), "'"),
- 'index_directory' => trim($sp->options->has('INDEX_DIRECTORY', true), "'"),
- 'max_rows' => $sp->options->has('MAX_ROWS', true),
- 'min_rows' => $sp->options->has('MIN_ROWS', true),
- 'tablespace' => $sp->options->has('TABLESPACE', true),
- 'node_group' => $sp->options->has('NODEGROUP', true),
- );
- }
- $subpartition =& $partition['subpartitions'][$j];
- $subpartition['prefix'] = 'partitions[' . $i . ']'
- . '[subpartitions][' . $j . ']';
- }
- }
- }
- return $partitionDetails;
- }
- /**
- * Update the table's partitioning based on $_REQUEST
- *
- * @return void
- */
- protected function updatePartitioning()
- {
- $sql_query = "ALTER TABLE " . Util::backquote($this->table) . " "
- . $this->createAddField->getPartitionsDefinition();
- // Execute alter query
- $result = $this->dbi->tryQuery($sql_query);
- if ($result !== false) {
- $message = Message::success(
- __('Table %1$s has been altered successfully.')
- );
- $message->addParam($this->table);
- $this->response->addHTML(
- Util::getMessage($message, $sql_query, 'success')
- );
- } else {
- $this->response->setRequestStatus(false);
- $this->response->addJSON(
- 'message',
- Message::rawError(
- __('Query error') . ':<br />' . $this->dbi->getError()
- )
- );
- }
- }
- /**
- * Function to get the type of command for multiple field handling
- *
- * @return string
- */
- protected function getMultipleFieldCommandType()
- {
- $types = array(
- 'change', 'drop', 'primary',
- 'index', 'unique', 'spatial',
- 'fulltext', 'browse'
- );
- foreach ($types as $type) {
- if (isset($_POST['submit_mult_' . $type . '_x'])) {
- return $type;
- }
- }
- if (isset($_POST['submit_mult'])) {
- return $_POST['submit_mult'];
- } elseif (isset($_POST['mult_btn'])
- && $_POST['mult_btn'] == __('Yes')
- ) {
- if (isset($_POST['selected'])) {
- $_POST['selected_fld'] = $_POST['selected'];
- }
- return 'row_delete';
- }
- return null;
- }
- /**
- * Function to display table browse for selected columns
- *
- * @param string $goto goto page url
- * @param string $pmaThemeImage URI of the pma theme image
- *
- * @return void
- */
- protected function displayTableBrowseForSelectedColumns($goto, $pmaThemeImage)
- {
- $GLOBALS['active_page'] = 'sql.php';
- $fields = array();
- foreach ($_POST['selected_fld'] as $sval) {
- $fields[] = Util::backquote($sval);
- }
- $sql_query = sprintf(
- 'SELECT %s FROM %s.%s',
- implode(', ', $fields),
- Util::backquote($this->db),
- Util::backquote($this->table)
- );
- // Parse and analyze the query
- $db = &$this->db;
- list(
- $analyzed_sql_results,
- $db,
- ) = ParseAnalyze::sqlQuery($sql_query, $db);
- // @todo: possibly refactor
- extract($analyzed_sql_results);
- $sql = new Sql();
- $this->response->addHTML(
- $sql->executeQueryAndGetQueryResponse(
- isset($analyzed_sql_results) ? $analyzed_sql_results : '',
- false, // is_gotofile
- $this->db, // db
- $this->table, // table
- null, // find_real_end
- null, // sql_query_for_bookmark
- null, // extra_data
- null, // message_to_show
- null, // message
- null, // sql_data
- $goto, // goto
- $pmaThemeImage, // pmaThemeImage
- null, // disp_query
- null, // disp_message
- null, // query_type
- $sql_query, // sql_query
- null, // selectedTables
- null // complete_query
- )
- );
- }
- /**
- * Update the table's structure based on $_REQUEST
- *
- * @return boolean $regenerate true if error occurred
- *
- */
- protected function updateColumns()
- {
- $err_url = 'tbl_structure.php' . Url::getCommon(
- array(
- 'db' => $this->db, 'table' => $this->table
- )
- );
- $regenerate = false;
- $field_cnt = count($_POST['field_name']);
- $changes = array();
- $adjust_privileges = array();
- for ($i = 0; $i < $field_cnt; $i++) {
- if (!$this->columnNeedsAlterTable($i)) {
- continue;
- }
- $changes[] = 'CHANGE ' . Table::generateAlter(
- Util::getValueByKey($_POST, "field_orig.${i}", ''),
- $_POST['field_name'][$i],
- $_POST['field_type'][$i],
- $_POST['field_length'][$i],
- $_POST['field_attribute'][$i],
- Util::getValueByKey($_POST, "field_collation.${i}", ''),
- Util::getValueByKey($_POST, "field_null.${i}", 'NO'),
- $_POST['field_default_type'][$i],
- $_POST['field_default_value'][$i],
- Util::getValueByKey($_POST, "field_extra.${i}", false),
- Util::getValueByKey($_POST, "field_comments.${i}", ''),
- Util::getValueByKey($_POST, "field_virtuality.${i}", ''),
- Util::getValueByKey($_POST, "field_expression.${i}", ''),
- Util::getValueByKey($_POST, "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($_POST['field_orig'][$i])
- ) !== false) {
- // delete the whole remembered sort expression
- $this->table_obj->removeUiProp(Table::PROP_SORTED_COLUMN);
- }
- if (isset($_POST['field_adjust_privileges'][$i])
- && ! empty($_POST['field_adjust_privileges'][$i])
- && $_POST['field_orig'][$i] != $_POST['field_name'][$i]
- ) {
- $adjust_privileges[$_POST['field_orig'][$i]]
- = $_POST['field_name'][$i];
- }
- } // end for
- if (count($changes) > 0 || isset($_POST['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($_POST['preview_sql'])) {
- Core::previewSQL(count($changes) > 0 ? $sql_query : '');
- }
- $columns_with_index = $this->dbi
- ->getTable($this->db, $this->table)
- ->getColumnsWithIndex(
- Index::PRIMARY | Index::UNIQUE | Index::INDEX
- | Index::SPATIAL | Index::FULLTEXT
- );
- $changedToBlob = array();
- // While changing the Column Collation
- // First change to BLOB
- for ($i = 0; $i < $field_cnt; $i++ ) {
- if (isset($_POST['field_collation'][$i])
- && isset($_POST['field_collation_orig'][$i])
- && $_POST['field_collation'][$i] !== $_POST['field_collation_orig'][$i]
- && ! in_array($_POST['field_orig'][$i], $columns_with_index)
- ) {
- $secondary_query = 'ALTER TABLE ' . Util::backquote(
- $this->table
- )
- . ' CHANGE ' . Util::backquote(
- $_POST['field_orig'][$i]
- )
- . ' ' . Util::backquote($_POST['field_orig'][$i])
- . ' BLOB';
- if (isset($_POST['field_virtuality'][$i])
- && isset($_POST['field_expression'][$i])) {
- if ($_POST['field_virtuality'][$i]) {
- $secondary_query .= ' AS (' . $_POST['field_expression'][$i] . ') '
- . $_POST['field_virtuality'][$i];
- }
- }
- $secondary_query .= ';';
- $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::getValueByKey($_POST, "field_orig.${i}", ''),
- $_POST['field_name'][$i],
- $_POST['field_type_orig'][$i],
- $_POST['field_length_orig'][$i],
- $_POST['field_attribute_orig'][$i],
- Util::getValueByKey($_POST, "field_collation_orig.${i}", ''),
- Util::getValueByKey($_POST, "field_null_orig.${i}", 'NO'),
- $_POST['field_default_type_orig'][$i],
- $_POST['field_default_value_orig'][$i],
- Util::getValueByKey($_POST, "field_extra_orig.${i}", false),
- Util::getValueByKey($_POST, "field_comments_orig.${i}", ''),
- Util::getValueByKey($_POST, "field_virtuality_orig.${i}", ''),
- Util::getValueByKey($_POST, "field_expression_orig.${i}", ''),
- Util::getValueByKey($_POST, "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($_POST['field_orig']) && is_array($_POST['field_orig'])) {
- foreach ($_POST['field_orig'] as $fieldindex => $fieldcontent) {
- if ($_POST['field_name'][$fieldindex] != $fieldcontent) {
- $this->relation->renameField(
- $this->db, $this->table, $fieldcontent,
- $_POST['field_name'][$fieldindex]
- );
- }
- }
- }
- // update mime types
- if (isset($_POST['field_mimetype'])
- && is_array($_POST['field_mimetype'])
- && $GLOBALS['cfg']['BrowseMIME']
- ) {
- foreach ($_POST['field_mimetype'] as $fieldindex => $mimetype) {
- if (isset($_POST['field_name'][$fieldindex])
- && strlen($_POST['field_name'][$fieldindex]) > 0
- ) {
- Transformations::setMIME(
- $this->db, $this->table,
- $_POST['field_name'][$fieldindex],
- $mimetype,
- $_POST['field_transformation'][$fieldindex],
- $_POST['field_transformation_options'][$fieldindex],
- $_POST['field_input_transformation'][$fieldindex],
- $_POST['field_input_transformation_options'][$fieldindex]
- );
- }
- }
- }
- return $regenerate;
- }
- /**
- * Adjusts the Privileges for all the columns whose names have changed
- *
- * @param array $adjust_privileges assoc array of old col names mapped to new
- * cols
- *
- * @return boolean $changed boolean whether at least one column privileges
- * adjusted
- */
- protected function adjustColumnPrivileges(array $adjust_privileges)
- {
- $changed = false;
- if (Util::getValueByKey($GLOBALS, 'col_priv', false)
- && Util::getValueByKey($GLOBALS, 'is_reload_priv', false)
- ) {
- $this->dbi->selectDb('mysql');
- // For Column specific privileges
- foreach ($adjust_privileges as $oldCol => $newCol) {
- $this->dbi->query(
- sprintf(
- 'UPDATE %s SET Column_name = "%s"
- WHERE Db = "%s"
- AND Table_name = "%s"
- AND Column_name = "%s";',
- Util::backquote('columns_priv'),
- $newCol, $this->db, $this->table, $oldCol
- )
- );
- // i.e. if atleast one column privileges adjusted
- $changed = true;
- }
- if ($changed) {
- // Finally FLUSH the new privileges
- $this->dbi->query("FLUSH PRIVILEGES;");
- }
- }
- return $changed;
- }
- /**
- * Verifies if some elements of a column have changed
- *
- * @param integer $i column index in the request
- *
- * @return boolean $alterTableNeeded true if we need to generate ALTER TABLE
- *
- */
- protected function columnNeedsAlterTable($i)
- {
- // these two fields are checkboxes so might not be part of the
- // request; therefore we define them to avoid notices below
- if (! isset($_POST['field_null'][$i])) {
- $_POST['field_null'][$i] = 'NO';
- }
- if (! isset($_POST['field_extra'][$i])) {
- $_POST['field_extra'][$i] = '';
- }
- // field_name does not follow the convention (corresponds to field_orig)
- if ($_POST['field_name'][$i] != $_POST['field_orig'][$i]) {
- return true;
- }
- $fields = array(
- 'field_attribute', 'field_collation', 'field_comments',
- 'field_default_value', 'field_default_type', 'field_extra',
- 'field_length', 'field_null', 'field_type'
- );
- foreach ($fields as $field) {
- if ($_POST[$field][$i] != $_POST[$field . '_orig'][$i]) {
- return true;
- }
- }
- return !empty($_POST['field_move_to'][$i]);
- }
- /**
- * Displays the table structure ('show table' works correct since 3.23.03)
- *
- * @param array $cfgRelation current relation parameters
- * @param array $columns_with_unique_index Columns with unique index
- * @param mixed $url_params Contains an associative
- * array with url params
- * @param Index|false $primary_index primary index or false if
- * no one exists
- * @param array $fields Fields
- * @param array $columns_with_index Columns with index
- *
- * @return string
- */
- protected function displayStructure(
- array $cfgRelation, array $columns_with_unique_index, $url_params,
- $primary_index, array $fields, array $columns_with_index
- ) {
- // prepare comments
- $comments_map = array();
- $mime_map = array();
- if ($GLOBALS['cfg']['ShowPropertyComments']) {
- $comments_map = $this->relation->getComments($this->db, $this->table);
- if ($cfgRelation['mimework'] && $GLOBALS['cfg']['BrowseMIME']) {
- $mime_map = Transformations::getMIME($this->db, $this->table, true);
- }
- }
- $centralColumns = new CentralColumns($GLOBALS['dbi']);
- $central_list = $centralColumns->getFromTable(
- $this->db,
- $this->table
- );
- $columns_list = array();
- $titles = array(
- 'Change' => Util::getIcon('b_edit', __('Change')),
- 'Drop' => Util::getIcon('b_drop', __('Drop')),
- 'NoDrop' => Util::getIcon('b_drop', __('Drop')),
- 'Primary' => Util::getIcon('b_primary', __('Primary')),
- 'Index' => Util::getIcon('b_index', __('Index')),
- 'Unique' => Util::getIcon('b_unique', __('Unique')),
- 'Spatial' => Util::getIcon('b_spatial', __('Spatial')),
- 'IdxFulltext' => Util::getIcon('b_ftext', __('Fulltext')),
- 'NoPrimary' => Util::getIcon('bd_primary', __('Primary')),
- 'NoIndex' => Util::getIcon('bd_index', __('Index')),
- 'NoUnique' => Util::getIcon('bd_unique', __('Unique')),
- 'NoSpatial' => Util::getIcon('bd_spatial', __('Spatial')),
- 'NoIdxFulltext' => Util::getIcon('bd_ftext', __('Fulltext')),
- 'DistinctValues' => Util::getIcon('b_browse', __('Distinct values')),
- );
- /**
- * Displays Space usage and row statistics
- */
- // BEGIN - Calc Table Space
- // Get valid statistics whatever is the table type
- if ($GLOBALS['cfg']['ShowStats']) {
- //get table stats in HTML format
- $tablestats = $this->getTableStats();
- //returning the response in JSON format to be used by Ajax
- $this->response->addJSON('tableStat', $tablestats);
- }
- // END - Calc Table Space
- $hideStructureActions = false;
- if ($GLOBALS['cfg']['HideStructureActions'] === true) {
- $hideStructureActions = true;
- }
- return Template::get('table/structure/display_structure')->render(
- array(
- 'hide_structure_actions' => $hideStructureActions,
- 'db' => $this->db,
- 'table' => $this->table,
- 'db_is_system_schema' => $this->_db_is_system_schema,
- 'tbl_is_view' => $this->_tbl_is_view,
- 'mime_map' => $mime_map,
- 'url_query' => $this->_url_query,
- 'url_params' => $url_params,
- 'titles' => $titles,
- 'tbl_storage_engine' => $this->_tbl_storage_engine,
- 'primary' => $primary_index,
- 'columns_with_unique_index' => $columns_with_unique_index,
- 'columns_list' => $columns_list,
- 'table_stats' => isset($tablestats) ? $tablestats : null,
- 'fields' => $fields,
- 'columns_with_index' => $columns_with_index,
- 'central_list' => $central_list,
- 'comments_map' => $comments_map,
- 'browse_mime' => $GLOBALS['cfg']['BrowseMIME'],
- 'show_column_comments' => $GLOBALS['cfg']['ShowColumnComments'],
- 'show_stats' => $GLOBALS['cfg']['ShowStats'],
- 'relation_commwork' => $GLOBALS['cfgRelation']['commwork'],
- 'relation_mimework' => $GLOBALS['cfgRelation']['mimework'],
- 'central_columns_work' => $GLOBALS['cfgRelation']['centralcolumnswork'],
- 'mysql_int_version' => $GLOBALS['dbi']->getVersion(),
- 'is_mariadb' => $GLOBALS['dbi']->isMariaDB(),
- 'pma_theme_image' => $GLOBALS['pmaThemeImage'],
- 'text_dir' => $GLOBALS['text_dir'],
- 'is_active' => Tracker::isActive(),
- 'have_partitioning' => Partition::havePartitioning(),
- 'partition_names' => Partition::getPartitionNames($this->db, $this->table),
- )
- );
- }
- /**
- * Get HTML snippet for display table statistics
- *
- * @return string $html_output
- */
- protected function getTableStats()
- {
- if (empty($this->_showtable)) {
- $this->_showtable = $this->dbi->getTable(
- $this->db, $this->table
- )->getStatusInfo(null, true);
- }
- if (empty($this->_showtable['Data_length'])) {
- $this->_showtable['Data_length'] = 0;
- }
- if (empty($this->_showtable['Index_length'])) {
- $this->_showtable['Index_length'] = 0;
- }
- $is_innodb = (isset($this->_showtable['Type'])
- && $this->_showtable['Type'] == 'InnoDB');
- $mergetable = $this->table_obj->isMerge();
- // this is to display for example 261.2 MiB instead of 268k KiB
- $max_digits = 3;
- $decimals = 1;
- list($data_size, $data_unit) = Util::formatByteDown(
- $this->_showtable['Data_length'], $max_digits, $decimals
- );
- if ($mergetable == false) {
- list($index_size, $index_unit) = Util::formatByteDown(
- $this->_showtable['Index_length'], $max_digits, $decimals
- );
- }
- // InnoDB returns a huge value in Data_free, do not use it
- if (! $is_innodb && isset($this->_showtable['Data_free'])
- && $this->_showtable['Data_free'] > 0
- ) {
- list($free_size, $free_unit) = Util::formatByteDown(
- $this->_showtable['Data_free'], $max_digits, $decimals
- );
- list($effect_size, $effect_unit) = Util::formatByteDown(
- $this->_showtable['Data_length']
- + $this->_showtable['Index_length']
- - $this->_showtable['Data_free'],
- $max_digits, $decimals
- );
- } else {
- list($effect_size, $effect_unit) = Util::formatByteDown(
- $this->_showtable['Data_length']
- + $this->_showtable['Index_length'],
- $max_digits, $decimals
- );
- }
- list($tot_size, $tot_unit) = Util::formatByteDown(
- $this->_showtable['Data_length'] + $this->_showtable['Index_length'],
- $max_digits, $decimals
- );
- if ($this->_table_info_num_rows > 0) {
- list($avg_size, $avg_unit) = Util::formatByteDown(
- ($this->_showtable['Data_length']
- + $this->_showtable['Index_length'])
- / $this->_showtable['Rows'],
- 6,
- 1
- );
- } else {
- $avg_size = $avg_unit = '';
- }
- return Template::get('table/structure/display_table_stats')->render(
- array(
- 'showtable' => $this->_showtable,
- 'table_info_num_rows' => $this->_table_info_num_rows,
- 'tbl_is_view' => $this->_tbl_is_view,
- 'db_is_system_schema' => $this->_db_is_system_schema,
- 'tbl_storage_engine' => $this->_tbl_storage_engine,
- 'url_query' => $this->_url_query,
- 'tbl_collation' => $this->_tbl_collation,
- 'is_innodb' => $is_innodb,
- 'mergetable' => $mergetable,
- 'avg_size' => isset($avg_size) ? $avg_size : null,
- 'avg_unit' => isset($avg_unit) ? $avg_unit : null,
- 'data_size' => $data_size,
- 'data_unit' => $data_unit,
- 'index_size' => isset($index_size) ? $index_size : null,
- 'index_unit' => isset($index_unit) ? $index_unit : null,
- 'free_size' => isset($free_size) ? $free_size : null,
- 'free_unit' => isset($free_unit) ? $free_unit : null,
- 'effect_size' => $effect_size,
- 'effect_unit' => $effect_unit,
- 'tot_size' => $tot_size,
- 'tot_unit' => $tot_unit,
- 'table' => $GLOBALS['table']
- )
- );
- }
- /**
- * Gets table primary key
- *
- * @return string
- */
- protected function getKeyForTablePrimary()
- {
- $this->dbi->selectDb($this->db);
- $result = $this->dbi->query(
- 'SHOW KEYS FROM ' . Util::backquote($this->table) . ';'
- );
- $primary = '';
- while ($row = $this->dbi->fetchAssoc($result)) {
- // Backups the list of primary keys
- if ($row['Key_name'] == 'PRIMARY') {
- $primary .= $row['Column_name'] . ', ';
- }
- } // end while
- $this->dbi->freeResult($result);
- return $primary;
- }
- /**
- * Get List of information for Submit Mult
- *
- * @param string $submit_mult mult_submit type
- * @param array $selected the selected columns
- * @param string $action action type
- *
- * @return array
- */
- protected function getDataForSubmitMult($submit_mult, $selected, $action)
- {
- $centralColumns = new CentralColumns($GLOBALS['dbi']);
- $what = null;
- $query_type = null;
- $is_unset_submit_mult = false;
- $mult_btn = null;
- $centralColsError = null;
- switch ($submit_mult) {
- case 'drop':
- $what = 'drop_fld';
- break;
- case 'primary':
- // Gets table primary key
- $primary = $this->getKeyForTablePrimary();
- if (empty($primary)) {
- // no primary key, so we can safely create new
- $is_unset_submit_mult = true;
- $query_type = 'primary_fld';
- $mult_btn = __('Yes');
- } else {
- // primary key exists, so lets as user
- $what = 'primary_fld';
- }
- break;
- case 'index':
- $is_unset_submit_mult = true;
- $query_type = 'index_fld';
- $mult_btn = __('Yes');
- break;
- case 'unique':
- $is_unset_submit_mult = true;
- $query_type = 'unique_fld';
- $mult_btn = __('Yes');
- break;
- case 'spatial':
- $is_unset_submit_mult = true;
- $query_type = 'spatial_fld';
- $mult_btn = __('Yes');
- break;
- case 'ftext':
- $is_unset_submit_mult = true;
- $query_type = 'fulltext_fld';
- $mult_btn = __('Yes');
- break;
- case 'add_to_central_columns':
- $centralColsError = $centralColumns->syncUniqueColumns(
- $selected,
- false
- );
- break;
- case 'remove_from_central_columns':
- $centralColsError = $centralColumns->deleteColumnsFromList(
- $selected,
- false
- );
- break;
- case 'change':
- $this->displayHtmlForColumnChange($selected, $action);
- // execution stops here but PhpMyAdmin\Response correctly finishes
- // the rendering
- exit;
- case 'browse':
- // this should already be handled by tbl_structure.php
- }
- return array(
- $what, $query_type, $is_unset_submit_mult, $mult_btn,
- $centralColsError
- );
- }
- }
|