diff options
Diffstat (limited to 'srcs/phpmyadmin/libraries/classes/Operations.php')
| -rw-r--r-- | srcs/phpmyadmin/libraries/classes/Operations.php | 2263 |
1 files changed, 2263 insertions, 0 deletions
diff --git a/srcs/phpmyadmin/libraries/classes/Operations.php b/srcs/phpmyadmin/libraries/classes/Operations.php new file mode 100644 index 0000000..7cedd17 --- /dev/null +++ b/srcs/phpmyadmin/libraries/classes/Operations.php @@ -0,0 +1,2263 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Holds the PhpMyAdmin\Operations class + * + * @package PhpMyAdmin + */ +declare(strict_types=1); + +namespace PhpMyAdmin; + +use PhpMyAdmin\Charsets\Charset; +use PhpMyAdmin\Charsets\Collation; +use PhpMyAdmin\Engines\Innodb; +use PhpMyAdmin\Plugins\Export\ExportSql; + +/** + * Set of functions with the operations section in phpMyAdmin + * + * @package PhpMyAdmin + */ +class Operations +{ + /** + * @var Relation + */ + private $relation; + + /** + * @var DatabaseInterface + */ + private $dbi; + + /** + * Operations constructor. + * + * @param DatabaseInterface $dbi DatabaseInterface object + * @param Relation $relation Relation object + */ + public function __construct(DatabaseInterface $dbi, Relation $relation) + { + $this->dbi = $dbi; + $this->relation = $relation; + } + + /** + * Get HTML output for database comment + * + * @param string $db database name + * + * @return string + */ + public function getHtmlForDatabaseComment($db) + { + $html_output = '<div>' + . '<form method="post" action="db_operations.php" id="formDatabaseComment">' + . Url::getHiddenInputs($db) + . '<fieldset>' + . '<legend>'; + if (Util::showIcons('ActionLinksMode')) { + $html_output .= Util::getImage('b_comment') . ' '; + } + $html_output .= __('Database comment'); + $html_output .= '</legend>'; + $html_output .= '<input type="text" name="comment" ' + . 'class="textfield"' + . 'value="' . htmlspecialchars($this->relation->getDbComment($db)) . '">' + . '</fieldset>'; + $html_output .= '<fieldset class="tblFooters">' + . '<input class="btn btn-primary" type="submit" value="' . __('Go') . '">' + . '</fieldset>' + . '</form>' + . '</div>'; + + return $html_output; + } + + /** + * Get HTML output for rename database + * + * @param string $db database name + * @param string $db_collation dataset collation + * + * @return string + */ + public function getHtmlForRenameDatabase($db, $db_collation) + { + $html_output = '<div>' + . '<form id="rename_db_form" ' + . 'class="ajax" ' + . 'method="post" action="db_operations.php" ' + . 'onsubmit="return Functions.emptyCheckTheField(this, \'newname\')">'; + if ($db_collation !== null) { + $html_output .= '<input type="hidden" name="db_collation" ' + . 'value="' . $db_collation + . '">' . "\n"; + } + $html_output .= '<input type="hidden" name="what" value="data">' + . '<input type="hidden" name="db_rename" value="true">' + . Url::getHiddenInputs($db) + . '<fieldset>' + . '<legend>'; + + if (Util::showIcons('ActionLinksMode')) { + $html_output .= Util::getImage('b_edit') . ' '; + } + $html_output .= __('Rename database to') + . '</legend>'; + + $html_output .= '<input id="new_db_name" type="text" name="newname" ' + . 'maxlength="64" class="textfield" required="required">'; + $html_output .= '<br>'; + + if ($GLOBALS['db_priv'] && $GLOBALS['table_priv'] + && $GLOBALS['col_priv'] && $GLOBALS['proc_priv'] + && $GLOBALS['is_reload_priv'] + ) { + $html_output .= '<input type="checkbox" name="adjust_privileges" ' + . 'value="1" id="checkbox_adjust_privileges" checked="checked">'; + } else { + $html_output .= '<input type="checkbox" name="adjust_privileges" ' + . 'value="1" id="checkbox_adjust_privileges" title="' . __( + 'You don\'t have sufficient privileges to perform this ' + . 'operation; Please refer to the documentation for more details' + ) + . '" disabled>'; + } + + $html_output .= '<label for="checkbox_adjust_privileges">' + . __('Adjust privileges') . Util::showDocu('faq', 'faq6-39') + . '</label><br>'; + + $html_output .= '' + . '</fieldset>' + . '<fieldset class="tblFooters">' + . '<input id="rename_db_input" class="btn btn-primary" type="submit" value="' . __('Go') . '">' + . '</fieldset>' + . '</form>' + . '</div>'; + + return $html_output; + } + + /** + * Get HTML for database drop link + * + * @param string $db database name + * + * @return string + */ + public function getHtmlForDropDatabaseLink($db) + { + $this_sql_query = 'DROP DATABASE ' . Util::backquote($db); + $this_url_params = [ + 'sql_query' => $this_sql_query, + 'back' => 'db_operations.php', + 'goto' => 'index.php', + 'reload' => '1', + 'purge' => '1', + 'message_to_show' => sprintf( + __('Database %s has been dropped.'), + htmlspecialchars(Util::backquote($db)) + ), + 'db' => null, + ]; + + $html_output = '<div>' + . '<fieldset class="caution">'; + $html_output .= '<legend>'; + if (Util::showIcons('ActionLinksMode')) { + $html_output .= Util::getImage('b_deltbl') . ' '; + } + $html_output .= __('Remove database') + . '</legend>'; + $html_output .= '<ul>'; + $html_output .= $this->getDeleteDataOrTablelink( + $this_url_params, + 'DROP_DATABASE', + __('Drop the database (DROP)'), + 'drop_db_anchor' + ); + $html_output .= '</ul></fieldset>' + . '</div>'; + + return $html_output; + } + + /** + * Get HTML snippet for copy database + * + * @param string $db database name + * @param string $db_collation dataset collation + * + * @return string + */ + public function getHtmlForCopyDatabase($db, $db_collation) + { + $drop_clause = 'DROP TABLE / DROP VIEW'; + $choices = [ + 'structure' => __('Structure only'), + 'data' => __('Structure and data'), + 'dataonly' => __('Data only'), + ]; + + $pma_switch_to_new = isset($_SESSION['pma_switch_to_new']) && $_SESSION['pma_switch_to_new']; + + $html_output = '<div>'; + $html_output .= '<form id="copy_db_form" ' + . 'class="ajax" ' + . 'method="post" action="db_operations.php" ' + . 'onsubmit="return Functions.emptyCheckTheField(this, \'newname\')">'; + + if ($db_collation !== null) { + $html_output .= '<input type="hidden" name="db_collation" ' + . 'value="' . $db_collation . '">' . "\n"; + } + $html_output .= '<input type="hidden" name="db_copy" value="true">' . "\n" + . Url::getHiddenInputs($db); + $html_output .= '<fieldset>' + . '<legend>'; + + if (Util::showIcons('ActionLinksMode')) { + $html_output .= Util::getImage('b_edit') . ' '; + } + $html_output .= __('Copy database to') + . '</legend>' + . '<input type="text" maxlength="64" name="newname" ' + . 'class="textfield" required="required"><br>' + . Util::getRadioFields( + 'what', + $choices, + 'data', + true + ); + $html_output .= '<br>'; + $html_output .= '<input type="checkbox" name="create_database_before_copying" ' + . 'value="1" id="checkbox_create_database_before_copying"' + . 'checked="checked">'; + $html_output .= '<label for="checkbox_create_database_before_copying">' + . __('CREATE DATABASE before copying') . '</label><br>'; + $html_output .= '<input type="checkbox" name="drop_if_exists" value="true"' + . 'id="checkbox_drop">'; + $html_output .= '<label for="checkbox_drop">' + . sprintf(__('Add %s'), $drop_clause) + . '</label><br>'; + $html_output .= '<input type="checkbox" name="sql_auto_increment" value="1" ' + . 'checked="checked" id="checkbox_auto_increment">'; + $html_output .= '<label for="checkbox_auto_increment">' + . __('Add AUTO_INCREMENT value') . '</label><br>'; + $html_output .= '<input type="checkbox" name="add_constraints" value="1"' + . 'id="checkbox_constraints" checked="checked">'; + $html_output .= '<label for="checkbox_constraints">' + . __('Add constraints') . '</label><br>'; + $html_output .= '<br>'; + + if ($GLOBALS['db_priv'] && $GLOBALS['table_priv'] + && $GLOBALS['col_priv'] && $GLOBALS['proc_priv'] + && $GLOBALS['is_reload_priv'] + ) { + $html_output .= '<input type="checkbox" name="adjust_privileges" ' + . 'value="1" id="checkbox_privileges" checked="checked">'; + } else { + $html_output .= '<input type="checkbox" name="adjust_privileges" ' + . 'value="1" id="checkbox_privileges" title="' . __( + 'You don\'t have sufficient privileges to perform this ' + . 'operation; Please refer to the documentation for more details' + ) + . '" disabled>'; + } + $html_output .= '<label for="checkbox_privileges">' + . __('Adjust privileges') . Util::showDocu('faq', 'faq6-39') + . '</label><br>'; + + $html_output .= '<input type="checkbox" name="switch_to_new" value="true"' + . 'id="checkbox_switch"' + . ($pma_switch_to_new ? ' checked="checked"' : '') . '>'; + $html_output .= '<label for="checkbox_switch">' + . __('Switch to copied database') . '</label>' + . '</fieldset>'; + $html_output .= '<fieldset class="tblFooters">' + . '<input class="btn btn-primary" type="submit" name="submit_copy" value="' . __('Go') . '">' + . '</fieldset>' + . '</form>' + . '</div>'; + + return $html_output; + } + + /** + * Get HTML snippet for change database charset + * + * @param string $db database name + * @param string $db_collation dataset collation + * + * @return string + */ + public function getHtmlForChangeDatabaseCharset($db, $db_collation) + { + $html_output = '<div>' + . '<form id="change_db_charset_form" '; + $html_output .= 'class="ajax" '; + $html_output .= 'method="post" action="db_operations.php">'; + + $html_output .= Url::getHiddenInputs($db); + + $html_output .= '<fieldset>' . "\n" + . ' <legend>'; + if (Util::showIcons('ActionLinksMode')) { + $html_output .= Util::getImage('s_asci') . ' '; + } + $html_output .= '<label for="select_db_collation">' . __('Collation') + . '</label>' . "\n" + . '</legend>' . "\n"; + $html_output .= '<select lang="en" dir="ltr" name="db_collation" id="select_db_collation">' . "\n"; + $html_output .= '<option value=""></option>' . "\n"; + + $charsets = Charsets::getCharsets($this->dbi, $GLOBALS['cfg']['Server']['DisableIS']); + $collations = Charsets::getCollations($this->dbi, $GLOBALS['cfg']['Server']['DisableIS']); + /** @var Charset $charset */ + foreach ($charsets as $charset) { + $html_output .= '<optgroup label="' . $charset->getName() + . '" title="' . $charset->getDescription() . '">' . "\n"; + /** @var Collation $collation */ + foreach ($collations[$charset->getName()] as $collation) { + $html_output .= '<option value="' . $collation->getName() + . '" title="' . $collation->getDescription() . '"' + . ($db_collation == $collation->getName() ? ' selected' : '') . '>' + . $collation->getName() . '</option>' . "\n"; + } + $html_output .= '</optgroup>' . "\n"; + } + $html_output .= '</select>' . "\n"; + $html_output .= '<br>' + . '<input type="checkbox" name="change_all_tables_collations"' + . 'id="checkbox_change_all_tables_collations">' + . '<label for="checkbox_change_all_tables_collations">' + . __('Change all tables collations') + . '</label>' + . '<br>' + . '<span id="span_change_all_tables_columns_collations"><input type="checkbox" name="change_all_tables_columns_collations"' + . 'id="checkbox_change_all_tables_columns_collations">' + . '<label for="checkbox_change_all_tables_columns_collations">' + . __('Change all tables columns collations') + . '</label></span>' + . '</fieldset>' + . '<fieldset class="tblFooters">' + . '<input class="btn btn-primary" type="submit" name="submitcollation"' + . ' value="' . __('Go') . '">' . "\n" + . '</fieldset>' . "\n" + . '</form></div>' . "\n"; + + return $html_output; + } + + /** + * Run the Procedure definitions and function definitions + * + * to avoid selecting alternatively the current and new db + * we would need to modify the CREATE definitions to qualify + * the db name + * + * @param string $db database name + * + * @return void + */ + public function runProcedureAndFunctionDefinitions($db) + { + $procedure_names = $this->dbi->getProceduresOrFunctions($db, 'PROCEDURE'); + if ($procedure_names) { + foreach ($procedure_names as $procedure_name) { + $this->dbi->selectDb($db); + $tmp_query = $this->dbi->getDefinition( + $db, + 'PROCEDURE', + $procedure_name + ); + if ($tmp_query !== null) { + // collect for later display + $GLOBALS['sql_query'] .= "\n" . $tmp_query; + $this->dbi->selectDb($_POST['newname']); + $this->dbi->query($tmp_query); + } + } + } + + $function_names = $this->dbi->getProceduresOrFunctions($db, 'FUNCTION'); + if ($function_names) { + foreach ($function_names as $function_name) { + $this->dbi->selectDb($db); + $tmp_query = $this->dbi->getDefinition( + $db, + 'FUNCTION', + $function_name + ); + if ($tmp_query !== null) { + // collect for later display + $GLOBALS['sql_query'] .= "\n" . $tmp_query; + $this->dbi->selectDb($_POST['newname']); + $this->dbi->query($tmp_query); + } + } + } + } + + /** + * Create database before copy + * + * @return void + */ + public function createDbBeforeCopy() + { + $local_query = 'CREATE DATABASE IF NOT EXISTS ' + . Util::backquote($_POST['newname']); + if (isset($_POST['db_collation'])) { + $local_query .= ' DEFAULT' + . Util::getCharsetQueryPart($_POST['db_collation']); + } + $local_query .= ';'; + $GLOBALS['sql_query'] .= $local_query; + + // save the original db name because Tracker.php which + // may be called under $this->dbi->query() changes $GLOBALS['db'] + // for some statements, one of which being CREATE DATABASE + $original_db = $GLOBALS['db']; + $this->dbi->query($local_query); + $GLOBALS['db'] = $original_db; + + // Set the SQL mode to NO_AUTO_VALUE_ON_ZERO to prevent MySQL from creating + // export statements it cannot import + $sql_set_mode = "SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO'"; + $this->dbi->query($sql_set_mode); + + // rebuild the database list because Table::moveCopy + // checks in this list if the target db exists + $GLOBALS['dblist']->databases->build(); + } + + /** + * Get views as an array and create SQL view stand-in + * + * @param array $tables_full array of all tables in given db or dbs + * @param ExportSql $export_sql_plugin export plugin instance + * @param string $db database name + * + * @return array + */ + public function getViewsAndCreateSqlViewStandIn( + array $tables_full, + $export_sql_plugin, + $db + ) { + $views = []; + foreach ($tables_full as $each_table => $tmp) { + // to be able to rename a db containing views, + // first all the views are collected and a stand-in is created + // the real views are created after the tables + if ($this->dbi->getTable($db, (string) $each_table)->isView()) { + // If view exists, and 'add drop view' is selected: Drop it! + if ($_POST['what'] != 'nocopy' + && isset($_POST['drop_if_exists']) + && $_POST['drop_if_exists'] == 'true' + ) { + $drop_query = 'DROP VIEW IF EXISTS ' + . Util::backquote($_POST['newname']) . '.' + . Util::backquote($each_table); + $this->dbi->query($drop_query); + + $GLOBALS['sql_query'] .= "\n" . $drop_query . ';'; + } + + $views[] = $each_table; + // Create stand-in definition to resolve view dependencies + $sql_view_standin = $export_sql_plugin->getTableDefStandIn( + $db, + $each_table, + "\n" + ); + $this->dbi->selectDb($_POST['newname']); + $this->dbi->query($sql_view_standin); + $GLOBALS['sql_query'] .= "\n" . $sql_view_standin; + } + } + return $views; + } + + /** + * Get sql query for copy/rename table and boolean for whether copy/rename or not + * + * @param array $tables_full array of all tables in given db or dbs + * @param boolean $move whether database name is empty or not + * @param string $db database name + * + * @return array SQL queries for the constraints + */ + public function copyTables(array $tables_full, $move, $db) + { + $sqlContraints = []; + foreach ($tables_full as $each_table => $tmp) { + // skip the views; we have created stand-in definitions + if ($this->dbi->getTable($db, (string) $each_table)->isView()) { + continue; + } + + // value of $what for this table only + $this_what = $_POST['what']; + + // do not copy the data from a Merge table + // note: on the calling FORM, 'data' means 'structure and data' + if ($this->dbi->getTable($db, (string) $each_table)->isMerge()) { + if ($this_what == 'data') { + $this_what = 'structure'; + } + if ($this_what == 'dataonly') { + $this_what = 'nocopy'; + } + } + + if ($this_what != 'nocopy') { + // keep the triggers from the original db+table + // (third param is empty because delimiters are only intended + // for importing via the mysql client or our Import feature) + $triggers = $this->dbi->getTriggers($db, (string) $each_table, ''); + + if (! Table::moveCopy( + $db, + $each_table, + $_POST['newname'], + $each_table, + (isset($this_what) ? $this_what : 'data'), + $move, + 'db_copy' + )) { + $GLOBALS['_error'] = true; + break; + } + // apply the triggers to the destination db+table + if ($triggers) { + $this->dbi->selectDb($_POST['newname']); + foreach ($triggers as $trigger) { + $this->dbi->query($trigger['create']); + $GLOBALS['sql_query'] .= "\n" . $trigger['create'] . ';'; + } + } + + // this does not apply to a rename operation + if (isset($_POST['add_constraints']) + && ! empty($GLOBALS['sql_constraints_query']) + ) { + $sqlContraints[] = $GLOBALS['sql_constraints_query']; + unset($GLOBALS['sql_constraints_query']); + } + } + } + return $sqlContraints; + } + + /** + * Run the EVENT definition for selected database + * + * to avoid selecting alternatively the current and new db + * we would need to modify the CREATE definitions to qualify + * the db name + * + * @param string $db database name + * + * @return void + */ + public function runEventDefinitionsForDb($db) + { + $event_names = $this->dbi->fetchResult( + 'SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA= \'' + . $this->dbi->escapeString($db) . '\';' + ); + if ($event_names) { + foreach ($event_names as $event_name) { + $this->dbi->selectDb($db); + $tmp_query = $this->dbi->getDefinition($db, 'EVENT', $event_name); + // collect for later display + $GLOBALS['sql_query'] .= "\n" . $tmp_query; + $this->dbi->selectDb($_POST['newname']); + $this->dbi->query($tmp_query); + } + } + } + + /** + * Handle the views, return the boolean value whether table rename/copy or not + * + * @param array $views views as an array + * @param boolean $move whether database name is empty or not + * @param string $db database name + * + * @return void + */ + public function handleTheViews(array $views, $move, $db) + { + // temporarily force to add DROP IF EXIST to CREATE VIEW query, + // to remove stand-in VIEW that was created earlier + // ( $_POST['drop_if_exists'] is used in moveCopy() ) + if (isset($_POST['drop_if_exists'])) { + $temp_drop_if_exists = $_POST['drop_if_exists']; + } + + $_POST['drop_if_exists'] = 'true'; + foreach ($views as $view) { + $copying_succeeded = Table::moveCopy( + $db, + $view, + $_POST['newname'], + $view, + 'structure', + $move, + 'db_copy' + ); + if (! $copying_succeeded) { + $GLOBALS['_error'] = true; + break; + } + } + unset($_POST['drop_if_exists']); + + if (isset($temp_drop_if_exists)) { + // restore previous value + $_POST['drop_if_exists'] = $temp_drop_if_exists; + } + } + + /** + * Adjust the privileges after Renaming the db + * + * @param string $oldDb Database name before renaming + * @param string $newname New Database name requested + * + * @return void + */ + public function adjustPrivilegesMoveDb($oldDb, $newname) + { + if ($GLOBALS['db_priv'] && $GLOBALS['table_priv'] + && $GLOBALS['col_priv'] && $GLOBALS['proc_priv'] + && $GLOBALS['is_reload_priv'] + ) { + $this->dbi->selectDb('mysql'); + $newname = str_replace("_", "\_", $newname); + $oldDb = str_replace("_", "\_", $oldDb); + + // For Db specific privileges + $query_db_specific = 'UPDATE ' . Util::backquote('db') + . 'SET Db = \'' . $this->dbi->escapeString($newname) + . '\' where Db = \'' . $this->dbi->escapeString($oldDb) . '\';'; + $this->dbi->query($query_db_specific); + + // For table specific privileges + $query_table_specific = 'UPDATE ' . Util::backquote('tables_priv') + . 'SET Db = \'' . $this->dbi->escapeString($newname) + . '\' where Db = \'' . $this->dbi->escapeString($oldDb) . '\';'; + $this->dbi->query($query_table_specific); + + // For column specific privileges + $query_col_specific = 'UPDATE ' . Util::backquote('columns_priv') + . 'SET Db = \'' . $this->dbi->escapeString($newname) + . '\' where Db = \'' . $this->dbi->escapeString($oldDb) . '\';'; + $this->dbi->query($query_col_specific); + + // For procedures specific privileges + $query_proc_specific = 'UPDATE ' . Util::backquote('procs_priv') + . 'SET Db = \'' . $this->dbi->escapeString($newname) + . '\' where Db = \'' . $this->dbi->escapeString($oldDb) . '\';'; + $this->dbi->query($query_proc_specific); + + // Finally FLUSH the new privileges + $flush_query = "FLUSH PRIVILEGES;"; + $this->dbi->query($flush_query); + } + } + + /** + * Adjust the privileges after Copying the db + * + * @param string $oldDb Database name before copying + * @param string $newname New Database name requested + * + * @return void + */ + public function adjustPrivilegesCopyDb($oldDb, $newname) + { + if ($GLOBALS['db_priv'] && $GLOBALS['table_priv'] + && $GLOBALS['col_priv'] && $GLOBALS['proc_priv'] + && $GLOBALS['is_reload_priv'] + ) { + $this->dbi->selectDb('mysql'); + $newname = str_replace("_", "\_", $newname); + $oldDb = str_replace("_", "\_", $oldDb); + + $query_db_specific_old = 'SELECT * FROM ' + . Util::backquote('db') . ' WHERE ' + . 'Db = "' . $oldDb . '";'; + + $old_privs_db = $this->dbi->fetchResult($query_db_specific_old, 0); + + foreach ($old_privs_db as $old_priv) { + $newDb_db_privs_query = 'INSERT INTO ' . Util::backquote('db') + . ' VALUES("' . $old_priv[0] . '", "' . $newname . '"'; + for ($i = 2; $i < count($old_priv); $i++) { + $newDb_db_privs_query .= ', "' . $old_priv[$i] . '"'; + } + $newDb_db_privs_query .= ')'; + + $this->dbi->query($newDb_db_privs_query); + } + + // For Table Specific privileges + $query_table_specific_old = 'SELECT * FROM ' + . Util::backquote('tables_priv') . ' WHERE ' + . 'Db = "' . $oldDb . '";'; + + $old_privs_table = $this->dbi->fetchResult( + $query_table_specific_old, + 0 + ); + + foreach ($old_privs_table as $old_priv) { + $newDb_table_privs_query = 'INSERT INTO ' . Util::backquote( + 'tables_priv' + ) . ' VALUES("' . $old_priv[0] . '", "' . $newname . '", "' + . $old_priv[2] . '", "' . $old_priv[3] . '", "' . $old_priv[4] + . '", "' . $old_priv[5] . '", "' . $old_priv[6] . '", "' + . $old_priv[7] . '");'; + + $this->dbi->query($newDb_table_privs_query); + } + + // For Column Specific privileges + $query_col_specific_old = 'SELECT * FROM ' + . Util::backquote('columns_priv') . ' WHERE ' + . 'Db = "' . $oldDb . '";'; + + $old_privs_col = $this->dbi->fetchResult( + $query_col_specific_old, + 0 + ); + + foreach ($old_privs_col as $old_priv) { + $newDb_col_privs_query = 'INSERT INTO ' . Util::backquote( + 'columns_priv' + ) . ' VALUES("' . $old_priv[0] . '", "' . $newname . '", "' + . $old_priv[2] . '", "' . $old_priv[3] . '", "' . $old_priv[4] + . '", "' . $old_priv[5] . '", "' . $old_priv[6] . '");'; + + $this->dbi->query($newDb_col_privs_query); + } + + // For Procedure Specific privileges + $query_proc_specific_old = 'SELECT * FROM ' + . Util::backquote('procs_priv') . ' WHERE ' + . 'Db = "' . $oldDb . '";'; + + $old_privs_proc = $this->dbi->fetchResult( + $query_proc_specific_old, + 0 + ); + + foreach ($old_privs_proc as $old_priv) { + $newDb_proc_privs_query = 'INSERT INTO ' . Util::backquote( + 'procs_priv' + ) . ' VALUES("' . $old_priv[0] . '", "' . $newname . '", "' + . $old_priv[2] . '", "' . $old_priv[3] . '", "' . $old_priv[4] + . '", "' . $old_priv[5] . '", "' . $old_priv[6] . '", "' + . $old_priv[7] . '");'; + + $this->dbi->query($newDb_proc_privs_query); + } + + // Finally FLUSH the new privileges + $flush_query = "FLUSH PRIVILEGES;"; + $this->dbi->query($flush_query); + } + } + + /** + * Create all accumulated constraints + * + * @param array $sqlConstratints array of sql constraints for the database + * + * @return void + */ + public function createAllAccumulatedConstraints(array $sqlConstratints) + { + $this->dbi->selectDb($_POST['newname']); + foreach ($sqlConstratints as $one_query) { + $this->dbi->query($one_query); + // and prepare to display them + $GLOBALS['sql_query'] .= "\n" . $one_query; + } + } + + /** + * Duplicate the bookmarks for the db (done once for each db) + * + * @param boolean $_error whether table rename/copy or not + * @param string $db database name + * + * @return void + */ + public function duplicateBookmarks($_error, $db) + { + if (! $_error && $db != $_POST['newname']) { + $get_fields = [ + 'user', + 'label', + 'query', + ]; + $where_fields = ['dbase' => $db]; + $new_fields = ['dbase' => $_POST['newname']]; + Table::duplicateInfo( + 'bookmarkwork', + 'bookmark', + $get_fields, + $where_fields, + $new_fields + ); + } + } + + /** + * Get the HTML snippet for order the table + * + * @param array $columns columns array + * + * @return string + */ + public function getHtmlForOrderTheTable(array $columns) + { + $html_output = '<div>'; + $html_output .= '<form method="post" id="alterTableOrderby" ' + . 'action="tbl_operations.php">'; + $html_output .= Url::getHiddenInputs( + $GLOBALS['db'], + $GLOBALS['table'] + ); + $html_output .= '<fieldset id="fieldset_table_order">' + . '<legend>' . __('Alter table order by') . '</legend>' + . '<select name="order_field">'; + + foreach ($columns as $fieldname) { + $html_output .= '<option ' + . 'value="' . htmlspecialchars($fieldname['Field']) . '">' + . htmlspecialchars($fieldname['Field']) . '</option>' . "\n"; + } + $html_output .= '</select> ' . __('(singly)') . ' ' + . '<br>' + . '<input id="order_order_asc" name="order_order"' + . ' type="radio" value="asc" checked="checked">' + . '<label for="order_order_asc">' . __('Ascending') . '</label>' + . '<input id="order_order_desc" name="order_order"' + . ' type="radio" value="desc">' + . '<label for="order_order_desc">' . __('Descending') . '</label>' + . '</fieldset>' + . '<fieldset class="tblFooters">' + . '<input type="hidden" name="submitorderby" value="1">' + . '<input class="btn btn-primary" type="submit" value="' . __('Go') . '">' + . '</fieldset>' + . '</form>' + . '</div>'; + + return $html_output; + } + + /** + * Get the HTML snippet for move table + * + * @return string + */ + public function getHtmlForMoveTable() + { + $html_output = '<div>'; + $html_output .= '<form method="post" action="tbl_operations.php"' + . ' id="moveTableForm" class="ajax"' + . ' onsubmit="return Functions.emptyCheckTheField(this, \'new_name\')">' + . Url::getHiddenInputs($GLOBALS['db'], $GLOBALS['table']); + + $html_output .= '<input type="hidden" name="reload" value="1">' + . '<input type="hidden" name="what" value="data">' + . '<fieldset id="fieldset_table_rename">'; + + $html_output .= '<legend>' . __('Move table to (database<b>.</b>table)') + . '</legend>'; + + if (count($GLOBALS['dblist']->databases) > $GLOBALS['cfg']['MaxDbList']) { + $html_output .= '<input type="text" maxlength="100" ' + . 'name="target_db" value="' . htmlspecialchars($GLOBALS['db']) + . '">'; + } else { + $html_output .= '<select class="halfWidth" name="target_db">' + . $GLOBALS['dblist']->databases->getHtmlOptions(true, false) + . '</select>'; + } + $html_output .= ' <strong>.</strong> '; + $html_output .= '<input class="halfWidth" type="text" name="new_name"' + . ' maxlength="64" required="required" ' + . 'value="' . htmlspecialchars($GLOBALS['table']) . '"><br>'; + + // starting with MySQL 5.0.24, SHOW CREATE TABLE includes the AUTO_INCREMENT + // next value but users can decide if they want it or not for the operation + + $html_output .= '<input type="checkbox" name="sql_auto_increment" ' + . 'value="1" id="checkbox_auto_increment_mv" checked="checked">' + . '<label for="checkbox_auto_increment_mv">' + . __('Add AUTO_INCREMENT value') + . '</label><br>'; + + if ($GLOBALS['table_priv'] && $GLOBALS['col_priv'] + && $GLOBALS['is_reload_priv'] + ) { + $html_output .= '<input type="checkbox" name="adjust_privileges" ' + . 'value="1" id="checkbox_privileges_tables_move" ' + . 'checked="checked">'; + } else { + $html_output .= '<input type="checkbox" name="adjust_privileges" ' + . 'value="1" id="checkbox_privileges_tables_move" title="' . __( + 'You don\'t have sufficient privileges to perform this ' + . 'operation; Please refer to the documentation for more details' + ) + . '" disabled>'; + } + $html_output .= '<label for="checkbox_privileges_tables_move">' + . __('Adjust privileges') . Util::showDocu('faq', 'faq6-39') + . '</label><br>'; + + $html_output .= '</fieldset><fieldset class="tblFooters">' + . '<input class="btn btn-primary" type="submit" name="submit_move" value="' . __('Go') . '">' + . '</fieldset>' + . '</form>' + . '</div>'; + + return $html_output; + } + + /** + * Get the HTML div for Table option + * + * @param Table $pma_table Table object + * @param string $com |
