2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * handles miscellaneous db operations:
10 * - viewing PDF schemas
14 declare(strict_types
=1);
16 use PhpMyAdmin\CheckUserPrivileges
;
17 use PhpMyAdmin\DatabaseInterface
;
18 use PhpMyAdmin\Display\CreateTable
;
19 use PhpMyAdmin\Message
;
20 use PhpMyAdmin\Operations
;
21 use PhpMyAdmin\Plugins
;
22 use PhpMyAdmin\Plugins\Export\ExportSql
;
23 use PhpMyAdmin\Relation
;
24 use PhpMyAdmin\RelationCleanup
;
25 use PhpMyAdmin\Response
;
28 if (! defined('ROOT_PATH')) {
29 define('ROOT_PATH', __DIR__
. DIRECTORY_SEPARATOR
);
32 global $cfg, $db, $server, $url_query;
34 require_once ROOT_PATH
. 'libraries/common.inc.php';
36 /** @var Response $response */
37 $response = $containerBuilder->get(Response
::class);
39 /** @var DatabaseInterface $dbi */
40 $dbi = $containerBuilder->get(DatabaseInterface
::class);
42 $checkUserPrivileges = new CheckUserPrivileges($dbi);
43 $checkUserPrivileges->getPrivileges();
45 $header = $response->getHeader();
46 $scripts = $header->getScripts();
47 $scripts->addFile('database/operations.js');
51 /** @var Relation $relation */
52 $relation = $containerBuilder->get('relation');
53 $operations = new Operations($dbi, $relation);
54 $relationCleanup = new RelationCleanup($dbi, $relation);
57 * Rename/move or copy database
60 && (! empty($_POST['db_rename']) ||
! empty($_POST['db_copy']))
62 if (! empty($_POST['db_rename'])) {
68 if (! isset($_POST['newname']) ||
strlen($_POST['newname']) === 0) {
69 $message = Message
::error(__('The database name is empty!'));
71 // lower_case_table_names=1 `DB` becomes `db`
72 if ($dbi->getLowerCaseNames() === '1') {
73 $_POST['newname'] = mb_strtolower(
78 if ($_POST['newname'] === $_REQUEST['db']) {
79 $message = Message
::error(
80 __('Cannot copy database to the same name. Change the name and try again.')
84 if ($move ||
! empty($_POST['create_database_before_copying'])) {
85 $operations->createDbBeforeCopy();
88 // here I don't use DELIMITER because it's not part of the
89 // language; I have to send each statement one by one
91 // to avoid selecting alternatively the current and new db
92 // we would need to modify the CREATE definitions to qualify
94 $operations->runProcedureAndFunctionDefinitions($db);
96 // go back to current db, just in case
99 $tables_full = $dbi->getTablesFull($db);
101 // remove all foreign key constraints, otherwise we can get errors
102 /** @var ExportSql $export_sql_plugin */
103 $export_sql_plugin = Plugins
::getPlugin(
106 'libraries/classes/Plugins/Export/',
108 'single_table' => isset($single_table),
109 'export_type' => 'database',
113 // create stand-in tables for views
114 $views = $operations->getViewsAndCreateSqlViewStandIn(
121 $sqlConstratints = $operations->copyTables(
129 $operations->handleTheViews($views, $move, $db);
133 // now that all tables exist, create all the accumulated constraints
134 if (! $_error && count($sqlConstratints) > 0) {
135 $operations->createAllAccumulatedConstraints($sqlConstratints);
137 unset($sqlConstratints);
139 if ($dbi->getVersion() >= 50100) {
140 // here DELIMITER is not used because it's not part of the
141 // language; each statement is sent one by one
143 $operations->runEventDefinitionsForDb($db);
146 // go back to current db, just in case
149 // Duplicate the bookmarks for this db (done once for each db)
150 $operations->duplicateBookmarks($_error, $db);
152 if (! $_error && $move) {
153 if (isset($_POST['adjust_privileges'])
154 && ! empty($_POST['adjust_privileges'])
156 $operations->adjustPrivilegesMoveDb($db, $_POST['newname']);
160 * cleanup pmadb stuff for this db
162 $relationCleanup->database($db);
164 // if someday the RENAME DATABASE reappears, do not DROP
165 $local_query = 'DROP DATABASE '
166 . Util
::backquote($db) . ';';
167 $sql_query .= "\n" . $local_query;
168 $dbi->query($local_query);
170 $message = Message
::success(
171 __('Database %1$s has been renamed to %2$s.')
173 $message->addParam($db);
174 $message->addParam($_POST['newname']);
175 } elseif (! $_error) {
176 if (isset($_POST['adjust_privileges'])
177 && ! empty($_POST['adjust_privileges'])
179 $operations->adjustPrivilegesCopyDb($db, $_POST['newname']);
182 $message = Message
::success(
183 __('Database %1$s has been copied to %2$s.')
185 $message->addParam($db);
186 $message->addParam($_POST['newname']);
188 $message = Message
::error();
192 /* Change database to be used */
193 if (! $_error && $move) {
194 $db = $_POST['newname'];
195 } elseif (! $_error) {
196 if (isset($_POST['switch_to_new'])
197 && $_POST['switch_to_new'] == 'true'
199 $_SESSION['pma_switch_to_new'] = true;
200 $db = $_POST['newname'];
202 $_SESSION['pma_switch_to_new'] = false;
209 * Database has been successfully renamed/moved. If in an Ajax request,
210 * generate the output with {@link PhpMyAdmin\Response} and exit
212 if ($response->isAjax()) {
213 $response->setRequestStatus($message->isSuccess());
214 $response->addJSON('message', $message);
215 $response->addJSON('newname', $_POST['newname']);
218 Util
::getMessage(null, $sql_query)
220 $response->addJSON('db', $db);
226 * Settings for relations stuff
228 $cfgRelation = $relation->getRelationsParam();
231 * Check if comments were updated
232 * (must be done before displaying the menu tabs)
234 if (isset($_POST['comment'])) {
235 $relation->setDbComment($db, $_POST['comment']);
238 require ROOT_PATH
. 'libraries/db_common.inc.php';
239 $url_query .= '&goto=db_operations.php';
241 // Gets the database structure
242 $sub_part = '_structure';
250 $db_is_system_schema,
254 ) = Util
::getDbInfo($db, $sub_part === null ?
'' : $sub_part);
258 if (isset($message)) {
259 echo Util
::getMessage($message, $sql_query);
263 $db_collation = $dbi->getDbCollation($db);
264 $is_information_schema = $dbi->isSystemSchema($db);
266 if (! $is_information_schema) {
267 if ($cfgRelation['commwork']) {
271 $response->addHTML($operations->getHtmlForDatabaseComment($db));
274 $response->addHTML('<div>');
275 $response->addHTML(CreateTable
::getHtml($db));
276 $response->addHTML('</div>');
281 if ($db != 'mysql') {
282 $response->addHTML($operations->getHtmlForRenameDatabase($db, $db_collation));
285 // Drop link if allowed
286 // Don't even try to drop information_schema.
287 // You won't be able to. Believe me. You won't.
288 // Don't allow to easily drop mysql database, RFE #1327514.
289 if (($dbi->isSuperuser() ||
$cfg['AllowUserDropDatabase'])
290 && ! $db_is_system_schema
293 $response->addHTML($operations->getHtmlForDropDatabaseLink($db));
298 $response->addHTML($operations->getHtmlForCopyDatabase($db, $db_collation));
301 * Change database charset
303 $response->addHTML($operations->getHtmlForChangeDatabaseCharset($db, $db_collation));
305 if (! $cfgRelation['allworks']
306 && $cfg['PmaNoRelation_DisableWarning'] == false
308 $message = Message
::notice(
310 'The phpMyAdmin configuration storage has been deactivated. ' .
314 $message->addParamHtml('<a href="./chk_rel.php" data-post="' . $url_query . '">');
315 $message->addParamHtml('</a>');
316 /* Show error if user has configured something, notice elsewhere */
317 if (! empty($cfg['Servers'][$server]['pmadb'])) {
318 $message->isError(true);
321 } // end if (!$is_information_schema)