2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * handles miscellaneous db operations:
10 * - viewing PDF schemas
19 require_once './libraries/common.inc.php';
20 require_once './libraries/Table.class.php';
21 require_once './libraries/mysql_charsets.lib.php';
23 // add blobstreaming library functions
24 require_once "./libraries/blobstreaming.lib.php";
27 * Rename/move or copy database
29 if (strlen($db) && (! empty($db_rename) ||
! empty($db_copy))) {
31 if (! empty($db_rename)) {
37 if (!isset($newname) ||
!strlen($newname)) {
38 $message = PMA_Message
::error('strDatabaseEmpty');
40 $sql_query = ''; // in case target db exists
43 (isset($create_database_before_copying) && $create_database_before_copying)) {
44 // lower_case_table_names=1 `DB` becomes `db`
45 $lower_case_table_names = PMA_DBI_fetch_value('SHOW VARIABLES LIKE "lower_case_table_names"', 0, 1);
46 if ($lower_case_table_names === '1') {
47 $newname = strtolower($newname);
50 $local_query = 'CREATE DATABASE ' . PMA_backquote($newname);
51 if (isset($db_collation)) {
52 $local_query .= ' DEFAULT' . PMA_generateCharsetQueryPart($db_collation);
55 $sql_query = $local_query;
56 // save the original db name because Tracker.class.php which
57 // may be called under PMA_DBI_query() changes $GLOBALS['db']
58 // for some statements, one of which being CREATE DATABASE
60 PMA_DBI_query($local_query);
64 // rebuild the database list because PMA_Table::moveCopy
65 // checks in this list if the target db exists
66 $GLOBALS['pma']->databases
->build();
69 if (PMA_MYSQL_INT_VERSION
>= 50000) {
70 // here I don't use DELIMITER because it's not part of the
71 // language; I have to send each statement one by one
73 // to avoid selecting alternatively the current and new db
74 // we would need to modify the CREATE definitions to qualify
76 $procedure_names = PMA_DBI_get_procedures_or_functions($db, 'PROCEDURE');
77 if ($procedure_names) {
78 foreach($procedure_names as $procedure_name) {
79 PMA_DBI_select_db($db);
80 $tmp_query = PMA_DBI_get_definition($db, 'PROCEDURE', $procedure_name);
81 // collect for later display
82 $GLOBALS['sql_query'] .= "\n" . $tmp_query;
83 PMA_DBI_select_db($newname);
84 PMA_DBI_query($tmp_query);
88 $function_names = PMA_DBI_get_procedures_or_functions($db, 'FUNCTION');
89 if ($function_names) {
90 foreach($function_names as $function_name) {
91 PMA_DBI_select_db($db);
92 $tmp_query = PMA_DBI_get_definition($db, 'FUNCTION', $function_name);
93 // collect for later display
94 $GLOBALS['sql_query'] .= "\n" . $tmp_query;
95 PMA_DBI_select_db($newname);
96 PMA_DBI_query($tmp_query);
100 // go back to current db, just in case
101 PMA_DBI_select_db($db);
103 if (isset($GLOBALS['add_constraints']) ||
$move) {
104 $GLOBALS['sql_constraints_query_full_db'] = array();
107 $tables_full = PMA_DBI_get_tables_full($db);
110 // remove all foreign key constraints, otherwise we can get errors
111 require_once './libraries/export/sql.php';
112 foreach ($tables_full as $each_table => $tmp) {
113 $sql_constraints = '';
114 $sql_drop_foreign_keys = '';
115 $sql_structure = PMA_getTableDef($db, $each_table, "\n", '', false, false);
116 if ($move && ! empty($sql_drop_foreign_keys)) {
117 PMA_DBI_query($sql_drop_foreign_keys);
119 // keep the constraint we just dropped
120 if (! empty($sql_constraints)) {
121 $GLOBALS['sql_constraints_query_full_db'][] = $sql_constraints;
124 unset($sql_constraints, $sql_drop_foreign_keys, $sql_structure);
127 foreach ($tables_full as $each_table => $tmp) {
128 // to be able to rename a db containing views,
129 // first all the views are collected and a stand-in is created
130 // the real views are created after the tables
131 if (PMA_Table
::isView($db, $each_table)) {
132 $views[] = $each_table;
133 // Create stand-in definition to resolve view dependencies
134 $sql_view_standin = PMA_getTableDefStandIn($db, $each_table, "\n");
135 PMA_DBI_query($sql_view_standin);
136 $GLOBALS['sql_query'] .= "\n" . $sql_view_standin . ';';
143 // value of $what for this table only
146 // do not copy the data from a Merge table
147 // note: on the calling FORM, 'data' means 'structure and data'
148 if (PMA_Table
::isMerge($db, $each_table)) {
149 if ($this_what == 'data') {
150 $this_what = 'structure';
152 if ($this_what == 'dataonly') {
153 $this_what = 'nocopy';
157 if ($this_what != 'nocopy') {
158 // keep the triggers from the original db+table
159 // (third param is empty because delimiters are only intended
160 // for importing via the mysql client or our Import feature)
161 $triggers = PMA_DBI_get_triggers($db, $each_table, '');
163 if (! PMA_Table
::moveCopy($db, $each_table, $newname, $each_table,
164 isset($this_what) ?
$this_what : 'data', $move, 'db_copy'))
167 // $sql_query is filled by PMA_Table::moveCopy()
168 $sql_query = $back . $sql_query;
171 // apply the triggers to the destination db+table
173 PMA_DBI_select_db($newname);
174 foreach ($triggers as $trigger) {
175 PMA_DBI_query($trigger['create']);
181 // this does not apply to a rename operation
182 if (isset($GLOBALS['add_constraints']) && !empty($GLOBALS['sql_constraints_query'])) {
183 $GLOBALS['sql_constraints_query_full_db'][] = $GLOBALS['sql_constraints_query'];
184 unset($GLOBALS['sql_constraints_query']);
187 // $sql_query is filled by PMA_Table::moveCopy()
188 $sql_query = $back . $sql_query;
194 // temporarily force to add DROP IF EXIST to CREATE VIEW query,
195 // to remove stand-in VIEW that was created earlier
196 $temp_drop_if_exists = $GLOBALS['drop_if_exists'];
197 $GLOBALS['drop_if_exists'] = 'true';
199 foreach ($views as $view) {
200 if (! PMA_Table
::moveCopy($db, $view, $newname, $view, 'structure', $move, 'db_copy')) {
205 // restore previous value
206 $GLOBALS['drop_if_exists'] = $temp_drop_if_exists;
208 unset($view, $views);
210 // now that all tables exist, create all the accumulated constraints
211 if (! $_error && count($GLOBALS['sql_constraints_query_full_db']) > 0) {
212 PMA_DBI_select_db($newname);
213 foreach ($GLOBALS['sql_constraints_query_full_db'] as $one_query) {
214 PMA_DBI_query($one_query);
215 // and prepare to display them
216 $GLOBALS['sql_query'] .= "\n" . $one_query;
219 unset($GLOBALS['sql_constraints_query_full_db'], $one_query);
222 if (PMA_MYSQL_INT_VERSION
>= 50100) {
223 // here DELIMITER is not used because it's not part of the
224 // language; each statement is sent one by one
226 // to avoid selecting alternatively the current and new db
227 // we would need to modify the CREATE definitions to qualify
229 $event_names = PMA_DBI_fetch_result('SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA= \'' . PMA_sqlAddslashes($db,true) . '\';');
231 foreach($event_names as $event_name) {
232 PMA_DBI_select_db($db);
233 $tmp_query = PMA_DBI_get_definition($db, 'EVENT', $event_name);
234 // collect for later display
235 $GLOBALS['sql_query'] .= "\n" . $tmp_query;
236 PMA_DBI_select_db($newname);
237 PMA_DBI_query($tmp_query);
241 // go back to current db, just in case
242 PMA_DBI_select_db($db);
244 // Duplicate the bookmarks for this db (done once for each db)
245 if (! $_error && $db != $newname) {
246 $get_fields = array('user', 'label', 'query');
247 $where_fields = array('dbase' => $db);
248 $new_fields = array('dbase' => $newname);
249 PMA_Table
::duplicateInfo('bookmarkwork', 'bookmark', $get_fields,
250 $where_fields, $new_fields);
253 if (! $_error && $move) {
255 * cleanup pmadb stuff for this db
257 require_once './libraries/relation_cleanup.lib.php';
258 PMA_relationsCleanupDatabase($db);
260 // if someday the RENAME DATABASE reappears, do not DROP
261 $local_query = 'DROP DATABASE ' . PMA_backquote($db) . ';';
262 $sql_query .= "\n" . $local_query;
263 PMA_DBI_query($local_query);
265 $message = PMA_Message
::success('strRenameDatabaseOK');
266 $message->addParam($db);
267 $message->addParam($newname);
268 } elseif (! $_error) {
269 $message = PMA_Message
::success('strCopyDatabaseOK');
270 $message->addParam($db);
271 $message->addParam($newname);
275 /* Change database to be used */
276 if (! $_error && $move) {
278 } elseif (! $_error) {
279 if (isset($switch_to_new) && $switch_to_new == 'true') {
280 PMA_setCookie('pma_switch_to_new', 'true');
283 PMA_setCookie('pma_switch_to_new', '');
287 if ($_error && ! isset($message)) {
288 $message = PMA_Message
::error();
294 * Enable/Disable/Repair BLOB Repository Monitoring for current database
296 if (strlen($db) > 0 && !empty($db_blob_streaming_op))
299 $PMA_Config = $_SESSION['PMA_Config'];
301 if (!empty($PMA_Config))
303 if ($PMA_Config->get('PBXT_NAME') !== strtolower($db))
305 // if Blobstreaming plugins exist, begin checking for Blobstreaming tables
306 if ($PMA_Config->get('BLOBSTREAMING_PLUGINS_EXIST'))
308 $bs_tables = $PMA_Config->get('BLOBSTREAMABLE_DATABASES');
309 $bs_tables = $bs_tables[$db];
311 $oneBSTableExists = FALSE;
313 // check if at least one blobstreaming table exists
314 foreach ($bs_tables as $table_key=>$tbl)
315 if ($bs_tables[$table_key]['Exists'])
317 $oneBSTableExists = TRUE;
321 switch ($db_blob_streaming_op)
323 // enable BLOB repository monitoring
325 // if blobstreaming tables do not exist, create them
326 if (!$oneBSTableExists)
327 PMA_BS_CreateTables($db);
329 // disable BLOB repository monitoring
331 // if at least one blobstreaming table exists, execute drop
332 if ($oneBSTableExists)
333 PMA_BS_DropTables($db);
335 // repair BLOB repository
337 // check if a blobstreaming table is missing
338 foreach ($bs_tables as $table_key=>$tbl)
339 if (!$bs_tables[$table_key]['Exists'])
341 PMA_DBI_select_db($db);
342 PMA_DBI_query(PMA_BS_GetTableStruct($table_key));
347 PMA_sendHeaderLocation($cfg['PmaAbsoluteUri'] . 'db_operations.php?' . PMA_generate_common_url ('','', '&') . (isset($db) ?
'&db=' . urlencode($db) : '') . (isset($token) ?
'&token=' . urlencode($token) : '') . (isset($goto) ?
'&goto=' . urlencode($goto) : '') . 'reload=1&purge=1');
348 } // end if ($PMA_Config->get('BLOBSTREAMING_PLUGINS_EXIST'))
349 } // end if ($PMA_Config->get('PBXT_NAME') !== strtolower($db))
354 * Settings for relations stuff
357 require_once './libraries/relation.lib.php';
358 $cfgRelation = PMA_getRelationsParam();
361 * Check if comments were updated
362 * (must be done before displaying the menu tabs)
364 if (isset($_REQUEST['comment'])) {
365 PMA_setDbComment($db, $comment);
369 * Prepares the tables list if the user where not redirected to this script
370 * because there is no table in the database ($is_info is true)
372 if (empty($is_info)) {
373 require './libraries/db_common.inc.php';
374 $url_query .= '&goto=db_operations.php';
376 // Gets the database structure
377 $sub_part = '_structure';
378 require './libraries/db_info.inc.php';
381 if (isset($message)) {
382 PMA_showMessage($message, $sql_query);
387 $db_collation = PMA_getDbCollation($db);
388 if ($db == 'information_schema') {
389 $is_information_schema = true;
391 $is_information_schema = false;
394 if (!$is_information_schema) {
396 require './libraries/display_create_table.lib.php';
398 if ($cfgRelation['commwork']) {
403 <form method
="post" action
="db_operations.php">
404 <?php
echo PMA_generate_common_hidden_inputs($db); ?
>
407 <?php
echo PMA_getIcon('b_comment.png', $strDBComment, false, true); ?
>
409 <input type
="text" name
="comment" class="textfield" size
="30"
411 echo htmlspecialchars(PMA_getDBComment($db)); ?>" />
412 <input type
="submit" value
="<?php echo $strGo; ?>" />
421 <form method
="post" action
="db_operations.php"
422 onsubmit
="return emptyFormElements(this, 'newname')">
424 if (isset($db_collation)) {
425 echo '<input type="hidden" name="db_collation" value="' . $db_collation
429 <input type
="hidden" name
="what" value
="data" />
430 <input type
="hidden" name
="db_rename" value
="true" />
431 <?php
echo PMA_generate_common_hidden_inputs($db); ?
>
435 if ($cfg['PropertiesIconic']) {
436 echo '<img class="icon" src="' . $pmaThemeImage . 'b_edit.png"'
437 .' alt="" width="16" height="16" />';
439 echo $strDBRename . ':';
442 <input type
="text" name
="newname" size
="30" class="textfield" value
="" />
444 echo '(' . $strCommand . ': ';
446 * @todo (see explanations above in a previous todo)
448 //if (PMA_MYSQL_INT_VERSION >= XYYZZ) {
449 // echo 'RENAME DATABASE';
451 echo 'INSERT INTO ... SELECT';
454 <input type
="submit" value
="<?php echo $strGo; ?>" onclick
="return confirmLink(this, 'CREATE DATABASE ... <?php echo $strAndThen; ?> DROP DATABASE <?php echo PMA_jsFormat($db); ?>')" />
463 <form method
="post" action
="db_operations.php"
464 onsubmit
="return emptyFormElements(this, 'newname')">
466 if (isset($db_collation)) {
467 echo '<input type="hidden" name="db_collation" value="' . $db_collation
470 echo '<input type="hidden" name="db_copy" value="true" />' . "\n";
471 echo PMA_generate_common_hidden_inputs($db);
476 if ($cfg['PropertiesIconic']) {
477 echo '<img class="icon" src="' . $pmaThemeImage . 'b_edit.png"'
478 .' alt="" width="16" height="16" />';
480 echo $strDBCopy . ':';
481 $drop_clause = 'DROP TABLE / DROP VIEW';
484 <input type
="text" name
="newname" size
="30" class="textfield" value
="" /><br
/>
487 'structure' => $strStrucOnly,
488 'data' => $strStrucData,
489 'dataonly' => $strDataOnly);
490 PMA_display_html_radio('what', $choices, 'data', true);
493 <input type
="checkbox" name
="create_database_before_copying" value
="1"
494 id
="checkbox_create_database_before_copying"
495 style
="vertical-align: middle" checked
="checked" />
496 <label
for="checkbox_create_database_before_copying">
497 <?php
echo $strCreateDatabaseBeforeCopying; ?
></label
><br
/>
498 <input type
="checkbox" name
="drop_if_exists" value
="true"
499 id
="checkbox_drop" style
="vertical-align: middle" />
500 <label
for="checkbox_drop"><?php
echo sprintf($strAddClause, $drop_clause); ?
></label
><br
/>
501 <input type
="checkbox" name
="sql_auto_increment" value
="1" checked
="checked"
502 id
="checkbox_auto_increment" style
="vertical-align: middle" />
503 <label
for="checkbox_auto_increment">
504 <?php
echo $strAddAutoIncrement; ?
></label
><br
/>
505 <input type
="checkbox" name
="add_constraints" value
="1"
506 id
="checkbox_constraints" style
="vertical-align: middle" />
507 <label
for="checkbox_constraints">
508 <?php
echo $strAddConstraints; ?
></label
><br
/>
512 if (isset($_COOKIE) && isset($_COOKIE['pma_switch_to_new'])
513 && $_COOKIE['pma_switch_to_new'] == 'true') {
514 $pma_switch_to_new = 'true';
517 <input type
="checkbox" name
="switch_to_new" value
="true"
519 <?php
echo ((isset($pma_switch_to_new) && $pma_switch_to_new == 'true') ?
' checked="checked"' : ''); ?
>
520 style
="vertical-align: middle" />
521 <label
for="checkbox_switch"><?php
echo $strSwitchToDatabase; ?
></label
>
523 <fieldset
class="tblFooters">
524 <input type
="submit" name
="submit_copy" value
="<?php echo $strGo; ?>" />
530 * BLOB streaming support
534 $PMA_Config = $_SESSION['PMA_Config'];
536 // if all blobstreaming plugins exist, begin checking for blobstreaming tables
537 if (!empty($PMA_Config))
539 if ($PMA_Config->get('PBXT_NAME') !== strtolower($db))
541 if ($PMA_Config->get('BLOBSTREAMING_PLUGINS_EXIST'))
543 $bs_tables = $PMA_Config->get('BLOBSTREAMABLE_DATABASES');
544 $bs_tables = $bs_tables[$db];
546 $oneBSTableExists = FALSE;
547 $allBSTablesExist = TRUE;
549 // first check that all blobstreaming tables do not exist
550 foreach ($bs_tables as $table_key=>$tbl)
551 if ($bs_tables[$table_key]['Exists'])
552 $oneBSTableExists = TRUE;
554 $allBSTablesExist = FALSE;
558 <form method
="post" action
="./db_operations.php">
559 <?php
echo PMA_generate_common_hidden_inputs($db); ?
>
562 <?php
echo PMA_getIcon('b_edit.png', $strBLOBRepository, false, true); ?
>
565 <?php
echo $strStatus; ?
>:
569 // if the blobstreaming tables exist, provide option to disable the BLOB repository
570 if ($allBSTablesExist)
573 <?php
echo $strBLOBRepositoryEnabled; ?
>
575 <fieldset
class="tblFooters">
576 <input type
="hidden" name
="db_blob_streaming_op" value
="disable" />
577 <input type
="submit" onclick
="return confirmDisableRepository('<?php echo $db; ?>');" value
="<?php echo $strBLOBRepositoryDisable; ?>" />
583 // if any of the blobstreaming tables are missing, provide option to repair the BLOB repository
584 if ($oneBSTableExists && !$allBSTablesExist)
587 <?php
echo $strBLOBRepositoryDamaged; ?
>
589 <fieldset
class="tblFooters">
590 <input type
="hidden" name
="db_blob_streaming_op" value
="repair" />
591 <input type
="submit" value
="<?php echo $strBLOBRepositoryRepair; ?>" />
595 // if none of the blobstreaming tables exist, provide option to enable BLOB repository
599 <?php
echo $strBLOBRepositoryDisabled; ?
>
601 <fieldset
class="tblFooters">
602 <input type
="hidden" name
="db_blob_streaming_op" value
="enable" />
603 <input type
="submit" value
="<?php echo $strBLOBRepositoryEnable; ?>" />
607 } // end if ($allBSTablesExist)
612 } // end if ($PMA_Config->get('BLOBSTREAMING_PLUGINS_EXIST'))
613 } // end if ($PMA_Config->get('PBXT_NAME') !== strtolower($db))
617 * Change database charset
619 echo '<form method="post" action="./db_operations.php">' . "\n"
620 . PMA_generate_common_hidden_inputs($db, $table)
621 . '<fieldset>' . "\n"
623 if ($cfg['PropertiesIconic']) {
624 echo '<img class="icon" src="' . $pmaThemeImage . 's_asci.png"'
625 .' alt="" width="16" height="16" />';
627 echo ' <label for="select_db_collation">' . $strCollation . ':</label>' . "\n"
628 . ' </legend>' . "\n"
629 . PMA_generateCharsetDropdownBox(PMA_CSDROPDOWN_COLLATION
,
630 'db_collation', 'select_db_collation', $db_collation, false, 3)
631 . ' <input type="submit" name="submitcollation"'
632 . ' value="' . $strGo . '" style="vertical-align: middle" />' . "\n"
633 . '</fieldset>' . "\n"
637 && !$cfgRelation['allworks'] && $cfg['PmaNoRelation_DisableWarning'] == false) {
638 $message = PMA_Message
::notice('strRelationNotWorking');
639 $message->addParam('<a href="' . $cfg['PmaAbsoluteUri'] . 'chk_rel.php?' . $url_query . '">', false);
640 $message->addParam('</a>', false);
641 /* Show error if user has configured something, notice elsewhere */
642 if (!empty($cfg['Servers'][$server]['pmadb'])) {
643 $message->isError(true);
647 } // end if (!$is_information_schema)
650 // not sure about displaying the PDF dialog in case db is information_schema
651 if ($cfgRelation['pdfwork'] && $num_tables > 0) { ?
>
652 <!-- Work on PDF Pages
-->
655 // We only show this if we find something in the new pdf_pages table
659 FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['pdf_pages']) . '
660 WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'';
661 $test_rs = PMA_query_as_controluser($test_query, null, PMA_DBI_QUERY_STORE
);
663 if ($test_rs && PMA_DBI_num_rows($test_rs) > 0) { ?
>
665 <form method
="post" action
="pdf_schema.php">
669 echo PMA_generate_common_hidden_inputs($db);
670 if ($cfg['PropertiesIconic']) {
671 echo '<img class="icon" src="' . $pmaThemeImage . 'b_view.png"'
672 .' alt="" width="16" height="16" />';
677 <label
for="pdf_page_number_opt"><?php
echo $strPageNumber; ?
></label
>
678 <select name
="pdf_page_number" id
="pdf_page_number_opt">
680 while ($pages = @PMA_DBI_fetch_assoc
($test_rs)) {
681 echo ' <option value="' . $pages['page_nr'] . '">'
682 . $pages['page_nr'] . ': ' . htmlspecialchars($pages['page_descr']) . '</option>' . "\n";
684 PMA_DBI_free_result($test_rs);
689 <input type
="checkbox" name
="show_grid" id
="show_grid_opt" />
690 <label
for="show_grid_opt"><?php
echo $strShowGrid; ?
></label
><br
/>
691 <input type
="checkbox" name
="show_color" id
="show_color_opt"
693 <label
for="show_color_opt"><?php
echo $strShowColor; ?
></label
><br
/>
694 <input type
="checkbox" name
="show_table_dimension" id
="show_table_dim_opt" />
695 <label
for="show_table_dim_opt"><?php
echo $strShowTableDimension; ?
>
697 <input type
="checkbox" name
="all_tab_same_wide" id
="all_tab_same_wide" />
698 <label
for="all_tab_same_wide"><?php
echo $strAllTableSameWidth; ?
>
700 <input type
="checkbox" name
="with_doc" id
="with_doc" checked
="checked" />
701 <label
for="with_doc"><?php
echo $strDataDict; ?
></label
><br
/>
702 <input type
="checkbox" name
="show_keys" id
="show_keys" />
703 <label
for="show_keys"><?php
echo $strShowKeys; ?
></label
><br
/>
705 <label
for="orientation_opt"><?php
echo $strShowDatadictAs; ?
></label
>
706 <select name
="orientation" id
="orientation_opt">
707 <option value
="L"><?php
echo $strLandscape;?
></option
>
708 <option value
="P"><?php
echo $strPortrait;?
></option
>
711 <label
for="paper_opt"><?php
echo $strPaperSize; ?
></label
>
712 <select name
="paper" id
="paper_opt">
714 foreach ($cfg['PDFPageSizes'] AS $key => $val) {
715 echo '<option value="' . $val . '"';
716 if ($val == $cfg['PDFDefaultPageSize']) {
717 echo ' selected="selected"';
719 echo ' >' . $val . '</option>' . "\n";
724 <fieldset
class="tblFooters">
725 <input type
="submit" value
="<?php echo $strGo; ?>" />
730 echo '<br /><a href="pdf_pages.php?' . $url_query . '">';
731 if ($cfg['PropertiesIconic']) {
732 echo '<img class="icon" src="' . $pmaThemeImage . 'b_edit.png"'
733 .' alt="" width="16" height="16" />';
735 echo $strEditPDFPages . '</a>';
739 * Displays the footer
741 require_once './libraries/footer.inc.php';