/** * Get HTML for display indexes * * @return string $html_output */ function PMA_getHtmlForDisplayIndexes() { $html_output = PMA_Util::getDivForSliderEffect('indexes', __('Indexes')); $html_output .= PMA_Index::getView($GLOBALS['table'], $GLOBALS['db']); $html_output .= '<fieldset class="tblFooters" style="text-align: left;">' . '<form action="tbl_indexes.php" method="post">'; $html_output .= PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table']) . sprintf(__('Create an index on %s columns'), '<input type="text" size="2" name="added_fields" value="1" />'); $html_output .= '<input type="hidden" name="create_index" value="1" />' . '<input class="add_index ajax"' . ' type="submit" value="' . __('Go') . '" />'; $html_output .= '</form>' . '</fieldset>' . '</div>' . '</div>'; return $html_output; }
/** * Get HTML for display indexes * * @return string $html_output */ function PMA_getHtmlForDisplayIndexes() { $html_output = '<div id="index_div" class="ajax'; if ($GLOBALS['cfg']['InitialSlidersState'] != 'disabled') { $html_output .= ' print_ignore'; } $html_output .= '" >'; $html_output .= PMA_Util::getDivForSliderEffect('indexes', __('Indexes')); $html_output .= PMA_Index::getHtmlForIndexes($GLOBALS['table'], $GLOBALS['db']); $html_output .= '<fieldset class="tblFooters print_ignore" style="text-align: ' . 'left;"><form action="tbl_indexes.php" method="post">'; $html_output .= PMA_URL_getHiddenInputs($GLOBALS['db'], $GLOBALS['table']); $html_output .= sprintf(__('Create an index on %s columns'), '<input type="number" name="added_fields" value="1" ' . 'min="1" required="required" />'); $html_output .= '<input type="hidden" name="create_index" value="1" />' . '<input class="add_index ajax"' . ' type="submit" value="' . __('Go') . '" />'; $html_output .= '</form>' . '</fieldset>' . '</div>' . '</div>'; return $html_output; }
/** * Validate whether the table exists. * * @return void */ protected function validateTableAndLoadFields() { $sql = 'DESCRIBE ' . PMA_Util::backquote($this->tableName); $result = $GLOBALS['dbi']->tryQuery($sql, null, PMA_DatabaseInterface::QUERY_STORE); if (!$result || !$GLOBALS['dbi']->numRows($result)) { $this->showMissingTableError(); } if ($this->showKeys) { $indexes = PMA_Index::getFromTable($this->tableName, $this->db); $all_columns = array(); foreach ($indexes as $index) { $all_columns = array_merge($all_columns, array_flip(array_keys($index->getColumns()))); } $this->fields = array_keys($all_columns); } else { while ($row = $GLOBALS['dbi']->fetchRow($result)) { $this->fields[] = $row[0]; } } }
/** * Prepare unsorted sql query and sort by key drop down * * @param array $analyzed_sql the analyzed query * @param string $sort_expression sort expression * * @return array two element array - $unsorted_sql_query, $drop_down_html * * @access private * * @see _getTableHeaders() */ private function _getUnsortedSqlAndSortByKeyDropDown($analyzed_sql, $sort_expression) { $drop_down_html = ''; // Just as fallback $unsorted_sql_query = $this->__get('sql_query'); if (isset($analyzed_sql[0]['unsorted_query'])) { $unsorted_sql_query = $analyzed_sql[0]['unsorted_query']; } // Handles the case of multiple clicks on a column's header // which would add many spaces before "ORDER BY" in the // generated query. $unsorted_sql_query = trim($unsorted_sql_query); // sorting by indexes, only if it makes sense (only one table ref) if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['querytype']) && $analyzed_sql[0]['querytype'] == self::QUERY_TYPE_SELECT && isset($analyzed_sql[0]['table_ref']) && count($analyzed_sql[0]['table_ref']) == 1) { // grab indexes data: $indexes = PMA_Index::getFromTable($this->__get('table'), $this->__get('db')); // do we have any index? if ($indexes) { $drop_down_html = $this->_getSortByKeyDropDown($indexes, $sort_expression, $unsorted_sql_query); } } return array($unsorted_sql_query, $drop_down_html); }
/** * Displays the headers of the results table * * @uses $_SESSION['tmp_user_values']['disp_direction'] * @uses $_SESSION['tmp_user_values']['repeat_cells'] * @uses $_SESSION['tmp_user_values']['max_rows'] * @uses $_SESSION['tmp_user_values']['display_text'] * @uses $_SESSION['tmp_user_values']['display_binary'] * @uses $_SESSION['tmp_user_values']['display_binary_as_hex'] * @param array which elements to display * @param array the list of fields properties * @param integer the total number of fields returned by the SQL query * @param array the analyzed query * * @return boolean $clause_is_unique * * @global string $db the database name * @global string $table the table name * @global string $goto the URL to go back in case of errors * @global string $sql_query the SQL query * @global integer $num_rows the total number of rows returned by the * SQL query * @global array $vertical_display informations used with vertical display * mode * * @access private * * @see PMA_displayTable() */ function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $analyzed_sql = '', $sort_expression, $sort_expression_nodirection, $sort_direction) { global $db, $table, $goto; global $sql_query, $num_rows; global $vertical_display, $highlight_columns; if ($analyzed_sql == '') { $analyzed_sql = array(); } // can the result be sorted? if ($is_display['sort_lnk'] == '1') { // Just as fallback $unsorted_sql_query = $sql_query; if (isset($analyzed_sql[0]['unsorted_query'])) { $unsorted_sql_query = $analyzed_sql[0]['unsorted_query']; } // Handles the case of multiple clicks on a column's header // which would add many spaces before "ORDER BY" in the // generated query. $unsorted_sql_query = trim($unsorted_sql_query); // sorting by indexes, only if it makes sense (only one table ref) if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['querytype']) && $analyzed_sql[0]['querytype'] == 'SELECT' && isset($analyzed_sql[0]['table_ref']) && count($analyzed_sql[0]['table_ref']) == 1) { // grab indexes data: $indexes = PMA_Index::getFromTable($table, $db); // do we have any index? if ($indexes) { if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { $span = $fields_cnt; if ($is_display['edit_lnk'] != 'nn') { $span++; } if ($is_display['del_lnk'] != 'nn') { $span++; } if ($is_display['del_lnk'] != 'kp' && $is_display['del_lnk'] != 'nn') { $span++; } } else { $span = $num_rows + floor($num_rows / $_SESSION['tmp_user_values']['repeat_cells']) + 1; } echo '<form action="sql.php" method="post">' . "\n"; echo PMA_generate_common_hidden_inputs($db, $table); echo $GLOBALS['strSortByKey'] . ': <select name="sql_query" onchange="this.form.submit();">' . "\n"; $used_index = false; $local_order = isset($sort_expression) ? $sort_expression : ''; foreach ($indexes as $index) { $asc_sort = '`' . implode('` ASC, `', array_keys($index->getColumns())) . '` ASC'; $desc_sort = '`' . implode('` DESC, `', array_keys($index->getColumns())) . '` DESC'; $used_index = $used_index || $local_order == $asc_sort || $local_order == $desc_sort; echo '<option value="' . htmlspecialchars($unsorted_sql_query . ' ORDER BY ' . $asc_sort) . '"' . ($local_order == $asc_sort ? ' selected="selected"' : '') . '>' . htmlspecialchars($index->getName()) . ' (' . $GLOBALS['strAscending'] . ')</option>'; echo '<option value="' . htmlspecialchars($unsorted_sql_query . ' ORDER BY ' . $desc_sort) . '"' . ($local_order == $desc_sort ? ' selected="selected"' : '') . '>' . htmlspecialchars($index->getName()) . ' (' . $GLOBALS['strDescending'] . ')</option>'; } echo '<option value="' . htmlspecialchars($unsorted_sql_query) . '"' . ($used_index ? '' : ' selected="selected"') . '>' . $GLOBALS['strNone'] . '</option>'; echo '</select>' . "\n"; echo '<noscript><input type="submit" value="' . $GLOBALS['strGo'] . '" /></noscript>'; echo '</form>' . "\n"; } } } $vertical_display['emptypre'] = 0; $vertical_display['emptyafter'] = 0; $vertical_display['textbtn'] = ''; // Display options (if we are not in print view) if (!(isset($GLOBALS['printview']) && $GLOBALS['printview'] == '1')) { echo '<form method="post" action="sql.php" name="displayOptionsForm" id="displayOptionsForm">'; $url_params = array('db' => $db, 'table' => $table, 'sql_query' => $sql_query, 'goto' => $goto, 'display_options_form' => 1); echo PMA_generate_common_hidden_inputs($url_params); echo '<br />'; PMA_generate_slider_effect('displayoptions', $GLOBALS['strOptions']); echo '<fieldset>'; echo '<div class="formelement">'; $choices = array('P' => $GLOBALS['strPartialText'], 'F' => $GLOBALS['strFullText']); PMA_display_html_radio('display_text', $choices, $_SESSION['tmp_user_values']['display_text']); echo '</div>'; // prepare full/partial text button or link if ($_SESSION['tmp_user_values']['display_text'] == 'F') { // currently in fulltext mode so show the opposite link $tmp_image_file = $GLOBALS['pmaThemeImage'] . 's_partialtext.png'; $tmp_txt = $GLOBALS['strPartialText']; $url_params['display_text'] = 'P'; } else { $tmp_image_file = $GLOBALS['pmaThemeImage'] . 's_fulltext.png'; $tmp_txt = $GLOBALS['strFullText']; $url_params['display_text'] = 'F'; } $tmp_image = '<img class="fulltext" width="50" height="20" src="' . $tmp_image_file . '" alt="' . $tmp_txt . '" title="' . $tmp_txt . '" />'; $tmp_url = 'sql.php' . PMA_generate_common_url($url_params); $full_or_partial_text_link = PMA_linkOrButton($tmp_url, $tmp_image, array(), false); unset($tmp_image_file, $tmp_txt, $tmp_url, $tmp_image); if ($GLOBALS['cfgRelation']['relwork'] && $GLOBALS['cfgRelation']['displaywork']) { echo '<div class="formelement">'; $choices = array('K' => $GLOBALS['strRelationalKey'], 'D' => $GLOBALS['strRelationalDisplayField']); PMA_display_html_radio('relational_display', $choices, $_SESSION['tmp_user_values']['relational_display']); echo '</div>'; } echo '<div class="formelement">'; PMA_display_html_checkbox('display_binary', $GLOBALS['strShowBinaryContents'], !empty($_SESSION['tmp_user_values']['display_binary']), false); echo '<br />'; PMA_display_html_checkbox('display_blob', $GLOBALS['strShowBLOBContents'], !empty($_SESSION['tmp_user_values']['display_blob']), false); echo '<br />'; PMA_display_html_checkbox('display_binary_as_hex', $GLOBALS['strShowBinaryContentsAsHex'], !empty($_SESSION['tmp_user_values']['display_binary_as_hex']), false); echo '</div>'; // I would have preferred to name this "display_transformation". // This is the only way I found to be able to keep this setting sticky // per SQL query, and at the same time have a default that displays // the transformations. echo '<div class="formelement">'; PMA_display_html_checkbox('hide_transformation', $GLOBALS['strHide'] . ' ' . $GLOBALS['strMIME_transformation'], !empty($_SESSION['tmp_user_values']['hide_transformation']), false); echo '</div>'; echo '<div class="clearfloat"></div>'; echo '</fieldset>'; echo '<fieldset class="tblFooters">'; echo '<input type="submit" value="' . $GLOBALS['strGo'] . '" />'; echo '</fieldset>'; echo '</div>'; echo '</form>'; } // Start of form for multi-rows edit/delete/export if ($is_display['del_lnk'] == 'dr' || $is_display['del_lnk'] == 'kp') { echo '<form method="post" action="tbl_row_action.php" name="rowsDeleteForm" id="rowsDeleteForm">' . "\n"; echo PMA_generate_common_hidden_inputs($db, $table, 1); echo '<input type="hidden" name="goto" value="sql.php" />' . "\n"; } echo '<table id="table_results" class="data">' . "\n"; if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { echo '<thead><tr>' . "\n"; } // 1. Displays the full/partial text button (part 1)... if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { $colspan = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? ' colspan="3"' : ''; } else { $rowspan = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? ' rowspan="3"' : ''; } // ... before the result table if ($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn' && $is_display['text_btn'] == '1') { $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 0; if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { ?> <th colspan="<?php echo $fields_cnt; ?> "></th> </tr> <tr> <?php } else { ?> <tr> <th colspan="<?php echo $num_rows + floor($num_rows / $_SESSION['tmp_user_values']['repeat_cells']) + 1; ?> "></th> </tr> <?php } // end vertical mode } elseif ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && $is_display['text_btn'] == '1') { $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 0; if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { ?> <th <?php echo $colspan; ?> ><?php echo $full_or_partial_text_link; ?> </th> <?php } else { $vertical_display['textbtn'] = ' <th ' . $rowspan . ' valign="middle">' . "\n" . ' ' . "\n" . ' </th>' . "\n"; } // end vertical mode } elseif ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn')) { $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 0; if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { ?> <td<?php echo $colspan; ?> ></td> <?php } else { $vertical_display['textbtn'] = ' <td' . $rowspan . '></td>' . "\n"; } // end vertical mode } // 2. Displays the fields' name // 2.0 If sorting links should be used, checks if the query is a "JOIN" // statement (see 2.1.3) // 2.0.1 Prepare Display column comments if enabled ($GLOBALS['cfg']['ShowBrowseComments']). // Do not show comments, if using horizontalflipped mode, because of space usage if ($GLOBALS['cfg']['ShowBrowseComments'] && $_SESSION['tmp_user_values']['disp_direction'] != 'horizontalflipped') { $comments_map = array(); if (isset($analyzed_sql[0]) && is_array($analyzed_sql[0])) { foreach ($analyzed_sql[0]['table_ref'] as $tbl) { $tb = $tbl['table_true_name']; $comments_map[$tb] = PMA_getComments($db, $tb); unset($tb); } } } if ($GLOBALS['cfgRelation']['commwork'] && $GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME'] && !$_SESSION['tmp_user_values']['hide_transformation']) { require_once './libraries/transformations.lib.php'; $GLOBALS['mime_map'] = PMA_getMIME($db, $table); } if ($is_display['sort_lnk'] == '1') { $select_expr = $analyzed_sql[0]['select_expr_clause']; } // garvin: See if we have to highlight any header fields of a WHERE query. // Uses SQL-Parser results. $highlight_columns = array(); if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['where_clause_identifiers'])) { $wi = 0; if (isset($analyzed_sql[0]['where_clause_identifiers']) && is_array($analyzed_sql[0]['where_clause_identifiers'])) { foreach ($analyzed_sql[0]['where_clause_identifiers'] as $wci_nr => $wci) { $highlight_columns[$wci] = 'true'; } } } for ($i = 0; $i < $fields_cnt; $i++) { // garvin: See if this column should get highlight because it's used in the // where-query. if (isset($highlight_columns[$fields_meta[$i]->name]) || isset($highlight_columns[PMA_backquote($fields_meta[$i]->name)])) { $condition_field = true; } else { $condition_field = false; } // 2.0 Prepare comment-HTML-wrappers for each row, if defined/enabled. if (isset($comments_map) && isset($comments_map[$fields_meta[$i]->table]) && isset($comments_map[$fields_meta[$i]->table][$fields_meta[$i]->name])) { $comments = '<span class="tblcomment">' . htmlspecialchars($comments_map[$fields_meta[$i]->table][$fields_meta[$i]->name]) . '</span>'; } else { $comments = ''; } // 2.1 Results can be sorted if ($is_display['sort_lnk'] == '1') { // 2.1.1 Checks if the table name is required; it's the case // for a query with a "JOIN" statement and if the column // isn't aliased, or in queries like // SELECT `1`.`master_field` , `2`.`master_field` // FROM `PMA_relation` AS `1` , `PMA_relation` AS `2` if (isset($fields_meta[$i]->table) && strlen($fields_meta[$i]->table)) { $sort_tbl = PMA_backquote($fields_meta[$i]->table) . '.'; } else { $sort_tbl = ''; } // 2.1.2 Checks if the current column is used to sort the // results // the orgname member does not exist for all MySQL versions // but if found, it's the one on which to sort $name_to_use_in_sort = $fields_meta[$i]->name; if (isset($fields_meta[$i]->orgname) && strlen($fields_meta[$i]->orgname)) { $name_to_use_in_sort = $fields_meta[$i]->orgname; } // $name_to_use_in_sort might contain a space due to // formatting of function expressions like "COUNT(name )" // so we remove the space in this situation $name_to_use_in_sort = str_replace(' )', ')', $name_to_use_in_sort); if (empty($sort_expression)) { $is_in_sort = false; } else { // Field name may be preceded by a space, or any number // of characters followed by a dot (tablename.fieldname) // so do a direct comparison for the sort expression; // this avoids problems with queries like // "SELECT id, count(id)..." and clicking to sort // on id or on count(id). // Another query to test this: // SELECT p.*, FROM_UNIXTIME(p.temps) FROM mytable AS p // (and try clicking on each column's header twice) if (!empty($sort_tbl) && strpos($sort_expression_nodirection, $sort_tbl) === false && strpos($sort_expression_nodirection, '(') === false) { $sort_expression_nodirection = $sort_tbl . $sort_expression_nodirection; } $is_in_sort = str_replace('`', '', $sort_tbl) . $name_to_use_in_sort == str_replace('`', '', $sort_expression_nodirection) ? true : false; } // 2.1.3 Check the field name for a bracket. // If it contains one, it's probably a function column // like 'COUNT(`field`)' if (strpos($name_to_use_in_sort, '(') !== false) { $sort_order = ' ORDER BY ' . $name_to_use_in_sort . ' '; } else { $sort_order = ' ORDER BY ' . $sort_tbl . PMA_backquote($name_to_use_in_sort) . ' '; } unset($name_to_use_in_sort); // 2.1.4 Do define the sorting URL if (!$is_in_sort) { // loic1: patch #455484 ("Smart" order) $GLOBALS['cfg']['Order'] = strtoupper($GLOBALS['cfg']['Order']); if ($GLOBALS['cfg']['Order'] === 'SMART') { $sort_order .= preg_match('@time|date@i', $fields_meta[$i]->type) ? 'DESC' : 'ASC'; } else { $sort_order .= $GLOBALS['cfg']['Order']; } $order_img = ''; } elseif ('DESC' == $sort_direction) { $sort_order .= ' ASC'; $order_img = ' <img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 's_desc.png" width="11" height="9" alt="' . $GLOBALS['strDescending'] . '" title="' . $GLOBALS['strDescending'] . '" id="soimg' . $i . '" />'; } else { $sort_order .= ' DESC'; $order_img = ' <img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 's_asc.png" width="11" height="9" alt="' . $GLOBALS['strAscending'] . '" title="' . $GLOBALS['strAscending'] . '" id="soimg' . $i . '" />'; } if (preg_match('@(.*)([[:space:]](LIMIT (.*)|PROCEDURE (.*)|FOR UPDATE|LOCK IN SHARE MODE))@i', $unsorted_sql_query, $regs3)) { $sorted_sql_query = $regs3[1] . $sort_order . $regs3[2]; } else { $sorted_sql_query = $unsorted_sql_query . $sort_order; } $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $sorted_sql_query); $order_url = 'sql.php' . PMA_generate_common_url($_url_params); // 2.1.5 Displays the sorting URL // added 20004-06-09: Michael Keck <*****@*****.**> // enable sort order swapping for image $order_link_params = array(); if (isset($order_img) && $order_img != '') { if (strstr($order_img, 'asc')) { $order_link_params['onmouseover'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_desc.png\'; }'; $order_link_params['onmouseout'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_asc.png\'; }'; } elseif (strstr($order_img, 'desc')) { $order_link_params['onmouseover'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_asc.png\'; }'; $order_link_params['onmouseout'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_desc.png\'; }'; } } if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'css') { $order_link_params['style'] = 'direction: ltr; writing-mode: tb-rl;'; } $order_link_params['title'] = $GLOBALS['strSort']; $order_link_content = $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'fake' ? PMA_flipstring(htmlspecialchars($fields_meta[$i]->name), "<br />\n") : htmlspecialchars($fields_meta[$i]->name); $order_link = PMA_linkOrButton($order_url, $order_link_content . $order_img, $order_link_params, false, true); if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { echo '<th'; if ($condition_field) { echo ' class="condition"'; } if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { echo ' valign="bottom"'; } echo '>' . $order_link . $comments . '</th>'; } $vertical_display['desc'][] = ' <th ' . ($condition_field ? ' class="condition"' : '') . '>' . "\n" . $order_link . $comments . ' </th>' . "\n"; } else { if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { echo '<th'; if ($condition_field) { echo ' class="condition"'; } if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { echo ' valign="bottom"'; } if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'css') { echo ' style="direction: ltr; writing-mode: tb-rl;"'; } echo '>'; if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'fake') { echo PMA_flipstring(htmlspecialchars($fields_meta[$i]->name), '<br />'); } else { echo htmlspecialchars($fields_meta[$i]->name); } echo "\n" . $comments . '</th>'; } $vertical_display['desc'][] = ' <th ' . ($condition_field ? ' class="condition"' : '') . '>' . "\n" . ' ' . htmlspecialchars($fields_meta[$i]->name) . "\n" . $comments . ' </th>'; } // end else (2.2) } // end for // 3. Displays the needed checkboxes at the right // column of the result table header if possible and required... if ($GLOBALS['cfg']['ModifyDeleteAtRight'] && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn') && $is_display['text_btn'] == '1') { $vertical_display['emptyafter'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 1; if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { echo "\n"; ?> <th <?php echo $colspan; ?> ><?php echo $full_or_partial_text_link; ?> </th> <?php } else { $vertical_display['textbtn'] = ' <th ' . $rowspan . ' valign="middle">' . "\n" . ' ' . "\n" . ' </th>' . "\n"; } // end vertical mode } elseif ($GLOBALS['cfg']['ModifyDeleteAtRight'] && ($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn') && !$GLOBALS['is_header_sent']) { $vertical_display['emptyafter'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 1; if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { echo "\n"; ?> <td<?php echo $colspan; ?> ></td> <?php } else { $vertical_display['textbtn'] = ' <td' . $rowspan . '></td>' . "\n"; } // end vertical mode } if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { ?> </tr> </thead> <?php } return true; }
/** * Prepare unsorted sql query and sort by key drop down * * @param array $analyzed_sql_results analyzed sql results * @param string $sort_expression sort expression * * @return array two element array - $unsorted_sql_query, $drop_down_html * * @access private * * @see _getTableHeaders() */ private function _getUnsortedSqlAndSortByKeyDropDown($analyzed_sql_results, $sort_expression) { $drop_down_html = ''; $unsorted_sql_query = SqlParser\Utils\Query::replaceClause($analyzed_sql_results['statement'], $analyzed_sql_results['parser']->list, 'ORDER BY', ''); // Data is sorted by indexes only if it there is only one table. if ($this->_isSelect($analyzed_sql_results)) { // grab indexes data: $indexes = PMA_Index::getFromTable($this->__get('table'), $this->__get('db')); // do we have any index? if (!empty($indexes)) { $drop_down_html = $this->_getSortByKeyDropDown($indexes, $sort_expression, $unsorted_sql_query); } } return array($unsorted_sql_query, $drop_down_html); }
*/ $columns = $GLOBALS['dbi']->getColumns($GLOBALS['db'], $GLOBALS['table']); /** * Displays the page */ $response->addHTML('<div id="boxContainer" data-box-width="300">'); /** * Order the table */ $hideOrderTable = false; // `ALTER TABLE ORDER BY` does not make sense for InnoDB tables that contain // a user-defined clustered index (PRIMARY KEY or NOT NULL UNIQUE index). // InnoDB always orders table rows according to such an index if one is present. if ($tbl_storage_engine == 'INNODB') { include_once 'libraries/Index.class.php'; $indexes = PMA_Index::getFromTable($GLOBALS['table'], $GLOBALS['db']); foreach ($indexes as $name => $idx) { if ($name == 'PRIMARY') { $hideOrderTable = true; break; } elseif (!$idx->getNonUnique()) { $notNull = true; foreach ($idx->getColumns() as $column) { if ($column->getNull()) { $notNull = false; break; } } if ($notNull) { $hideOrderTable = true; break;
/** * Get columns with unique index * * @param string $db database name * @param string $table tablename * * @return array $columns_with_unique_index An array of columns with unique index, * with $column name as the array key */ function PMA_getColumnsWithUniqueIndex($db, $table) { $columns_with_unique_index = array(); foreach (PMA_Index::getFromTable($table, $db) as $index) { if ($index->isUnique() && $index->getChoice() == 'UNIQUE') { $columns = $index->getColumns(); foreach ($columns as $column_name => $dummy) { $columns_with_unique_index[$column_name] = 1; } } } return $columns_with_unique_index; }
/** * Function to check over array of indexes and look for common problems * * @uses is_string() * @uses is_array() * @uses count() * @uses array_pop() * @uses reset() * @uses current() * @access public * @param string name of table * @return string Output HTML */ public static function findDuplicates($table, $schema) { $indexes = PMA_Index::getFromTable($table, $schema); $output = ''; // count($indexes) < 2: // there is no need to check if there less than two indexes if (count($indexes) < 2) { return $output; } // remove last index from stack and ... while ($while_index = array_pop($indexes)) { // ... compare with every remaining index in stack foreach ($indexes as $each_index) { if ($each_index->getCompareData() !== $while_index->getCompareData()) { continue; } // did not find any difference // so it makes no sense to have this two equal indexes $message = PMA_Message::error(__('The indexes %1$s and %2$s seem to be equal and one of them could possibly be removed.')); $message->addParam($each_index->getName()); $message->addParam($while_index->getName()); $output .= $message->getDisplay(); // there is no need to check any further indexes if we have already // found that this one has a duplicate continue 2; } } return $output; }
$url_params['goto'] = 'tbl_structure.php'; $url_params['back'] = 'tbl_structure.php'; // Check column names for MySQL reserved words $reserved_word_column_messages = PMA_getReservedWordColumnNameMessages($db, $table); $response->addHTML($reserved_word_column_messages); /** * Prepares the table structure display */ /** * Gets tables informations */ require_once 'libraries/tbl_info.inc.php'; require_once 'libraries/Index.class.php'; // 2. Gets table keys and retains them // @todo should be: $server->db($db)->table($table)->primary() $primary = PMA_Index::getPrimary($table, $db); $columns_with_unique_index = PMA_getColumnsWithUniqueIndex($db, $table); // 3. Get fields $fields = (array) $GLOBALS['dbi']->getColumns($db, $table, null, true); // Get more complete field information // For now, this is done just for MySQL 4.1.2+ new TIMESTAMP options // but later, if the analyser returns more information, it // could be executed for any MySQL version and replace // the info given by SHOW FULL COLUMNS FROM. // // We also need this to correctly learn if a TIMESTAMP is NOT NULL, since // SHOW FULL COLUMNS or INFORMATION_SCHEMA incorrectly says NULL // and SHOW CREATE TABLE says NOT NULL (tested // in MySQL 4.0.25 and 5.0.21, http://bugs.mysql.com/20910). $show_create_table = $GLOBALS['dbi']->fetchValue('SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table), 0, 1); $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
/** * Test for PMA_Index_Column * * @return void */ public function testColumns() { $index = new PMA_Index(); $index->addColumns($this->_params['columns']); $index_columns = $index->getColumns(); $index_column = $index_columns['column1']; $this->assertEquals('column1', $index_column->getName()); $this->assertEquals('index1', $index_column->getSeqInIndex()); $this->assertEquals('Collation1', $index_column->getCollation()); $this->assertEquals('Cardinality1', $index_column->getCardinality()); }
/** * Verify whether the result set contains all the columns * of at least one unique key * * @param string $db database name * @param string $table table name * @param string $fields_meta meta fields * * @return boolean whether the result set contains a unique key */ function PMA_resultSetContainsUniqueKey($db, $table, $fields_meta) { $resultSetColumnNames = array(); foreach ($fields_meta as $oneMeta) { $resultSetColumnNames[] = $oneMeta->name; } foreach (PMA_Index::getFromTable($table, $db) as $index) { if ($index->isUnique()) { $indexColumns = $index->getColumns(); $numberFound = 0; foreach ($indexColumns as $indexColumnName => $dummy) { if (in_array($indexColumnName, $resultSetColumnNames)) { $numberFound++; } } if ($numberFound == count($indexColumns)) { return true; } } } return false; }
/** * Create relevant index statements * * @param array $index an array of index columns * @param string $index_choice index choice that which represents * the index type of $indexed_fields * @param boolean $is_create_tbl true if requirement is to get the statement * for table creation * * @return array an array of sql statements for indexes */ function PMA_buildIndexStatements($index, $index_choice, $is_create_tbl = true) { $statement = array(); if (!count($index)) { return $statement; } $sql_query = PMA_getStatementPrefix($is_create_tbl) . ' ' . $index_choice; if (!empty($index['Key_name']) && $index['Key_name'] != 'PRIMARY') { $sql_query .= ' ' . PMA_Util::backquote($index['Key_name']); } $index_fields = array(); foreach ($index['columns'] as $key => $column) { $index_fields[$key] = PMA_Util::backquote($_REQUEST['field_name'][$column['col_index']]); if ($column['size']) { $index_fields[$key] .= '(' . $column['size'] . ')'; } } // end while $sql_query .= ' (' . implode(', ', $index_fields) . ')'; $keyBlockSizes = $index['Key_block_size']; if (!empty($keyBlockSizes)) { $sql_query .= " KEY_BLOCK_SIZE = " . PMA_Util::sqlAddSlashes($keyBlockSizes); } // specifying index type is allowed only for primary, unique and index only $type = $index['Index_type']; if ($index['Index_choice'] != 'SPATIAL' && $index['Index_choice'] != 'FULLTEXT' && in_array($type, PMA_Index::getIndexTypes())) { $sql_query .= ' USING ' . $type; } $parser = $index['Parser']; if ($index['Index_choice'] == 'FULLTEXT' && !empty($parser)) { $sql_query .= " WITH PARSER " . PMA_Util::sqlAddSlashes($parser); } $comment = $index['Index_comment']; if (!empty($comment)) { $sql_query .= " COMMENT '" . PMA_Util::sqlAddSlashes($comment) . "'"; } $statement[] = $sql_query; return $statement; }
$fields[$row['Field']] = $tmp[1] . '(' . str_replace(',', ', ', $tmp[2]) . ')'; } else { $fields[$row['Field']] = $row['Type']; } } // end while // Prepares the form values if (isset($_REQUEST['index'])) { if (is_array($_REQUEST['index'])) { // coming already from form $index = new PMA_Index($_REQUEST['index']); } else { $index = PMA_Index::singleton($db, $table, $_REQUEST['index']); } } else { $index = new PMA_Index(); } /** * Process the data from the edit/create index form, * run the query to build the new index * and moves back to "tbl_sql.php" */ if (isset($_REQUEST['do_save_data'])) { $error = false; // $sql_query is the one displayed in the query box $sql_query = 'ALTER TABLE ' . PMA_backquote($db) . '.' . PMA_backquote($table); // Drops the old index if (!empty($_REQUEST['old_index'])) { if ($_REQUEST['old_index'] == 'PRIMARY') { $sql_query .= ' DROP PRIMARY KEY,'; } else {
/** * find all the possible partial dependencies based on data in the table. * * @param string $table current table * @param string $db current database * * @return HTML containing the list of all the possible partial dependencies */ function PMA_findPartialDependencies($table, $db) { $dependencyList = array(); $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']); $columns = (array) $GLOBALS['dbi']->getColumnNames($db, $table, $GLOBALS['userlink']); $columns = (array) PMA_Util::backquote($columns); $totalRowsRes = $GLOBALS['dbi']->fetchResult('SELECT COUNT(*) FROM (SELECT * FROM ' . PMA_Util::backquote($table) . ' LIMIT 500) as dt;'); $totalRows = $totalRowsRes[0]; $primary = PMA_Index::getPrimary($table, $db); $primarycols = $primary->getColumns(); $pk = array(); foreach ($primarycols as $col) { $pk[] = PMA_Util::backquote($col->getName()); } $partialKeys = PMA_getAllCombinationPartialKeys($pk); $distinctValCount = PMA_findDistinctValuesCount(array_unique(array_merge($columns, $partialKeys)), $table); foreach ($columns as $column) { if (!in_array($column, $pk)) { foreach ($partialKeys as $partialKey) { if ($partialKey && PMA_checkPartialDependency($partialKey, $column, $table, $distinctValCount[$partialKey], $distinctValCount[$column], $totalRows)) { $dependencyList[$partialKey][] = $column; } } } } $html = __('This list is based on a subset of the table\'s data ' . 'and is not necessarily accurate. ') . '<div class="dependencies_box">'; foreach ($dependencyList as $dependon => $colList) { $html .= '<span class="displayblock">' . '<input type="button" class="pickPd" value="' . __('Pick') . '"/>' . '<span class="determinants">' . htmlspecialchars(str_replace('`', '', $dependon)) . '</span> -> ' . '<span class="dependents">' . htmlspecialchars(str_replace('`', '', implode(', ', $colList))) . '</span>' . '</span>'; } if (empty($dependencyList)) { $html .= '<p class="displayblock desc">' . __('No partial dependencies found!') . '</p>'; } $html .= '</div>'; return $html; }
echo ' </td>' . "\n"; } ?> </tr> <?php } // end foreach ?> </tbody> </table> <?php if (!$tbl_is_view && !PMA_is_system_schema($db)) { /** * Displays indexes */ echo PMA_Index::getView($table, $db, true); /** * Displays Space usage and row statistics * */ if ($cfg['ShowStats']) { $nonisam = false; if (isset($showtable['Type']) && !preg_match('@ISAM|HEAP@i', $showtable['Type'])) { $nonisam = true; } if ($nonisam == false) { // Gets some sizes $mergetable = PMA_Table::isMerge($db, $table); list($data_size, $data_unit) = PMA_formatByteDown($showtable['Data_length']); if ($mergetable == false) { list($index_size, $index_unit) = PMA_formatByteDown($showtable['Index_length']);
$disp_mode = 'nnnn110111'; } if (isset($label)) { $message = PMA_message::success(__('Bookmark %s created')); $message->addParam($label); $message->display(); } PMA_displayTable($result, $disp_mode, $analyzed_sql); PMA_DBI_free_result($result); // BEGIN INDEX CHECK See if indexes should be checked. if (isset($query_type) && $query_type == 'check_tbl' && isset($selected) && is_array($selected)) { foreach ($selected as $idx => $tbl_name) { $check = PMA_Index::findDuplicates($tbl_name, $db); if (! empty($check)) { printf(__('Problems with indexes of table `%s`'), $tbl_name); echo $check; } } } // End INDEX CHECK // Bookmark support if required if ($disp_mode[7] == '1' && (! empty($cfg['Bookmark']) && empty($id_bookmark)) && ! empty($sql_query) ) { echo "\n"; $goto = 'sql.php?'
/** * The "PMA_RT_Table" constructor * * @param string $ The table name * @param integer $ The font size * @param integer $ The max. with among tables * @global object The current PDF document * @global integer The current page number (from the * $cfg['Servers'][$i]['table_coords'] table) * @global array The relations settings * @global string The current db name * @access private * @see PMA_PDF, PMA_RT_Table::PMA_RT_Table_setWidth, PMA_RT_Table::PMA_RT_Table_setHeight */ function __construct($table_name, $ff, &$same_wide_width, $show_keys) { global $pdf, $pdf_page_number, $cfgRelation, $db; $this->table_name = $table_name; $sql = 'DESCRIBE ' . PMA_backquote($table_name); $result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE); if (!$result || !PMA_DBI_num_rows($result)) { $pdf->PMA_PDF_die(sprintf($GLOBALS['strPdfInvalidTblName'], $table_name)); } // load fields //check to see if it will load all fields or only the foreign keys if ($show_keys) { $indexes = PMA_Index::getFromTable($this->table_name, $db); $all_columns = array(); foreach ($indexes as $index) { $all_columns = array_merge($all_columns, array_flip(array_keys($index->getColumns()))); } $this->fields = array_keys($all_columns); } else { while ($row = PMA_DBI_fetch_row($result)) { $this->fields[] = $row[0]; } } // height and width $this->PMA_RT_Table_setWidth($ff); $this->PMA_RT_Table_setHeight(); if ($same_wide_width < $this->width) { $same_wide_width = $this->width; } // x and y $sql = 'SELECT x, y FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'' . ' AND table_name = \'' . PMA_sqlAddslashes($table_name) . '\'' . ' AND pdf_page_number = ' . $pdf_page_number; $result = PMA_query_as_cu($sql, false, PMA_DBI_QUERY_STORE); if (!$result || !PMA_DBI_num_rows($result)) { $pdf->PMA_PDF_die(sprintf($GLOBALS['strConfigureTableCoord'], $table_name)); } list($this->x, $this->y) = PMA_DBI_fetch_row($result); $this->x = (double) $this->x; $this->y = (double) $this->y; // displayfield $this->displayfield = PMA_getDisplayField($db, $table_name); // index $result = PMA_DBI_query('SHOW INDEX FROM ' . PMA_backquote($table_name) . ';', null, PMA_DBI_QUERY_STORE); if (PMA_DBI_num_rows($result) > 0) { while ($row = PMA_DBI_fetch_assoc($result)) { if ($row['Key_name'] == 'PRIMARY') { $this->primary[] = $row['Column_name']; } } } // end if }
/** * The "Table_Stats" constructor * * @param string $tableName The table name * @param integer $fontSize The font size * @param integer $pageNumber The current page number (from the * $cfg['Servers'][$i]['table_coords'] table) * @param integer &$sameWideWidth The max. with among tables * @param boolean $showKeys Whether to display keys or not * @param boolean $showInfo Whether to display table position or not * * @global object The current PDF document * @global array The relations settings * @global string The current db name * * @return void * * @see PMA_Schema_PDF, Table_Stats::Table_Stats_setWidth, * Table_Stats::Table_Stats_setHeight */ function __construct($tableName, $fontSize, $pageNumber, &$sameWideWidth, $showKeys = false, $showInfo = false) { global $pdf, $cfgRelation, $db; $this->_tableName = $tableName; $sql = 'DESCRIBE ' . PMA_backquote($tableName); $result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE); if (!$result || !PMA_DBI_num_rows($result)) { $pdf->Error(sprintf(__('The %s table doesn\'t exist!'), $tableName)); } // load fields //check to see if it will load all fields or only the foreign keys if ($showKeys) { $indexes = PMA_Index::getFromTable($this->_tableName, $db); $all_columns = array(); foreach ($indexes as $index) { $all_columns = array_merge($all_columns, array_flip(array_keys($index->getColumns()))); } $this->fields = array_keys($all_columns); } else { while ($row = PMA_DBI_fetch_row($result)) { $this->fields[] = $row[0]; } } $this->_showInfo = $showInfo; $this->_setHeight(); /* * setWidth must me after setHeight, because title * can include table height which changes table width */ $this->_setWidth($fontSize); if ($sameWideWidth < $this->width) { $sameWideWidth = $this->width; } $sql = 'SELECT x, y FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\'' . ' AND table_name = \'' . PMA_sqlAddSlashes($tableName) . '\'' . ' AND pdf_page_number = ' . $pageNumber; $result = PMA_query_as_controluser($sql, false, PMA_DBI_QUERY_STORE); if (!$result || !PMA_DBI_num_rows($result)) { $pdf->Error(sprintf(__('Please configure the coordinates for table %s'), $tableName)); } list($this->x, $this->y) = PMA_DBI_fetch_row($result); $this->x = (double) $this->x; $this->y = (double) $this->y; /* * displayfield */ $this->displayfield = PMA_getDisplayField($db, $tableName); /* * index */ $result = PMA_DBI_query('SHOW INDEX FROM ' . PMA_backquote($tableName) . ';', null, PMA_DBI_QUERY_STORE); if (PMA_DBI_num_rows($result) > 0) { while ($row = PMA_DBI_fetch_assoc($result)) { if ($row['Key_name'] == 'PRIMARY') { $this->primary[] = $row['Column_name']; } } } }
/** * Get columns with indexes * * @param int $types types bitmask * * @return array an array of columns */ function getColumnsWithIndex($types) { $columns_with_index = array(); foreach (PMA_Index::getFromTableByChoice($this->_name, $this->_db_name, $types) as $index) { $columns = $index->getColumns(); foreach ($columns as $column_name => $dummy) { $columns_with_index[] = $column_name; } } return $columns_with_index; }
/** * If there are more than 20 rows, displays browse/select/insert/empty/drop * links again */ if ($fields_cnt > 20) { require './libraries/tbl_links.inc.php'; } // end if ($fields_cnt > 20) /** * Displays indexes */ if (!$tbl_is_view && !$db_is_information_schema && 'ARCHIVE' != $tbl_type) { /** * Display indexes */ echo PMA_Index::getView($table, $db); ?> <br /> <form action="./tbl_indexes.php" method="post" onsubmit="return checkFormElementInRange(this, 'idx_num_fields', '<?php echo str_replace('\'', '\\\'', $GLOBALS['strInvalidColumnCount']); ?> ', 1)"> <fieldset> <?php echo PMA_generate_common_hidden_inputs($db, $table); echo sprintf($strCreateIndex, '<input type="text" size="2" name="added_fields" value="1" />'); ?> <input type="submit" name="create_index" value="<?php
/** * Returns descriptions of columns in given table (all or given by $column) * * @param string $database name of database * @param string $table name of table to retrieve columns from * @param string $column name of column, null to show all columns * @param boolean $full whether to return full info or only column names * @param mixed $link mysql link resource * * @return array array indexed by column names or, * if $column is given, flat array description */ public function getColumns($database, $table, $column = null, $full = false, $link = null) { $sql = $this->getColumnsSql($database, $table, $column, $full); $fields = $this->fetchResult($sql, 'Field', null, $link); if (!is_array($fields) || count($fields) == 0) { return array(); } // Check if column is a part of multiple-column index and set its 'Key'. $indexes = PMA_Index::getFromTable($table, $database); foreach ($fields as $field => $field_data) { if (!empty($field_data['Key'])) { continue; } foreach ($indexes as $index) { /** @var PMA_Index $index */ if (!$index->hasColumn($field)) { continue; } $index_columns = $index->getColumns(); if ($index_columns[$field]->getSeqInIndex() > 1) { if ($index->isUnique()) { $fields[$field]['Key'] = 'UNI'; } else { $fields[$field]['Key'] = 'MUL'; } } } } if (PMA_DRIZZLE) { // fix Key column, it's much simpler in PHP than in SQL $has_pk = false; $has_pk_candidates = false; foreach ($fields as $f) { if ($f['Key'] == 'PRI') { $has_pk = true; break; } else { if ($f['Null'] == 'NO' && ($f['Key'] == 'MUL' || $f['Key'] == 'UNI')) { $has_pk_candidates = true; } } } if (!$has_pk && $has_pk_candidates) { $secureDatabase = PMA_Util::sqlAddSlashes($database); // check whether we can promote some unique index to PRI $sql = "\n SELECT i.index_name, p.column_name\n FROM data_dictionary.indexes i\n JOIN data_dictionary.index_parts p\n USING (table_schema, table_name)\n WHERE i.table_schema = '" . $secureDatabase . "'\n AND i.table_name = '" . PMA_Util::sqlAddSlashes($table) . "'\n AND i.is_unique\n AND NOT i.is_nullable"; $result = $this->fetchResult($sql, 'index_name', null, $link); $result = $result ? array_shift($result) : array(); foreach ($result as $f) { $fields[$f]['Key'] = 'PRI'; } } } return $column != null ? array_shift($fields) : $fields; }
/** * Returns all indices * * @param bool $unique_only whether to include only unique ones * * @return array indices */ function PMA_getAllKeys($unique_only = false) { include_once './libraries/Index.class.php'; $keys = array(); foreach ($GLOBALS['PMD']['TABLE_NAME_SMALL'] as $I => $table) { $schema = $GLOBALS['PMD']['OWNER'][$I]; // for now, take into account only the first index segment foreach (PMA_Index::getFromTable($table, $schema) as $index) { if ($unique_only && !$index->isUnique()) { continue; } $columns = $index->getColumns(); foreach ($columns as $column_name => $dummy) { $keys[$schema . '.' . $table . '.' . $column_name] = 1; } } } return $keys; }
/** * Function to send html for column dropdown list * * @return void */ function PMA_sendHtmlForColumnDropdownList() { $response = PMA_Response::getInstance(); $foreignTable = $_REQUEST['foreignTable']; $table_obj = new PMA_Table($foreignTable, $_REQUEST['foreignDb']); // Since views do not have keys defined on them provide the full list of columns if (PMA_Table::isView($_REQUEST['foreignDb'], $foreignTable)) { $columnList = $table_obj->getColumns(false, false); } else { $columnList = $table_obj->getIndexedColumns(false, false); } $columns = array(); foreach ($columnList as $column) { $columns[] = htmlspecialchars($column); } $response->addJSON('columns', $columns); // @todo should be: $server->db($db)->table($table)->primary() $primary = PMA_Index::getPrimary($foreignTable, $_REQUEST['foreignDb']); if (false === $primary) { return; } $primarycols = array_keys($primary->getColumns()); $response->addJSON('primary', $primarycols); }
/** * Function to get html to display problems in indexes * * @param string $query_type query type * @param array|null $selectedTables array of table names selected from the * database structure page, for an action * like check table, optimize table, * analyze table or repair table * @param string $db current database * * @return string */ function PMA_getHtmlForIndexesProblems($query_type, $selectedTables, $db) { // BEGIN INDEX CHECK See if indexes should be checked. if (isset($query_type) && $query_type == 'check_tbl' && isset($selectedTables) && is_array($selectedTables)) { $indexes_problems_html = ''; foreach ($selectedTables as $tbl_name) { $check = PMA_Index::findDuplicates($tbl_name, $db); if (!empty($check)) { $indexes_problems_html .= sprintf(__('Problems with indexes of table `%s`'), $tbl_name); $indexes_problems_html .= $check; } } } else { $indexes_problems_html = null; } return $indexes_problems_html; }
/** * Get columns with indexes * * @param string $db database name * @param string $table tablename * @param int $types types bitmask * * @return array an array of columns */ function PMA_getColumnsWithIndex($db, $table, $types) { $columns_with_index = array(); foreach (PMA_Index::getFromTableByChoice($table, $db, $types) as $index) { $columns = $index->getColumns(); foreach ($columns as $column_name => $dummy) { $columns_with_index[$column_name] = 1; } } return array_keys($columns_with_index); }
$response->addHTML('<div id="structure-action-links">'); if ($tbl_is_view) { $response->addHTML(PMA_getHtmlForEditView($url_params)); } $response->addHTML(PMA_getHtmlForOptionalActionLinks($url_query, $tbl_is_view, $db_is_system_schema)); $response->addHTML('</div>'); if (!$tbl_is_view && !$db_is_system_schema) { $response->addHTML('<br />'); $response->addHTML(PMA_getHtmlForAddColumn($columns_list)); } /** * Displays indexes */ if (!$tbl_is_view && !$db_is_system_schema && 'ARCHIVE' != $tbl_storage_engine) { //return the list of index $response->addJSON('indexes_list', PMA_Index::getHtmlForIndexes($GLOBALS['table'], $GLOBALS['db'])); $response->addHTML(PMA_getHtmlForDisplayIndexes()); } /** * Displays Space usage and row statistics */ // BEGIN - Calc Table Space // Get valid statistics whatever is the table type if ($cfg['ShowStats']) { //get table stats in HTML format $tablestats = PMA_getHtmlForDisplayTableStats($showtable, $table_info_num_rows, $tbl_is_view, $db_is_system_schema, $tbl_storage_engine, $url_query, $tbl_collation); //returning the response in JSON format to be used by Ajax $response->addJSON('tableStat', $tablestats); $response->addHTML($tablestats); } // END - Calc Table Space
$fields[$row['Field']] = $tmp[1] . '(' . str_replace(',', ', ', $tmp[2]) . ')'; } else { $fields[$row['Field']] = $row['Type']; } } // end while // Prepares the form values if (isset($_REQUEST['index'])) { if (is_array($_REQUEST['index'])) { // coming already from form $index = new PMA_Index($_REQUEST['index']); } else { $index = PMA_Index::singleton($db, $table, $_REQUEST['index']); } } else { $index = new PMA_Index; } /** * Process the data from the edit/create index form, * run the query to build the new index * and moves back to "tbl_sql.php" */ if (isset($_REQUEST['do_save_data'])) { $error = false; // $sql_query is the one displayed in the query box $sql_query = 'ALTER TABLE ' . PMA_backquote($db) . '.' . PMA_backquote($table); // Drops the old index if (! empty($_REQUEST['old_index'])) {
/** * return html for Table Structure * * @param bool $have_rel whether have relation * @param bool $tbl_is_view Is a table view? * @param array $columns columns list * @param array $analyzed_sql analyzed sql * @param array $res_rel relations array * @param string $db database * @param string $table table * @param array $cfgRelation config from PMA_getRelationsParam * @param array $cfg global config * @param array $showtable showing table information * @param int $cell_align_left cell align left * * @return string */ function PMA_getHtmlForTableStructure($have_rel, $tbl_is_view, $columns, $analyzed_sql, $res_rel, $db, $table, $cfgRelation, $cfg, $showtable, $cell_align_left) { /** * Displays the table structure */ $html = '<table style="width: 100%;">'; $html .= '<thead>'; $html .= '<tr>'; $html .= '<th>' . __('Column') . '</th>'; $html .= '<th>' . __('Type') . '</th>'; $html .= '<th>' . __('Null') . '</th>'; $html .= '<th>' . __('Default') . '</th>'; if ($have_rel) { $html .= '<th>' . __('Links to') . '</th>' . "\n"; } $html .= ' <th>' . __('Comments') . '</th>' . "\n"; if ($cfgRelation['mimework']) { $html .= ' <th>MIME</th>' . "\n"; } $html .= '</tr>'; $html .= '</thead>'; $html .= '<tbody>'; $html .= PMA_getHtmlForPrintViewColumns($tbl_is_view, $columns, $analyzed_sql, $have_rel, $res_rel, $db, $table, $cfgRelation); $html .= '</tbody>'; $html .= '</table>'; if (!$tbl_is_view && !$GLOBALS['dbi']->isSystemSchema($db)) { /** * Displays indexes */ $html .= PMA_Index::getView($table, $db, true); /** * Displays Space usage and row statistics * */ if ($cfg['ShowStats']) { $html .= PMA_getHtmlForSpaceUsageAndRowStatistics($showtable, $db, $table, $cell_align_left); } // end if ($cfg['ShowStats']) } return $html; }
/** * Function to get html for displaying the index form * * @param array $fields fields * @param PMA_Index $index index * @param array $form_params form parameters * @param int $add_fields number of fields in the form * * @return string */ function PMA_getHtmlForIndexForm($fields, $index, $form_params, $add_fields) { $html = ""; $html .= '<form action="tbl_indexes.php" method="post" name="index_frm" id="' . 'index_frm" class="ajax"' . 'onsubmit="if (typeof(this.elements[\'index[Key_name]\'].disabled) !=' . ' \'undefined\') {' . 'this.elements[\'index[Key_name]\'].disabled = false}">'; $html .= PMA_URL_getHiddenInputs($form_params); $html .= '<fieldset id="index_edit_fields">'; $html .= '<div class="index_info">'; $html .= '<div>' . '<div class="label">' . '<strong>' . '<label for="input_index_name">' . __('Index name:') . PMA_Util::showHint(PMA_Message::notice(__('"PRIMARY" <b>must</b> be the name of' . ' and <b>only of</b> a primary key!'))) . '</label>' . '</strong>' . '</div>' . '<input type="text" name="index[Key_name]" id="input_index_name"' . ' size="25"' . 'value="' . htmlspecialchars($index->getName()) . '"' . 'onfocus="this.select()" />' . '</div>'; $html .= '<div>' . '<div class="label">' . '<strong>' . '<label for="input_index_comment">' . __('Comment:') . '</label>' . '</strong>' . '</div>' . '<input type="text" name="index[Index_comment]" ' . 'id="input_index_comment" size="30"' . 'value="' . htmlspecialchars($index->getComment()) . '"' . 'onfocus="this.select()" />' . '</div>'; $html .= '<div>' . '<div class="label">' . '<strong>' . '<label for="select_index_type">' . __('Index type:') . PMA_Util::showMySQLDocu('ALTER_TABLE') . '</label>' . '</strong>' . '</div>' . '<select name="index[Index_type]" id="select_index_type" ' . (isset($_REQUEST['create_edit_table']) ? 'disabled="disabled"' : '') . '>' . $index->generateIndexSelector() . '</select>' . '</div>'; $html .= '<div class="clearfloat"></div>'; $html .= '</div>'; $html .= '<table id="index_columns">'; $html .= '<thead>' . '<tr>' . '<th>' . __('Column') . '</th>' . '<th>' . __('Size') . '</th>' . '</tr>' . '</thead>'; $odd_row = true; $spatial_types = array('geometry', 'point', 'linestring', 'polygon', 'multipoint', 'multilinestring', 'multipolygon', 'geomtrycollection'); $html .= '<tbody>'; /* @var $column PMA_Index_Column */ foreach ($index->getColumns() as $column) { $html .= '<tr class="'; $html .= $odd_row ? 'odd' : 'even'; $html .= 'noclick">'; $html .= '<td><span class="drag_icon" title="' . __('Drag to reorder') . '"' . '></span>'; $html .= '<select name="index[columns][names][]">'; $html .= '<option value="">-- ' . __('Ignore') . ' --</option>'; foreach ($fields as $field_name => $field_type) { if (($index->getType() != 'FULLTEXT' || preg_match('/(char|text)/i', $field_type)) && ($index->getType() != 'SPATIAL' || in_array($field_type, $spatial_types))) { $html .= '<option value="' . htmlspecialchars($field_name) . '"' . ($field_name == $column->getName() ? ' selected="selected"' : '') . '>' . htmlspecialchars($field_name) . ' [' . htmlspecialchars($field_type) . ']' . '</option>' . "\n"; } } // end foreach $fields $html .= '</select>'; $html .= '</td>'; $html .= '<td>'; $html .= '<input type="text" size="5" onfocus="this.select()"' . 'name="index[columns][sub_parts][]" value="'; if ($index->getType() != 'SPATIAL') { $html .= $column->getSubPart(); } $html .= '"/>'; $html .= '</td>'; $html .= '</tr>'; $odd_row = !$odd_row; } // end foreach $edited_index_info['Sequences'] for ($i = 0; $i < $add_fields; $i++) { $html .= '<tr class="'; $html .= $odd_row ? 'odd' : 'even'; $html .= 'noclick">'; $html .= '<td><span class="drag_icon" title="' . __('Drag to reorder') . '"' . '></span>'; $html .= '<select name="index[columns][names][]">'; $html .= '<option value="">-- ' . __('Ignore') . ' --</option>'; $j = 0; foreach ($fields as $field_name => $field_type) { if (isset($_REQUEST['create_edit_table'])) { $col_index = $field_type[1]; $field_type = $field_type[0]; } $html .= '<option value="' . htmlspecialchars(isset($col_index) ? $col_index : $field_name) . '" ' . ($j++ == $i ? 'selected="selected"' : '') . '>' . htmlspecialchars($field_name) . ' [' . htmlspecialchars($field_type) . ']' . '</option>' . "\n"; } // end foreach $fields $html .= '</select>'; $html .= '</td>'; $html .= '<td>' . '<input type="text" size="5" onfocus="this.select()"' . 'name="index[columns][sub_parts][]" value="" />' . '</td>'; $html .= '</tr>'; $odd_row = !$odd_row; } // end foreach $edited_index_info['Sequences'] $html .= '</tbody>'; $html .= '</table>'; $html .= '</fieldset>'; $html .= '<fieldset class="tblFooters">'; $btn_value = sprintf(__('Add %s column(s) to index'), 1); $html .= '<div class="slider"></div>'; $html .= '<div class="add_fields">'; $html .= '<input type="submit" value="' . $btn_value . '" />'; $html .= '</div>'; $html .= '</fieldset>'; $html .= '</form>'; return $html; }