Merge branch 'QA_5_1'
Signed-off-by: William Desportes <williamdes@wdes.fr>
This commit is contained in:
commit
806e2740ba
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1,3 +1,5 @@
|
||||
*.php text diff=php
|
||||
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
.github export-ignore
|
||||
|
||||
@ -116,6 +116,9 @@ phpMyAdmin - ChangeLog
|
||||
- issue #16942 Fix table Import with CSV using LOAD DATA LOCAL causes error "LOAD DATA LOCAL INFILE is forbidden"
|
||||
- issue #16942 Fix auto-detection for "LOAD DATA LOCAL INFILE" LOCAL option
|
||||
- issue #16067 Make select elements with multiple items resizable
|
||||
- issue Fix the display of Indexes that use Expressions and not column names
|
||||
- issue Allow to create the phpMyAdmin storage database using a different name than "phpmyadmin" using the interface
|
||||
- issue #17092 Document that "$cfg['Servers'][$i]['designer_coords']" was removed in version 4.3.0
|
||||
|
||||
5.1.1 (2021-06-04)
|
||||
- issue #13325 Fixed created procedure shows up in triggers and events and vice-versa
|
||||
|
||||
@ -863,6 +863,24 @@ Server connection settings
|
||||
|
||||
.. seealso:: :ref:`faqpdf`.
|
||||
|
||||
.. _designer_coords:
|
||||
.. config:option:: $cfg['Servers'][$i]['designer_coords']
|
||||
|
||||
:type: string
|
||||
:default: ``''``
|
||||
|
||||
.. versionadded:: 2.10.0
|
||||
|
||||
Since release 2.10.0 a Designer interface is available; it permits to
|
||||
visually manage the relations.
|
||||
|
||||
.. deprecated:: 4.3.0
|
||||
|
||||
This setting was removed and the Designer table positioning data is now stored into :config:option:`$cfg['Servers'][$i]['table\_coords']`.
|
||||
|
||||
.. note::
|
||||
You can now delete the table `pma__designer_coords` from your phpMyAdmin configuration storage database and remove :config:option:`$cfg['Servers'][$i]['designer\_coords']` from your configuration file.
|
||||
|
||||
.. _col_com:
|
||||
.. config:option:: $cfg['Servers'][$i]['column_info']
|
||||
|
||||
|
||||
@ -35,9 +35,11 @@ class CheckRelationsController extends AbstractController
|
||||
'fix_pmadb' => $_POST['fix_pmadb'] ?? null,
|
||||
];
|
||||
|
||||
$cfgStorageDbName = $this->relation->getConfigurationStorageDbName();
|
||||
|
||||
// If request for creating the pmadb
|
||||
if (isset($params['create_pmadb']) && $this->relation->createPmaDatabase()) {
|
||||
$this->relation->fixPmaTables('phpmyadmin');
|
||||
if (isset($params['create_pmadb']) && $this->relation->createPmaDatabase($cfgStorageDbName)) {
|
||||
$this->relation->fixPmaTables($cfgStorageDbName);
|
||||
}
|
||||
|
||||
// If request for creating all PMA tables.
|
||||
|
||||
@ -264,14 +264,17 @@ class Index
|
||||
*/
|
||||
public function addColumn(array $params)
|
||||
{
|
||||
if (
|
||||
! isset($params['Column_name'])
|
||||
|| strlen($params['Column_name']) <= 0
|
||||
) {
|
||||
$key = $params['Column_name'] ?? $params['Expression'] ?? '';
|
||||
if (isset($params['Expression'])) {
|
||||
// The Expression only does not make the key unique, add a sequence number
|
||||
$key .= $params['Seq_in_index'];
|
||||
}
|
||||
|
||||
if (strlen($key) <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->columns[$params['Column_name']] = new IndexColumn($params);
|
||||
$this->columns[$key] = new IndexColumn($params);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -47,6 +47,13 @@ class IndexColumn
|
||||
*/
|
||||
private $cardinality = null;
|
||||
|
||||
/**
|
||||
* If the Index uses an expression and not a name
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $expression = null;
|
||||
|
||||
/**
|
||||
* @param array $params an array containing the parameters of the index column
|
||||
*/
|
||||
@ -55,6 +62,22 @@ class IndexColumn
|
||||
$this->set($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the Index has an expression
|
||||
*/
|
||||
public function hasExpression(): bool
|
||||
{
|
||||
return $this->expression !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Index expression if it has one
|
||||
*/
|
||||
public function getExpression(): ?string
|
||||
{
|
||||
return $this->expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets parameters of the index column
|
||||
*
|
||||
@ -84,6 +107,10 @@ class IndexColumn
|
||||
$this->subPart = $params['Sub_part'];
|
||||
}
|
||||
|
||||
if (isset($params['Expression'])) {
|
||||
$this->expression = $params['Expression'];
|
||||
}
|
||||
|
||||
if (! isset($params['Null'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2965,6 +2965,11 @@ class ExportSql extends ExportPlugin
|
||||
// Key's columns.
|
||||
if (! empty($field->key)) {
|
||||
foreach ($field->key->columns as $key => $column) {
|
||||
if (! isset($column['name'])) {
|
||||
// In case the column has no name field
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($aliases[$oldDatabase]['tables'][$oldTable]['columns'][$column['name']])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2052,13 +2052,13 @@ class Relation
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a table named phpmyadmin to be used as configuration storage
|
||||
*
|
||||
* @return bool
|
||||
* Create a database to be used as configuration storage
|
||||
*/
|
||||
public function createPmaDatabase()
|
||||
public function createPmaDatabase(string $configurationStorageDbName): bool
|
||||
{
|
||||
$this->dbi->tryQuery('CREATE DATABASE IF NOT EXISTS `phpmyadmin`');
|
||||
$this->dbi->tryQuery(
|
||||
'CREATE DATABASE IF NOT EXISTS ' . Util::backquote($configurationStorageDbName)
|
||||
);
|
||||
|
||||
$error = $this->dbi->getError();
|
||||
if (! $error) {
|
||||
@ -2068,10 +2068,13 @@ class Relation
|
||||
$GLOBALS['message'] = $error;
|
||||
|
||||
if ($GLOBALS['errno'] === 1044) {
|
||||
$GLOBALS['message'] = __(
|
||||
'You do not have necessary privileges to create a database named'
|
||||
. ' \'phpmyadmin\'. You may go to \'Operations\' tab of any'
|
||||
. ' database to set up the phpMyAdmin configuration storage there.'
|
||||
$GLOBALS['message'] = sprintf(
|
||||
__(
|
||||
'You do not have necessary privileges to create a database named'
|
||||
. ' \'%s\'. You may go to \'Operations\' tab of any'
|
||||
. ' database to set up the phpMyAdmin configuration storage there.'
|
||||
),
|
||||
$configurationStorageDbName
|
||||
);
|
||||
}
|
||||
|
||||
@ -2191,7 +2194,7 @@ class Relation
|
||||
$params['create_pmadb'] = 1;
|
||||
$message = Message::notice(
|
||||
__(
|
||||
'%sCreate%s a database named \'phpmyadmin\' and setup '
|
||||
'%sCreate%s a database named \'%s\' and setup '
|
||||
. 'the phpMyAdmin configuration storage there.'
|
||||
)
|
||||
);
|
||||
@ -2216,6 +2219,12 @@ class Relation
|
||||
);
|
||||
$message->addParamHtml('</a>');
|
||||
|
||||
if ($allTables && $createDb) {
|
||||
$message->addParam(
|
||||
$this->getConfigurationStorageDbName()
|
||||
);
|
||||
}
|
||||
|
||||
return $retval . $message->getDisplay();
|
||||
}
|
||||
|
||||
@ -2309,4 +2318,14 @@ class Relation
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
public function getConfigurationStorageDbName(): string
|
||||
{
|
||||
global $cfg;
|
||||
|
||||
$cfgStorageDbName = $cfg['Server']['pmadb'] ?? '';
|
||||
|
||||
// Use "phpmyadmin" as a default database name to check to keep the behavior consistent
|
||||
return empty($cfgStorageDbName) ? 'phpmyadmin' : $cfgStorageDbName;
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@
|
||||
<tr class="noclick">
|
||||
{% endif %}
|
||||
<td>
|
||||
{{ column.getName() }}
|
||||
{% if column.hasExpression() %}{{ column.getExpression() }}{% else %}{{ column.getName() }}{% endif %}
|
||||
{% if column.getSubPart() is not empty %}
|
||||
({{ column.getSubPart() }})
|
||||
{% endif %}
|
||||
|
||||
@ -474,7 +474,7 @@
|
||||
<tr class="noclick">
|
||||
{% endif %}
|
||||
<td>
|
||||
{{ column.getName() }}
|
||||
{% if column.hasExpression() %}{{ column.getExpression() }}{% else %}{{ column.getName() }}{% endif %}
|
||||
{% if column.getSubPart() is not empty %}
|
||||
({{ column.getSubPart() }})
|
||||
{% endif %}
|
||||
|
||||
@ -115,6 +115,17 @@ abstract class AbstractTestCase extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
protected function assertAllErrorCodesConsumed(): void
|
||||
{
|
||||
if ($this->dummyDbi->hasUnUsedErrors() === false) {
|
||||
$this->assertTrue(true);// increment the assertion count
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->fail('Some error codes where not used !');
|
||||
}
|
||||
|
||||
protected function loadContainerBuilder(): void
|
||||
{
|
||||
global $containerBuilder;
|
||||
|
||||
@ -324,4 +324,570 @@ class RelationTest extends AbstractTestCase
|
||||
$foreigner
|
||||
);
|
||||
}
|
||||
|
||||
public function testFixPmaTablesNothingWorks(): void
|
||||
{
|
||||
parent::setGlobalDbi();
|
||||
parent::loadDefaultConfig();
|
||||
|
||||
$this->relation = new Relation($this->dbi);
|
||||
|
||||
$this->dummyDbi->removeDefaultResults();
|
||||
$this->dummyDbi->addResult(
|
||||
'SHOW TABLES FROM `db_pma`;',
|
||||
false
|
||||
);
|
||||
|
||||
$this->relation->fixPmaTables('db_pma', false);
|
||||
$this->assertAllQueriesConsumed();
|
||||
}
|
||||
|
||||
public function testFixPmaTablesNormal(): void
|
||||
{
|
||||
parent::setGlobalDbi();
|
||||
parent::loadDefaultConfig();
|
||||
|
||||
$GLOBALS['db'] = '';
|
||||
$GLOBALS['server'] = 1;
|
||||
$GLOBALS['cfg']['Server']['user'] = '';
|
||||
$GLOBALS['cfg']['Server']['pmadb'] = '';
|
||||
$GLOBALS['cfg']['Server']['bookmarktable'] = '';
|
||||
$GLOBALS['cfg']['Server']['relation'] = '';
|
||||
$GLOBALS['cfg']['Server']['table_info'] = '';
|
||||
$GLOBALS['cfg']['Server']['table_coords'] = '';
|
||||
$GLOBALS['cfg']['Server']['column_info'] = '';
|
||||
$GLOBALS['cfg']['Server']['pdf_pages'] = '';
|
||||
$GLOBALS['cfg']['Server']['history'] = '';
|
||||
$GLOBALS['cfg']['Server']['recent'] = '';
|
||||
$GLOBALS['cfg']['Server']['favorite'] = '';
|
||||
$GLOBALS['cfg']['Server']['table_uiprefs'] = '';
|
||||
$GLOBALS['cfg']['Server']['tracking'] = '';
|
||||
$GLOBALS['cfg']['Server']['userconfig'] = '';
|
||||
$GLOBALS['cfg']['Server']['users'] = '';
|
||||
$GLOBALS['cfg']['Server']['usergroups'] = '';
|
||||
$GLOBALS['cfg']['Server']['navigationhiding'] = '';
|
||||
$GLOBALS['cfg']['Server']['savedsearches'] = '';
|
||||
$GLOBALS['cfg']['Server']['central_columns'] = '';
|
||||
$GLOBALS['cfg']['Server']['designer_settings'] = '';
|
||||
$GLOBALS['cfg']['Server']['export_templates'] = '';
|
||||
|
||||
$this->relation = new Relation($this->dbi);
|
||||
|
||||
$this->dummyDbi->removeDefaultResults();
|
||||
$this->dummyDbi->addResult(
|
||||
'SHOW TABLES FROM `db_pma`;',
|
||||
[
|
||||
['pma__userconfig'],
|
||||
],
|
||||
['Tables_in_db_pma']
|
||||
);
|
||||
|
||||
$this->dummyDbi->addResult(
|
||||
'SHOW TABLES FROM `db_pma`',
|
||||
[
|
||||
['pma__userconfig'],
|
||||
],
|
||||
['Tables_in_db_pma']
|
||||
);
|
||||
|
||||
$this->dummyDbi->addResult(
|
||||
'SELECT NULL FROM pma__userconfig LIMIT 0',
|
||||
[['NULL']]
|
||||
);
|
||||
$this->dummyDbi->addSelectDb('db_pma');
|
||||
|
||||
$this->assertArrayHasKey('relation', $_SESSION, 'The cache is expected to be filled');
|
||||
$this->assertSame([], $_SESSION['relation']);
|
||||
|
||||
$this->relation->fixPmaTables('db_pma', false);
|
||||
|
||||
$this->assertArrayHasKey('relation', $_SESSION, 'The cache is expected to be filled');
|
||||
|
||||
$this->assertSame([
|
||||
'version' => $_SESSION['relation'][$GLOBALS['server']]['version'],
|
||||
'relwork' => false,
|
||||
'displaywork' => false,
|
||||
'bookmarkwork' => false,
|
||||
'pdfwork' => false,
|
||||
'commwork' => false,
|
||||
'mimework' => false,
|
||||
'historywork' => false,
|
||||
'recentwork' => false,
|
||||
'favoritework' => false,
|
||||
'uiprefswork' => false,
|
||||
'trackingwork' => false,
|
||||
'userconfigwork' => true,// The only one than has a table and passes check
|
||||
'menuswork' => false,
|
||||
'navwork' => false,
|
||||
'savedsearcheswork' => false,
|
||||
'centralcolumnswork' => false,
|
||||
'designersettingswork' => false,
|
||||
'exporttemplateswork' => false,
|
||||
'allworks' => false,
|
||||
'user' => '',
|
||||
'db' => 'db_pma',
|
||||
'userconfig' => 'pma__userconfig',
|
||||
], $_SESSION['relation'][$GLOBALS['server']]);
|
||||
|
||||
$this->assertAllQueriesConsumed();
|
||||
$this->assertAllSelectsConsumed();
|
||||
}
|
||||
|
||||
public function testFixPmaTablesNormalFixTables(): void
|
||||
{
|
||||
parent::setGlobalDbi();
|
||||
parent::loadDefaultConfig();
|
||||
|
||||
$GLOBALS['db'] = '';
|
||||
$GLOBALS['server'] = 1;
|
||||
$GLOBALS['cfg']['Server']['user'] = '';
|
||||
$GLOBALS['cfg']['Server']['pmadb'] = '';
|
||||
$GLOBALS['cfg']['Server']['bookmarktable'] = '';
|
||||
$GLOBALS['cfg']['Server']['relation'] = '';
|
||||
$GLOBALS['cfg']['Server']['table_info'] = '';
|
||||
$GLOBALS['cfg']['Server']['table_coords'] = '';
|
||||
$GLOBALS['cfg']['Server']['column_info'] = '';
|
||||
$GLOBALS['cfg']['Server']['pdf_pages'] = '';
|
||||
$GLOBALS['cfg']['Server']['history'] = '';
|
||||
$GLOBALS['cfg']['Server']['recent'] = '';
|
||||
$GLOBALS['cfg']['Server']['favorite'] = '';
|
||||
$GLOBALS['cfg']['Server']['table_uiprefs'] = '';
|
||||
$GLOBALS['cfg']['Server']['tracking'] = '';
|
||||
$GLOBALS['cfg']['Server']['userconfig'] = '';
|
||||
$GLOBALS['cfg']['Server']['users'] = '';
|
||||
$GLOBALS['cfg']['Server']['usergroups'] = '';
|
||||
$GLOBALS['cfg']['Server']['navigationhiding'] = '';
|
||||
$GLOBALS['cfg']['Server']['savedsearches'] = '';
|
||||
$GLOBALS['cfg']['Server']['central_columns'] = '';
|
||||
$GLOBALS['cfg']['Server']['designer_settings'] = '';
|
||||
$GLOBALS['cfg']['Server']['export_templates'] = '';
|
||||
|
||||
$this->relation = new Relation($this->dbi);
|
||||
|
||||
$this->dummyDbi->removeDefaultResults();
|
||||
$this->dummyDbi->addResult(
|
||||
'SHOW TABLES FROM `db_pma`;',
|
||||
[
|
||||
['pma__userconfig'],
|
||||
],
|
||||
['Tables_in_db_pma']
|
||||
);
|
||||
|
||||
$this->dummyDbi->addResult(
|
||||
'SHOW TABLES FROM `db_pma`',
|
||||
[
|
||||
['pma__userconfig'],
|
||||
],
|
||||
['Tables_in_db_pma']
|
||||
);
|
||||
|
||||
$this->dummyDbi->addResult(
|
||||
'SELECT NULL FROM pma__userconfig LIMIT 0',
|
||||
[['NULL']]
|
||||
);
|
||||
$this->dummyDbi->addSelectDb('db_pma');
|
||||
$this->dummyDbi->addSelectDb('db_pma');
|
||||
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__bookmark` '
|
||||
. '-- CREATE TABLE IF NOT EXISTS `pma__bookmark` ( '
|
||||
. '`id` int(10) unsigned NOT NULL auto_increment,'
|
||||
. ' `dbase` varchar(255) NOT NULL default \'\','
|
||||
. ' `user` varchar(255) NOT NULL default \'\','
|
||||
. ' `label` varchar(255) COLLATE utf8_general_ci NOT NULL default \'\','
|
||||
. ' `query` text NOT NULL, PRIMARY KEY (`id`) )'
|
||||
. ' COMMENT=\'Bookmarks\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__relation` '
|
||||
. '-- CREATE TABLE IF NOT EXISTS `pma__relation` ( '
|
||||
. '`master_db` varchar(64) NOT NULL default \'\', `master_table` varchar(64) NOT NULL default \'\','
|
||||
. ' `master_field` varchar(64) NOT NULL default \'\', `foreign_db` varchar(64) NOT NULL default \'\','
|
||||
. ' `foreign_table` varchar(64) NOT NULL default \'\','
|
||||
. ' `foreign_field` varchar(64) NOT NULL default \'\','
|
||||
. ' PRIMARY KEY (`master_db`,`master_table`,`master_field`),'
|
||||
. ' KEY `foreign_field` (`foreign_db`,`foreign_table`) ) COMMENT=\'Relation table\''
|
||||
. ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__table_info`'
|
||||
. ' -- CREATE TABLE IF NOT EXISTS `pma__table_info` ( '
|
||||
. '`db_name` varchar(64) NOT NULL default \'\', `table_name` varchar(64) NOT NULL default \'\','
|
||||
. ' `display_field` varchar(64) NOT NULL default \'\', PRIMARY KEY (`db_name`,`table_name`) )'
|
||||
. ' COMMENT=\'Table information for phpMyAdmin\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__table_coords`'
|
||||
. ' -- CREATE TABLE IF NOT EXISTS `pma__table_coords` ( '
|
||||
. '`db_name` varchar(64) NOT NULL default \'\', `table_name` varchar(64) NOT NULL default \'\','
|
||||
. ' `pdf_page_number` int(11) NOT NULL default \'0\', `x` float unsigned NOT NULL default \'0\','
|
||||
. ' `y` float unsigned NOT NULL default \'0\','
|
||||
. ' PRIMARY KEY (`db_name`,`table_name`,`pdf_page_number`) )'
|
||||
. ' COMMENT=\'Table coordinates for phpMyAdmin PDF output\''
|
||||
. ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__pdf_pages`'
|
||||
. ' -- CREATE TABLE IF NOT EXISTS `pma__pdf_pages` ( '
|
||||
. '`db_name` varchar(64) NOT NULL default \'\', `page_nr` int(10) unsigned NOT NULL auto_increment,'
|
||||
. ' `page_descr` varchar(50) COLLATE utf8_general_ci NOT NULL default \'\', PRIMARY KEY (`page_nr`),'
|
||||
. ' KEY `db_name` (`db_name`) ) COMMENT=\'PDF relation pages for phpMyAdmin\''
|
||||
. ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__column_info`'
|
||||
. ' -- CREATE TABLE IF NOT EXISTS `pma__column_info` ( '
|
||||
. '`id` int(5) unsigned NOT NULL auto_increment, `db_name` varchar(64) NOT NULL default \'\','
|
||||
. ' `table_name` varchar(64) NOT NULL default \'\', `column_name` varchar(64) NOT NULL default \'\','
|
||||
. ' `comment` varchar(255) COLLATE utf8_general_ci NOT NULL default \'\','
|
||||
. ' `mimetype` varchar(255) COLLATE utf8_general_ci NOT NULL default \'\','
|
||||
. ' `transformation` varchar(255) NOT NULL default \'\','
|
||||
. ' `transformation_options` varchar(255) NOT NULL default \'\','
|
||||
. ' `input_transformation` varchar(255) NOT NULL default \'\','
|
||||
. ' `input_transformation_options` varchar(255) NOT NULL default \'\','
|
||||
. ' PRIMARY KEY (`id`), UNIQUE KEY `db_name` (`db_name`,`table_name`,`column_name`) )'
|
||||
. ' COMMENT=\'Column information for phpMyAdmin\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__history` '
|
||||
. '-- CREATE TABLE IF NOT EXISTS `pma__history` ( '
|
||||
. '`id` bigint(20) unsigned NOT NULL auto_increment, `username` varchar(64) NOT NULL default \'\','
|
||||
. ' `db` varchar(64) NOT NULL default \'\', `table` varchar(64) NOT NULL default \'\','
|
||||
. ' `timevalue` timestamp NOT NULL default CURRENT_TIMESTAMP, `sqlquery` text NOT NULL,'
|
||||
. ' PRIMARY KEY (`id`), KEY `username` (`username`,`db`,`table`,`timevalue`) )'
|
||||
. ' COMMENT=\'SQL history for phpMyAdmin\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__recent` '
|
||||
. '-- CREATE TABLE IF NOT EXISTS `pma__recent` ( '
|
||||
. '`username` varchar(64) NOT NULL, `tables` text NOT NULL, PRIMARY KEY (`username`) )'
|
||||
. ' COMMENT=\'Recently accessed tables\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__favorite` '
|
||||
. '-- CREATE TABLE IF NOT EXISTS `pma__favorite` ( '
|
||||
. '`username` varchar(64) NOT NULL, `tables` text NOT NULL, PRIMARY KEY (`username`) )'
|
||||
. ' COMMENT=\'Favorite tables\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__table_uiprefs`'
|
||||
. ' -- CREATE TABLE IF NOT EXISTS `pma__table_uiprefs` ( '
|
||||
. '`username` varchar(64) NOT NULL, `db_name` varchar(64) NOT NULL,'
|
||||
. ' `table_name` varchar(64) NOT NULL, `prefs` text NOT NULL,'
|
||||
. ' `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,'
|
||||
. ' PRIMARY KEY (`username`,`db_name`,`table_name`) ) COMMENT=\'Tables\'\' UI preferences\''
|
||||
. ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__tracking` '
|
||||
. '-- CREATE TABLE IF NOT EXISTS `pma__tracking` ( '
|
||||
. '`db_name` varchar(64) NOT NULL, `table_name` varchar(64) NOT NULL,'
|
||||
. ' `version` int(10) unsigned NOT NULL, `date_created` datetime NOT NULL,'
|
||||
. ' `date_updated` datetime NOT NULL, `schema_snapshot` text NOT NULL,'
|
||||
. ' `schema_sql` text, `data_sql` longtext, `tracking`'
|
||||
. ' set(\'UPDATE\',\'REPLACE\',\'INSERT\',\'DELETE\','
|
||||
. '\'TRUNCATE\',\'CREATE DATABASE\',\'ALTER DATABASE\','
|
||||
. '\'DROP DATABASE\',\'CREATE TABLE\',\'ALTER TABLE\','
|
||||
. '\'RENAME TABLE\',\'DROP TABLE\',\'CREATE INDEX\','
|
||||
. '\'DROP INDEX\',\'CREATE VIEW\',\'ALTER VIEW\',\'DROP VIEW\')'
|
||||
. ' default NULL, `tracking_active` int(1) unsigned NOT NULL'
|
||||
. ' default \'1\', PRIMARY KEY (`db_name`,`table_name`,`version`) )'
|
||||
. ' COMMENT=\'Database changes tracking for phpMyAdmin\''
|
||||
. ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__users` '
|
||||
. '-- CREATE TABLE IF NOT EXISTS `pma__users` ( '
|
||||
. '`username` varchar(64) NOT NULL, `usergroup` varchar(64) NOT NULL,'
|
||||
. ' PRIMARY KEY (`username`,`usergroup`) )'
|
||||
. ' COMMENT=\'Users and their assignments to user groups\''
|
||||
. ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__usergroups`'
|
||||
. ' -- CREATE TABLE IF NOT EXISTS `pma__usergroups` ( '
|
||||
. '`usergroup` varchar(64) NOT NULL, `tab` varchar(64) NOT NULL,'
|
||||
. ' `allowed` enum(\'Y\',\'N\') NOT NULL DEFAULT \'N\','
|
||||
. ' PRIMARY KEY (`usergroup`,`tab`,`allowed`) )'
|
||||
. ' COMMENT=\'User groups with configured menu items\''
|
||||
. ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__navigationhiding`'
|
||||
. ' -- CREATE TABLE IF NOT EXISTS `pma__navigationhiding` ( '
|
||||
. '`username` varchar(64) NOT NULL, `item_name` varchar(64)'
|
||||
. ' NOT NULL, `item_type` varchar(64) NOT NULL, `db_name` varchar(64) NOT NULL,'
|
||||
. ' `table_name` varchar(64) NOT NULL,'
|
||||
. ' PRIMARY KEY (`username`,`item_name`,`item_type`,`db_name`,`table_name`) )'
|
||||
. ' COMMENT=\'Hidden items of navigation tree\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__savedsearches`'
|
||||
. ' -- CREATE TABLE IF NOT EXISTS `pma__savedsearches` ( '
|
||||
. '`id` int(5) unsigned NOT NULL auto_increment, `username` varchar(64) NOT NULL default \'\','
|
||||
. ' `db_name` varchar(64) NOT NULL default \'\', `search_name` varchar(64) NOT NULL default \'\','
|
||||
. ' `search_data` text NOT NULL, PRIMARY KEY (`id`),'
|
||||
. ' UNIQUE KEY `u_savedsearches_username_dbname` (`username`,`db_name`,`search_name`) )'
|
||||
. ' COMMENT=\'Saved searches\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__central_columns`'
|
||||
. ' -- CREATE TABLE IF NOT EXISTS `pma__central_columns` ( '
|
||||
. '`db_name` varchar(64) NOT NULL, `col_name` varchar(64) NOT NULL, `col_type` varchar(64) NOT NULL,'
|
||||
. ' `col_length` text, `col_collation` varchar(64) NOT NULL, `col_isNull` boolean NOT NULL,'
|
||||
. ' `col_extra` varchar(255) default \'\', `col_default` text,'
|
||||
. ' PRIMARY KEY (`db_name`,`col_name`) )'
|
||||
. ' COMMENT=\'Central list of columns\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__designer_settings`'
|
||||
. ' -- CREATE TABLE IF NOT EXISTS `pma__designer_settings` ( '
|
||||
. '`username` varchar(64) NOT NULL, `settings_data` text NOT NULL,'
|
||||
. ' PRIMARY KEY (`username`) )'
|
||||
. ' COMMENT=\'Settings related to Designer\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__export_templates`'
|
||||
. ' -- CREATE TABLE IF NOT EXISTS `pma__export_templates` ( '
|
||||
. '`id` int(5) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(64) NOT NULL,'
|
||||
. ' `export_type` varchar(10) NOT NULL, `template_name` varchar(64) NOT NULL,'
|
||||
. ' `template_data` text NOT NULL, PRIMARY KEY (`id`),'
|
||||
. ' UNIQUE KEY `u_user_type_template` (`username`,`export_type`,`template_name`) )'
|
||||
. ' COMMENT=\'Saved export templates\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
[]
|
||||
);
|
||||
|
||||
$this->assertSame('', $GLOBALS['cfg']['Server']['pmadb']);
|
||||
$this->assertArrayHasKey('relation', $_SESSION, 'The cache is expected to be filled');
|
||||
$this->assertSame([], $_SESSION['relation']);
|
||||
|
||||
$this->relation->fixPmaTables('db_pma', true);
|
||||
$this->assertArrayNotHasKey('message', $GLOBALS);
|
||||
$this->assertArrayHasKey('relation', $_SESSION, 'The cache is expected to be filled');
|
||||
$this->assertSame('db_pma', $GLOBALS['cfg']['Server']['pmadb']);
|
||||
|
||||
$this->assertSame([
|
||||
'version' => $_SESSION['relation'][$GLOBALS['server']]['version'],
|
||||
'relwork' => false,
|
||||
'displaywork' => false,
|
||||
'bookmarkwork' => false,
|
||||
'pdfwork' => false,
|
||||
'commwork' => false,
|
||||
'mimework' => false,
|
||||
'historywork' => false,
|
||||
'recentwork' => false,
|
||||
'favoritework' => false,
|
||||
'uiprefswork' => false,
|
||||
'trackingwork' => false,
|
||||
'userconfigwork' => true,// The only one than has a table and passes check
|
||||
'menuswork' => false,
|
||||
'navwork' => false,
|
||||
'savedsearcheswork' => false,
|
||||
'centralcolumnswork' => false,
|
||||
'designersettingswork' => false,
|
||||
'exporttemplateswork' => false,
|
||||
'allworks' => false,
|
||||
'user' => '',
|
||||
'db' => 'db_pma',
|
||||
'userconfig' => 'pma__userconfig',
|
||||
], $_SESSION['relation'][$GLOBALS['server']]);
|
||||
|
||||
$this->assertAllQueriesConsumed();
|
||||
$this->assertAllSelectsConsumed();
|
||||
}
|
||||
|
||||
public function testFixPmaTablesNormalFixTablesFails(): void
|
||||
{
|
||||
parent::setGlobalDbi();
|
||||
parent::loadDefaultConfig();
|
||||
|
||||
$GLOBALS['db'] = '';
|
||||
$GLOBALS['server'] = 1;
|
||||
$GLOBALS['cfg']['Server']['user'] = '';
|
||||
$GLOBALS['cfg']['Server']['pmadb'] = '';
|
||||
$GLOBALS['cfg']['Server']['bookmarktable'] = '';
|
||||
$GLOBALS['cfg']['Server']['relation'] = '';
|
||||
$GLOBALS['cfg']['Server']['table_info'] = '';
|
||||
$GLOBALS['cfg']['Server']['table_coords'] = '';
|
||||
$GLOBALS['cfg']['Server']['column_info'] = '';
|
||||
$GLOBALS['cfg']['Server']['pdf_pages'] = '';
|
||||
$GLOBALS['cfg']['Server']['history'] = '';
|
||||
$GLOBALS['cfg']['Server']['recent'] = '';
|
||||
$GLOBALS['cfg']['Server']['favorite'] = '';
|
||||
$GLOBALS['cfg']['Server']['table_uiprefs'] = '';
|
||||
$GLOBALS['cfg']['Server']['tracking'] = '';
|
||||
$GLOBALS['cfg']['Server']['userconfig'] = '';
|
||||
$GLOBALS['cfg']['Server']['users'] = '';
|
||||
$GLOBALS['cfg']['Server']['usergroups'] = '';
|
||||
$GLOBALS['cfg']['Server']['navigationhiding'] = '';
|
||||
$GLOBALS['cfg']['Server']['savedsearches'] = '';
|
||||
$GLOBALS['cfg']['Server']['central_columns'] = '';
|
||||
$GLOBALS['cfg']['Server']['designer_settings'] = '';
|
||||
$GLOBALS['cfg']['Server']['export_templates'] = '';
|
||||
|
||||
$this->relation = new Relation($this->dbi);
|
||||
|
||||
$this->dummyDbi->removeDefaultResults();
|
||||
$this->dummyDbi->addResult(
|
||||
'SHOW TABLES FROM `db_pma`;',
|
||||
[
|
||||
['pma__userconfig'],
|
||||
],
|
||||
['Tables_in_db_pma']
|
||||
);
|
||||
|
||||
// Fail the query
|
||||
$this->dummyDbi->addErrorCode('MYSQL_ERROR');
|
||||
$this->dummyDbi->addResult(
|
||||
'-- -------------------------------------------------------- -- --'
|
||||
. ' Table structure for table `pma__bookmark` '
|
||||
. '-- CREATE TABLE IF NOT EXISTS `pma__bookmark` ( '
|
||||
. '`id` int(10) unsigned NOT NULL auto_increment,'
|
||||
. ' `dbase` varchar(255) NOT NULL default \'\','
|
||||
. ' `user` varchar(255) NOT NULL default \'\','
|
||||
. ' `label` varchar(255) COLLATE utf8_general_ci NOT NULL default \'\','
|
||||
. ' `query` text NOT NULL, PRIMARY KEY (`id`) )'
|
||||
. ' COMMENT=\'Bookmarks\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;',
|
||||
false
|
||||
);
|
||||
$this->dummyDbi->addSelectDb('db_pma');
|
||||
|
||||
$this->assertSame('', $GLOBALS['cfg']['Server']['pmadb']);
|
||||
$this->assertArrayHasKey('relation', $_SESSION, 'The cache is expected to be filled');
|
||||
$this->assertSame([], $_SESSION['relation']);
|
||||
|
||||
$this->relation->fixPmaTables('db_pma', true);
|
||||
|
||||
$this->assertArrayHasKey('message', $GLOBALS);
|
||||
$this->assertArrayHasKey('relation', $_SESSION, 'The cache is expected to be filled');
|
||||
$this->assertSame('MYSQL_ERROR', $GLOBALS['message']);
|
||||
$this->assertSame('', $GLOBALS['cfg']['Server']['pmadb']);
|
||||
|
||||
$this->assertSame([], $_SESSION['relation']);
|
||||
|
||||
$this->assertAllQueriesConsumed();
|
||||
$this->assertAllErrorCodesConsumed();
|
||||
$this->assertAllSelectsConsumed();
|
||||
}
|
||||
|
||||
public function testCreatePmaDatabase(): void
|
||||
{
|
||||
parent::setGlobalDbi();
|
||||
parent::loadDefaultConfig();
|
||||
$this->relation = new Relation($this->dbi);
|
||||
|
||||
$this->dummyDbi->removeDefaultResults();
|
||||
$this->dummyDbi->addErrorCode(false);
|
||||
$this->dummyDbi->addResult(
|
||||
'CREATE DATABASE IF NOT EXISTS `phpmyadmin`',
|
||||
[]
|
||||
);
|
||||
|
||||
$this->assertArrayNotHasKey('errno', $GLOBALS);
|
||||
|
||||
$this->assertTrue(
|
||||
$this->relation->createPmaDatabase('phpmyadmin')
|
||||
);
|
||||
|
||||
$this->assertArrayNotHasKey('message', $GLOBALS);
|
||||
|
||||
$this->assertAllQueriesConsumed();
|
||||
$this->assertAllErrorCodesConsumed();
|
||||
}
|
||||
|
||||
public function testCreatePmaDatabaseFailsError1044(): void
|
||||
{
|
||||
parent::setGlobalDbi();
|
||||
parent::loadDefaultConfig();
|
||||
$this->relation = new Relation($this->dbi);
|
||||
|
||||
$this->dummyDbi->removeDefaultResults();
|
||||
$this->dummyDbi->addErrorCode('MYSQL_ERROR');
|
||||
$this->dummyDbi->addResult(
|
||||
'CREATE DATABASE IF NOT EXISTS `phpmyadmin`',
|
||||
false
|
||||
);
|
||||
|
||||
$GLOBALS['errno'] = 1044;// ER_DBACCESS_DENIED_ERROR
|
||||
|
||||
$this->assertFalse(
|
||||
$this->relation->createPmaDatabase('phpmyadmin')
|
||||
);
|
||||
|
||||
$this->assertArrayHasKey('message', $GLOBALS);
|
||||
$this->assertSame(
|
||||
'You do not have necessary privileges to create a database named'
|
||||
. ' \'phpmyadmin\'. You may go to \'Operations\' tab of any'
|
||||
. ' database to set up the phpMyAdmin configuration storage there.',
|
||||
$GLOBALS['message']
|
||||
);
|
||||
|
||||
$this->assertAllQueriesConsumed();
|
||||
$this->assertAllErrorCodesConsumed();
|
||||
}
|
||||
|
||||
public function testCreatePmaDatabaseFailsError1040(): void
|
||||
{
|
||||
parent::setGlobalDbi();
|
||||
parent::loadDefaultConfig();
|
||||
$this->relation = new Relation($this->dbi);
|
||||
|
||||
$this->dummyDbi->removeDefaultResults();
|
||||
$this->dummyDbi->addErrorCode('Too many connections');
|
||||
$this->dummyDbi->addResult(
|
||||
'CREATE DATABASE IF NOT EXISTS `pma_1040`',
|
||||
false
|
||||
);
|
||||
|
||||
$GLOBALS['errno'] = 1040;
|
||||
|
||||
$this->assertFalse(
|
||||
$this->relation->createPmaDatabase('pma_1040')
|
||||
);
|
||||
|
||||
$this->assertArrayHasKey('message', $GLOBALS);
|
||||
$this->assertSame(
|
||||
'Too many connections',
|
||||
$GLOBALS['message']
|
||||
);
|
||||
|
||||
$this->assertAllQueriesConsumed();
|
||||
$this->assertAllErrorCodesConsumed();
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,6 +84,9 @@ class DbiDummy implements DbiExtension
|
||||
*/
|
||||
private $dummyQueries = [];
|
||||
|
||||
/** @var array<int,string|false> */
|
||||
private $fifoErrorCodes = [];
|
||||
|
||||
public const OFFSET_GLOBAL = 1000;
|
||||
|
||||
public function __construct()
|
||||
@ -141,6 +144,11 @@ class DbiDummy implements DbiExtension
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasUnUsedErrors(): bool
|
||||
{
|
||||
return $this->fifoErrorCodes !== [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
@ -425,6 +433,12 @@ class DbiDummy implements DbiExtension
|
||||
*/
|
||||
public function getError($link)
|
||||
{
|
||||
foreach ($this->fifoErrorCodes as $i => $code) {
|
||||
unset($this->fifoErrorCodes[$i]);
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -567,6 +581,16 @@ class DbiDummy implements DbiExtension
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error or false as no error to the stack
|
||||
*
|
||||
* @param string|false $code
|
||||
*/
|
||||
public function addErrorCode($code): void
|
||||
{
|
||||
$this->fifoErrorCodes[] = $code;
|
||||
}
|
||||
|
||||
public function removeDefaultResults(): void
|
||||
{
|
||||
$this->dummyQueries = [];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user