/** * Test for rename * * @return void */ public function testRename() { $table = 'PMA_BookMark'; $db = 'PMA'; Util::cacheSet('lower_case_table_names', false); $table = new Table($table, $db); //rename to same name $table_new = 'PMA_BookMark'; $result = $table->rename($table_new); $this->assertEquals(true, $result); //isValidName //space in table name $table_new = 'PMA_BookMark '; $result = $table->rename($table_new); $this->assertEquals(false, $result); //empty name $table_new = ''; $result = $table->rename($table_new); $this->assertEquals(false, $result); //dot in table name $table_new = 'PMA_.BookMark'; $result = $table->rename($table_new); $this->assertEquals(false, $result); $table_new = 'PMA_BookMark_new'; $db_new = 'PMA_new'; $result = $table->rename($table_new, $db_new); $this->assertEquals(true, $result); //message $this->assertEquals("Table PMA_BookMark has been renamed to PMA_BookMark_new.", $table->getLastMessage()); }
*/ if (isset($_REQUEST['table_maintenance'])) { include_once 'sql.php'; unset($result); } /** * Updates table comment, type and options if required */ if (isset($_REQUEST['submitoptions'])) { $_message = ''; $warning_messages = array(); if (isset($_REQUEST['new_name'])) { // Get original names before rename operation $oldTable = $pma_table->getName(); $oldDb = $pma_table->getDbName(); if ($pma_table->rename($_REQUEST['new_name'])) { if (isset($_REQUEST['adjust_privileges']) && !empty($_REQUEST['adjust_privileges'])) { PMA_AdjustPrivileges_renameOrMoveTable($oldDb, $oldTable, $_REQUEST['db'], $_REQUEST['new_name']); } // Reselect the original DB $GLOBALS['db'] = $oldDb; $GLOBALS['dbi']->selectDb($oldDb); $_message .= $pma_table->getLastMessage(); $result = true; $GLOBALS['table'] = $pma_table->getName(); $reread_info = true; $reload = true; } else { $_message .= $pma_table->getLastError(); $result = false; }
/** * Copies or renames table * * @param string $source_db source database * @param string $source_table source table * @param string $target_db target database * @param string $target_table target table * @param string $what what to be moved or copied (data, dataonly) * @param bool $move whether to move * @param string $mode mode * * @return bool true if success, false otherwise */ public static function moveCopy($source_db, $source_table, $target_db, $target_table, $what, $move, $mode) { global $err_url; // Try moving the tables directly, using native `RENAME` statement. if ($move && $what == 'data') { $tbl = new Table($source_table, $source_db); if ($tbl->rename($target_table, $target_db)) { $GLOBALS['message'] = $tbl->getLastMessage(); return true; } } // Setting required export settings. $GLOBALS['sql_backquotes'] = 1; $GLOBALS['asfile'] = 1; // Ensuring the target database is valid. if (!$GLOBALS['pma']->databases->exists($source_db, $target_db)) { if (!$GLOBALS['pma']->databases->exists($source_db)) { $GLOBALS['message'] = Message::rawError(sprintf(__('Source database `%s` was not found!'), htmlspecialchars($source_db))); } if (!$GLOBALS['pma']->databases->exists($target_db)) { $GLOBALS['message'] = Message::rawError(sprintf(__('Target database `%s` was not found!'), htmlspecialchars($target_db))); } return false; } /** * The full name of source table, quoted. * @var string $source */ $source = Util::backquote($source_db) . '.' . Util::backquote($source_table); // If the target database is not specified, the operation is taking // place in the same database. if (!isset($target_db) || !mb_strlen($target_db)) { $target_db = $source_db; } // Selecting the database could avoid some problems with replicated // databases, when moving table from replicated one to not replicated one. $GLOBALS['dbi']->selectDb($target_db); /** * The full name of target table, quoted. * @var string $target */ $target = Util::backquote($target_db) . '.' . Util::backquote($target_table); // No table is created when this is a data-only operation. if ($what != 'dataonly') { include_once "libraries/plugin_interface.lib.php"; /** * Instance used for exporting the current structure of the table. * * @var \PMA\libraries\plugins\export\ExportSql */ $export_sql_plugin = PMA_getPlugin("export", "sql", 'libraries/plugins/export/', array('export_type' => 'table', 'single_table' => false)); $no_constraints_comments = true; $GLOBALS['sql_constraints_query'] = ''; // set the value of global sql_auto_increment variable if (isset($_POST['sql_auto_increment'])) { $GLOBALS['sql_auto_increment'] = $_POST['sql_auto_increment']; } /** * The old structure of the table.. * @var string $sql_structure */ $sql_structure = $export_sql_plugin->getTableDef($source_db, $source_table, "\n", $err_url, false, false); unset($no_constraints_comments); // ----------------------------------------------------------------- // Phase 0: Preparing structures used. /** * The destination where the table is moved or copied to. * @var Expression */ $destination = new Expression($target_db, $target_table, ''); // Find server's SQL mode so the builder can generate correct // queries. // One of the options that alters the behaviour is `ANSI_QUOTES`. Context::setMode($GLOBALS['dbi']->fetchValue("SELECT @@sql_mode")); // ----------------------------------------------------------------- // Phase 1: Dropping existent element of the same name (if exists // and required). if (isset($_REQUEST['drop_if_exists']) && $_REQUEST['drop_if_exists'] == 'true') { /** * Drop statement used for building the query. * @var DropStatement $statement */ $statement = new DropStatement(); $tbl = new Table($target_db, $target_table); $statement->options = new OptionsArray(array($tbl->isView() ? 'VIEW' : 'TABLE', 'IF EXISTS')); $statement->fields = array($destination); // Building the query. $drop_query = $statement->build() . ';'; // Executing it. $GLOBALS['dbi']->query($drop_query); $GLOBALS['sql_query'] .= "\n" . $drop_query; // If an existing table gets deleted, maintain any entries for // the PMA_* tables. $maintain_relations = true; } // ----------------------------------------------------------------- // Phase 2: Generating the new query of this structure. /** * The parser responsible for parsing the old queries. * @var Parser $parser */ $parser = new Parser($sql_structure); if (!empty($parser->statements[0])) { /** * The CREATE statement of this structure. * @var \SqlParser\Statements\CreateStatement $statement */ $statement = $parser->statements[0]; // Changing the destination. $statement->name = $destination; // Building back the query. $sql_structure = $statement->build() . ';'; // Executing it. $GLOBALS['dbi']->query($sql_structure); $GLOBALS['sql_query'] .= "\n" . $sql_structure; } // ----------------------------------------------------------------- // Phase 3: Adding constraints. // All constraint names are removed because they must be unique. if (($move || isset($GLOBALS['add_constraints'])) && !empty($GLOBALS['sql_constraints_query'])) { $parser = new Parser($GLOBALS['sql_constraints_query']); /** * The ALTER statement that generates the constraints. * @var \SqlParser\Statements\AlterStatement $statement */ $statement = $parser->statements[0]; // Changing the altered table to the destination. $statement->table = $destination; // Removing the name of the constraints. foreach ($statement->altered as $idx => $altered) { // All constraint names are removed because they must be unique. if ($altered->options->has('CONSTRAINT')) { $altered->field = null; } } // Building back the query. $GLOBALS['sql_constraints_query'] = $statement->build() . ';'; // Executing it. if ($mode == 'one_table') { $GLOBALS['dbi']->query($GLOBALS['sql_constraints_query']); } $GLOBALS['sql_query'] .= "\n" . $GLOBALS['sql_constraints_query']; if ($mode == 'one_table') { unset($GLOBALS['sql_constraints_query']); } } // ----------------------------------------------------------------- // Phase 4: Adding indexes. // View phase 3. if (!empty($GLOBALS['sql_indexes'])) { $parser = new Parser($GLOBALS['sql_indexes']); /** * The ALTER statement that generates the indexes. * @var \SqlParser\Statements\AlterStatement $statement */ $statement = $parser->statements[0]; // Changing the altered table to the destination. $statement->table = $destination; // Removing the name of the constraints. foreach ($statement->altered as $idx => $altered) { // All constraint names are removed because they must be unique. if ($altered->options->has('CONSTRAINT')) { $altered->field = null; } } // Building back the query. $GLOBALS['sql_indexes'] = $statement->build() . ';'; // Executing it. if ($mode == 'one_table' || $mode == 'db_copy') { $GLOBALS['dbi']->query($GLOBALS['sql_indexes']); } $GLOBALS['sql_query'] .= "\n" . $GLOBALS['sql_indexes']; if ($mode == 'one_table' || $mode == 'db_copy') { unset($GLOBALS['sql_indexes']); } } // ----------------------------------------------------------------- // Phase 5: Adding AUTO_INCREMENT. if (!empty($GLOBALS['sql_auto_increments'])) { if ($mode == 'one_table' || $mode == 'db_copy') { $parser = new Parser($GLOBALS['sql_auto_increments']); /** * The ALTER statement that alters the AUTO_INCREMENT value. * @var \SqlParser\Statements\AlterStatement $statement */ $statement = $parser->statements[0]; // Changing the altered table to the destination. $statement->table = $destination; // Building back the query. $GLOBALS['sql_auto_increments'] = $statement->build() . ';'; // Executing it. $GLOBALS['dbi']->query($GLOBALS['sql_auto_increments']); $GLOBALS['sql_query'] .= "\n" . $GLOBALS['sql_auto_increments']; unset($GLOBALS['sql_auto_increments']); } } } else { $GLOBALS['sql_query'] = ''; } $_table = new Table($target_table, $target_db); // Copy the data unless this is a VIEW if (($what == 'data' || $what == 'dataonly') && !$_table->isView()) { $sql_set_mode = "SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO'"; $GLOBALS['dbi']->query($sql_set_mode); $GLOBALS['sql_query'] .= "\n\n" . $sql_set_mode . ';'; $sql_insert_data = 'INSERT INTO ' . $target . ' SELECT * FROM ' . $source; $GLOBALS['dbi']->query($sql_insert_data); $GLOBALS['sql_query'] .= "\n\n" . $sql_insert_data . ';'; } PMA_getRelationsParam(); // Drops old table if the user has requested to move it if ($move) { // This could avoid some problems with replicated databases, when // moving table from replicated one to not replicated one $GLOBALS['dbi']->selectDb($source_db); $_source_table = new Table($source_table, $source_db); if ($_source_table->isView()) { $sql_drop_query = 'DROP VIEW'; } else { $sql_drop_query = 'DROP TABLE'; } $sql_drop_query .= ' ' . $source; $GLOBALS['dbi']->query($sql_drop_query); // Renable table in configuration storage PMA_REL_renameTable($source_db, $target_db, $source_table, $target_table); $GLOBALS['sql_query'] .= "\n\n" . $sql_drop_query . ';'; // end if ($move) return true; } // we are copying // Create new entries as duplicates from old PMA DBs if ($what == 'dataonly' || isset($maintain_relations)) { return true; } if ($GLOBALS['cfgRelation']['commwork']) { // Get all comments and MIME-Types for current table $comments_copy_rs = PMA_queryAsControlUser('SELECT column_name, comment' . ($GLOBALS['cfgRelation']['mimework'] ? ', mimetype, transformation, transformation_options' : '') . ' FROM ' . Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . Util::backquote($GLOBALS['cfgRelation']['column_info']) . ' WHERE ' . ' db_name = \'' . Util::sqlAddSlashes($source_db) . '\'' . ' AND ' . ' table_name = \'' . Util::sqlAddSlashes($source_table) . '\''); // Write every comment as new copied entry. [MIME] while ($comments_copy_row = $GLOBALS['dbi']->fetchAssoc($comments_copy_rs)) { $new_comment_query = 'REPLACE INTO ' . Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . Util::backquote($GLOBALS['cfgRelation']['column_info']) . ' (db_name, table_name, column_name, comment' . ($GLOBALS['cfgRelation']['mimework'] ? ', mimetype, transformation, transformation_options' : '') . ') ' . ' VALUES(' . '\'' . Util::sqlAddSlashes($target_db) . '\',\'' . Util::sqlAddSlashes($target_table) . '\',\'' . Util::sqlAddSlashes($comments_copy_row['column_name']) . '\'' . ($GLOBALS['cfgRelation']['mimework'] ? ',\'' . Util::sqlAddSlashes($comments_copy_row['comment']) . '\',' . '\'' . Util::sqlAddSlashes($comments_copy_row['mimetype']) . '\',' . '\'' . Util::sqlAddSlashes($comments_copy_row['transformation']) . '\',' . '\'' . Util::sqlAddSlashes($comments_copy_row['transformation_options']) . '\'' : '') . ')'; PMA_queryAsControlUser($new_comment_query); } // end while $GLOBALS['dbi']->freeResult($comments_copy_rs); unset($comments_copy_rs); } // duplicating the bookmarks must not be done here, but // just once per db $get_fields = array('display_field'); $where_fields = array('db_name' => $source_db, 'table_name' => $source_table); $new_fields = array('db_name' => $target_db, 'table_name' => $target_table); Table::duplicateInfo('displaywork', 'table_info', $get_fields, $where_fields, $new_fields); /** * @todo revise this code when we support cross-db relations */ $get_fields = array('master_field', 'foreign_table', 'foreign_field'); $where_fields = array('master_db' => $source_db, 'master_table' => $source_table); $new_fields = array('master_db' => $target_db, 'foreign_db' => $target_db, 'master_table' => $target_table); Table::duplicateInfo('relwork', 'relation', $get_fields, $where_fields, $new_fields); $get_fields = array('foreign_field', 'master_table', 'master_field'); $where_fields = array('foreign_db' => $source_db, 'foreign_table' => $source_table); $new_fields = array('master_db' => $target_db, 'foreign_db' => $target_db, 'foreign_table' => $target_table); Table::duplicateInfo('relwork', 'relation', $get_fields, $where_fields, $new_fields); /** * @todo Can't get duplicating PDFs the right way. The * page numbers always get screwed up independently from * duplication because the numbers do not seem to be stored on a * per-database basis. Would the author of pdf support please * have a look at it? * $get_fields = array('page_descr'); $where_fields = array('db_name' => $source_db); $new_fields = array('db_name' => $target_db); $last_id = Table::duplicateInfo( 'pdfwork', 'pdf_pages', $get_fields, $where_fields, $new_fields ); if (isset($last_id) && $last_id >= 0) { $get_fields = array('x', 'y'); $where_fields = array( 'db_name' => $source_db, 'table_name' => $source_table ); $new_fields = array( 'db_name' => $target_db, 'table_name' => $target_table, 'pdf_page_number' => $last_id ); Table::duplicateInfo( 'pdfwork', 'table_coords', $get_fields, $where_fields, $new_fields ); } */ return true; }