aggregate more index code into PMA_index class

This commit is contained in:
Sebastian Mendel
2008-02-07 14:59:02 +00:00
parent 0988650bb5
commit eb07812dbb
7 changed files with 153 additions and 314 deletions

View File

@@ -290,6 +290,40 @@ class PMA_Index
return $this->_type; return $this->_type;
} }
/**
* Return a list of all index types
*
* @return array index types
*/
static public function getTypes()
{
return array(
'PRIMARY',
'INDEX',
'UNIQUE',
'FULLTEXT',
);
}
public function getTypeSelector()
{
$html_options = '';
foreach (PMA_Index::getTypes() as $each_index_type) {
if ($each_index_type === 'PRIMARY'
&& $this->_name !== 'PRIMARY'
&& PMA_Index::getPrimary($this->_table, $this->_schema)) {
// skip PRIMARY if there is already one in the table
continue;
}
$html_options .= '<option value="' . $each_index_type . '"'
. (($this->_type == $each_index_type) ? ' selected="selected"' : '')
. '>'. $each_index_type . '</option>' . "\n";
}
return $html_options;
}
public function getPacked() public function getPacked()
{ {
return $this->_packed; return $this->_packed;
@@ -364,9 +398,9 @@ class PMA_Index
* @return array Index collection array * @return array Index collection array
* @author Garvin Hicking (pma@supergarv.de) * @author Garvin Hicking (pma@supergarv.de)
*/ */
static public function getView($table, $db, $print_mode = false) static public function getView($table, $schema, $print_mode = false)
{ {
$indexes = PMA_Index::getFromTable($table, $db); $indexes = PMA_Index::getFromTable($table, $schema);
if (count($indexes) < 1) { if (count($indexes) < 1) {
return PMA_Message::warning('strNoIndex')->getDisplay(); return PMA_Message::warning('strNoIndex')->getDisplay();
@@ -459,11 +493,76 @@ class PMA_Index
$r .= '</table>'; $r .= '</table>';
if (! $print_mode) { if (! $print_mode) {
//$r .= PMA_check_indexes($ret_keys); $r .= PMA_Index::findDuplicates($table, $schema);
} }
return $r; return $r;
} }
public function getCompareData()
{
$data = array(
// 'Non_unique' => $this->_non_unique,
'Packed' => $this->_packed,
'Index_type' => $this->_type,
);
foreach ($this->_columns as $column) {
$data['columns'][] = $column->getCompareData();
}
return $data;
}
/**
* Function to check over array of indexes and look for common problems
*
* @uses $GLOBALS['strIndexesSeemEqual']
* @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
*/
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::warning('strIndexesSeemEqual');
$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;
}
} }
class PMA_Index_Column class PMA_Index_Column
@@ -566,5 +665,16 @@ class PMA_Index_Column
{ {
return $this->_sub_part; return $this->_sub_part;
} }
public function getCompareData()
{
return array(
'Column_name' => $this->_name,
'Seq_in_index' => $this->_seq_in_index,
'Collation' => $this->_collation,
'Sub_part' => $this->_sub_part,
'Null' => $this->_null,
);
}
} }
?> ?>

View File

@@ -10,6 +10,7 @@
* *
*/ */
require_once './libraries/Table.class.php'; require_once './libraries/Table.class.php';
require_once './libraries/Index.class.php';
/** /**
* Defines the display mode to use for the results of a SQL query * Defines the display mode to use for the results of a SQL query
@@ -483,40 +484,10 @@ function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $
isset($analyzed_sql[0]['table_ref']) && count($analyzed_sql[0]['table_ref']) == 1) { isset($analyzed_sql[0]['table_ref']) && count($analyzed_sql[0]['table_ref']) == 1) {
// grab indexes data: // grab indexes data:
PMA_DBI_select_db($db); $indexes = PMA_Index::getFromTable($table, $db);
if (!defined('PMA_IDX_INCLUDED')) {
$ret_keys = PMA_get_indexes($table);
}
$prev_index = '';
foreach ($ret_keys as $row) {
if ($row['Key_name'] != $prev_index){
$indexes[] = $row['Key_name'];
$prev_index = $row['Key_name'];
}
$indexes_info[$row['Key_name']]['Sequences'][] = $row['Seq_in_index'];
$indexes_info[$row['Key_name']]['Non_unique'] = $row['Non_unique'];
if (isset($row['Cardinality'])) {
$indexes_info[$row['Key_name']]['Cardinality'] = $row['Cardinality'];
}
// I don't know what does the following column mean....
// $indexes_info[$row['Key_name']]['Packed'] = $row['Packed'];
$indexes_info[$row['Key_name']]['Comment'] = (isset($row['Comment']))
? $row['Comment']
: '';
$indexes_info[$row['Key_name']]['Index_type'] = (isset($row['Index_type']))
? $row['Index_type']
: '';
$indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name'] = $row['Column_name'];
if (isset($row['Sub_part'])) {
$indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part'] = $row['Sub_part'];
}
} // end while
// do we have any index? // do we have any index?
if (isset($indexes_data)) { if ($indexes) {
if ($_SESSION['userconf']['disp_direction'] == 'horizontal' if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
|| $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') { || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
@@ -535,30 +506,28 @@ function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $
} }
echo '<form action="sql.php" method="post">' . "\n"; echo '<form action="sql.php" method="post">' . "\n";
echo PMA_generate_common_hidden_inputs($db, $table, 5); echo PMA_generate_common_hidden_inputs($db, $table);
echo $GLOBALS['strSortByKey'] . ': <select name="sql_query" onchange="this.form.submit();">' . "\n"; echo $GLOBALS['strSortByKey'] . ': <select name="sql_query" onchange="this.form.submit();">' . "\n";
$used_index = false; $used_index = false;
$local_order = (isset($sort_expression) ? $sort_expression : ''); $local_order = (isset($sort_expression) ? $sort_expression : '');
foreach ($indexes_data AS $key => $val) { foreach ($indexes as $index) {
$asc_sort = ''; $asc_sort = '`' . implode('` ASC, `', array_keys($index->getColumns())) . '` ASC';
$desc_sort = ''; $desc_sort = '`' . implode('` DESC, `', array_keys($index->getColumns())) . '` DESC';
foreach ($val AS $key2 => $val2) {
$asc_sort .= PMA_backquote($val2['Column_name']) . ' ASC , ';
$desc_sort .= PMA_backquote($val2['Column_name']) . ' DESC , ';
}
$asc_sort = substr($asc_sort, 0, -3);
$desc_sort = substr($desc_sort, 0, -3);
$used_index = $used_index || $local_order == $asc_sort || $local_order == $desc_sort; $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($key) . ' (' . $GLOBALS['strAscending'] . ')</option>'; echo '<option value="'
echo "\n"; . htmlspecialchars($unsorted_sql_query . ' ORDER BY ' . $asc_sort)
echo '<option value="' . htmlspecialchars($unsorted_sql_query . ' ORDER BY ' . $desc_sort) . '"' . ($local_order == $desc_sort ? ' selected="selected"' : '') . '>' . htmlspecialchars($key) . ' (' . $GLOBALS['strDescending'] . ')</option>'; . '"' . ($local_order == $asc_sort ? ' selected="selected"' : '')
echo "\n"; . '>' . 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 '<option value="' . htmlspecialchars($unsorted_sql_query) . '"' . ($used_index ? '' : ' selected="selected"') . '>' . $GLOBALS['strNone'] . '</option>';
echo "\n";
echo '</select>' . "\n"; echo '</select>' . "\n";
echo '<noscript><input type="submit" value="' . $GLOBALS['strGo'] . '" /></noscript>'; echo '<noscript><input type="submit" value="' . $GLOBALS['strGo'] . '" /></noscript>';
echo "\n";
echo '</form>' . "\n"; echo '</form>' . "\n";
} }
} }

View File

@@ -1,177 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* function library for handling table indexes
*
* @version $Id$
*/
/**
* Return a list of all index types
*
* @access public
* @return array Index types
* @author Garvin Hicking (pma@supergarv.de)
*/
function PMA_get_indextypes()
{
return array(
'PRIMARY',
'INDEX',
'UNIQUE',
'FULLTEXT',
);
}
/**
* Function to get all index information from a certain table
*
* @uses PMA_DBI_fetch_result()
* @uses PMA_backquote()
* @param string $tbl_name Table name to ftech indexes from
* @param string $err_url_0 Error URL
*
* @access public
* @return array Index keys
*/
function PMA_get_indexes($tbl_name, $err_url_0 = '')
{
return PMA_DBI_fetch_result('SHOW KEYS FROM ' . PMA_backquote($tbl_name));
}
/**
* Function to check over array of indexes and look for common problems
*
* @uses $GLOBALS['strIndexesSeemEqual']
* @uses PMA_get_indexes()
* @uses is_string()
* @uses is_array()
* @uses count()
* @uses array_pop()
* @uses reset()
* @uses current()
* @access public
* @param mixed array of indexes from PMA_get_indexes()
* or name of table
* @return string Output HTML
*/
function PMA_check_indexes($idx_collection)
{
if (is_string($idx_collection)) {
$idx_collection = PMA_get_indexes($idx_collection);
}
// count($idx_collection) < 2:
// there is no need to check if there less than two indexes
if (! is_array($idx_collection) || count($idx_collection) < 2) {
return false;
}
$indexes = array();
foreach ($idx_collection as $index_field) {
$indexes[$index_field['Key_name']][$index_field['Column_name']]
= $index_field;
}
$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_name => $each_index) {
if (count($while_index) !== count($each_index)) {
// number of fields are not equal
continue;
}
// compare some key elements of every column in this two indexes
foreach ($each_index as $col_name => $each_index_column) {
if (! isset($while_index[$col_name])
// the position
|| $while_index[$col_name]['Seq_in_index'] !== $each_index_column['Seq_in_index']
// the order, ASC or DESC
|| $while_index[$col_name]['Collation'] !== $each_index_column['Collation']
// the length
|| $while_index[$col_name]['Sub_part'] !== $each_index_column['Sub_part']
// BTREE or HASH
|| $while_index[$col_name]['Index_type'] !== $each_index_column['Index_type']) {
continue 2;
}
}
// did not find any difference
// so it makes no sense to have this two equal indexes
// use first column from index to fetch index name
reset($while_index);
$first_column = current($while_index);
$message = PMA_Message::warning('strIndexesSeemEqual');
$message->addParam($each_index_name);
$message->addParam($first_column['Key_name']);
$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;
}
}
if ($output) {
$output = '<tr><td colspan=7">' . $output . '</td></tr>';
}
return $output;
}
/**
* Loop array of returned index keys and extract key information to
* seperate arrays. Those arrays are passed by reference.
*
* @param array Referenced Array of indexes
* @param array Referenced return array
* @param array Referenced return array
*
* @access public
* @return boolean void
* @author Garvin Hicking (pma@supergarv.de)
*/
function PMA_extract_indexes(&$ret_keys, &$indexes_info, &$indexes_data)
{
if (! is_array($ret_keys)) {
return false;
}
$prev_index = '';
foreach ($ret_keys as $row) {
if ($row['Key_name'] != $prev_index){
$indexes[] = $row['Key_name'];
$prev_index = $row['Key_name'];
}
$indexes_info[$row['Key_name']]['Sequences'][] = $row['Seq_in_index'];
$indexes_info[$row['Key_name']]['Non_unique'] = $row['Non_unique'];
if (isset($row['Cardinality'])) {
$indexes_info[$row['Key_name']]['Cardinality'] = $row['Cardinality'];
}
// I don't know what does following column mean....
// $indexes_info[$row['Key_name']]['Packed'] = $row['Packed'];
$indexes_info[$row['Key_name']]['Comment'] = (isset($row['Comment']))
? $row['Comment']
: '';
$indexes_info[$row['Key_name']]['Index_type'] = (isset($row['Index_type']))
? $row['Index_type']
: '';
$indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name'] = $row['Column_name'];
if (isset($row['Sub_part'])) {
$indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part'] = $row['Sub_part'];
}
} // end while
return true;
}
?>

View File

@@ -186,72 +186,42 @@ function get_script_contr()
} }
/** /**
* @uses $GLOBALS['db'] * @uses get_all_keys()
* @uses $GLOBALS['PMD']
* @uses PMA_DBI_select_db()
* @uses PMA_get_indexes()
* @uses PMA_extract_indexes()
* @uses count()
* @return array unique or primary indizes * @return array unique or primary indizes
*/ */
function get_pk_or_unique_keys() function get_pk_or_unique_keys()
{ {
require_once './libraries/tbl_indexes.lib.php'; return get_all_keys(true);
PMA_DBI_select_db($GLOBALS['db']);
$tables_pk_or_unique_keys = array();
for ($I = 0; $I < count($GLOBALS['PMD']['TABLE_NAME_SMALL']); $I++) {
$ret_keys = PMA_get_indexes($GLOBALS['PMD']['TABLE_NAME_SMALL'][$I]);
if (! empty($ret_keys)) {
// reset those as the function uses them by reference
$indexes_info = $indexes_data = array();
PMA_extract_indexes($ret_keys, $indexes_info, $indexes_data);
// for now, take into account only the first index segment
foreach ($indexes_data as $key_name => $one_index) {
$column_name = $one_index[1]['Column_name'];
if (isset($indexes_info[$key_name])
&& $indexes_info[$key_name]['Non_unique'] == 0) {
$tables_pk_or_unique_keys[$GLOBALS['PMD']['OWNER'][$I] . '.' .$GLOBALS['PMD']['TABLE_NAME_SMALL'][$I] . '.' . $column_name] = 1;
}
}
}
}
return $tables_pk_or_unique_keys;
} }
/** /**
* returns all indizes * returns all indizes
* *
* @uses $GLOBALS['db']
* @uses $GLOBALS['PMD'] * @uses $GLOBALS['PMD']
* @uses PMA_DBI_select_db() * @uses PMA_Index::getFromTable()
* @uses PMA_get_indexes() * @uses PMA_Index->isUnique()
* @uses PMA_extract_indexes() * @uses PMA_Index->getColumns()
* @uses count() * @param boolean whether to include ony unique ones
* @return array indizes * @return array indizes
*/ */
function get_all_keys() function get_all_keys($unique_only = false)
{ {
require_once './libraries/tbl_indexes.lib.php'; require_once './libraries/Index.class.php';
PMA_DBI_select_db($GLOBALS['db']); $keys = array();
$tables_all_keys = array();
foreach ($GLOBALS['PMD']['TABLE_NAME_SMALL'] as $I => $table) {
for ($I = 0; $I < count($GLOBALS['PMD']['TABLE_NAME_SMALL']); $I++) { $schema = $GLOBALS['PMD']['OWNER'][$I];
$ret_keys = PMA_get_indexes($GLOBALS['PMD']['TABLE_NAME_SMALL'][$I]); // for now, take into account only the first index segment
if (! empty($ret_keys)) { foreach (PMA_Index::getFromTable($table, $schema) as $index) {
// reset those as the function uses them by reference if ($unique_only && $index->isUnique()) {
$indexes_info = $indexes_data = array(); $column = key($index->getColumns());
PMA_extract_indexes($ret_keys, $indexes_info, $indexes_data); $keys[$schema . '.' .$table . '.' . $column] = 1;
// for now, take into account only the first index segment
foreach ($indexes_data as $one_index) {
$column_name = $one_index[1]['Column_name'];
$tables_all_keys[$GLOBALS['PMD']['OWNER'][$I] . '.' .$GLOBALS['PMD']['TABLE_NAME_SMALL'][$I] . '.' . $column_name] = 1;
} }
} }
} }
return $tables_all_keys;
return $keys;
} }
/** /**

13
sql.php
View File

@@ -11,7 +11,6 @@
*/ */
require_once './libraries/common.inc.php'; require_once './libraries/common.inc.php';
require_once './libraries/Table.class.php'; require_once './libraries/Table.class.php';
require_once './libraries/tbl_indexes.lib.php';
require_once './libraries/check_user_privileges.lib.php'; require_once './libraries/check_user_privileges.lib.php';
require_once './libraries/bookmark.lib.php'; require_once './libraries/bookmark.lib.php';
@@ -625,16 +624,10 @@ else {
// BEGIN INDEX CHECK See if indexes should be checked. // BEGIN INDEX CHECK See if indexes should be checked.
if (isset($query_type) && $query_type == 'check_tbl' && isset($selected) && is_array($selected)) { if (isset($query_type) && $query_type == 'check_tbl' && isset($selected) && is_array($selected)) {
foreach ($selected as $idx => $tbl_name) { foreach ($selected as $idx => $tbl_name) {
$check = PMA_check_indexes($tbl_name); $check = PMA_Index::findDuplicates($tbl_name, $db);
if (! empty($check)) { if (! empty($check)) {
?> printf($strIndexWarningTable, $tbl_name);
<table border="0" cellpadding="2" cellspacing="0"> echo $check;
<tr>
<td class="tblHeaders" colspan="7"><?php printf($strIndexWarningTable, urldecode($tbl_name)); ?></td>
</tr>
<?php echo $check; ?>
</table>
<?php
} }
} }
} // End INDEX CHECK } // End INDEX CHECK

View File

@@ -10,22 +10,9 @@
* Gets some core libraries * Gets some core libraries
*/ */
require_once './libraries/common.inc.php'; require_once './libraries/common.inc.php';
require_once './libraries/tbl_indexes.lib.php';
require_once './libraries/Index.class.php'; require_once './libraries/Index.class.php';
require_once './libraries/tbl_common.php'; require_once './libraries/tbl_common.php';
/**
* Gets fields and indexes informations
*/
$err_url_0 = 'db_sql.php?' . PMA_generate_common_url($db);
// Gets table keys and store them in arrays
$indexes_info = array();
$indexes_data = array();
$ret_keys = PMA_get_indexes($table, $err_url_0);
PMA_extract_indexes($ret_keys, $indexes_info, $indexes_data);
// Get fields and stores their name/type // Get fields and stores their name/type
$fields = array(); $fields = array();
foreach (PMA_DBI_get_fields($db, $table) as $row) { foreach (PMA_DBI_get_fields($db, $table) as $row) {
@@ -183,19 +170,7 @@ echo (isset($_REQUEST['create_index'])
<div class="formelement"> <div class="formelement">
<label for="select_index_type"><?php echo $strIndexType; ?></label> <label for="select_index_type"><?php echo $strIndexType; ?></label>
<select name="index[Index_type]" id="select_index_type" onchange="return checkIndexName()"> <select name="index[Index_type]" id="select_index_type" onchange="return checkIndexName()">
<?php <?php echo $index->getTypeSelector(); ?>
foreach (PMA_get_indextypes() as $each_index_type) {
if ($each_index_type === 'PRIMARY'
&& $index->getName() !== 'PRIMARY'
&& isset($indexes_info['PRIMARY'])) {
// skip PRIMARY if there is already one in the table
continue;
}
echo '<option value="' . $each_index_type . '"'
. (($index->getType() == $each_index_type) ? ' selected="selected"' : '')
. '>'. $each_index_type . '</option>' . "\n";
}
?>
</select> </select>
<?php echo PMA_showMySQLDocu('SQL-Syntax', 'ALTER_TABLE'); ?> <?php echo PMA_showMySQLDocu('SQL-Syntax', 'ALTER_TABLE'); ?>
</div> </div>

View File

@@ -31,7 +31,6 @@ if (! isset($the_tables) || ! is_array($the_tables)) {
*/ */
require_once './libraries/relation.lib.php'; require_once './libraries/relation.lib.php';
require_once './libraries/transformations.lib.php'; require_once './libraries/transformations.lib.php';
require_once './libraries/tbl_indexes.lib.php';
require_once './libraries/Index.class.php'; require_once './libraries/Index.class.php';
$cfgRelation = PMA_getRelationsParam(); $cfgRelation = PMA_getRelationsParam();