diff --git a/ChangeLog b/ChangeLog index 23fd898e05..6b1c357026 100644 --- a/ChangeLog +++ b/ChangeLog @@ -50,6 +50,7 @@ phpMyAdmin - ChangeLog - bug #4352 Settings > Manage: incorrect messages - bug #4337 "More" in Actions area doesn't collapse to fit available space - bug #4375 Group two DB, one's name is the prefix of the other one +- bug #4070 Confusing database/table grouping 4.1.14.0 (not yet released) - bug #4365 Creating bookmark with multiple queries not working diff --git a/doc/config.rst b/doc/config.rst index 1a8faf021e..213822920e 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -1374,13 +1374,21 @@ Cookie authentication options Navigation panel setup ---------------------- +.. config:option:: $cfg['FirstLevelNavigationItems'] + + :type: integer + :default: 25 + + The number of first level databases that can be displayed on each page + of navigation tree. + .. config:option:: $cfg['MaxNavigationItems'] :type: integer :default: 250 - The number of items that can be displayed on each page of the - navigation tree. + The number of items (tables, columns, indexes) that can be displayed on each + page of the navigation tree. .. config:option:: $cfg['NavigationTreeEnableGrouping'] diff --git a/libraries/config.default.php b/libraries/config.default.php index 1953cea6b6..4f0064e740 100644 --- a/libraries/config.default.php +++ b/libraries/config.default.php @@ -847,6 +847,13 @@ $cfg['Error_Handler']['display'] = false; * Navigation panel setup */ +/** + * maximum number of first level databases displayed in navigation panel + * + * @global integer $cfg['FirstLevelNavigationItems'] + */ +$cfg['FirstLevelNavigationItems'] = 25; + /** * maximum number of items displayed in navigation panel * diff --git a/libraries/config.values.php b/libraries/config.values.php index d5b63ad45e..b8012291db 100644 --- a/libraries/config.values.php +++ b/libraries/config.values.php @@ -211,6 +211,7 @@ $cfg_db['_validators'] = array( 'CharTextareaRows' => 'validatePositiveNumber', 'ExecTimeLimit' => 'validateNonNegativeNumber', 'Export/sql_max_query_size' => 'validatePositiveNumber', + 'FirstLevelNavigationItems' => 'validatePositiveNumber', 'ForeignKeyMaxLimit' => 'validatePositiveNumber', 'Import/csv_enclosed' => array(array('validateByRegex', '/^.?$/')), 'Import/csv_escaped' => array(array('validateByRegex', '/^.$/')), diff --git a/libraries/config/messages.inc.php b/libraries/config/messages.inc.php index 2c2c5c9d4b..07f59b65ba 100644 --- a/libraries/config/messages.inc.php +++ b/libraries/config/messages.inc.php @@ -398,6 +398,11 @@ $strConfigMaxDbList_cmt = __('Users cannot set a higher value'); $strConfigMaxDbList_desc = __('Maximum number of databases displayed in database list.'); $strConfigMaxDbList_name = __('Maximum databases'); +$strConfigFirstLevelNavigationItems_desc = __( + 'The number of items that can be displayed on each page on first level of the ' + . 'navigation tree.' +); +$strConfigFirstLevelNavigationItems_name = __('Maximum items on first level'); $strConfigMaxNavigationItems_desc = __( 'The number of items that can be displayed on each page of the navigation tree.' ); diff --git a/libraries/config/setup.forms.php b/libraries/config/setup.forms.php index ddd01711af..1c612378e5 100644 --- a/libraries/config/setup.forms.php +++ b/libraries/config/setup.forms.php @@ -170,6 +170,7 @@ $forms['Navi_panel']['Navi_panel'] = array( 'NavigationLogoLink', 'NavigationLogoLinkWindow', 'NavigationTreePointerEnable', + 'FirstLevelNavigationItems', 'MaxNavigationItems', 'NavigationTreeEnableGrouping', 'NavigationTreeDisableDatabaseExpansion', diff --git a/libraries/config/user_preferences.forms.php b/libraries/config/user_preferences.forms.php index 19601c119f..51b481fa76 100644 --- a/libraries/config/user_preferences.forms.php +++ b/libraries/config/user_preferences.forms.php @@ -83,6 +83,7 @@ $forms['Navi_panel']['Navi_panel'] = array( 'NavigationLogoLink', 'NavigationLogoLinkWindow', 'NavigationTreePointerEnable', + 'FirstLevelNavigationItems', 'MaxNavigationItems', 'NavigationTreeEnableGrouping', 'NavigationTreeDisableDatabaseExpansion', diff --git a/libraries/navigation/NavigationTree.class.php b/libraries/navigation/NavigationTree.class.php index 7958cd3b91..865aa22110 100644 --- a/libraries/navigation/NavigationTree.class.php +++ b/libraries/navigation/NavigationTree.class.php @@ -157,15 +157,20 @@ class PMA_NavigationTree /* * @todo describe a scenario where this code is executed */ - $query = "SELECT (COUNT(`SCHEMA_NAME`) DIV %d) * %d "; - $query .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA` "; - $query .= "WHERE `SCHEMA_NAME` < '%s' "; - $query .= "ORDER BY `SCHEMA_NAME` ASC"; + $query = "SELECT (COUNT(DB_first_level) DIV %d) * %d "; + $query .= "from ( "; + $query .= " SELECT distinct SUBSTRING_INDEX(SCHEMA_NAME, "; + $query .= " '{$GLOBALS['cfg']['NavigationTreeDbSeparator']}', 1) "; + $query .= " DB_first_level "; + $query .= " FROM INFORMATION_SCHEMA.SCHEMATA "; + $query .= " WHERE `SCHEMA_NAME` < '%s' "; + $query .= ") t "; + $retval = $GLOBALS['dbi']->fetchValue( sprintf( $query, - (int)$GLOBALS['cfg']['MaxNavigationItems'], - (int)$GLOBALS['cfg']['MaxNavigationItems'], + (int)$GLOBALS['cfg']['FirstLevelNavigationItems'], + (int)$GLOBALS['cfg']['FirstLevelNavigationItems'], PMA_Util::sqlAddSlashes($GLOBALS['db']) ) ); @@ -1145,7 +1150,7 @@ class PMA_NavigationTree array('server' => $GLOBALS['server']), 'navigation.php', 'frame_navigation', - $GLOBALS['cfg']['MaxNavigationItems'], + $GLOBALS['cfg']['FirstLevelNavigationItems'], 'pos', array('dbselector') ); diff --git a/libraries/navigation/Nodes/Node.class.php b/libraries/navigation/Nodes/Node.class.php index 5354985de1..70dd75b098 100644 --- a/libraries/navigation/Nodes/Node.class.php +++ b/libraries/navigation/Nodes/Node.class.php @@ -361,10 +361,25 @@ class Node public function getData($type, $pos, $searchClause = '') { $query = "SELECT `SCHEMA_NAME` "; - $query .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA` "; + $query .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA`, "; + $query .= "("; + $query .= "select DB_first_level "; + $query .= "from ( "; + $query .= "SELECT distinct SUBSTRING_INDEX(SCHEMA_NAME, "; + $query .= "'{$GLOBALS['cfg']['NavigationTreeDbSeparator']}', 1) "; + $query .= "DB_first_level "; + $query .= "FROM INFORMATION_SCHEMA.SCHEMATA "; $query .= $this->_getWhereClause($searchClause); - $query .= "ORDER BY `SCHEMA_NAME` ASC "; - $query .= "LIMIT $pos, {$GLOBALS['cfg']['MaxNavigationItems']}"; + $query .= ") t "; + $query .= "ORDER BY DB_first_level ASC "; + $query .= "LIMIT $pos, {$GLOBALS['cfg']['FirstLevelNavigationItems']}"; + $query .= ") t2 "; + $query .= "where 1 = locate(concat(DB_first_level, "; + $query .= "'{$GLOBALS['cfg']['NavigationTreeDbSeparator']}'), "; + $query .= "concat(SCHEMA_NAME, "; + $query .= "'{$GLOBALS['cfg']['NavigationTreeDbSeparator']}')) "; + $query .= "order by SCHEMA_NAME ASC"; + return $GLOBALS['dbi']->fetchResult($query); } @@ -380,9 +395,14 @@ class Node */ public function getPresence($type = '', $searchClause = '') { - $query = "SELECT COUNT(*) "; - $query .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA` "; + $query = "select COUNT(*) "; + $query .= "from ( "; + $query .= "SELECT distinct SUBSTRING_INDEX(SCHEMA_NAME, "; + $query .= "'{$GLOBALS['cfg']['NavigationTreeDbSeparator']}', 1) "; + $query .= "DB_first_level "; + $query .= "FROM INFORMATION_SCHEMA.SCHEMATA "; $query .= $this->_getWhereClause($searchClause); + $query .= ") t "; $retval = (int)$GLOBALS['dbi']->fetchValue($query); return $retval; } diff --git a/test/classes/navigation/PMA_Node_test.php b/test/classes/navigation/PMA_Node_test.php index 9dd221fffa..c16b9586c1 100644 --- a/test/classes/navigation/PMA_Node_test.php +++ b/test/classes/navigation/PMA_Node_test.php @@ -342,13 +342,26 @@ class Node_Test extends PHPUnit_Framework_TestCase if (! isset($GLOBALS['cfg'])) { $GLOBALS['cfg'] = array(); } - $GLOBALS['cfg']['MaxNavigationItems'] = $limit; + $GLOBALS['cfg']['FirstLevelNavigationItems'] = $limit; + $GLOBALS['cfg']['NavigationTreeDbSeparator'] = '_'; $expectedSql = "SELECT `SCHEMA_NAME` "; - $expectedSql .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA` "; + $expectedSql .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA`, "; + $expectedSql .= "("; + $expectedSql .= "select DB_first_level "; + $expectedSql .= "from ( "; + $expectedSql .= "SELECT distinct SUBSTRING_INDEX(SCHEMA_NAME, "; + $expectedSql .= "'_', 1) "; + $expectedSql .= "DB_first_level "; + $expectedSql .= "FROM INFORMATION_SCHEMA.SCHEMATA "; $expectedSql .= "WHERE TRUE "; - $expectedSql .= "ORDER BY `SCHEMA_NAME` ASC "; + $expectedSql .= ") t "; + $expectedSql .= "ORDER BY DB_first_level ASC "; $expectedSql .= "LIMIT $pos, $limit"; + $expectedSql .= ") t2 "; + $expectedSql .= "where 1 = locate(concat(DB_first_level, '_'), "; + $expectedSql .= "concat(SCHEMA_NAME, '_')) "; + $expectedSql .= "order by SCHEMA_NAME ASC"; // It would have been better to mock _getWhereClause method // but stangely, mocking private methods is not supported in PHPUnit @@ -381,10 +394,15 @@ class Node_Test extends PHPUnit_Framework_TestCase if (! isset($GLOBALS['cfg']['Servers'][0])) { $GLOBALS['cfg']['Servers'][0] = array(); } + $GLOBALS['cfg']['NavigationTreeDbSeparator'] = '_'; - $query = "SELECT COUNT(*) "; - $query .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA` "; + $query = "select COUNT(*) "; + $query .= "from ( "; + $query .= "SELECT distinct SUBSTRING_INDEX(SCHEMA_NAME, '_', 1) "; + $query .= "DB_first_level "; + $query .= "FROM INFORMATION_SCHEMA.SCHEMATA "; $query .= "WHERE TRUE "; + $query .= ") t "; // It would have been better to mock _getWhereClause method // but strangely, mocking private methods is not supported in PHPUnit