Upgraded phpmyadmin to 4.0.4 (All Languages) - No modifications yet
[openemr.git] / phpmyadmin / libraries / structure.lib.php
blobe6d76dd837f4f889c4d867d7597f7de89eb03d51
1 <?php
3 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 /**
5 * set of functions for structure section in pma
7 * @package PhpMyAdmin
8 */
9 if (!defined('PHPMYADMIN')) {
10 exit;
13 /**
14 * Get the HTML links for action links
15 * Actions are, Browse, Search, Browse table label, empty table
17 * @param array $current_table current table
18 * @param boolean $table_is_view Is table view or not
19 * @param string $tbl_url_query table url query
20 * @param array $titles titles and icons for action links
21 * @param string $truename table name
22 * @param boolean $db_is_information_schema is database information schema or not
23 * @param string $url_query url query
25 * @return array ($browse_table, $search_table, $browse_table_label, $empty_table,
26 * $tracking_icon)
28 function PMA_getHtmlForActionLinks($current_table, $table_is_view, $tbl_url_query,
29 $titles, $truename, $db_is_information_schema, $url_query
30 ) {
31 $empty_table = '';
33 if ($current_table['TABLE_ROWS'] > 0 || $table_is_view) {
34 $may_have_rows = true;
35 } else {
36 $may_have_rows = false;
39 $browse_table = '<a href="sql.php?' . $tbl_url_query . '&amp;pos=0">';
40 if ($may_have_rows) {
41 $browse_table .= $titles['Browse'];
42 } else {
43 $browse_table .= $titles['NoBrowse'];
45 $browse_table .= '</a>';
47 $search_table = '<a href="tbl_select.php?' . $tbl_url_query . '">';
48 if ($may_have_rows) {
49 $search_table .= $titles['Search'];
50 } else {
51 $search_table .= $titles['NoSearch'];
53 $search_table .= '</a>';
55 $browse_table_label = '<a href="sql.php?' . $tbl_url_query . '&amp;pos=0">'
56 . $truename . '</a>';
58 if (!$db_is_information_schema) {
59 $empty_table = '<a class="truncate_table_anchor ajax"';
60 $empty_table .= ' href="sql.php?' . $tbl_url_query
61 . '&amp;sql_query=';
62 $empty_table .= urlencode(
63 'TRUNCATE ' . PMA_Util::backquote($current_table['TABLE_NAME'])
65 $empty_table .= '&amp;message_to_show='
66 . urlencode(
67 sprintf(
68 __('Table %s has been emptied'),
69 htmlspecialchars($current_table['TABLE_NAME'])
72 . '">';
73 if ($may_have_rows) {
74 $empty_table .= $titles['Empty'];
75 } else {
76 $empty_table .= $titles['NoEmpty'];
78 $empty_table .= '</a>';
79 // truncating views doesn't work
80 if ($table_is_view) {
81 $empty_table = '&nbsp;';
85 $tracking_icon = '';
86 if (PMA_Tracker::isActive()) {
87 if (PMA_Tracker::isTracked($GLOBALS["db"], $truename)) {
88 $tracking_icon = '<a href="tbl_tracking.php?' . $url_query
89 . '&amp;table=' . $truename . '">'
90 . PMA_Util::getImage(
91 'eye.png', __('Tracking is active.')
93 . '</a>';
94 } elseif (PMA_Tracker::getVersion($GLOBALS["db"], $truename) > 0) {
95 $tracking_icon = '<a href="tbl_tracking.php?' . $url_query
96 . '&amp;table=' . $truename . '">'
97 . PMA_Util::getImage(
98 'eye_grey.png', __('Tracking is not active.')
100 . '</a>';
104 return array($browse_table,
105 $search_table,
106 $browse_table_label,
107 $empty_table,
108 $tracking_icon
113 * Get table drop query and drop message
115 * @param boolean $table_is_view Is table view or not
116 * @param string $current_table current table
118 * @return array ($drop_query, $drop_message)
120 function PMA_getTableDropQueryAndMessage($table_is_view, $current_table)
122 $drop_query = 'DROP '
123 . (($table_is_view || $current_table['ENGINE'] == null) ? 'VIEW' : 'TABLE')
124 . ' ' . PMA_Util::backquote(
125 $current_table['TABLE_NAME']
127 $drop_message = sprintf(
128 (($table_is_view || $current_table['ENGINE'] == null)
129 ? __('View %s has been dropped')
130 : __('Table %s has been dropped')),
131 str_replace(
132 ' ',
133 '&nbsp;',
134 htmlspecialchars($current_table['TABLE_NAME'])
137 return array($drop_query, $drop_message);
141 * Get HTML body for table summery
143 * @param integer $num_tables number of tables
144 * @param boolean $server_slave_status server slave state
145 * @param boolean $db_is_information_schema whether database is information
146 * schema or not
147 * @param integer $sum_entries sum entries
148 * @param string $db_collation collation of given db
149 * @param boolean $is_show_stats whether stats is show or not
150 * @param double $sum_size sum size
151 * @param double $overhead_size overhead size
152 * @param string $create_time_all create time
153 * @param string $update_time_all update time
154 * @param string $check_time_all check time
155 * @param integer $sum_row_count_pre sum row count pre
157 * @return string $html_output
159 function PMA_getHtmlBodyForTableSummary($num_tables, $server_slave_status,
160 $db_is_information_schema, $sum_entries, $db_collation, $is_show_stats,
161 $sum_size, $overhead_size, $create_time_all, $update_time_all,
162 $check_time_all, $sum_row_count_pre
164 if ($is_show_stats) {
165 list($sum_formatted, $unit) = PMA_Util::formatByteDown(
166 $sum_size, 3, 1
168 list($overhead_formatted, $overhead_unit)
169 = PMA_Util::formatByteDown($overhead_size, 3, 1);
172 $html_output = '<tbody id="tbl_summary_row">'
173 . '<tr><th></th>';
174 $html_output .= '<th class="tbl_num nowrap">';
175 $html_output .= sprintf(
176 _ngettext('%s table', '%s tables', $num_tables),
177 PMA_Util::formatNumber($num_tables, 0)
179 $html_output .= '</th>';
181 if ($server_slave_status) {
182 $html_output .= '<th>' . __('Replication') . '</th>' . "\n";
184 $html_output .= '<th colspan="'. ($db_is_information_schema ? 3 : 6) . '">'
185 . __('Sum')
186 . '</th>';
187 $html_output .= '<th class="value tbl_rows">'
188 . $sum_row_count_pre . PMA_Util::formatNumber($sum_entries, 0)
189 . '</th>';
191 if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
192 $default_engine = PMA_DBI_fetch_value(
193 'SHOW VARIABLES LIKE \'storage_engine\';',
197 $html_output .= '<th class="center">' . "\n"
198 . '<dfn title="'
199 . sprintf(
200 __('%s is the default storage engine on this MySQL server.'),
201 $default_engine
203 . '">' .$default_engine . '</dfn></th>' . "\n";
204 // we got a case where $db_collation was empty
205 $html_output .= '<th>' . "\n";
207 if (! empty($db_collation)) {
208 $html_output .= '<dfn title="'
209 . PMA_getCollationDescr($db_collation)
210 . ' (' . __('Default') . ')">'
211 . $db_collation
212 . '</dfn>';
214 $html_output .= '</th>';
216 if ($is_show_stats) {
217 $html_output .= '<th class="value tbl_size">'
218 . $sum_formatted . ' ' . $unit
219 . '</th>';
220 $html_output .= '<th class="value tbl_overhead">'
221 . $overhead_formatted . ' ' . $overhead_unit
222 . '</th>';
225 if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
226 $html_output .= '<th class="value tbl_creation">' . "\n"
227 . ' '
228 . ($create_time_all
229 ? PMA_Util::localisedDate(strtotime($create_time_all))
230 : '-'
232 . '</th>';
235 if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
236 $html_output .= '<th class="value tbl_last_update">' . "\n"
237 . ' '
238 . ($update_time_all
239 ? PMA_Util::localisedDate(strtotime($update_time_all))
240 : '-'
242 . '</th>';
245 if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
246 $html_output .= '<th class="value tbl_last_check">' . "\n"
247 . ' '
248 . ($check_time_all
249 ? PMA_Util::localisedDate(strtotime($check_time_all))
250 : '-'
252 . '</th>';
254 $html_output .= '</tr>'
255 . '</tbody>';
257 return $html_output;
261 * Get HTML for "check all" check box with "with selected" dropdown
263 * @param string $pmaThemeImage pma theme image url
264 * @param string $text_dir url for text directory
265 * @param string $overhead_check overhead check
266 * @param boolean $db_is_information_schema whether database is information
267 * schema or not
268 * @param string $hidden_fields hidden fields
270 * @return string $html_output
272 function PMA_getHtmlForCheckAllTables($pmaThemeImage, $text_dir,
273 $overhead_check, $db_is_information_schema, $hidden_fields
275 $html_output = '<div class="clearfloat">';
276 $html_output .= '<img class="selectallarrow" '
277 . 'src="' .$pmaThemeImage .'arrow_'.$text_dir.'.png' . '"'
278 . 'width="38" height="22" alt="' . __('With selected:') . '" />';
280 $html_output .= '<input type="checkbox" id="checkall" '
281 . 'title="' . __('Check All') .'" />';
282 $html_output .= '<label for="checkall">' .__('Check All') . '</label>';
284 if ($overhead_check != '') {
285 $html_output .= PMA_getHtmlForCheckTablesHavingOverheadlink(
286 $overhead_check
290 $html_output .= '<select name="submit_mult" class="autosubmit" '
291 . 'style="margin: 0 3em 0 3em;">';
293 $html_output .= '<option value="' . __('With selected:')
294 . '" selected="selected">'
295 . __('With selected:') . '</option>' . "\n";
296 $html_output .= '<option value="export" >'
297 . __('Export') . '</option>' . "\n";
298 $html_output .= '<option value="print" >'
299 . __('Print view') . '</option>' . "\n";
301 if (!$db_is_information_schema
302 && !$GLOBALS['cfg']['DisableMultiTableMaintenance']
304 $html_output .= '<option value="empty_tbl" >'
305 . __('Empty') . '</option>' . "\n";
306 $html_output .= '<option value="drop_tbl" >'
307 . __('Drop') . '</option>' . "\n";
308 $html_output .= '<option value="check_tbl" >'
309 . __('Check table') . '</option>' . "\n";
310 if (!PMA_DRIZZLE) {
311 $html_output .= '<option value="optimize_tbl" >'
312 . __('Optimize table') . '</option>' . "\n";
313 $html_output .= '<option value="repair_tbl" >'
314 . __('Repair table') . '</option>' . "\n";
316 $html_output .= '<option value="analyze_tbl" >'
317 . __('Analyze table') . '</option>' . "\n";
318 $html_output .= '<option value="add_prefix_tbl" >'
319 . __('Add prefix to table') . '</option>' . "\n";
320 $html_output .= '<option value="replace_prefix_tbl" >'
321 . __('Replace table prefix') . '</option>' . "\n";
322 $html_output .= '<option value="copy_tbl_change_prefix" >'
323 . __('Copy table with prefix') . '</option>' . "\n";
325 $html_output .= '</select>'
326 . implode("\n", $hidden_fields) . "\n";
327 $html_output .= '</div>';
329 return $html_output;
333 * Get HTML code for "Check tables having overhead" link
335 * @param string $overhead_check overhead check
337 * @return string $html_output
339 function PMA_getHtmlForCheckTablesHavingOverheadlink($overhead_check)
341 return ' / '
342 . '<a href="#" onclick="unMarkAllRows(\'tablesForm\');'
343 . $overhead_check . 'return false;">'
344 . __('Check tables having overhead')
345 . '</a>';
350 * Get HTML links for "Print view" options
352 * @param string $url_query url query
354 * @return string $html_output
356 function PMA_getHtmlForTablePrintViewLink($url_query)
358 return '<p>'
359 . '<a href="db_printview.php?' . $url_query . '" target="print_view">'
360 . PMA_Util::getIcon(
361 'b_print.png',
362 __('Print view'),
363 true
364 ) . '</a>';
368 * Get HTML links "Data Dictionary" options
370 * @param string $url_query url query
372 * @return string $html_output
374 function PMA_getHtmlForDataDictionaryLink($url_query)
376 return '<a href="db_datadict.php?' . $url_query . '" target="print_view">'
377 . PMA_Util::getIcon(
378 'b_tblanalyse.png',
379 __('Data Dictionary'),
380 true
381 ) . '</a>'
382 . '</p>';
386 * Get Time for Create time, update time and check time
388 * @param array $current_table current table
389 * @param string $time_label Create_time, Update_time, Check_time
390 * @param integer $time_all time
392 * @return array ($time, $time_all)
394 function PMA_getTimeForCreateUpdateCheck($current_table, $time_label, $time_all)
396 $showtable = PMA_Table::sGetStatusInfo(
397 $GLOBALS['db'],
398 $current_table['TABLE_NAME'],
399 null,
400 true
402 $time = isset($showtable[$time_label])
403 ? $showtable[$time_label]
404 : false;
406 // show oldest creation date in summary row
407 if ($time && (!$time_all || $time < $time_all)) {
408 $time_all = $time;
410 return array($time, $time_all);
414 * Get HTML for each table row of the database structure table,
415 * And this function returns $odd_row param also
417 * @param integer $curr current entry
418 * @param boolean $odd_row whether row is odd or not
419 * @param boolean $table_is_view whether table is view or not
420 * @param array $current_table current table
421 * @param string $browse_table_label browse table label action link
422 * @param string $tracking_icon tracking icon
423 * @param boolean $server_slave_status server slave state
424 * @param string $browse_table browse table action link
425 * @param string $tbl_url_query table url query
426 * @param string $search_table search table action link
427 * @param boolean $db_is_information_schema whether db is information schema or not
428 * @param array $titles titles array
429 * @param string $empty_table empty table action link
430 * @param string $drop_query table dropt query
431 * @param string $drop_message table drop message
432 * @param string $collation collation
433 * @param string $formatted_size formatted size
434 * @param string $unit unit
435 * @param string $overhead overhead
436 * @param string $create_time create time
437 * @param string $update_time last update time
438 * @param string $check_time last check time
439 * @param boolean $is_show_stats whether stats is show or not
440 * @param boolean $ignored ignored
441 * @param boolean $do do
442 * @param intger $colspan_for_structure colspan for structure
444 * @return array $html_output, $odd_row
446 function PMA_getHtmlForStructureTableRow(
447 $curr, $odd_row, $table_is_view, $current_table,
448 $browse_table_label, $tracking_icon,$server_slave_status,
449 $browse_table, $tbl_url_query, $search_table,
450 $db_is_information_schema,$titles, $empty_table, $drop_query, $drop_message,
451 $collation, $formatted_size, $unit, $overhead, $create_time, $update_time,
452 $check_time,$is_show_stats, $ignored, $do, $colspan_for_structure
454 $html_output = '<tr class="' . ($odd_row ? 'odd' : 'even');
455 $odd_row = ! $odd_row;
456 $html_output .= ($table_is_view ? ' is_view' : '')
457 .'" id="row_tbl_' . $curr . '">';
459 $html_output .= '<td class="center">'
460 . '<input type="checkbox" name="selected_tbl[]" class="checkall" '
461 . 'value="' . htmlspecialchars($current_table['TABLE_NAME']) . '" '
462 . 'id="checkbox_tbl_' . $curr .'" /></td>';
464 $html_output .= '<th>'
465 . $browse_table_label
466 . (! empty($tracking_icon) ? $tracking_icon : '')
467 . '</th>';
469 if ($server_slave_status) {
470 $html_output .= '<td class="center">'
471 . ($ignored
472 ? PMA_Util::getImage('s_cancel.png', 'NOT REPLICATED')
473 : '')
474 . ($do
475 ? PMA_Util::getImage('s_success.png', 'REPLICATED')
476 : '')
477 . '</td>';
480 $html_output .= '<td class="center">' . $browse_table . '</td>';
481 $html_output .= '<td class="center">'
482 . '<a href="tbl_structure.php?' . $tbl_url_query . '">'
483 . $titles['Structure'] . '</a></td>';
484 $html_output .= '<td class="center">' . $search_table . '</td>';
486 if (! $db_is_information_schema) {
487 $html_output .= PMA_getHtmlForInsertEmptyDropActionLinks(
488 $tbl_url_query, $table_is_view,
489 $titles, $empty_table, $current_table, $drop_query, $drop_message
491 } // end if (! $db_is_information_schema)
493 // there is a null value in the ENGINE
494 // - when the table needs to be repaired, or
495 // - when it's a view
496 // so ensure that we'll display "in use" below for a table
497 // that needs to be repaired
498 if (isset($current_table['TABLE_ROWS'])
499 && ($current_table['ENGINE'] != null
500 || $table_is_view)
502 $html_output .= PMA_getHtmlForNotNullEngineViewTable(
503 $table_is_view, $current_table, $collation, $is_show_stats,
504 $tbl_url_query, $formatted_size, $unit, $overhead, $create_time,
505 $update_time, $check_time
507 } elseif ($table_is_view) {
508 $html_output .= PMA_getHtmlForViewTable($is_show_stats);
509 } else {
510 $html_output .= PMA_getHtmlForRepairtable(
511 $colspan_for_structure,
512 $db_is_information_schema
514 } // end if (isset($current_table['TABLE_ROWS'])) else
515 $html_output .= '</tr>';
517 return array($html_output, $odd_row);
521 * Get HTML for Insert/Empty/Drop action links
523 * @param string $tbl_url_query table url query
524 * @param boolean $table_is_view whether table is view or not
525 * @param array $titles titles array
526 * @param string $empty_table HTML link for empty table
527 * @param array $current_table current table
528 * @param string $drop_query query for drop table
529 * @param string $drop_message table drop message
531 * @return string $html_output
533 function PMA_getHtmlForInsertEmptyDropActionLinks($tbl_url_query, $table_is_view,
534 $titles, $empty_table, $current_table, $drop_query, $drop_message
536 $html_output = '<td class="insert_table center">'
537 . '<a href="tbl_change.php?' . $tbl_url_query . '">'
538 . $titles['Insert']
539 . '</a></td>';
540 $html_output .= '<td class="center">' . $empty_table . '</td>';
541 $html_output .= '<td class="center">';
542 $html_output .= '<a ';
543 $html_output .= 'class="ajax drop_table_anchor';
544 if ($table_is_view || $current_table['ENGINE'] == null) {
545 // this class is used in db_structure.js to display the
546 // correct confirmation message
547 $html_output .= ' view';
549 $html_output .= '"';
550 $html_output .= 'href="sql.php?' . $tbl_url_query
551 . '&amp;reload=1&amp;purge=1&amp;sql_query='
552 . urlencode($drop_query) . '&amp;message_to_show='
553 . urlencode($drop_message) . '" >'
554 . $titles['Drop'] . '</a></td>';
556 return $html_output;
560 * Get HTML for show stats
562 * @param string $tbl_url_query tabel url query
563 * @param string $formatted_size formatted size
564 * @param string $unit unit
565 * @param string $overhead overhead
567 * @return string $html_output
569 function PMA_getHtmlForShowStats($tbl_url_query, $formatted_size,
570 $unit, $overhead
572 $html_output = '<td class="value tbl_size"><a'
573 . 'href="tbl_structure.php?' . $tbl_url_query . '#showusage" >'
574 . '<span>' . $formatted_size . '</span> '
575 . '<span class="unit">' . $unit . '</span>'
576 . '</a></td>';
577 $html_output .= '<td class="value tbl_overhead">' . $overhead . '</td>';
579 return $html_output;
583 * Get HTML to show database structure creation, last update and last checkx time
585 * @param string $create_time create time
586 * @param string $update_time last update time
587 * @param string $check_time last check time
589 * @return string $html_output
591 function PMA_getHtmlForStructureTimes($create_time, $update_time, $check_time)
593 $html_output = '';
594 if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
595 $html_output .= '<td class="value tbl_creation">'
596 . ($create_time
597 ? PMA_Util::localisedDate(strtotime($create_time))
598 : '-' )
599 . '</td>';
600 } // end if
601 if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
602 $html_output .= '<td class="value tbl_last_update">'
603 . ($update_time
604 ? PMA_Util::localisedDate(strtotime($update_time))
605 : '-' )
606 . '</td>';
607 } // end if
608 if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
609 $html_output .= '<td class="value tbl_last_check">'
610 . ($check_time
611 ? PMA_Util::localisedDate(strtotime($check_time))
612 : '-' )
613 . '</td>';
615 return $html_output;
619 * Get HTML for ENGINE value not null or view tables that are not empty tables
621 * @param boolean $table_is_view whether table is view
622 * @param array $current_table current table
623 * @param string $collation collation
624 * @param boolean $is_show_stats whether atats show or not
625 * @param string $tbl_url_query table url query
626 * @param string $formatted_size formatted size
627 * @param string $unit unit
628 * @param string $overhead overhead
629 * @param string $create_time create time
630 * @param string $update_time update time
631 * @param string $check_time check time
633 * @return string $html_output
635 function PMA_getHtmlForNotNullEngineViewTable($table_is_view, $current_table,
636 $collation, $is_show_stats, $tbl_url_query, $formatted_size, $unit,
637 $overhead, $create_time, $update_time, $check_time
639 $html_output = '';
640 $row_count_pre = '';
641 $show_superscript = '';
642 if ($table_is_view) {
643 // Drizzle views use FunctionEngine, and the only place where they are
644 // available are I_S and D_D schemas, where we do exact counting
645 if ($current_table['TABLE_ROWS'] >= $GLOBALS['cfg']['MaxExactCountViews']
646 && $current_table['ENGINE'] != 'FunctionEngine'
648 $row_count_pre = '~';
649 $sum_row_count_pre = '~';
650 $show_superscript = PMA_Util::showHint(
651 PMA_sanitize(
652 sprintf(
653 __('This view has at least this number of rows. Please refer to %sdocumentation%s.'),
654 '[doc@cfg_MaxExactCountViews]',
655 '[/doc]'
660 } elseif ($current_table['ENGINE'] == 'InnoDB'
661 && (! $current_table['COUNTED'])
663 // InnoDB table: we did not get an accurate row count
664 $row_count_pre = '~';
665 $sum_row_count_pre = '~';
666 $show_superscript = '';
669 $html_output .= '<td class="value tbl_rows">'
670 . $row_count_pre . PMA_Util::formatNumber(
671 $current_table['TABLE_ROWS'], 0
673 . $show_superscript . '</td>';
675 if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
676 $html_output .= '<td class="nowrap">'
677 . ($table_is_view ? __('View') : $current_table['ENGINE'])
678 . '</td>';
679 if (strlen($collation)) {
680 $html_output .= '<td class="nowrap">' . $collation . '</td>';
684 if ($is_show_stats) {
685 $html_output .= PMA_getHtmlForShowStats(
686 $tbl_url_query, $formatted_size, $unit, $overhead
690 $html_output .= PMA_getHtmlForStructureTimes(
691 $create_time, $update_time, $check_time
694 return $html_output;
698 * Get HTML snippet view table
700 * @param type $is_show_stats whether stats show or not
702 * @return string $html_output
704 function PMA_getHtmlForViewTable($is_show_stats)
706 $html_output = '<td class="value">-</td>'
707 . '<td>' . __('View') . '</td>'
708 . '<td>---</td>';
709 if ($is_show_stats) {
710 $html_output .= '<td class="value">-</td>'
711 . '<td class="value">-</td>';
713 return $html_output;
717 * display "in use" below for a table that needs to be repaired
719 * @param integer $colspan_for_structure colspan for structure
720 * @param boolean $db_is_information_schema whether db is information schema or not
722 * @return string HTML snippet
724 function PMA_getHtmlForRepairtable(
725 $colspan_for_structure,
726 $db_is_information_schema
728 return '<td colspan="'
729 . ($colspan_for_structure - ($db_is_information_schema ? 5 : 8)) . '"'
730 . 'class="center">'
731 . __('in use')
732 . '</td>';
736 * display table header (<table><thead>...</thead><tbody>)
738 * @param boolean $db_is_information_schema whether db is information schema or not
739 * @param boolean $replication whether to sho replication status
741 * @return html data
743 function PMA_TableHeader($db_is_information_schema = false, $replication = false)
745 $cnt = 0; // Let's count the columns...
747 if ($db_is_information_schema) {
748 $action_colspan = 3;
749 } else {
750 $action_colspan = 6;
753 $html_output = '<table class="data">' . "\n"
754 .'<thead>' . "\n"
755 .'<tr><th></th>' . "\n"
756 .'<th>'
757 . PMA_sortableTableHeader(__('Table'), 'table')
758 . '</th>' . "\n";
759 if ($replication) {
760 $html_output .= '<th>' . "\n"
761 .' ' . __('Replication') . "\n"
762 .'</th>';
764 $html_output .= '<th colspan="' . $action_colspan . '">' . "\n"
765 .' ' . __('Action') . "\n"
766 .'</th>'
767 // larger values are more interesting so default sort order is DESC
768 .'<th>' . PMA_sortableTableHeader(__('Rows'), 'records', 'DESC')
769 . PMA_Util::showHint(
770 PMA_sanitize(
771 __('May be approximate. See [doc@faq3-11]FAQ 3.11[/doc]')
773 ) . "\n"
774 .'</th>' . "\n";
775 if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
776 $html_output .= '<th>' . PMA_sortableTableHeader(__('Type'), 'type')
777 . '</th>' . "\n";
778 $cnt++;
779 $html_output .= '<th>'
780 . PMA_sortableTableHeader(__('Collation'), 'collation')
781 . '</th>' . "\n";
782 $cnt++;
784 if ($GLOBALS['is_show_stats']) {
785 // larger values are more interesting so default sort order is DESC
786 $html_output .= '<th>'
787 . PMA_sortableTableHeader(__('Size'), 'size', 'DESC')
788 . '</th>' . "\n"
789 // larger values are more interesting so default sort order is DESC
790 . '<th>'
791 . PMA_sortableTableHeader(__('Overhead'), 'overhead', 'DESC')
792 . '</th>' . "\n";
793 $cnt += 2;
795 if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
796 // larger values are more interesting so default sort order is DESC
797 $html_output .= '<th>'
798 . PMA_sortableTableHeader(__('Creation'), 'creation', 'DESC')
799 . '</th>' . "\n";
800 $cnt += 2;
802 if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
803 // larger values are more interesting so default sort order is DESC
804 $html_output .= '<th>'
805 . PMA_sortableTableHeader(__('Last update'), 'last_update', 'DESC')
806 . '</th>' . "\n";
807 $cnt += 2;
809 if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
810 // larger values are more interesting so default sort order is DESC
811 $html_output .= '<th>'
812 . PMA_sortableTableHeader(__('Last check'), 'last_check', 'DESC')
813 . '</th>' . "\n";
814 $cnt += 2;
816 $html_output .= '</tr>' . "\n";
817 $html_output .= '</thead>' . "\n";
818 $html_output .= '<tbody>' . "\n";
819 $GLOBALS['colspan_for_structure'] = $cnt + $action_colspan + 3;
821 return $html_output;
825 * Creates a clickable column header for table information
827 * @param string $title title to use for the link
828 * @param string $sort corresponds to sortable data name mapped in
829 * libraries/db_info.inc.php
830 * @param string $initial_sort_order initial sort order
832 * @return string link to be displayed in the table header
834 function PMA_sortableTableHeader($title, $sort, $initial_sort_order = 'ASC')
836 // Set some defaults
837 $requested_sort = 'table';
838 $requested_sort_order = $future_sort_order = $initial_sort_order;
840 // If the user requested a sort
841 if (isset($_REQUEST['sort'])) {
842 $requested_sort = $_REQUEST['sort'];
844 if (isset($_REQUEST['sort_order'])) {
845 $requested_sort_order = $_REQUEST['sort_order'];
849 $order_img = '';
850 $order_link_params = array();
851 $order_link_params['title'] = __('Sort');
853 // If this column was requested to be sorted.
854 if ($requested_sort == $sort) {
855 if ($requested_sort_order == 'ASC') {
856 $future_sort_order = 'DESC';
857 // current sort order is ASC
858 $order_img = ' ' . PMA_Util::getImage(
859 's_asc.png',
860 __('Ascending'),
861 array('class' => 'sort_arrow', 'title' => '')
863 $order_img .= ' ' . PMA_Util::getImage(
864 's_desc.png',
865 __('Descending'),
866 array('class' => 'sort_arrow hide', 'title' => '')
868 // but on mouse over, show the reverse order (DESC)
869 $order_link_params['onmouseover'] = "$('.sort_arrow').toggle();";
870 // on mouse out, show current sort order (ASC)
871 $order_link_params['onmouseout'] = "$('.sort_arrow').toggle();";
872 } else {
873 $future_sort_order = 'ASC';
874 // current sort order is DESC
875 $order_img = ' ' . PMA_Util::getImage(
876 's_asc.png',
877 __('Ascending'),
878 array('class' => 'sort_arrow hide', 'title' => '')
880 $order_img .= ' ' . PMA_Util::getImage(
881 's_desc.png',
882 __('Descending'),
883 array('class' => 'sort_arrow', 'title' => '')
885 // but on mouse over, show the reverse order (ASC)
886 $order_link_params['onmouseover'] = "$('.sort_arrow').toggle();";
887 // on mouse out, show current sort order (DESC)
888 $order_link_params['onmouseout'] = "$('.sort_arrow').toggle();";
892 $_url_params = array(
893 'db' => $_REQUEST['db'],
896 $url = 'db_structure.php'.PMA_generate_common_url($_url_params);
897 // We set the position back to 0 every time they sort.
898 $url .= "&amp;pos=0&amp;sort=$sort&amp;sort_order=$future_sort_order";
900 return PMA_Util::linkOrButton(
901 $url, $title . $order_img, $order_link_params
906 * Get the alias ant truname
908 * @param string $tooltip_aliasname tooltip alias name
909 * @param array $current_table current table
910 * @param string $tooltip_truename tooltip true name
912 * @return array ($alias, $truename)
914 function PMA_getAliasAndTrueName($tooltip_aliasname, $current_table,
915 $tooltip_truename
917 $alias = (! empty($tooltip_aliasname)
918 && isset($tooltip_aliasname[$current_table['TABLE_NAME']])
920 ? str_replace(
921 ' ', '&nbsp;',
922 htmlspecialchars($tooltip_truename[$current_table['TABLE_NAME']])
924 : str_replace(
925 ' ', '&nbsp;',
926 htmlspecialchars($current_table['TABLE_NAME'])
928 $truename = (! empty($tooltip_truename)
929 && isset($tooltip_truename[$current_table['TABLE_NAME']])
931 ? str_replace(
932 ' ', '&nbsp;',
933 htmlspecialchars($tooltip_truename[$current_table['TABLE_NAME']])
935 : str_replace(
936 ' ', '&nbsp;',
937 htmlspecialchars($current_table['TABLE_NAME'])
940 return array($alias, $truename);
944 * Get the server slave state
946 * @param boolean $server_slave_status server slave state
947 * @param string $truename true name
949 * @return array ($do, $ignored)
951 function PMA_getServerSlaveStatus($server_slave_status, $truename)
953 $ignored = false;
954 $do = false;
955 include_once 'libraries/replication.inc.php';
956 if ($server_slave_status) {
957 if ((strlen(array_search($truename, $server_slave_Do_Table)) > 0)
958 || (strlen(array_search($GLOBALS['db'], $server_slave_Do_DB)) > 0)
959 || (count($server_slave_Do_DB) == 1 && count($server_slave_Ignore_DB) == 1)
961 $do = true;
963 foreach ($server_slave_Wild_Do_Table as $db_table) {
964 $table_part = PMA_extract_db_or_table($db_table, 'table');
965 if (($GLOBALS['db'] == PMA_extract_db_or_table($db_table, 'db'))
966 && (preg_match("@^" . substr($table_part, 0, strlen($table_part) - 1) . "@", $truename))
968 $do = true;
972 if ((strlen(array_search($truename, $server_slave_Ignore_Table)) > 0)
973 || (strlen(array_search($GLOBALS['db'], $server_slave_Ignore_DB)) > 0)
975 $ignored = true;
977 foreach ($server_slave_Wild_Ignore_Table as $db_table) {
978 $table_part = PMA_extract_db_or_table($db_table, 'table');
979 if (($db == PMA_extract_db_or_table($db_table))
980 && (preg_match("@^" . substr($table_part, 0, strlen($table_part) - 1) . "@", $truename))
982 $ignored = true;
986 return array($do, $ignored);
990 * Get the value set for ENGINE table,
991 * $current_table, $formatted_size, $unit, $formatted_overhead,
992 * $overhead_unit, $overhead_size, $table_is_view
994 * @param array $current_table current table
995 * @param boolean $db_is_information_schema whether db is information schema or not
996 * @param boolean $is_show_stats whether stats show or not
997 * @param boolean $table_is_view whether table is view or not
998 * @param double $sum_size totle table size
999 * @param double $overhead_size overhead size
1001 * @return array
1003 function PMA_getStuffForEngineTypeTable($current_table, $db_is_information_schema,
1004 $is_show_stats, $table_is_view, $sum_size, $overhead_size
1006 $formatted_size = '-';
1007 $unit = '';
1008 $formatted_overhead = '';
1009 $overhead_unit = '';
1011 switch ( $current_table['ENGINE']) {
1012 // MyISAM, ISAM or Heap table: Row count, data size and index size
1013 // are accurate; data size is accurate for ARCHIVE
1014 case 'MyISAM' :
1015 case 'ISAM' :
1016 case 'HEAP' :
1017 case 'MEMORY' :
1018 case 'ARCHIVE' :
1019 case 'Aria' :
1020 case 'Maria' :
1021 list($current_table, $formatted_size, $unit, $formatted_overhead,
1022 $overhead_unit, $overhead_size, $sum_size) = PMA_getValuesForAriaTable(
1023 $db_is_information_schema, $current_table, $is_show_stats,
1024 $sum_size, $overhead_size, $formatted_size, $unit,
1025 $formatted_overhead, $overhead_unit
1027 break;
1028 case 'InnoDB' :
1029 case 'PBMS' :
1030 // InnoDB table: Row count is not accurate but data and index sizes are.
1031 // PBMS table in Drizzle: TABLE_ROWS is taken from table cache,
1032 // so it may be unavailable
1033 list($current_table, $formatted_size, $unit, $sum_size)
1034 = PMA_getValuesForPbmsTable($current_table, $is_show_stats, $sum_size);
1035 //$display_rows = ' - ';
1036 break;
1037 // Mysql 5.0.x (and lower) uses MRG_MyISAM
1038 // and MySQL 5.1.x (and higher) uses MRG_MYISAM
1039 // Both are aliases for MERGE
1040 case 'MRG_MyISAM' :
1041 case 'MRG_MYISAM' :
1042 case 'MERGE' :
1043 case 'BerkeleyDB' :
1044 // Merge or BerkleyDB table: Only row count is accurate.
1045 if ($is_show_stats) {
1046 $formatted_size = ' - ';
1047 $unit = '';
1049 break;
1050 // for a view, the ENGINE is sometimes reported as null,
1051 // or on some servers it's reported as "SYSTEM VIEW"
1052 case null :
1053 case 'SYSTEM VIEW' :
1054 case 'FunctionEngine' :
1055 // if table is broken, Engine is reported as null, so one more test
1056 if ($current_table['TABLE_TYPE'] == 'VIEW') {
1057 // countRecords() takes care of $cfg['MaxExactCountViews']
1058 $current_table['TABLE_ROWS'] = PMA_Table::countRecords(
1059 $GLOBALS['db'], $current_table['TABLE_NAME'],
1060 $force_exact = true, $is_view = true
1062 $table_is_view = true;
1064 break;
1065 default :
1066 // Unknown table type.
1067 if ($is_show_stats) {
1068 $formatted_size = __('unknown');
1069 $unit = '';
1071 } // end switch
1073 return array($current_table, $formatted_size, $unit, $formatted_overhead,
1074 $overhead_unit, $overhead_size, $table_is_view, $sum_size
1079 * Get values for ARIA/MARIA tables
1080 * $current_table, $formatted_size, $unit, $formatted_overhead,
1081 * $overhead_unit, $overhead_size
1083 * @param boolean $db_is_information_schema whether db is information schema or not
1084 * @param array $current_table current table
1085 * @param boolean $is_show_stats whether stats show or not
1086 * @param double $sum_size sum size
1087 * @param double $overhead_size overhead size
1089 * @return array
1091 function PMA_getValuesForAriaTable($db_is_information_schema, $current_table,
1092 $is_show_stats, $sum_size, $overhead_size, $formatted_size, $unit,
1093 $formatted_overhead, $overhead_unit
1095 if ($db_is_information_schema) {
1096 $current_table['Rows'] = PMA_Table::countRecords(
1097 $GLOBALS['db'], $current_table['Name']
1101 if ($is_show_stats) {
1102 $tblsize = doubleval($current_table['Data_length'])
1103 + doubleval($current_table['Index_length']);
1104 $sum_size += $tblsize;
1105 list($formatted_size, $unit) = PMA_Util::formatByteDown(
1106 $tblsize, 3, ($tblsize > 0) ? 1 : 0
1108 if (isset($current_table['Data_free']) && $current_table['Data_free'] > 0) {
1109 list($formatted_overhead, $overhead_unit)
1110 = PMA_Util::formatByteDown(
1111 $current_table['Data_free'], 3,
1112 (($current_table['Data_free'] > 0) ? 1 : 0)
1114 $overhead_size += $current_table['Data_free'];
1117 return array($current_table, $formatted_size, $unit, $formatted_overhead,
1118 $overhead_unit, $overhead_size, $sum_size
1123 * Get valuse for PBMS table
1124 * $current_table, $formatted_size, $unit, $sum_size
1126 * @param array $current_table current table
1127 * @param boolean $is_show_stats whether stats show or not
1128 * @param double $sum_size sum size
1130 * @return array
1132 function PMA_getValuesForPbmsTable($current_table, $is_show_stats, $sum_size)
1134 if (($current_table['ENGINE'] == 'InnoDB'
1135 && $current_table['TABLE_ROWS'] < $GLOBALS['cfg']['MaxExactCount'])
1136 || !isset($current_table['TABLE_ROWS'])
1138 $current_table['COUNTED'] = true;
1139 $current_table['TABLE_ROWS'] = PMA_Table::countRecords(
1140 $GLOBALS['db'], $current_table['TABLE_NAME'],
1141 $force_exact = true, $is_view = false
1143 } else {
1144 $current_table['COUNTED'] = false;
1147 // Drizzle doesn't provide data and index length, check for null
1148 if ($is_show_stats && $current_table['Data_length'] !== null) {
1149 $tblsize = $current_table['Data_length'] + $current_table['Index_length'];
1150 $sum_size += $tblsize;
1151 list($formatted_size, $unit) = PMA_Util::formatByteDown(
1152 $tblsize, 3, (($tblsize > 0) ? 1 : 0)
1156 return array($current_table, $formatted_size, $unit, $sum_size);
1160 * table structure
1164 * Get the HTML snippet for structure table table header
1166 * @param type $db_is_information_schema whether db is information schema or not
1167 * @param type $tbl_is_view whether table is view or nt
1169 * @return string $html_output
1171 function PMA_getHtmlForTableStructureHeader(
1172 $db_is_information_schema,
1173 $tbl_is_view
1175 $html_output = '<thead>';
1176 $html_output .= '<tr>';
1177 $html_output .= '<th></th>'
1178 . '<th>#</th>'
1179 . '<th>' . __('Name') . '</th>'
1180 . '<th>' . __('Type'). '</th>'
1181 . '<th>' . __('Collation') . '</th>'
1182 . '<th>' . __('Attributes') . '</th>'
1183 . '<th>' . __('Null') . '</th>'
1184 . '<th>' . __('Default') . '</th>'
1185 . '<th>' . __('Extra') . '</th>';
1187 if ($db_is_information_schema || $tbl_is_view) {
1188 $html_output .= '<th>' . __('View') . '</th>';
1189 } else { /* see tbl_structure.js, function moreOptsMenuResize() */
1190 $colspan = 9;
1191 if (PMA_DRIZZLE) {
1192 $colspan -= 2;
1194 if ($GLOBALS['cfg']['PropertiesIconic']) {
1195 $colspan--;
1197 $html_output .= '<th colspan="' . $colspan . '" '
1198 . 'class="action">' . __('Action') . '</th>';
1200 $html_output .= '</tr>'
1201 . '</thead>';
1203 return $html_output;
1207 * Get HTML for structure table's rows and return $odd_row parameter also
1208 * For "Action" Column, this function contains only HTML code for "Change"
1209 * and "Drop"
1211 * @param array $row current row
1212 * @param string $rownum row number
1213 * @param string $displayed_field_name displayed field name
1214 * @param string $type_nowrap type nowrap
1215 * @param array $extracted_columnspec associative array containing type,
1216 * spec_in_brackets and possibly
1217 * enum_set_values (another array)
1218 * @param string $type_mime mime type
1219 * @param string $field_charset field charset
1220 * @param string $attribute attribute (BINARY, UNSIGNED,
1221 * UNSIGNED ZEROFILL,
1222 * on update CURRENT_TIMESTAMP)
1223 * @param boolean $tbl_is_view whether tables is view or not
1224 * @param boolean $db_is_information_schema whether db is information schema or not
1225 * @param string $url_query url query
1226 * @param string $field_encoded field encoded
1227 * @param array $titles tittles array
1228 * @param string $table table
1230 * @return array ($html_output, $odd_row)
1232 function PMA_getHtmlTableStructureRow($row, $rownum,
1233 $displayed_field_name, $type_nowrap, $extracted_columnspec, $type_mime,
1234 $field_charset, $attribute, $tbl_is_view, $db_is_information_schema,
1235 $url_query, $field_encoded, $titles, $table
1237 $html_output = '<td class="center">'
1238 . '<input type="checkbox" class="checkall" name="selected_fld[]" '
1239 . 'value="' . htmlspecialchars($row['Field']) . '" '
1240 . 'id="checkbox_row_' . $rownum . '"/>'
1241 . '</td>';
1243 $html_output .= '<td class="right">'
1244 . $rownum
1245 . '</td>';
1247 $html_output .= '<th class="nowrap">'
1248 . '<label for="checkbox_row_' . $rownum . '">'
1249 . $displayed_field_name . '</label>'
1250 . '</th>';
1252 $html_output .= '<td' . $type_nowrap . '>'
1253 .'<bdo dir="ltr" lang="en">'
1254 . $extracted_columnspec['displayed_type'] . $type_mime
1255 . '</bdo></td>';
1257 $html_output .= '<td>' .
1258 (empty($field_charset)
1259 ? ''
1260 : '<dfn title="' . PMA_getCollationDescr($field_charset) . '">'
1261 . $field_charset . '</dfn>'
1263 . '</td>';
1265 $html_output .= '<td class="column_attribute nowrap">'
1266 . $attribute . '</td>';
1267 $html_output .= '<td>'
1268 . (($row['Null'] == 'YES') ? __('Yes') : __('No')) . ' </td>';
1270 $html_output .= '<td class="nowrap">';
1271 if (isset($row['Default'])) {
1272 if ($extracted_columnspec['type'] == 'bit') {
1273 // here, $row['Default'] contains something like b'010'
1274 $html_output .= PMA_Util::convertBitDefaultValue($row['Default']);
1275 } else {
1276 $html_output .= $row['Default'];
1278 } else {
1279 $html_output .= '<i>' . _pgettext('None for default', 'None') . '</i>';
1281 $html_output .= '</td>';
1283 $html_output .= '<td class="nowrap">' . strtoupper($row['Extra']) . '</td>';
1285 $html_output .= PMA_getHtmlForDropColumn(
1286 $tbl_is_view, $db_is_information_schema,
1287 $url_query, $field_encoded,
1288 $titles, $table, $row
1291 return $html_output;
1295 * Get HTML code for "Drop" Action link
1297 * @param boolean $tbl_is_view whether tables is view or not
1298 * @param boolean $db_is_information_schema whether db is information schema or not
1299 * @param string $url_query url query
1300 * @param string $field_encoded field encoded
1301 * @param array $titles tittles array
1302 * @param string $table table
1303 * @param array $row current row
1305 * @return string $html_output
1307 function PMA_getHtmlForDropColumn($tbl_is_view, $db_is_information_schema,
1308 $url_query, $field_encoded, $titles, $table, $row
1310 $html_output = '';
1312 if (! $tbl_is_view && ! $db_is_information_schema) {
1313 $html_output .= '<td class="edit center">'
1314 . '<a class="change_column_anchor ajax"'
1315 . ' href="tbl_structure.php?'
1316 . $url_query . '&amp;field=' . $field_encoded
1317 . '&amp;change_column=1">'
1318 . $titles['Change'] . '</a>' . '</td>';
1319 $html_output .= '<td class="drop center">'
1320 . '<a class="drop_column_anchor ajax"'
1321 . ' href="sql.php?' . $url_query . '&amp;sql_query='
1322 . urlencode(
1323 'ALTER TABLE ' . PMA_Util::backquote($table)
1324 . ' DROP ' . PMA_Util::backquote($row['Field']) . ';'
1326 . '&amp;dropped_column=' . urlencode($row['Field'])
1327 . '&amp;message_to_show=' . urlencode(
1328 sprintf(
1329 __('Column %s has been dropped'),
1330 htmlspecialchars($row['Field'])
1332 ) . '" >'
1333 . $titles['Drop'] . '</a>'
1334 . '</td>';
1337 return $html_output;
1341 * Get HTML for "check all" check box with "with selected" actions in table
1342 * structure
1344 * @param string $pmaThemeImage pma theme image url
1345 * @param string $text_dir test directory
1346 * @param boolean $tbl_is_view whether table is view or not
1347 * @param boolean $db_is_information_schema whether db is information schema or not
1348 * @param string $tbl_storage_engine table storage engine
1350 * @return string $html_output
1352 function PMA_getHtmlForCheckAllTableColumn($pmaThemeImage, $text_dir,
1353 $tbl_is_view, $db_is_information_schema, $tbl_storage_engine
1355 $html_output = '<img class="selectallarrow" '
1356 . 'src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png' . '"'
1357 . 'width="38" height="22" alt="' . __('With selected:') . '" />';
1359 $html_output .= '<input type="checkbox" id="checkall" '
1360 . 'title="' . __('Check All') . '" />'
1361 . '<label for="checkall">' . __('Check All') . '</label>';
1363 $html_output .= '<i style="margin-left: 2em">'
1364 . __('With selected:') . '</i>';
1366 $html_output .= PMA_Util::getButtonOrImage(
1367 'submit_mult', 'mult_submit', 'submit_mult_browse',
1368 __('Browse'), 'b_browse.png', 'browse'
1371 if (! $tbl_is_view && ! $db_is_information_schema) {
1372 $html_output .= PMA_Util::getButtonOrImage(
1373 'submit_mult', 'mult_submit change_columns_anchor ajax',
1374 'submit_mult_change', __('Change'), 'b_edit.png', 'change'
1376 $html_output .= PMA_Util::getButtonOrImage(
1377 'submit_mult', 'mult_submit', 'submit_mult_drop',
1378 __('Drop'), 'b_drop.png', 'drop'
1380 if ('ARCHIVE' != $tbl_storage_engine) {
1381 $html_output .= PMA_Util::getButtonOrImage(
1382 'submit_mult', 'mult_submit', 'submit_mult_primary',
1383 __('Primary'), 'b_primary.png', 'primary'
1385 $html_output .= PMA_Util::getButtonOrImage(
1386 'submit_mult', 'mult_submit', 'submit_mult_unique',
1387 __('Unique'), 'b_unique.png', 'unique'
1389 $html_output .= PMA_Util::getButtonOrImage(
1390 'submit_mult', 'mult_submit', 'submit_mult_index',
1391 __('Index'), 'b_index.png', 'index'
1395 if (! empty($tbl_storage_engine) && $tbl_storage_engine == 'MYISAM') {
1396 $html_output .= PMA_Util::getButtonOrImage(
1397 'submit_mult', 'mult_submit', 'submit_mult_spatial',
1398 __('Spatial'), 'b_spatial.png', 'spatial'
1401 if (! empty($tbl_storage_engine)
1402 && ($tbl_storage_engine == 'MYISAM'
1403 || $tbl_storage_engine == 'ARIA'
1404 || $tbl_storage_engine == 'MARIA')
1406 $html_output .= PMA_Util::getButtonOrImage(
1407 'submit_mult', 'mult_submit', 'submit_mult_fulltext',
1408 __('Fulltext'), 'b_ftext.png', 'ftext'
1412 return $html_output;
1416 * Get HTML for move columns dialog
1418 * @return string $html_output
1420 function PMA_getHtmlDivForMoveColumnsDialog()
1422 $html_output = '<div id="move_columns_dialog" '
1423 . 'title="' . __('Move columns') . '" style="display: none">';
1425 $html_output .= '<p>'
1426 . __('Move the columns by dragging them up and down.') . '</p>';
1428 $html_output .= '<form action="tbl_structure.php">'
1429 . '<div>'
1430 . PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table'])
1431 . '<ul></ul>'
1432 . '</div>'
1433 . '</form>'
1434 . '</div>';
1436 return $html_output;
1440 * Get HTML for edit views'
1442 * @param string $url_params URL parameters
1444 * @return string $html_output
1446 function PMA_getHtmlForEditView($url_params)
1448 $create_view = PMA_DBI_get_definition(
1449 $GLOBALS['db'], 'VIEW', $GLOBALS['table']
1451 $create_view = preg_replace('@^CREATE@', 'ALTER', $create_view);
1452 $html_output = PMA_Util::linkOrButton(
1453 'tbl_sql.php' . PMA_generate_common_url(
1454 $url_params +
1455 array(
1456 'sql_query' => $create_view,
1457 'show_query' => '1',
1460 PMA_Util::getIcon('b_edit.png', __('Edit view'), true)
1462 return $html_output;
1466 * Get HTML links for 'Print view', 'Relation view', 'Propose table structure',
1467 * 'Track table' and 'Move columns'
1469 * @param string $url_query url query
1470 * @param boolean $tbl_is_view whether table is view or not
1471 * @param boolean $db_is_information_schema whether db is information schema or not
1472 * @param string $tbl_storage_engine table storage engine
1473 * @param array $cfgRelation current relation parameters
1475 * @return string $html_output
1477 function PMA_getHtmlForOptionalActionLinks($url_query, $tbl_is_view,
1478 $db_is_information_schema, $tbl_storage_engine, $cfgRelation
1480 $html_output = '<a href="tbl_printview.php?' . $url_query . '" target="print_view">'
1481 . PMA_Util::getIcon('b_print.png', __('Print view'), true)
1482 . '</a>';
1484 if (! $tbl_is_view && ! $db_is_information_schema) {
1485 // if internal relations are available, or foreign keys are supported
1486 // ($tbl_storage_engine comes from libraries/tbl_info.inc.php
1488 if ($cfgRelation['relwork']
1489 || PMA_Util::isForeignKeySupported($tbl_storage_engine)
1491 $html_output .= '<a href="tbl_relation.php?' . $url_query . '">'
1492 . PMA_Util::getIcon(
1493 'b_relations.png', __('Relation view'), true
1495 . '</a>';
1497 if (!PMA_DRIZZLE) {
1498 $html_output .= '<a href="sql.php?' . $url_query
1499 . '&amp;session_max_rows=all&amp;sql_query=' . urlencode(
1500 'SELECT * FROM ' . PMA_Util::backquote($GLOBALS['table'])
1501 . ' PROCEDURE ANALYSE()'
1502 ) . '">'
1503 . PMA_Util::getIcon(
1504 'b_tblanalyse.png',
1505 __('Propose table structure'),
1506 true
1508 . '</a>';
1509 $html_output .= PMA_Util::showMySQLDocu(
1510 'Extending_MySQL', 'procedure_analyse'
1511 ) . "\n";
1513 if (PMA_Tracker::isActive()) {
1514 $html_output .= '<a href="tbl_tracking.php?' . $url_query . '">'
1515 . PMA_Util::getIcon('eye.png', __('Track table'), true)
1516 . '</a>';
1518 $html_output .= '<a href="#" id="move_columns_anchor">'
1519 . PMA_Util::getIcon('b_move.png', __('Move columns'), true)
1520 . '</a>';
1523 return $html_output;
1527 * Get HTML snippet for "Add column" feature in structure table
1529 * @param array $columns_list column list array
1531 * @return string $html_output
1533 function PMA_getHtmlForAddColumn($columns_list)
1535 $html_output = '<form method="post" action="tbl_addfield.php" '
1536 . 'id="addColumns" name="addColumns" '
1537 . 'onsubmit="return checkFormElementInRange('
1538 . 'this, \'num_fields\', \'' . str_replace(
1539 '\'',
1540 '\\\'',
1541 __('You have to add at least one column.')
1542 ) . '\', 1)'
1543 . '">';
1545 $html_output .= PMA_generate_common_hidden_inputs(
1546 $GLOBALS['db'],
1547 $GLOBALS['table']
1549 if ($GLOBALS['cfg']['PropertiesIconic']) {
1550 $html_output .=PMA_Util::getImage(
1551 'b_insrow.png',
1552 __('Add column')
1555 $num_fields = '<input type="text" name="num_fields" size="2" '
1556 . 'maxlength="2" value="1" onfocus="this.select()" />';
1557 $html_output .= sprintf(__('Add %s column(s)'), $num_fields);
1559 // I tried displaying the drop-down inside the label but with Firefox
1560 // the drop-down was blinking
1561 $column_selector = '<select name="after_field" '
1562 . 'onclick="this.form.field_where[2].checked=true" '
1563 . 'onchange="this.form.field_where[2].checked=true">';
1565 foreach ($columns_list as $one_column_name) {
1566 $column_selector .= '<option '
1567 . 'value="' . htmlspecialchars($one_column_name) . '">'
1568 . htmlspecialchars($one_column_name)
1569 . '</option>';
1571 $column_selector .= '</select>';
1573 $choices = array(
1574 'last' => __('At End of Table'),
1575 'first' => __('At Beginning of Table'),
1576 'after' => sprintf(__('After %s'), '')
1578 $html_output .= PMA_Util::getRadioFields(
1579 'field_where', $choices, 'last', false
1581 $html_output .= $column_selector;
1582 $html_output .= '<input type="submit" value="' . __('Go') . '" />'
1583 . '</form>';
1585 return $html_output;
1589 * Get HTML snippet for table rows in the Information ->Space usage table
1591 * @param boolean $odd_row whether current row is odd or even
1592 * @param string $name type of usage
1593 * @param string $value value of usage
1594 * @param string $unit unit
1596 * @return string $html_output
1598 function PMA_getHtmlForSpaceUsageTableRow($odd_row, $name, $value, $unit)
1600 $html_output = '<tr class="' . (($odd_row = !$odd_row) ? 'odd' : 'even') . '">';
1601 $html_output .= '<th class="name">' . $name . '</th>';
1602 $html_output .= '<td class="value">' . $value . '</td>';
1603 $html_output .= '<td class="unit">' . $unit . '</td>';
1604 $html_output .= '</tr>';
1606 return $html_output;
1610 * Get HTML for Optimize link if overhead in Information fieldset
1612 * @param type $url_query URL query
1614 * @return string $html_output
1616 function PMA_getHtmlForOptimizeLink($url_query)
1618 $html_output = '<tr class="tblFooters">';
1619 $html_output .= '<td colspan="3" class="center">';
1620 $html_output .= '<a href="sql.php?' . $url_query
1621 . '&pos=0&amp;sql_query=' . urlencode(
1622 'OPTIMIZE TABLE ' . PMA_Util::backquote($GLOBALS['table'])
1624 . '">'
1625 . PMA_Util::getIcon('b_tbloptimize.png', __('Optimize table'))
1626 . '</a>';
1627 $html_output .= '</td>';
1628 $html_output .= '</tr>';
1630 return $html_output;
1634 * Get HTML for 'Row statistics' table row
1636 * @param type $odd_row whether current row is odd or even
1637 * @param type $name statement name
1638 * @param type $value value
1640 * @return string $html_output
1642 function PMA_getHtmlForRowStatsTableRow($odd_row, $name, $value)
1644 $html_output = '<tr class="' . (($odd_row = !$odd_row) ? 'odd' : 'even') . '">';
1645 $html_output .= '<th class="name">' . $name . '</th>';
1646 $html_output .= '<td class="value">' . $value . '</td>';
1647 $html_output .= '</tr>';
1649 return $html_output;
1653 * Get HTML snippet for display Row statistics table
1655 * @param array $showtable show table array
1656 * @param string $tbl_collation table collation
1657 * @param boolean $is_innodb whether table is innob or not
1658 * @param boolean $mergetable Checks if current table is a merge table
1659 * @param integer $avg_size average size
1660 * @param string $avg_unit average unit
1662 * @return string $html_output
1664 function getHtmlForRowStatsTable($showtable, $tbl_collation,
1665 $is_innodb, $mergetable, $avg_size, $avg_unit
1667 $odd_row = false;
1668 $html_output = '<table id="tablerowstats" class="data">';
1669 $html_output .= '<caption class="tblHeaders">'
1670 . __('Row statistics') . '</caption>';
1671 $html_output .= '<tbody>';
1673 if (isset($showtable['Row_format'])) {
1674 if ($showtable['Row_format'] == 'Fixed') {
1675 $value = __('static');
1676 } elseif ($showtable['Row_format'] == 'Dynamic') {
1677 $value = __('dynamic');
1678 } else {
1679 $value = $showtable['Row_format'];
1681 $html_output .= PMA_getHtmlForRowStatsTableRow(
1682 $odd_row, __('Format'), $value
1684 $odd_row = !$odd_row;
1686 if (! empty($showtable['Create_options'])) {
1687 if ($showtable['Create_options'] == 'partitioned') {
1688 $value = __('partitioned');
1689 } else {
1690 $value = $showtable['Create_options'];
1692 $html_output .= PMA_getHtmlForRowStatsTableRow(
1693 $odd_row, __('Options'), $value
1695 $odd_row = !$odd_row;
1697 if (!empty($tbl_collation)) {
1698 $value = '<dfn title="' . PMA_getCollationDescr($tbl_collation) . '">'
1699 . $tbl_collation . '</dfn>';
1700 $html_output .= PMA_getHtmlForRowStatsTableRow(
1701 $odd_row, __('Collation'), $value
1703 $odd_row = !$odd_row;
1705 if (!$is_innodb && isset($showtable['Rows'])) {
1706 $html_output .= PMA_getHtmlForRowStatsTableRow(
1707 $odd_row,
1708 __('Rows'),
1709 PMA_Util::formatNumber($showtable['Rows'], 0)
1711 $odd_row = !$odd_row;
1713 if (!$is_innodb
1714 && isset($showtable['Avg_row_length'])
1715 && $showtable['Avg_row_length'] > 0
1717 list($avg_row_length_value, $avg_row_length_unit)
1718 = PMA_Util::formatByteDown(
1719 $showtable['Avg_row_length'],
1723 $html_output .= PMA_getHtmlForRowStatsTableRow(
1724 $odd_row,
1725 __('Row length'),
1726 ($avg_row_length_value . ' ' . $avg_row_length_unit)
1728 unset($avg_row_length_value, $avg_row_length_unit);
1729 $odd_row = !$odd_row;
1731 if (!$is_innodb
1732 && isset($showtable['Data_length'])
1733 && $showtable['Rows'] > 0
1734 && $mergetable == false
1736 $html_output .= PMA_getHtmlForRowStatsTableRow(
1737 $odd_row,
1738 __('Row size'),
1739 ($avg_size . ' ' . $avg_unit)
1741 $odd_row = !$odd_row;
1743 if (isset($showtable['Auto_increment'])) {
1744 $html_output .= PMA_getHtmlForRowStatsTableRow(
1745 $odd_row,
1746 __('Next autoindex'),
1747 PMA_Util::formatNumber($showtable['Auto_increment'], 0)
1749 $odd_row = !$odd_row;
1751 if (isset($showtable['Create_time'])) {
1752 $html_output .= PMA_getHtmlForRowStatsTableRow(
1753 $odd_row,
1754 __('Creation'),
1755 PMA_Util::localisedDate(strtotime($showtable['Create_time']))
1757 $odd_row = !$odd_row;
1759 if (isset($showtable['Update_time'])) {
1760 $html_output .= PMA_getHtmlForRowStatsTableRow(
1761 $odd_row,
1762 __('Last update'),
1763 PMA_Util::localisedDate(strtotime($showtable['Update_time']))
1765 $odd_row = !$odd_row;
1767 if (isset($showtable['Check_time'])) {
1768 $html_output .= PMA_getHtmlForRowStatsTableRow(
1769 $odd_row,
1770 __('Last check'),
1771 PMA_Util::localisedDate(strtotime($showtable['Check_time']))
1774 $html_output .= '</tbody>'
1775 . '</table>'
1776 . '</fieldset>'
1777 . '</div>';
1779 return $html_output;
1783 * Get HTML snippet for action row in structure table,
1784 * This function returns common HTML <td> for Primary, Unique, Index,
1785 * Spatial actions
1787 * @param array $type column type
1788 * @param array $tbl_storage_engine table storage engine
1789 * @param string $class class attribute for <td>
1790 * @param boolean $hasField has field
1791 * @param boolean $hasLinkClass has <a> the class attribute
1792 * @param string $url_query url query
1793 * @param boolean $primary primary if set, false otherwise
1794 * @param string $syntax Sql syntax
1795 * @param string $message message to show
1796 * @param string $action action
1797 * @param array $titles titles array
1798 * @param array $row current row
1799 * @param boolean $isPrimary is primary action
1801 * @return array $html_output, $action_enabled
1803 function PMA_getHtmlForActionRowInStructureTable($type, $tbl_storage_engine,
1804 $class, $hasField, $hasLinkClass, $url_query, $primary, $syntax,
1805 $message, $action, $titles, $row, $isPrimary
1807 $html_output = '<li class="'. $class .'">';
1809 if ($type == 'text'
1810 || $type == 'blob'
1811 || 'ARCHIVE' == $tbl_storage_engine
1812 || $hasField
1814 $html_output .= $titles['No' . $action];
1815 $action_enabled = false;
1816 } else {
1817 $html_output .= '<a rel="samepage" '
1818 . ($hasLinkClass ? 'class="ajax add_primary_key_anchor" ' : '')
1819 . 'href="sql.php?' . $url_query . '&amp;sql_query='
1820 . urlencode(
1821 'ALTER TABLE ' . PMA_Util::backquote($GLOBALS['table'])
1822 . ($isPrimary ? ($primary ? ' DROP PRIMARY KEY,' : '') : '')
1823 . ' ' . $syntax . '('
1824 . PMA_Util::backquote($row['Field']) . ');'
1826 . '&amp;message_to_show=' . urlencode(
1827 sprintf(
1828 $message,
1829 htmlspecialchars($row['Field'])
1831 ) . '" >'
1832 . $titles[$action] . '</a>';
1833 $action_enabled = true;
1835 $html_output .= '</li>';
1837 return array($html_output, $action_enabled);
1841 * Get HTML for fulltext action,
1842 * and this function returns $fulltext_enabled boolean value also
1844 * @param string $tbl_storage_engine table storage engine
1845 * @param string $type column type
1846 * @param string $url_query url query
1847 * @param array $row current row
1848 * @param array $titles titles array
1850 * @return type array $html_output, $fulltext_enabled
1852 function PMA_getHtmlForFullTextAction($tbl_storage_engine, $type, $url_query,
1853 $row, $titles
1855 $html_output = '<li class="fulltext nowrap">';
1856 if (! empty($tbl_storage_engine)
1857 && ($tbl_storage_engine == 'MYISAM'
1858 || $tbl_storage_engine == 'ARIA'
1859 || $tbl_storage_engine == 'MARIA'
1860 || ($tbl_storage_engine == 'INNODB' && PMA_MYSQL_INT_VERSION >= 50604))
1861 && (strpos(' ' . $type, 'text') || strpos(' ' . $type, 'char'))
1863 $html_output .= '<a rel="samepage" href="sql.php?' . $url_query . '&amp;sql_query='
1864 . urlencode(
1865 'ALTER TABLE ' . PMA_Util::backquote($GLOBALS['table'])
1866 . ' ADD FULLTEXT(' . PMA_Util::backquote($row['Field'])
1867 . ');'
1869 . '&amp;message_to_show='
1870 . urlencode(
1871 sprintf(
1872 __('An index has been added on %s'),
1873 htmlspecialchars($row['Field'])
1876 . '">';
1877 $html_output .= $titles['IdxFulltext'] . '</a>';
1878 $fulltext_enabled = true;
1879 } else {
1880 $html_output .= $titles['NoIdxFulltext'];
1881 $fulltext_enabled = false;
1883 $html_output .= '</li>';
1884 return array($html_output, $fulltext_enabled);
1888 * Get HTML snippet for "Distinc Value" action
1890 * @param string $url_query url query
1891 * @param array $row current row
1892 * @param array $titles titles array
1894 * @return string $html_output
1896 function PMA_getHtmlForDistinctValueAction($url_query, $row, $titles)
1898 $html_output = '<li class="browse nowrap">';
1899 $html_output .= '<a href="sql.php?' . $url_query . '&amp;sql_query='
1900 . urlencode(
1901 'SELECT COUNT(*) AS ' . PMA_Util::backquote(__('Rows'))
1902 . ', ' . PMA_Util::backquote($row['Field'])
1903 . ' FROM ' . PMA_Util::backquote($GLOBALS['table'])
1904 . ' GROUP BY ' . PMA_Util::backquote($row['Field'])
1905 . ' ORDER BY ' . PMA_Util::backquote($row['Field'])
1907 . '">'
1908 . $titles['DistinctValues']
1909 . '</a>';
1910 $html_output .= '</li>';
1912 return $html_output;
1916 * Get HTML snippet for Actions in table structure
1918 * @param string $type column type
1919 * @param string $tbl_storage_engine table storage engine
1920 * @param boolean $primary primary if set, false otherwise
1921 * @param string $field_name column name
1922 * @param string $url_query url query
1923 * @param array $titles titles array
1924 * @param array $row current row
1925 * @param string $rownum row number
1926 * @param array $hidden_titles hidden titles
1927 * @param array $columns_with_unique_index columns with unique index
1929 * @return string $html_output;
1931 function PMA_getHtmlForActionsInTableStructure($type, $tbl_storage_engine,
1932 $primary, $field_name, $url_query, $titles, $row, $rownum, $hidden_titles,
1933 $columns_with_unique_index
1935 $html_output = '<td><ul class="table-structure-actions resizable-menu">';
1936 list($primary, $primary_enabled)
1937 = PMA_getHtmlForActionRowInStructureTable(
1938 $type, $tbl_storage_engine,
1939 'primary nowrap',
1940 ($primary && $primary->hasColumn($field_name)),
1941 true, $url_query, $primary,
1942 'ADD PRIMARY KEY',
1943 __('A primary key has been added on %s'),
1944 'Primary', $titles, $row, true
1946 $html_output .= $primary;
1947 list($unique, $unique_enabled)
1948 = PMA_getHtmlForActionRowInStructureTable(
1949 $type, $tbl_storage_engine,
1950 'unique nowrap',
1951 isset($columns_with_unique_index[$field_name]),
1952 false, $url_query, $primary, 'ADD UNIQUE',
1953 __('An index has been added on %s'),
1954 'Unique', $titles, $row, false
1956 $html_output .= $unique;
1957 list($index, $index_enabled)
1958 = PMA_getHtmlForActionRowInStructureTable(
1959 $type, $tbl_storage_engine,
1960 'index nowrap', false, false, $url_query,
1961 $primary, 'ADD INDEX', __('An index has been added on %s'),
1962 'Index', $titles, $row, false
1964 $html_output .= $index;
1965 if (!PMA_DRIZZLE) {
1966 $spatial_types = array(
1967 'geometry', 'point', 'linestring', 'polygon', 'multipoint',
1968 'multilinestring', 'multipolygon', 'geomtrycollection'
1970 list($spatial, $spatial_enabled)
1971 = PMA_getHtmlForActionRowInStructureTable(
1972 $type, $tbl_storage_engine,
1973 'spatial nowrap',
1974 (! in_array($type, $spatial_types)
1975 || 'MYISAM' != $tbl_storage_engine
1977 false, $url_query, $primary, 'ADD SPATIAL',
1978 __('An index has been added on %s'), 'Spatial',
1979 $titles, $row, false
1981 $html_output .= $spatial;
1983 // FULLTEXT is possible on TEXT, CHAR and VARCHAR
1984 list ($fulltext, $fulltext_enabled) = PMA_getHtmlForFullTextAction(
1985 $tbl_storage_engine, $type, $url_query, $row, $titles
1987 $html_output .= $fulltext;
1989 $html_output .= PMA_getHtmlForDistinctValueAction($url_query, $row, $titles);
1990 $html_output .= '</ul></td>';
1991 return $html_output;
1995 * Get hidden action titles (image and string)
1997 * @return array $hidden_titles
1999 function PMA_getHiddenTitlesArray()
2001 $hidden_titles = array();
2002 $hidden_titles['DistinctValues'] = PMA_Util::getIcon(
2003 'b_browse.png', __('Distinct values'), true
2005 $hidden_titles['Primary'] = PMA_Util::getIcon(
2006 'b_primary.png', __('Add primary key'), true
2008 $hidden_titles['NoPrimary'] = PMA_Util::getIcon(
2009 'bd_primary.png', __('Add primary key'), true
2011 $hidden_titles['Index'] = PMA_Util::getIcon(
2012 'b_index.png', __('Add index'), true
2014 $hidden_titles['NoIndex'] = PMA_Util::getIcon(
2015 'bd_index.png', __('Add index'), true
2017 $hidden_titles['Unique'] = PMA_Util::getIcon(
2018 'b_unique.png', __('Add unique index'), true
2020 $hidden_titles['NoUnique'] = PMA_Util::getIcon(
2021 'bd_unique.png', __('Add unique index'), true
2023 $hidden_titles['Spatial'] = PMA_Util::getIcon(
2024 'b_spatial.png', __('Add SPATIAL index'), true
2026 $hidden_titles['NoSpatial'] = PMA_Util::getIcon(
2027 'bd_spatial.png', __('Add SPATIAL index'), true
2029 $hidden_titles['IdxFulltext'] = PMA_Util::getIcon(
2030 'b_ftext.png', __('Add FULLTEXT index'), true
2032 $hidden_titles['NoIdxFulltext'] = PMA_Util::getIcon(
2033 'bd_ftext.png', __('Add FULLTEXT index'), true
2036 return $hidden_titles;
2040 * Get action titles (image or string array
2042 * @return array $titles
2044 function PMA_getActionTitlesArray()
2046 $titles = array();
2047 $titles['Change']
2048 = PMA_Util::getIcon('b_edit.png', __('Change'));
2049 $titles['Drop']
2050 = PMA_Util::getIcon('b_drop.png', __('Drop'));
2051 $titles['NoDrop']
2052 = PMA_Util::getIcon('b_drop.png', __('Drop'));
2053 $titles['Primary']
2054 = PMA_Util::getIcon('b_primary.png', __('Primary'));
2055 $titles['Index']
2056 = PMA_Util::getIcon('b_index.png', __('Index'));
2057 $titles['Unique']
2058 = PMA_Util::getIcon('b_unique.png', __('Unique'));
2059 $titles['Spatial']
2060 = PMA_Util::getIcon('b_spatial.png', __('Spatial'));
2061 $titles['IdxFulltext']
2062 = PMA_Util::getIcon('b_ftext.png', __('Fulltext'));
2063 $titles['NoPrimary']
2064 = PMA_Util::getIcon('bd_primary.png', __('Primary'));
2065 $titles['NoIndex']
2066 = PMA_Util::getIcon('bd_index.png', __('Index'));
2067 $titles['NoUnique']
2068 = PMA_Util::getIcon('bd_unique.png', __('Unique'));
2069 $titles['NoSpatial']
2070 = PMA_Util::getIcon('bd_spatial.png', __('Spatial'));
2071 $titles['NoIdxFulltext']
2072 = PMA_Util::getIcon('bd_ftext.png', __('Fulltext'));
2073 $titles['DistinctValues']
2074 = PMA_Util::getIcon('b_browse.png', __('Distinct values'));
2076 return $titles;
2080 * Get HTML snippet for display table statistics
2082 * @param array $showtable full table status info
2083 * @param integer $table_info_num_rows table info number of rows
2084 * @param boolean $tbl_is_view whether table is view or not
2085 * @param boolean $db_is_information_schema whether db is information schema or not
2086 * @param string $tbl_storage_engine table storage engine
2087 * @param string $url_query url query
2088 * @param string $tbl_collation table collation
2090 * @return string $html_output
2092 function PMA_getHtmlForDisplayTableStats($showtable, $table_info_num_rows,
2093 $tbl_is_view, $db_is_information_schema, $tbl_storage_engine, $url_query,
2094 $tbl_collation
2096 $html_output = '<div id="tablestatistics">';
2097 if (empty($showtable)) {
2098 $showtable = PMA_Table::sGetStatusInfo(
2099 $GLOBALS['db'], $GLOBALS['table'], null, true
2103 $nonisam = false;
2104 $is_innodb = (isset($showtable['Type']) && $showtable['Type'] == 'InnoDB');
2105 if (isset($showtable['Type'])
2106 && ! preg_match('@ISAM|HEAP@i', $showtable['Type'])
2108 $nonisam = true;
2111 // Gets some sizes
2113 $mergetable = PMA_Table::isMerge($GLOBALS['db'], $GLOBALS['table']);
2115 // this is to display for example 261.2 MiB instead of 268k KiB
2116 $max_digits = 3;
2117 $decimals = 1;
2118 list($data_size, $data_unit) = PMA_Util::formatByteDown(
2119 $showtable['Data_length'], $max_digits, $decimals
2121 if ($mergetable == false) {
2122 list($index_size, $index_unit) = PMA_Util::formatByteDown(
2123 $showtable['Index_length'], $max_digits, $decimals
2126 // InnoDB returns a huge value in Data_free, do not use it
2127 if (! $is_innodb
2128 && isset($showtable['Data_free'])
2129 && $showtable['Data_free'] > 0
2131 list($free_size, $free_unit) = PMA_Util::formatByteDown(
2132 $showtable['Data_free'], $max_digits, $decimals
2134 list($effect_size, $effect_unit) = PMA_Util::formatByteDown(
2135 $showtable['Data_length'] + $showtable['Index_length'] - $showtable['Data_free'],
2136 $max_digits, $decimals
2138 } else {
2139 list($effect_size, $effect_unit) = PMA_Util::formatByteDown(
2140 $showtable['Data_length'] + $showtable['Index_length'],
2141 $max_digits, $decimals
2144 list($tot_size, $tot_unit) = PMA_Util::formatByteDown(
2145 $showtable['Data_length'] + $showtable['Index_length'],
2146 $max_digits, $decimals
2148 if ($table_info_num_rows > 0) {
2149 list($avg_size, $avg_unit) = PMA_Util::formatByteDown(
2150 ($showtable['Data_length'] + $showtable['Index_length']) / $showtable['Rows'],
2151 6, 1
2155 // Displays them
2156 $odd_row = false;
2158 $html_output .= '<fieldset>'
2159 . '<legend>' . __('Information') . '</legend>'
2160 . '<a id="showusage"></a>';
2162 if (! $tbl_is_view && ! $db_is_information_schema) {
2163 $html_output .= '<table id="tablespaceusage" class="data">'
2164 . '<caption class="tblHeaders">' . __('Space usage') . '</caption>'
2165 . '<tbody>';
2167 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2168 $odd_row, __('Data'), $data_size, $data_unit
2170 $odd_row = !$odd_row;
2172 if (isset($index_size)) {
2173 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2174 $odd_row, __('Index'), $index_size, $index_unit
2176 $odd_row = !$odd_row;
2179 if (isset($free_size)) {
2180 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2181 $odd_row, __('Overhead'), $free_size, $free_unit
2183 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2184 $odd_row, __('Effective'), $effect_size, $effect_unit
2186 $odd_row = !$odd_row;
2188 if (isset($tot_size) && $mergetable == false) {
2189 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2190 $odd_row, __('Total'), $tot_size, $tot_unit
2192 $odd_row = !$odd_row;
2194 // Optimize link if overhead
2195 if (isset($free_size) && !PMA_DRIZZLE
2196 && ($tbl_storage_engine == 'MYISAM'
2197 || $tbl_storage_engine == 'ARIA'
2198 || $tbl_storage_engine == 'MARIA'
2199 || $tbl_storage_engine == 'BDB')
2201 $html_output .= PMA_getHtmlForOptimizeLink($url_query);
2203 $html_output .= '</tbody>'
2204 . '</table>';
2207 $html_output .= getHtmlForRowStatsTable(
2208 $showtable, $tbl_collation,
2209 $is_innodb, $mergetable,
2210 (isset ($avg_size) ? $avg_size : ''),
2211 (isset ($avg_unit) ? $avg_unit : '')
2214 return $html_output;
2218 * Displays HTML for changing one or more columns
2220 * @param string $db database name
2221 * @param string $table table name
2222 * @param array $selected the selected columns
2223 * @param string $action target script to call
2225 * @return boolean $regenerate true if error occurred
2228 function PMA_displayHtmlForColumnChange($db, $table, $selected, $action)
2230 // $selected comes from multi_submits.inc.php
2231 if (empty($selected)) {
2232 $selected[] = $_REQUEST['field'];
2233 $selected_cnt = 1;
2234 } else { // from a multiple submit
2235 $selected_cnt = count($selected);
2239 * @todo optimize in case of multiple fields to modify
2241 for ($i = 0; $i < $selected_cnt; $i++) {
2242 $fields_meta[] = PMA_DBI_get_columns($db, $table, $selected[$i], true);
2244 $num_fields = count($fields_meta);
2245 // set these globals because tbl_columns_definition_form.inc.php
2246 // verifies them
2247 // @todo: refactor tbl_columns_definition_form.inc.php so that it uses
2248 // function params
2249 $GLOBALS['action'] = 'tbl_structure.php';
2250 $GLOBALS['num_fields'] = $num_fields;
2252 // Get more complete field information.
2253 // For now, this is done to obtain MySQL 4.1.2+ new TIMESTAMP options
2254 // and to know when there is an empty DEFAULT value.
2255 // Later, if the analyser returns more information, it
2256 // could be executed to replace the info given by SHOW FULL COLUMNS FROM.
2258 * @todo put this code into a require()
2259 * or maybe make it part of PMA_DBI_get_columns();
2262 // We also need this to correctly learn if a TIMESTAMP is NOT NULL, since
2263 // SHOW FULL COLUMNS says NULL and SHOW CREATE TABLE says NOT NULL (tested
2264 // in MySQL 4.0.25).
2266 $show_create_table = PMA_DBI_fetch_value(
2267 'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table),
2268 0, 1
2270 $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
2271 unset($show_create_table);
2273 * Form for changing properties.
2275 include 'libraries/tbl_columns_definition_form.inc.php';
2280 * Update the table's structure based on $_REQUEST
2282 * @param string $db database name
2283 * @param string $table table name
2285 * @return boolean $regenerate true if error occurred
2288 function PMA_updateColumns($db, $table)
2290 $err_url = 'tbl_structure.php?' . PMA_generate_common_url($db, $table);
2291 $regenerate = false;
2292 $field_cnt = count($_REQUEST['field_name']);
2293 $key_fields = array();
2294 $changes = array();
2296 for ($i = 0; $i < $field_cnt; $i++) {
2297 $changes[] = 'CHANGE ' . PMA_Table::generateAlter(
2298 isset($_REQUEST['field_orig'][$i])
2299 ? $_REQUEST['field_orig'][$i]
2300 : '',
2301 $_REQUEST['field_name'][$i],
2302 $_REQUEST['field_type'][$i],
2303 $_REQUEST['field_length'][$i],
2304 $_REQUEST['field_attribute'][$i],
2305 isset($_REQUEST['field_collation'][$i])
2306 ? $_REQUEST['field_collation'][$i]
2307 : '',
2308 isset($_REQUEST['field_null'][$i])
2309 ? $_REQUEST['field_null'][$i]
2310 : 'NOT NULL',
2311 $_REQUEST['field_default_type'][$i],
2312 $_REQUEST['field_default_value'][$i],
2313 isset($_REQUEST['field_extra'][$i])
2314 ? $_REQUEST['field_extra'][$i]
2315 : false,
2316 isset($_REQUEST['field_comments'][$i])
2317 ? $_REQUEST['field_comments'][$i]
2318 : '',
2319 $key_fields,
2321 isset($_REQUEST['field_move_to'][$i])
2322 ? $_REQUEST['field_move_to'][$i]
2323 : ''
2325 } // end for
2327 // Builds the primary keys statements and updates the table
2328 $key_query = '';
2330 * this is a little bit more complex
2332 * @todo if someone selects A_I when altering a column we need to check:
2333 * - no other column with A_I
2334 * - the column has an index, if not create one
2336 if (count($key_fields)) {
2337 $fields = array();
2338 foreach ($key_fields as $each_field) {
2339 if (isset($_REQUEST['field_name'][$each_field]) && strlen($_REQUEST['field_name'][$each_field])) {
2340 $fields[] = PMA_Util::backquote($_REQUEST['field_name'][$each_field]);
2342 } // end for
2343 $key_query = ', ADD KEY (' . implode(', ', $fields) . ') ';
2347 // To allow replication, we first select the db to use and then run queries
2348 // on this db.
2349 if (! PMA_DBI_select_db($db)) {
2350 PMA_Util::mysqlDie(
2351 PMA_DBI_getError(),
2352 'USE ' . PMA_Util::backquote($db) . ';',
2354 $err_url
2357 $sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ';
2358 $sql_query .= implode(', ', $changes) . $key_query;
2359 $sql_query .= ';';
2360 $result = PMA_DBI_try_query($sql_query);
2362 $response = PMA_Response::getInstance();
2363 if ($result !== false) {
2364 $message = PMA_Message::success(
2365 __('Table %1$s has been altered successfully')
2367 $message->addParam($table);
2370 * If comments were sent, enable relation stuff
2372 include_once 'libraries/transformations.lib.php';
2374 // update field names in relation
2375 if (isset($_REQUEST['field_orig']) && is_array($_REQUEST['field_orig'])) {
2376 foreach ($_REQUEST['field_orig'] as $fieldindex => $fieldcontent) {
2377 if ($_REQUEST['field_name'][$fieldindex] != $fieldcontent) {
2378 PMA_REL_renameField(
2379 $db, $table, $fieldcontent,
2380 $_REQUEST['field_name'][$fieldindex]
2386 // update mime types
2387 if (isset($_REQUEST['field_mimetype'])
2388 && is_array($_REQUEST['field_mimetype'])
2389 && $GLOBALS['cfg']['BrowseMIME']
2391 foreach ($_REQUEST['field_mimetype'] as $fieldindex => $mimetype) {
2392 if (isset($_REQUEST['field_name'][$fieldindex])
2393 && strlen($_REQUEST['field_name'][$fieldindex])
2395 PMA_setMIME(
2396 $db, $table, $_REQUEST['field_name'][$fieldindex],
2397 $mimetype,
2398 $_REQUEST['field_transformation'][$fieldindex],
2399 $_REQUEST['field_transformation_options'][$fieldindex]
2405 $response->addHTML(
2406 PMA_Util::getMessage($message, $sql_query, 'success')
2408 } else {
2409 // An error happened while inserting/updating a table definition
2410 $response->isSuccess(false);
2411 $response->addJSON('message',
2412 PMA_Message::rawError(__('Query error') . ':<br />'.PMA_DBI_getError())
2414 $regenerate = true;
2416 return $regenerate;
2420 * Moves columns in the table's structure based on $_REQUEST
2422 * @param string $db database name
2423 * @param string $table table name
2425 function PMA_moveColumns($db, $table)
2427 PMA_DBI_select_db($db);
2430 * load the definitions for all columns
2432 $columns = PMA_DBI_get_columns_full($db, $table);
2433 $column_names = array_keys($columns);
2434 $changes = array();
2435 $we_dont_change_keys = array();
2437 // move columns from first to last
2438 for ($i = 0, $l = count($_REQUEST['move_columns']); $i < $l; $i++) {
2439 $column = $_REQUEST['move_columns'][$i];
2440 // is this column already correctly placed?
2441 if ($column_names[$i] == $column) {
2442 continue;
2445 // it is not, let's move it to index $i
2446 $data = $columns[$column];
2447 $extracted_columnspec = PMA_Util::extractColumnSpec($data['Type']);
2448 if (isset($data['Extra']) && $data['Extra'] == 'on update CURRENT_TIMESTAMP') {
2449 $extracted_columnspec['attribute'] = $data['Extra'];
2450 unset($data['Extra']);
2452 $current_timestamp = false;
2453 if ($data['Type'] == 'timestamp' && $data['Default'] == 'CURRENT_TIMESTAMP') {
2454 $current_timestamp = true;
2456 $default_type
2457 = $data['Null'] === 'YES' && $data['Default'] === null
2458 ? 'NULL'
2459 : ($current_timestamp
2460 ? 'CURRENT_TIMESTAMP'
2461 : ($data['Default'] == ''
2462 ? 'NONE'
2463 : 'USER_DEFINED'));
2465 $changes[] = 'CHANGE ' . PMA_Table::generateAlter(
2466 $column,
2467 $column,
2468 strtoupper($extracted_columnspec['type']),
2469 $extracted_columnspec['spec_in_brackets'],
2470 $extracted_columnspec['attribute'],
2471 isset($data['Collation']) ? $data['Collation'] : '',
2472 $data['Null'] === 'YES' ? 'NULL' : 'NOT NULL',
2473 $default_type,
2474 $current_timestamp ? '' : $data['Default'],
2475 isset($data['Extra']) && $data['Extra'] !== '' ? $data['Extra'] : false,
2476 isset($data['Comments']) && $data['Comments'] !== ''
2477 ? $data['Comments'] : false,
2478 $we_dont_change_keys,
2480 $i === 0 ? '-first' : $column_names[$i - 1]
2482 // update current column_names array, first delete old position
2483 for ($j = 0, $ll = count($column_names); $j < $ll; $j++) {
2484 if ($column_names[$j] == $column) {
2485 unset($column_names[$j]);
2488 // insert moved column
2489 array_splice($column_names, $i, 0, $column);
2491 $response = PMA_Response::getInstance();
2492 if (empty($changes)) { // should never happen
2493 $response->isSuccess(false);
2494 exit;
2496 $move_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ';
2497 $move_query .= implode(', ', $changes);
2498 // move columns
2499 $result = PMA_DBI_try_query($move_query);
2500 $tmp_error = PMA_DBI_getError();
2501 if ($tmp_error) {
2502 $response->isSuccess(false);
2503 $response->addJSON('message', PMA_Message::error($tmp_error));
2504 } else {
2505 $message = PMA_Message::success(
2506 __('The columns have been moved successfully.')
2508 $response->addJSON('message', $message);
2509 $response->addJSON('columns', $column_names);
2511 exit;