From 4677dac58f290eb950547b16a4dcf8ea1a1cd7f1 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 28 Dec 2023 15:47:01 +0100 Subject: [PATCH 1/8] Refactor Indexes::doSaveData() Signed-off-by: Kamil Tekiela --- app/services.php | 2 +- phpstan-baseline.neon | 9 +-- psalm-baseline.xml | 9 +-- .../Table/IndexRenameController.php | 55 ++++++++++++++++- src/Controllers/Table/IndexesController.php | 59 ++++++++++++++++--- src/Table/Indexes.php | 56 ++---------------- src/Table/Table.php | 8 +-- .../Table/IndexRenameControllerTest.php | 2 +- .../Table/IndexesControllerTest.php | 2 +- .../Table/Structure/SpatialControllerTest.php | 8 +-- .../Table/Structure/UniqueControllerTest.php | 8 +-- tests/classes/Table/IndexesTest.php | 30 ++++------ 12 files changed, 142 insertions(+), 106 deletions(-) diff --git a/app/services.php b/app/services.php index 51de1ca115..993d5e7f97 100644 --- a/app/services.php +++ b/app/services.php @@ -193,7 +193,7 @@ return [ ], 'table_indexes' => [ 'class' => Indexes::class, - 'arguments' => ['$response' => '@response', '$template' => '@template', '$dbi' => '@dbi'], + 'arguments' => ['$dbi' => '@dbi'], ], 'table_maintenance' => ['class' => PhpMyAdmin\Table\Maintenance::class, 'arguments' => ['$dbi' => '@dbi']], 'table_search' => ['class' => Search::class, 'arguments' => ['$dbi' => '@dbi']], diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 90752741d6..93a34a0013 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -4931,7 +4931,7 @@ parameters: path: src/Controllers/Table/IndexRenameController.php - - message: "#^Parameter \\#7 \\$oldIndexName of method PhpMyAdmin\\\\Table\\\\Indexes\\:\\:doSaveData\\(\\) expects string, mixed given\\.$#" + message: "#^Parameter \\#6 \\$oldIndexName of method PhpMyAdmin\\\\Table\\\\Indexes\\:\\:doSaveData\\(\\) expects string, mixed given\\.$#" count: 1 path: src/Controllers/Table/IndexRenameController.php @@ -15367,7 +15367,7 @@ parameters: - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 18 + count: 19 path: src/Table/Table.php - @@ -17910,11 +17910,6 @@ parameters: count: 1 path: tests/classes/Table/IndexesTest.php - - - message: "#^Parameter \\#2 \\$haystack of method PHPUnit\\\\Framework\\\\Assert\\:\\:assertStringContainsString\\(\\) expects string, mixed given\\.$#" - count: 1 - path: tests/classes/Table/IndexesTest.php - - message: "#^Call to an undefined method PhpMyAdmin\\\\DatabaseInterface\\:\\:expects\\(\\)\\.$#" count: 4 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index c63e23a1e9..c141de8376 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -11787,9 +11787,6 @@ true|Message - - return $sqlQuery; - uiprefs =& $_SESSION['tmpval']['table_uiprefs'][$serverId][$this->dbName][$this->name]]]> @@ -15256,6 +15253,9 @@ $value + + clear + @@ -15275,9 +15275,6 @@ Config::getInstance() DatabaseInterface::getInstance() - - - method willReturn diff --git a/src/Controllers/Table/IndexRenameController.php b/src/Controllers/Table/IndexRenameController.php index 6a5d2a9b46..f528102105 100644 --- a/src/Controllers/Table/IndexRenameController.php +++ b/src/Controllers/Table/IndexRenameController.php @@ -5,10 +5,12 @@ declare(strict_types=1); namespace PhpMyAdmin\Controllers\Table; use PhpMyAdmin\Config; +use PhpMyAdmin\Container\ContainerBuilder; use PhpMyAdmin\Controllers\AbstractController; use PhpMyAdmin\Current; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\DbTableExists; +use PhpMyAdmin\Html\Generator; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Identifiers\DatabaseName; use PhpMyAdmin\Identifiers\TableName; @@ -96,16 +98,63 @@ final class IndexRenameController extends AbstractController if (isset($_POST['do_save_data'])) { $oldIndexName = $request->getParsedBodyParam('old_index', ''); - $this->indexes->doSaveData( - $request, + $previewSql = $request->hasBodyParam('preview_sql'); + + $sqlResult = $this->indexes->doSaveData( $index, true, Current::$database, Current::$table, - $request->hasBodyParam('preview_sql'), + $previewSql, $oldIndexName, ); + // If there is a request for SQL previewing. + if ($previewSql) { + $this->response->addJSON( + 'sql_data', + $this->template->render('preview_sql', ['query_data' => $sqlResult]), + ); + + return; + } + + if ($sqlResult instanceof Message) { + $this->response->setRequestStatus(false); + $this->response->addJSON('message', $sqlResult); + + return; + } + + if ($request->isAjax()) { + $message = Message::success( + __('Table %1$s has been altered successfully.'), + ); + $message->addParam(Current::$table); + $this->response->addJSON( + 'message', + Generator::getMessage($message, $sqlResult, 'success'), + ); + + $indexes = Index::getFromTable($this->dbi, Current::$table, Current::$database); + $indexesDuplicates = Index::findDuplicates(Current::$table, Current::$database); + + $this->response->addJSON( + 'index_table', + $this->template->render('indexes', [ + 'url_params' => ['db' => Current::$database, 'table' => Current::$table], + 'indexes' => $indexes, + 'indexes_duplicates' => $indexesDuplicates, + ]), + ); + + return; + } + + /** @var StructureController $controller */ + $controller = ContainerBuilder::getContainer()->get(StructureController::class); + $controller($request); + return; } diff --git a/src/Controllers/Table/IndexesController.php b/src/Controllers/Table/IndexesController.php index ced8656efb..8353823770 100644 --- a/src/Controllers/Table/IndexesController.php +++ b/src/Controllers/Table/IndexesController.php @@ -5,10 +5,12 @@ declare(strict_types=1); namespace PhpMyAdmin\Controllers\Table; use PhpMyAdmin\Config; +use PhpMyAdmin\Container\ContainerBuilder; use PhpMyAdmin\Controllers\AbstractController; use PhpMyAdmin\Current; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\DbTableExists; +use PhpMyAdmin\Html\Generator; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Identifiers\DatabaseName; use PhpMyAdmin\Identifiers\TableName; @@ -100,14 +102,55 @@ class IndexesController extends AbstractController } if (isset($_POST['do_save_data'])) { - $this->indexes->doSaveData( - $request, - $index, - false, - Current::$database, - Current::$table, - $request->hasBodyParam('preview_sql'), - ); + $previewSql = $request->hasBodyParam('preview_sql'); + + $sqlResult = $this->indexes->doSaveData($index, false, Current::$database, Current::$table, $previewSql); + + if ($sqlResult instanceof Message) { + $this->response->setRequestStatus(false); + $this->response->addJSON('message', $sqlResult); + + return; + } + + // If there is a request for SQL previewing. + if ($previewSql) { + $this->response->addJSON( + 'sql_data', + $this->template->render('preview_sql', ['query_data' => $sqlResult]), + ); + + return; + } + + if ($request->isAjax()) { + $message = Message::success( + __('Table %1$s has been altered successfully.'), + ); + $message->addParam(Current::$table); + $this->response->addJSON( + 'message', + Generator::getMessage($message, $sqlResult, 'success'), + ); + + $indexes = Index::getFromTable($this->dbi, Current::$table, Current::$database); + $indexesDuplicates = Index::findDuplicates(Current::$table, Current::$database); + + $this->response->addJSON( + 'index_table', + $this->template->render('indexes', [ + 'url_params' => ['db' => Current::$database, 'table' => Current::$table], + 'indexes' => $indexes, + 'indexes_duplicates' => $indexesDuplicates, + ]), + ); + + return; + } + + /** @var StructureController $controller */ + $controller = ContainerBuilder::getContainer()->get(StructureController::class); + $controller($request); return; } diff --git a/src/Table/Indexes.php b/src/Table/Indexes.php index f882b3350d..8457486e3a 100644 --- a/src/Table/Indexes.php +++ b/src/Table/Indexes.php @@ -4,26 +4,18 @@ declare(strict_types=1); namespace PhpMyAdmin\Table; -use PhpMyAdmin\Container\ContainerBuilder; -use PhpMyAdmin\Controllers\Table\StructureController; use PhpMyAdmin\DatabaseInterface; -use PhpMyAdmin\Html\Generator; -use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Identifiers\DatabaseName; use PhpMyAdmin\Index; use PhpMyAdmin\Message; use PhpMyAdmin\Query\Compatibility; use PhpMyAdmin\Query\Generator as QueryGenerator; -use PhpMyAdmin\ResponseRenderer; -use PhpMyAdmin\Template; use function __; final class Indexes { public function __construct( - protected ResponseRenderer $response, - protected Template $template, private DatabaseInterface $dbi, ) { } @@ -37,14 +29,13 @@ final class Indexes * @param bool $renameMode Rename the Index mode */ public function doSaveData( - ServerRequest $request, Index $index, bool $renameMode, string $db, string $table, bool $previewSql, string $oldIndexName = '', - ): void { + ): string|Message { $error = false; if ($renameMode && Compatibility::isCompatibleRenameIndex($this->dbi->getVersion())) { if ($oldIndexName === 'PRIMARY') { @@ -64,56 +55,21 @@ final class Indexes $index->getName(), ); } else { - $sqlQuery = $this->dbi->getTable($db, $table) - ->getSqlQueryForIndexCreateOrEdit($index, $error); + $sqlQuery = $this->dbi->getTable($db, $table)->getSqlQueryForIndexCreateOrEdit($index, $error); } // If there is a request for SQL previewing. if ($previewSql) { - $this->response->addJSON( - 'sql_data', - $this->template->render('preview_sql', ['query_data' => $sqlQuery]), - ); - - return; + return $sqlQuery; } - if ($error) { - $this->response->setRequestStatus(false); - $this->response->addJSON('message', $error); - - return; + if ($error instanceof Message) { + return $error; } $this->dbi->query($sqlQuery); - if ($request->isAjax()) { - $message = Message::success( - __('Table %1$s has been altered successfully.'), - ); - $message->addParam($table); - $this->response->addJSON( - 'message', - Generator::getMessage($message, $sqlQuery, 'success'), - ); - $indexes = Index::getFromTable($this->dbi, $table, $db); - $indexesDuplicates = Index::findDuplicates($table, $db); - - $this->response->addJSON( - 'index_table', - $this->template->render('indexes', [ - 'url_params' => ['db' => $db, 'table' => $table], - 'indexes' => $indexes, - 'indexes_duplicates' => $indexesDuplicates, - ]), - ); - - return; - } - - /** @var StructureController $controller */ - $controller = ContainerBuilder::getContainer()->get(StructureController::class); - $controller($request); + return $sqlQuery; } public function executeAddIndexSql(string|DatabaseName $db, string $sql): Message diff --git a/src/Table/Table.php b/src/Table/Table.php index b4acea2b30..b8c0b3b92f 100644 --- a/src/Table/Table.php +++ b/src/Table/Table.php @@ -1878,10 +1878,10 @@ class Table implements Stringable /** * Function to get the sql query for index creation or edit * - * @param Index $index current index - * @param bool $error whether error occurred or not + * @param Index $index current index + * @param Message|false $error whether error occurred or not */ - public function getSqlQueryForIndexCreateOrEdit(Index $index, bool &$error): string + public function getSqlQueryForIndexCreateOrEdit(Index $index, Message|false &$error): string { // $sql_query is the one displayed in the query box $sqlQuery = sprintf( @@ -1891,7 +1891,7 @@ class Table implements Stringable ); // Drops the old index - if (! empty($_POST['old_index'])) { + if (isset($_POST['old_index'])) { $oldIndex = is_array($_POST['old_index']) ? $_POST['old_index']['Key_name'] : $_POST['old_index']; if ($oldIndex === 'PRIMARY') { $sqlQuery .= ' DROP PRIMARY KEY,'; diff --git a/tests/classes/Controllers/Table/IndexRenameControllerTest.php b/tests/classes/Controllers/Table/IndexRenameControllerTest.php index 9248da82d7..bbdb70556b 100644 --- a/tests/classes/Controllers/Table/IndexRenameControllerTest.php +++ b/tests/classes/Controllers/Table/IndexRenameControllerTest.php @@ -48,7 +48,7 @@ class IndexRenameControllerTest extends AbstractTestCase $response, $template, $dbi, - new Indexes($response, $template, $dbi), + new Indexes($dbi), new DbTableExists($dbi), ))($request); $this->assertSame($expected, $response->getHTMLResult()); diff --git a/tests/classes/Controllers/Table/IndexesControllerTest.php b/tests/classes/Controllers/Table/IndexesControllerTest.php index bcb3f4a02c..4c946d904f 100644 --- a/tests/classes/Controllers/Table/IndexesControllerTest.php +++ b/tests/classes/Controllers/Table/IndexesControllerTest.php @@ -96,7 +96,7 @@ class IndexesControllerTest extends AbstractTestCase $response, $template, $dbi, - new Indexes($response, $template, $dbi), + new Indexes($dbi), new DbTableExists($dbi), ); diff --git a/tests/classes/Controllers/Table/Structure/SpatialControllerTest.php b/tests/classes/Controllers/Table/Structure/SpatialControllerTest.php index d382166f2b..224ad8ac4f 100644 --- a/tests/classes/Controllers/Table/Structure/SpatialControllerTest.php +++ b/tests/classes/Controllers/Table/Structure/SpatialControllerTest.php @@ -36,7 +36,7 @@ class SpatialControllerTest extends AbstractTestCase $controllerStub = $this->createMock(StructureController::class); $controllerStub->expects($this->once())->method('__invoke')->with($request); - $indexes = new Indexes(new ResponseRenderer(), new Template(), DatabaseInterface::getInstance()); + $indexes = new Indexes(DatabaseInterface::getInstance()); $controller = new SpatialController(new ResponseRenderer(), new Template(), $controllerStub, $indexes); $controller($request); @@ -64,7 +64,7 @@ class SpatialControllerTest extends AbstractTestCase $controllerStub = $this->createMock(StructureController::class); $controllerStub->expects($this->once())->method('__invoke')->with($request); - $indexes = new Indexes(new ResponseRenderer(), new Template(), DatabaseInterface::getInstance()); + $indexes = new Indexes(DatabaseInterface::getInstance()); $controller = new SpatialController(new ResponseRenderer(), new Template(), $controllerStub, $indexes); $controller($request); @@ -90,7 +90,7 @@ class SpatialControllerTest extends AbstractTestCase $controllerStub->expects($this->never())->method('__invoke'); $response = new ResponseRenderer(); - $indexes = new Indexes(new ResponseRenderer(), new Template(), DatabaseInterface::getInstance()); + $indexes = new Indexes(DatabaseInterface::getInstance()); $controller = new SpatialController($response, new Template(), $controllerStub, $indexes); $controller($request); @@ -120,7 +120,7 @@ class SpatialControllerTest extends AbstractTestCase $controllerStub = $this->createMock(StructureController::class); $controllerStub->expects($this->once())->method('__invoke')->with($request); - $indexes = new Indexes(new ResponseRenderer(), new Template(), DatabaseInterface::getInstance()); + $indexes = new Indexes(DatabaseInterface::getInstance()); $controller = new SpatialController(new ResponseRenderer(), new Template(), $controllerStub, $indexes); $controller($request); diff --git a/tests/classes/Controllers/Table/Structure/UniqueControllerTest.php b/tests/classes/Controllers/Table/Structure/UniqueControllerTest.php index 7d8dc3b923..5ec1e554ec 100644 --- a/tests/classes/Controllers/Table/Structure/UniqueControllerTest.php +++ b/tests/classes/Controllers/Table/Structure/UniqueControllerTest.php @@ -36,7 +36,7 @@ class UniqueControllerTest extends AbstractTestCase $controllerStub = $this->createMock(StructureController::class); $controllerStub->expects($this->once())->method('__invoke')->with($request); - $indexes = new Indexes(new ResponseRenderer(), new Template(), DatabaseInterface::getInstance()); + $indexes = new Indexes(DatabaseInterface::getInstance()); $controller = new UniqueController(new ResponseRenderer(), new Template(), $controllerStub, $indexes); $controller($request); @@ -64,7 +64,7 @@ class UniqueControllerTest extends AbstractTestCase $controllerStub = $this->createMock(StructureController::class); $controllerStub->expects($this->once())->method('__invoke')->with($request); - $indexes = new Indexes(new ResponseRenderer(), new Template(), DatabaseInterface::getInstance()); + $indexes = new Indexes(DatabaseInterface::getInstance()); $controller = new UniqueController(new ResponseRenderer(), new Template(), $controllerStub, $indexes); $controller($request); @@ -90,7 +90,7 @@ class UniqueControllerTest extends AbstractTestCase $controllerStub->expects($this->never())->method('__invoke'); $response = new ResponseRenderer(); - $indexes = new Indexes(new ResponseRenderer(), new Template(), DatabaseInterface::getInstance()); + $indexes = new Indexes(DatabaseInterface::getInstance()); $controller = new UniqueController($response, new Template(), $controllerStub, $indexes); $controller($request); @@ -120,7 +120,7 @@ class UniqueControllerTest extends AbstractTestCase $controllerStub = $this->createMock(StructureController::class); $controllerStub->expects($this->once())->method('__invoke')->with($request); - $indexes = new Indexes(new ResponseRenderer(), new Template(), DatabaseInterface::getInstance()); + $indexes = new Indexes(DatabaseInterface::getInstance()); $controller = new UniqueController(new ResponseRenderer(), new Template(), $controllerStub, $indexes); $controller($request); diff --git a/tests/classes/Table/IndexesTest.php b/tests/classes/Table/IndexesTest.php index 5f16a220af..cde9d42d01 100644 --- a/tests/classes/Table/IndexesTest.php +++ b/tests/classes/Table/IndexesTest.php @@ -7,13 +7,10 @@ namespace PhpMyAdmin\Tests\Table; use PhpMyAdmin\Config; use PhpMyAdmin\Current; use PhpMyAdmin\DatabaseInterface; -use PhpMyAdmin\Http\Factory\ServerRequestFactory; use PhpMyAdmin\Index; use PhpMyAdmin\Table\Indexes; use PhpMyAdmin\Table\Table; -use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; -use PhpMyAdmin\Tests\Stubs\ResponseRenderer as ResponseStub; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(Indexes::class)] @@ -65,25 +62,24 @@ class IndexesTest extends AbstractTestCase $dbi->expects($this->any())->method('getTable') ->willReturn($table); - $response = new ResponseStub(); $index = new Index(); - $indexes = new Indexes($response, new Template(), $dbi); - - $request = ServerRequestFactory::create()->createServerRequest('GET', 'http://example.com/') - ->withQueryParams(['ajax_request' => '1']); + $indexes = new Indexes($dbi); // Preview SQL - $indexes->doSaveData($request, $index, false, Current::$database, Current::$table, true); - $jsonArray = $response->getJSONResult(); - $this->assertArrayHasKey('sql_data', $jsonArray); - $this->assertStringContainsString($sqlQuery, $jsonArray['sql_data']); + $sqlResult = $indexes->doSaveData($index, false, Current::$database, Current::$table, true); + $this->assertIsString($sqlResult); + $this->assertStringContainsString($sqlQuery, $sqlResult); // Alter success - $response->clear(); - $indexes->doSaveData($request, $index, false, Current::$database, Current::$table, false); - $jsonArray = $response->getJSONResult(); - $this->assertArrayHasKey('index_table', $jsonArray); - $this->assertArrayHasKey('message', $jsonArray); + $sqlResult = $indexes->doSaveData($index, false, Current::$database, Current::$table, false); + $this->assertIsString($sqlResult); + $this->assertStringContainsString($sqlQuery, $sqlResult); + + // Error message + // Cannot be tested at the moment. + // $index->setName('PRIMARY'); // Cannot rename any index to primary so the operation should fail + // $indexes->doSaveData($index, false, Current::$database, Current::$table, false); + // $this->assertInstanceOf(Message::class, $sqlResult); } } From 1a1737c36f7155b3705a8310c7a2cd6d0dda75c7 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 28 Dec 2023 21:33:29 +0100 Subject: [PATCH 2/8] Move getSqlQueryForIndexCreateOrEdit() Signed-off-by: Kamil Tekiela --- phpstan-baseline.neon | 34 +++----- psalm-baseline.xml | 25 ++---- src/Index.php | 2 +- src/Table/Indexes.php | 129 ++++++++++++++++++++++++++-- src/Table/Table.php | 114 ------------------------ tests/classes/Table/IndexesTest.php | 73 +++++++++------- tests/classes/Table/TableTest.php | 37 -------- 7 files changed, 185 insertions(+), 229 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 93a34a0013..6f74f0d873 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -15165,6 +15165,16 @@ parameters: count: 1 path: src/Table/Indexes.php + - + message: "#^Only booleans are allowed in a negated boolean, int\\|null given\\.$#" + count: 1 + path: src/Table/Indexes.php + + - + message: "#^Parameter \\#1 \\$identifier of static method PhpMyAdmin\\\\Util\\:\\:backquote\\(\\) expects string\\|Stringable\\|null, mixed given\\.$#" + count: 1 + path: src/Table/Indexes.php + - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" count: 2 @@ -15437,7 +15447,7 @@ parameters: - message: "#^Only booleans are allowed in a negated boolean, int\\|null given\\.$#" - count: 2 + count: 1 path: src/Table/Table.php - @@ -15477,7 +15487,7 @@ parameters: - message: "#^Parameter \\#1 \\$identifier of static method PhpMyAdmin\\\\Util\\:\\:backquote\\(\\) expects string\\|Stringable\\|null, mixed given\\.$#" - count: 7 + count: 6 path: src/Table/Table.php - @@ -17895,21 +17905,6 @@ parameters: count: 1 path: tests/classes/Stubs/ResponseRenderer.php - - - message: "#^Call to an undefined method PhpMyAdmin\\\\DatabaseInterface\\:\\:expects\\(\\)\\.$#" - count: 1 - path: tests/classes/Table/IndexesTest.php - - - - message: "#^Cannot call method method\\(\\) on mixed\\.$#" - count: 1 - path: tests/classes/Table/IndexesTest.php - - - - message: "#^Cannot call method willReturn\\(\\) on mixed\\.$#" - count: 1 - path: tests/classes/Table/IndexesTest.php - - message: "#^Call to an undefined method PhpMyAdmin\\\\DatabaseInterface\\:\\:expects\\(\\)\\.$#" count: 4 @@ -17920,11 +17915,6 @@ parameters: count: 1 path: tests/classes/Table/TableTest.php - - - message: "#^Cannot access offset 'Key_name' on mixed\\.$#" - count: 1 - path: tests/classes/Table/TableTest.php - - message: "#^Cannot access offset 'SCHEMA_TABLES' on mixed\\.$#" count: 1 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index c141de8376..d147296794 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -11466,6 +11466,14 @@ + + + $oldIndex + + + getSubPart()]]> + + @@ -11736,7 +11744,6 @@ - $oldIndex @@ -11776,7 +11783,6 @@ altered]]> - getSubPart()]]> @@ -15270,19 +15276,6 @@ providerColumnMetaDefault - - - Config::getInstance() - DatabaseInterface::getInstance() - - - method - willReturn - - - expects - - providerForTestFromArray @@ -15316,8 +15309,6 @@ DatabaseInterface::getInstance() DatabaseInterface::getInstance() DatabaseInterface::getInstance() - DatabaseInterface::getInstance() - DatabaseInterface::getInstance() diff --git a/src/Index.php b/src/Index.php index 6f31c17d8f..29116955fa 100644 --- a/src/Index.php +++ b/src/Index.php @@ -209,7 +209,7 @@ class Index $key .= $params['Seq_in_index']; } - if (strlen($key) <= 0) { + if ($key === '') { return; } diff --git a/src/Table/Indexes.php b/src/Table/Indexes.php index 8457486e3a..be98025074 100644 --- a/src/Table/Indexes.php +++ b/src/Table/Indexes.php @@ -10,11 +10,18 @@ use PhpMyAdmin\Index; use PhpMyAdmin\Message; use PhpMyAdmin\Query\Compatibility; use PhpMyAdmin\Query\Generator as QueryGenerator; +use PhpMyAdmin\Util; use function __; +use function implode; +use function in_array; +use function is_array; +use function sprintf; final class Indexes { + private Message|null $error = null; + public function __construct( private DatabaseInterface $dbi, ) { @@ -36,13 +43,12 @@ final class Indexes bool $previewSql, string $oldIndexName = '', ): string|Message { - $error = false; if ($renameMode && Compatibility::isCompatibleRenameIndex($this->dbi->getVersion())) { if ($oldIndexName === 'PRIMARY') { if ($index->getName() === '') { $index->setName('PRIMARY'); } elseif ($index->getName() !== 'PRIMARY') { - $error = Message::error( + $this->error = Message::error( __('The name of the primary key must be "PRIMARY"!'), ); } @@ -55,7 +61,7 @@ final class Indexes $index->getName(), ); } else { - $sqlQuery = $this->dbi->getTable($db, $table)->getSqlQueryForIndexCreateOrEdit($index, $error); + $sqlQuery = $this->getSqlQueryForIndexCreateOrEdit($db, $table, $index); } // If there is a request for SQL previewing. @@ -63,8 +69,8 @@ final class Indexes return $sqlQuery; } - if ($error instanceof Message) { - return $error; + if ($this->error instanceof Message) { + return $this->error; } $this->dbi->query($sqlQuery); @@ -72,6 +78,119 @@ final class Indexes return $sqlQuery; } + /** + * Function to get the sql query for index creation or edit + * + * @param Index $index current index + */ + public function getSqlQueryForIndexCreateOrEdit(string $dbName, string $tableName, Index $index): string + { + // $sql_query is the one displayed in the query box + $sqlQuery = sprintf( + 'ALTER TABLE %s.%s', + Util::backquote($dbName), + Util::backquote($tableName), + ); + + // Drops the old index + if (isset($_POST['old_index'])) { + $oldIndex = is_array($_POST['old_index']) ? $_POST['old_index']['Key_name'] : $_POST['old_index']; + if ($oldIndex === 'PRIMARY') { + $sqlQuery .= ' DROP PRIMARY KEY,'; + } else { + $sqlQuery .= sprintf( + ' DROP INDEX %s,', + Util::backquote($oldIndex), + ); + } + } + + // Builds the new one + switch ($index->getChoice()) { + case 'PRIMARY': + if ($index->getName() == '') { + $index->setName('PRIMARY'); + } elseif ($index->getName() !== 'PRIMARY') { + $this->error = Message::error( + __('The name of the primary key must be "PRIMARY"!'), + ); + } + + $sqlQuery .= ' ADD PRIMARY KEY'; + break; + case 'FULLTEXT': + case 'UNIQUE': + case 'INDEX': + case 'SPATIAL': + if ($index->getName() === 'PRIMARY') { + $this->error = Message::error( + __('Can\'t rename index to PRIMARY!'), + ); + } + + $sqlQuery .= sprintf( + ' ADD %s', + $index->getChoice(), + ); + if ($index->getName() !== '') { + $sqlQuery .= ' ' . Util::backquote($index->getName()); + } + + break; + } + + $indexFields = []; + foreach ($index->getColumns() as $key => $column) { + $indexFields[$key] = Util::backquote($column->getName()); + if (! $column->getSubPart()) { + continue; + } + + $indexFields[$key] .= '(' . $column->getSubPart() . ')'; + } + + if ($indexFields === []) { + $this->error = Message::error(__('No index parts defined!')); + } else { + $sqlQuery .= ' (' . implode(', ', $indexFields) . ')'; + } + + $keyBlockSizes = $index->getKeyBlockSize(); + if ($keyBlockSizes !== 0) { + $sqlQuery .= ' KEY_BLOCK_SIZE = ' . $keyBlockSizes; + } + + // specifying index type is allowed only for primary, unique and index only + // TokuDB is using Fractal Tree, Using Type is not useless + // Ref: https://mariadb.com/kb/en/storage-engine-index-types/ + $type = $index->getType(); + if ( + $index->getChoice() !== 'SPATIAL' + && $index->getChoice() !== 'FULLTEXT' + && in_array($type, Index::getIndexTypes(), true) + && ! $this->dbi->getTable($dbName, $tableName)->isEngine('TOKUDB') + ) { + $sqlQuery .= ' USING ' . $type; + } + + $parser = $index->getParser(); + if ($index->getChoice() === 'FULLTEXT' && $parser !== '') { + $sqlQuery .= ' WITH PARSER ' . $parser; + } + + $comment = $index->getComment(); + if ($comment !== '') { + $sqlQuery .= sprintf( + ' COMMENT %s', + $this->dbi->quoteString($comment), + ); + } + + $sqlQuery .= ';'; + + return $sqlQuery; + } + public function executeAddIndexSql(string|DatabaseName $db, string $sql): Message { $this->dbi->selectDb($db); diff --git a/src/Table/Table.php b/src/Table/Table.php index b8c0b3b92f..71f17fff35 100644 --- a/src/Table/Table.php +++ b/src/Table/Table.php @@ -1875,120 +1875,6 @@ class Table implements Stringable return Index::singleton($this->dbi, $this->dbName, $this->name, $index); } - /** - * Function to get the sql query for index creation or edit - * - * @param Index $index current index - * @param Message|false $error whether error occurred or not - */ - public function getSqlQueryForIndexCreateOrEdit(Index $index, Message|false &$error): string - { - // $sql_query is the one displayed in the query box - $sqlQuery = sprintf( - 'ALTER TABLE %s.%s', - Util::backquote($this->dbName), - Util::backquote($this->name), - ); - - // Drops the old index - if (isset($_POST['old_index'])) { - $oldIndex = is_array($_POST['old_index']) ? $_POST['old_index']['Key_name'] : $_POST['old_index']; - if ($oldIndex === 'PRIMARY') { - $sqlQuery .= ' DROP PRIMARY KEY,'; - } else { - $sqlQuery .= sprintf( - ' DROP INDEX %s,', - Util::backquote($oldIndex), - ); - } - } - - // Builds the new one - switch ($index->getChoice()) { - case 'PRIMARY': - if ($index->getName() == '') { - $index->setName('PRIMARY'); - } elseif ($index->getName() !== 'PRIMARY') { - $error = Message::error( - __('The name of the primary key must be "PRIMARY"!'), - ); - } - - $sqlQuery .= ' ADD PRIMARY KEY'; - break; - case 'FULLTEXT': - case 'UNIQUE': - case 'INDEX': - case 'SPATIAL': - if ($index->getName() === 'PRIMARY') { - $error = Message::error( - __('Can\'t rename index to PRIMARY!'), - ); - } - - $sqlQuery .= sprintf( - ' ADD %s', - $index->getChoice(), - ); - if ($index->getName() !== '') { - $sqlQuery .= ' ' . Util::backquote($index->getName()); - } - - break; - } - - $indexFields = []; - foreach ($index->getColumns() as $key => $column) { - $indexFields[$key] = Util::backquote($column->getName()); - if (! $column->getSubPart()) { - continue; - } - - $indexFields[$key] .= '(' . $column->getSubPart() . ')'; - } - - if ($indexFields === []) { - $error = Message::error(__('No index parts defined!')); - } else { - $sqlQuery .= ' (' . implode(', ', $indexFields) . ')'; - } - - $keyBlockSizes = $index->getKeyBlockSize(); - if ($keyBlockSizes !== 0) { - $sqlQuery .= ' KEY_BLOCK_SIZE = ' . $keyBlockSizes; - } - - // specifying index type is allowed only for primary, unique and index only - // TokuDB is using Fractal Tree, Using Type is not useless - // Ref: https://mariadb.com/kb/en/storage-engine-index-types/ - $type = $index->getType(); - if ( - $index->getChoice() !== 'SPATIAL' - && $index->getChoice() !== 'FULLTEXT' - && in_array($type, Index::getIndexTypes(), true) - && ! $this->isEngine('TOKUDB') - ) { - $sqlQuery .= ' USING ' . $type; - } - - $parser = $index->getParser(); - if ($index->getChoice() === 'FULLTEXT' && $parser !== '') { - $sqlQuery .= ' WITH PARSER ' . $parser; - } - - $comment = $index->getComment(); - if ($comment !== '') { - $sqlQuery .= sprintf( - ' COMMENT %s', - $this->dbi->quoteString($comment), - ); - } - - $sqlQuery .= ';'; - - return $sqlQuery; - } - /** * Function to handle update for display field * diff --git a/tests/classes/Table/IndexesTest.php b/tests/classes/Table/IndexesTest.php index cde9d42d01..e9f18eac16 100644 --- a/tests/classes/Table/IndexesTest.php +++ b/tests/classes/Table/IndexesTest.php @@ -4,67 +4,52 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Table; -use PhpMyAdmin\Config; use PhpMyAdmin\Current; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Index; +use PhpMyAdmin\Message; use PhpMyAdmin\Table\Indexes; use PhpMyAdmin\Table\Table; use PhpMyAdmin\Tests\AbstractTestCase; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\MockObject\MockObject; #[CoversClass(Indexes::class)] class IndexesTest extends AbstractTestCase { + private DatabaseInterface&MockObject $dbi; + protected function setUp(): void { parent::setUp(); - /** - * SET these to avoid undefined index error - */ Current::$database = 'db'; Current::$table = 'table'; - $config = Config::getInstance(); - $config->selectedServer['pmadb'] = ''; - $config->selectedServer['DisableIS'] = false; - $GLOBALS['urlParams'] = ['db' => 'db', 'server' => 1]; - $dbi = $this->getMockBuilder(DatabaseInterface::class) + $this->dbi = $this->getMockBuilder(DatabaseInterface::class) ->disableOriginalConstructor() ->getMock(); - - $indexs = [ - ['Schema' => 'Schema1', 'Key_name' => 'Key_name1', 'Column_name' => 'Column_name1'], - ['Schema' => 'Schema2', 'Key_name' => 'Key_name2', 'Column_name' => 'Column_name2'], - ['Schema' => 'Schema3', 'Key_name' => 'Key_name3', 'Column_name' => 'Column_name3'], - ]; - - $dbi->expects($this->any())->method('getTableIndexes') - ->willReturn($indexs); - - DatabaseInterface::$instance = $dbi; - - //$_SESSION } public function testDoSaveData(): void { - $sqlQuery = 'ALTER TABLE `db`.`table` DROP PRIMARY KEY, ADD UNIQUE ;'; + $sqlQuery = 'ALTER TABLE `db`.`table` DROP PRIMARY KEY, ADD PRIMARY KEY (`id`);'; $table = $this->getMockBuilder(Table::class) ->disableOriginalConstructor() ->getMock(); - $table->expects($this->any())->method('getSqlQueryForIndexCreateOrEdit') - ->willReturn($sqlQuery); - - $dbi = DatabaseInterface::getInstance(); - $dbi->expects($this->any())->method('getTable') + $this->dbi->expects($this->any())->method('getTable') ->willReturn($table); $index = new Index(); + $index->set([ + 'Key_name' => 'PRIMARY', + 'columns' => [['Column_name' => 'id']], + ]); - $indexes = new Indexes($dbi); + $indexes = new Indexes($this->dbi); + + $_POST['old_index'] = 'PRIMARY'; // Preview SQL $sqlResult = $indexes->doSaveData($index, false, Current::$database, Current::$table, true); @@ -77,9 +62,31 @@ class IndexesTest extends AbstractTestCase $this->assertStringContainsString($sqlQuery, $sqlResult); // Error message - // Cannot be tested at the moment. - // $index->setName('PRIMARY'); // Cannot rename any index to primary so the operation should fail - // $indexes->doSaveData($index, false, Current::$database, Current::$table, false); - // $this->assertInstanceOf(Message::class, $sqlResult); + $index->setName('NOT PRIMARY'); // Cannot rename primary so the operation should fail + $sqlResult = $indexes->doSaveData($index, false, Current::$database, Current::$table, false); + $this->assertInstanceOf(Message::class, $sqlResult); + } + + public function testGetSqlQueryForIndexCreateOrEdit(): void + { + $table = $this->getMockBuilder(Table::class) + ->disableOriginalConstructor() + ->getMock(); + $this->dbi->expects($this->any())->method('getTable') + ->willReturn($table); + $indexes = new Indexes($this->dbi); + + $db = 'pma_db'; + $table = 'pma_table'; + $index = new Index(); + + $_POST['old_index'] = 'PRIMARY'; + $sql = $indexes->getSqlQueryForIndexCreateOrEdit($db, $table, $index); + $this->assertEquals('ALTER TABLE `pma_db`.`pma_table` DROP PRIMARY KEY, ADD UNIQUE;', $sql); + + $_POST['old_index'] = []; + $_POST['old_index']['Key_name'] = 'PRIMARY'; + $sql = $indexes->getSqlQueryForIndexCreateOrEdit($db, $table, $index); + $this->assertEquals('ALTER TABLE `pma_db`.`pma_table` DROP PRIMARY KEY, ADD UNIQUE;', $sql); } } diff --git a/tests/classes/Table/TableTest.php b/tests/classes/Table/TableTest.php index 3d4b81969a..e00096c26f 100644 --- a/tests/classes/Table/TableTest.php +++ b/tests/classes/Table/TableTest.php @@ -9,7 +9,6 @@ use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Dbal\Connection; -use PhpMyAdmin\Index; use PhpMyAdmin\ListDatabase; use PhpMyAdmin\Query\Cache; use PhpMyAdmin\SqlParser\Context; @@ -1180,42 +1179,6 @@ class TableTest extends AbstractTestCase $this->assertEquals($sqlExcepted, $sql); } - /** - * Tests for getSqlQueryForIndexCreateOrEdit() method. - */ - public function testGetSqlQueryForIndexCreateOrEdit(): void - { - $db = 'pma_db'; - $table = 'pma_table'; - $index = new Index(); - $error = false; - - $_POST['old_index'] = 'PRIMARY'; - - $table = new Table($table, $db, DatabaseInterface::getInstance()); - $sql = $table->getSqlQueryForIndexCreateOrEdit($index, $error); - - $this->assertEquals('ALTER TABLE `pma_db`.`pma_table` DROP PRIMARY KEY, ADD UNIQUE;', $sql); - } - - /** - * Tests for getSqlQueryForIndexCreateOrEdit() method. - */ - public function testGetSqlQueryForIndexCreateOrEditSecondFormat(): void - { - $db = 'pma_db'; - $table = 'pma_table'; - $index = new Index(); - $error = false; - - $_POST['old_index']['Key_name'] = 'PRIMARY'; - - $table = new Table($table, $db, DatabaseInterface::getInstance()); - $sql = $table->getSqlQueryForIndexCreateOrEdit($index, $error); - - $this->assertEquals('ALTER TABLE `pma_db`.`pma_table` DROP PRIMARY KEY, ADD UNIQUE;', $sql); - } - /** * Test for getColumns */ From 187d9488661e4d5f7a4ccb37c323af94dbbdedf3 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 28 Dec 2023 22:09:31 +0100 Subject: [PATCH 3/8] Redesign IndexRenameController Signed-off-by: Kamil Tekiela --- psalm-baseline.xml | 11 +- .../templates/table/index_rename_form.twig | 2 +- .../Table/IndexRenameController.php | 209 ++++++++---------- .../Table/IndexRenameControllerTest.php | 7 +- 4 files changed, 95 insertions(+), 134 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index d147296794..e5a783b6a4 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -3568,20 +3568,15 @@ + $indexName + $indexName $oldIndexName + $indexName $oldIndexName - - - $oldIndex - - - - $oldIndex - diff --git a/resources/templates/table/index_rename_form.twig b/resources/templates/table/index_rename_form.twig index a57ecca0dc..58552cd0f1 100644 --- a/resources/templates/table/index_rename_form.twig +++ b/resources/templates/table/index_rename_form.twig @@ -15,7 +15,7 @@ checkParameters(['db', 'table'])) { - return; - } - - $GLOBALS['urlParams'] = ['db' => Current::$database, 'table' => Current::$table]; - $GLOBALS['errorUrl'] = Util::getScriptNameForOption( - Config::getInstance()->settings['DefaultTabTable'], - 'table', - ); - $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); - - $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { - if ($request->isAjax()) { - $this->response->setRequestStatus(false); - $this->response->addJSON('message', Message::error(__('No databases selected.'))); - - return; - } - - $this->redirect('/', ['reload' => true, 'message' => __('No databases selected.')]); - - return; - } - - $tableName = TableName::tryFrom($request->getParam('table')); - if ($tableName === null || ! $this->dbTableExists->hasTable($databaseName, $tableName)) { - if ($request->isAjax()) { - $this->response->setRequestStatus(false); - $this->response->addJSON('message', Message::error(__('No table selected.'))); - - return; - } - - $this->redirect('/', ['reload' => true, 'message' => __('No table selected.')]); - - return; - } + if (! $this->checkParameters(['db', 'table'])) { + return; } - if (isset($_POST['index'])) { - if (is_array($_POST['index'])) { - // coming already from form - $oldIndex = is_array($_POST['old_index']) ? $_POST['old_index']['Key_name'] : $_POST['old_index']; - $index = clone $this->dbi->getTable(Current::$database, Current::$table)->getIndex($oldIndex); - $index->setName($_POST['index']['Key_name']); - } else { - $index = $this->dbi->getTable(Current::$database, Current::$table)->getIndex($_POST['index']); - } - } else { - $index = new Index(); - } - - if (isset($_POST['do_save_data'])) { - $oldIndexName = $request->getParsedBodyParam('old_index', ''); - $previewSql = $request->hasBodyParam('preview_sql'); - - $sqlResult = $this->indexes->doSaveData( - $index, - true, - Current::$database, - Current::$table, - $previewSql, - $oldIndexName, - ); - - // If there is a request for SQL previewing. - if ($previewSql) { - $this->response->addJSON( - 'sql_data', - $this->template->render('preview_sql', ['query_data' => $sqlResult]), - ); - - return; - } - - if ($sqlResult instanceof Message) { - $this->response->setRequestStatus(false); - $this->response->addJSON('message', $sqlResult); - - return; - } + $GLOBALS['urlParams'] = ['db' => Current::$database, 'table' => Current::$table]; + $GLOBALS['errorUrl'] = Util::getScriptNameForOption( + Config::getInstance()->settings['DefaultTabTable'], + 'table', + ); + $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); + $databaseName = DatabaseName::tryFrom($request->getParam('db')); + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { - $message = Message::success( - __('Table %1$s has been altered successfully.'), - ); - $message->addParam(Current::$table); - $this->response->addJSON( - 'message', - Generator::getMessage($message, $sqlResult, 'success'), - ); - - $indexes = Index::getFromTable($this->dbi, Current::$table, Current::$database); - $indexesDuplicates = Index::findDuplicates(Current::$table, Current::$database); - - $this->response->addJSON( - 'index_table', - $this->template->render('indexes', [ - 'url_params' => ['db' => Current::$database, 'table' => Current::$table], - 'indexes' => $indexes, - 'indexes_duplicates' => $indexesDuplicates, - ]), - ); + $this->response->setRequestStatus(false); + $this->response->addJSON('message', Message::error(__('No databases selected.'))); return; } - /** @var StructureController $controller */ - $controller = ContainerBuilder::getContainer()->get(StructureController::class); - $controller($request); + $this->redirect('/', ['reload' => true, 'message' => __('No databases selected.')]); return; } - $this->displayRenameForm($index); - } + $tableName = TableName::tryFrom($request->getParam('table')); + if ($tableName === null || ! $this->dbTableExists->hasTable($databaseName, $tableName)) { + if ($request->isAjax()) { + $this->response->setRequestStatus(false); + $this->response->addJSON('message', Message::error(__('No table selected.'))); - /** - * Display the rename form to rename an index - * - * @param Index $index An Index instance. - */ - private function displayRenameForm(Index $index): void - { - $this->dbi->selectDb(Current::$database); + return; + } - $formParams = ['db' => Current::$database, 'table' => Current::$table]; + $this->redirect('/', ['reload' => true, 'message' => __('No table selected.')]); - if (isset($_POST['old_index'])) { - $formParams['old_index'] = $_POST['old_index']; - } elseif (isset($_POST['index'])) { - $formParams['old_index'] = $_POST['index']; + return; } - $this->render('table/index_rename_form', ['index' => $index, 'form_params' => $formParams]); + $oldIndexName = $request->getParsedBodyParam('old_index'); + $indexName = $request->getParsedBodyParam('index'); + if ($oldIndexName === null) { + $index = $this->dbi->getTable($databaseName->getName(), $tableName->getName())->getIndex($indexName); + + $formParams = [ + 'db' => $databaseName->getName(), + 'table' => $tableName->getName(), + 'old_index' => $index->getName(), + ]; + + $this->render('table/index_rename_form', ['index' => $index, 'form_params' => $formParams]); + + return; + } + + // coming already from form + $index = $this->dbi->getTable($databaseName->getName(), $tableName->getName())->getIndex($oldIndexName); + $index->setName($indexName); + + $previewSql = $request->hasBodyParam('preview_sql'); + + $sqlResult = $this->indexes->doSaveData( + $index, + true, + $databaseName->getName(), + $tableName->getName(), + $previewSql, + $oldIndexName, + ); + + if ($previewSql) { + $this->response->addJSON( + 'sql_data', + $this->template->render('preview_sql', ['query_data' => $sqlResult]), + ); + + return; + } + + if ($sqlResult instanceof Message) { + $this->response->setRequestStatus(false); + $this->response->addJSON('message', $sqlResult); + + return; + } + + $message = Message::success(__('Table %1$s has been altered successfully.')); + $message->addParam($tableName->getName()); + $this->response->addJSON( + 'message', + Generator::getMessage($message, $sqlResult, 'success'), + ); + + $indexes = Index::getFromTable($this->dbi, $tableName->getName(), $databaseName->getName()); + $indexesDuplicates = Index::findDuplicates($tableName->getName(), $databaseName->getName()); + + $this->response->addJSON( + 'index_table', + $this->template->render('indexes', [ + 'url_params' => ['db' => $databaseName->getName(), 'table' => $tableName->getName()], + 'indexes' => $indexes, + 'indexes_duplicates' => $indexesDuplicates, + ]), + ); } } diff --git a/tests/classes/Controllers/Table/IndexRenameControllerTest.php b/tests/classes/Controllers/Table/IndexRenameControllerTest.php index bbdb70556b..c8966680ed 100644 --- a/tests/classes/Controllers/Table/IndexRenameControllerTest.php +++ b/tests/classes/Controllers/Table/IndexRenameControllerTest.php @@ -36,12 +36,13 @@ class IndexRenameControllerTest extends AbstractTestCase $template = new Template(); $expected = $template->render('table/index_rename_form', [ - 'index' => new Index(), - 'form_params' => ['db' => 'test_db', 'table' => 'test_table'], + 'index' => new Index(['Key_name' => 'index']), + 'form_params' => ['db' => 'test_db', 'table' => 'test_table', 'old_index' => 'index'], ]); $request = ServerRequestFactory::create()->createServerRequest('GET', 'http://example.com/') - ->withQueryParams(['db' => 'test_db', 'table' => 'test_table']); + ->withQueryParams(['db' => 'test_db', 'table' => 'test_table']) + ->withParsedBody(['index' => 'index']); $response = new ResponseRenderer(); (new IndexRenameController( From b22dc9e4aa7b4375dd39c7b90184090e1672f7a9 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 28 Dec 2023 23:37:06 +0100 Subject: [PATCH 4/8] Remove doSaveData() method Signed-off-by: Kamil Tekiela --- phpstan-baseline.neon | 4 +- .../Table/IndexRenameController.php | 17 ++-- src/Controllers/Table/IndexesController.php | 23 +++--- src/Table/Indexes.php | 81 +++++++------------ tests/classes/Table/IndexesTest.php | 50 +++++------- 5 files changed, 74 insertions(+), 101 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 6f74f0d873..e5b2227864 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -4926,12 +4926,12 @@ parameters: path: src/Controllers/Table/IndexRenameController.php - - message: "#^Parameter \\#1 \\$params of static method PhpMyAdmin\\\\Url\\:\\:getCommon\\(\\) expects array\\, mixed given\\.$#" + message: "#^Parameter \\#1 \\$oldIndexName of method PhpMyAdmin\\\\Table\\\\Indexes\\:\\:getSqlQueryForRename\\(\\) expects string, mixed given\\.$#" count: 1 path: src/Controllers/Table/IndexRenameController.php - - message: "#^Parameter \\#6 \\$oldIndexName of method PhpMyAdmin\\\\Table\\\\Indexes\\:\\:doSaveData\\(\\) expects string, mixed given\\.$#" + message: "#^Parameter \\#1 \\$params of static method PhpMyAdmin\\\\Url\\:\\:getCommon\\(\\) expects array\\, mixed given\\.$#" count: 1 path: src/Controllers/Table/IndexRenameController.php diff --git a/src/Controllers/Table/IndexRenameController.php b/src/Controllers/Table/IndexRenameController.php index 0deba28fa0..9f9b40c917 100644 --- a/src/Controllers/Table/IndexRenameController.php +++ b/src/Controllers/Table/IndexRenameController.php @@ -101,36 +101,37 @@ final class IndexRenameController extends AbstractController $previewSql = $request->hasBodyParam('preview_sql'); - $sqlResult = $this->indexes->doSaveData( + $sqlQuery = $this->indexes->getSqlQueryForRename( + $oldIndexName, $index, - true, $databaseName->getName(), $tableName->getName(), - $previewSql, - $oldIndexName, ); if ($previewSql) { $this->response->addJSON( 'sql_data', - $this->template->render('preview_sql', ['query_data' => $sqlResult]), + $this->template->render('preview_sql', ['query_data' => $sqlQuery]), ); return; } - if ($sqlResult instanceof Message) { + $logicError = $this->indexes->getError(); + if ($logicError instanceof Message) { $this->response->setRequestStatus(false); - $this->response->addJSON('message', $sqlResult); + $this->response->addJSON('message', $logicError); return; } + $this->dbi->query($sqlQuery); + $message = Message::success(__('Table %1$s has been altered successfully.')); $message->addParam($tableName->getName()); $this->response->addJSON( 'message', - Generator::getMessage($message, $sqlResult, 'success'), + Generator::getMessage($message, $sqlQuery, 'success'), ); $indexes = Index::getFromTable($this->dbi, $tableName->getName(), $databaseName->getName()); diff --git a/src/Controllers/Table/IndexesController.php b/src/Controllers/Table/IndexesController.php index 8353823770..784487827b 100644 --- a/src/Controllers/Table/IndexesController.php +++ b/src/Controllers/Table/IndexesController.php @@ -104,25 +104,28 @@ class IndexesController extends AbstractController if (isset($_POST['do_save_data'])) { $previewSql = $request->hasBodyParam('preview_sql'); - $sqlResult = $this->indexes->doSaveData($index, false, Current::$database, Current::$table, $previewSql); - - if ($sqlResult instanceof Message) { - $this->response->setRequestStatus(false); - $this->response->addJSON('message', $sqlResult); - - return; - } + $sqlQuery = $this->indexes->getSqlQueryForIndexCreateOrEdit(Current::$database, Current::$table, $index); // If there is a request for SQL previewing. if ($previewSql) { $this->response->addJSON( 'sql_data', - $this->template->render('preview_sql', ['query_data' => $sqlResult]), + $this->template->render('preview_sql', ['query_data' => $sqlQuery]), ); return; } + $logicError = $this->indexes->getError(); + if ($logicError instanceof Message) { + $this->response->setRequestStatus(false); + $this->response->addJSON('message', $logicError); + + return; + } + + $this->dbi->query($sqlQuery); + if ($request->isAjax()) { $message = Message::success( __('Table %1$s has been altered successfully.'), @@ -130,7 +133,7 @@ class IndexesController extends AbstractController $message->addParam(Current::$table); $this->response->addJSON( 'message', - Generator::getMessage($message, $sqlResult, 'success'), + Generator::getMessage($message, $sqlQuery, 'success'), ); $indexes = Index::getFromTable($this->dbi, Current::$table, Current::$database); diff --git a/src/Table/Indexes.php b/src/Table/Indexes.php index be98025074..6887cfe6be 100644 --- a/src/Table/Indexes.php +++ b/src/Table/Indexes.php @@ -22,60 +22,13 @@ final class Indexes { private Message|null $error = null; - public function __construct( - private DatabaseInterface $dbi, - ) { + public function __construct(private readonly DatabaseInterface $dbi) + { } - /** - * Process the data from the edit/create index form, - * run the query to build the new index - * and moves back to /table/sql - * - * @param Index $index An Index instance. - * @param bool $renameMode Rename the Index mode - */ - public function doSaveData( - Index $index, - bool $renameMode, - string $db, - string $table, - bool $previewSql, - string $oldIndexName = '', - ): string|Message { - if ($renameMode && Compatibility::isCompatibleRenameIndex($this->dbi->getVersion())) { - if ($oldIndexName === 'PRIMARY') { - if ($index->getName() === '') { - $index->setName('PRIMARY'); - } elseif ($index->getName() !== 'PRIMARY') { - $this->error = Message::error( - __('The name of the primary key must be "PRIMARY"!'), - ); - } - } - - $sqlQuery = QueryGenerator::getSqlQueryForIndexRename( - $db, - $table, - $oldIndexName, - $index->getName(), - ); - } else { - $sqlQuery = $this->getSqlQueryForIndexCreateOrEdit($db, $table, $index); - } - - // If there is a request for SQL previewing. - if ($previewSql) { - return $sqlQuery; - } - - if ($this->error instanceof Message) { - return $this->error; - } - - $this->dbi->query($sqlQuery); - - return $sqlQuery; + public function getError(): Message|null + { + return $this->error; } /** @@ -191,6 +144,30 @@ final class Indexes return $sqlQuery; } + public function getSqlQueryForRename(string $oldIndexName, Index $index, string $db, string $table): string + { + if (! Compatibility::isCompatibleRenameIndex($this->dbi->getVersion())) { + return $this->getSqlQueryForIndexCreateOrEdit($db, $table, $index); + } + + if ($oldIndexName === 'PRIMARY') { + if ($index->getName() === '') { + $index->setName('PRIMARY'); + } elseif ($index->getName() !== 'PRIMARY') { + $this->error = Message::error( + __('The name of the primary key must be "PRIMARY"!'), + ); + } + } + + return QueryGenerator::getSqlQueryForIndexRename( + $db, + $table, + $oldIndexName, + $index->getName(), + ); + } + public function executeAddIndexSql(string|DatabaseName $db, string $sql): Message { $this->dbi->selectDb($db); diff --git a/tests/classes/Table/IndexesTest.php b/tests/classes/Table/IndexesTest.php index e9f18eac16..0f146b041c 100644 --- a/tests/classes/Table/IndexesTest.php +++ b/tests/classes/Table/IndexesTest.php @@ -31,40 +31,24 @@ class IndexesTest extends AbstractTestCase ->getMock(); } - public function testDoSaveData(): void + public function testGetSqlQueryForRename(): void { - $sqlQuery = 'ALTER TABLE `db`.`table` DROP PRIMARY KEY, ADD PRIMARY KEY (`id`);'; + $sqlQuery = 'ALTER TABLE `db`.`table` RENAME INDEX `0` TO `ABC`;'; - $table = $this->getMockBuilder(Table::class) - ->disableOriginalConstructor() - ->getMock(); - $this->dbi->expects($this->any())->method('getTable') - ->willReturn($table); + $this->dbi->expects($this->any())->method('getVersion') + ->willReturn(50700); - $index = new Index(); - $index->set([ - 'Key_name' => 'PRIMARY', - 'columns' => [['Column_name' => 'id']], - ]); + $index = new Index(['Key_name' => 'ABC']); $indexes = new Indexes($this->dbi); - $_POST['old_index'] = 'PRIMARY'; - - // Preview SQL - $sqlResult = $indexes->doSaveData($index, false, Current::$database, Current::$table, true); - $this->assertIsString($sqlResult); - $this->assertStringContainsString($sqlQuery, $sqlResult); - - // Alter success - $sqlResult = $indexes->doSaveData($index, false, Current::$database, Current::$table, false); - $this->assertIsString($sqlResult); + $sqlResult = $indexes->getSqlQueryForRename('0', $index, Current::$database, Current::$table); $this->assertStringContainsString($sqlQuery, $sqlResult); // Error message $index->setName('NOT PRIMARY'); // Cannot rename primary so the operation should fail - $sqlResult = $indexes->doSaveData($index, false, Current::$database, Current::$table, false); - $this->assertInstanceOf(Message::class, $sqlResult); + $indexes->getSqlQueryForRename('PRIMARY', $index, Current::$database, Current::$table); + $this->assertInstanceOf(Message::class, $indexes->getError()); } public function testGetSqlQueryForIndexCreateOrEdit(): void @@ -78,15 +62,23 @@ class IndexesTest extends AbstractTestCase $db = 'pma_db'; $table = 'pma_table'; - $index = new Index(); + $index = new Index([ + 'Key_name' => 'PRIMARY', + 'columns' => [['Column_name' => 'id']], + ]); + + $sqlQueryExpected = 'ALTER TABLE `pma_db`.`pma_table` DROP PRIMARY KEY, ADD PRIMARY KEY (`id`);'; $_POST['old_index'] = 'PRIMARY'; - $sql = $indexes->getSqlQueryForIndexCreateOrEdit($db, $table, $index); - $this->assertEquals('ALTER TABLE `pma_db`.`pma_table` DROP PRIMARY KEY, ADD UNIQUE;', $sql); + $this->assertEquals($sqlQueryExpected, $indexes->getSqlQueryForIndexCreateOrEdit($db, $table, $index)); $_POST['old_index'] = []; $_POST['old_index']['Key_name'] = 'PRIMARY'; - $sql = $indexes->getSqlQueryForIndexCreateOrEdit($db, $table, $index); - $this->assertEquals('ALTER TABLE `pma_db`.`pma_table` DROP PRIMARY KEY, ADD UNIQUE;', $sql); + $this->assertEquals($sqlQueryExpected, $indexes->getSqlQueryForIndexCreateOrEdit($db, $table, $index)); + + // Error message + $index->setName('NOT PRIMARY'); // Cannot rename primary so the operation should fail + $indexes->getSqlQueryForIndexCreateOrEdit($db, $table, $index); + $this->assertInstanceOf(Message::class, $indexes->getError()); } } From 6e2d43bdd978eb628b45b14537e68b837188d0de Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 28 Dec 2023 23:50:34 +0100 Subject: [PATCH 5/8] Add $oldIndexName as param Signed-off-by: Kamil Tekiela --- phpstan-baseline.neon | 10 +++++----- psalm-baseline.xml | 4 +--- src/Controllers/Table/IndexesController.php | 12 +++++++++++- src/Table/Indexes.php | 18 ++++++++++-------- tests/classes/Table/IndexesTest.php | 11 +++++------ 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e5b2227864..2e3ece07e6 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -4955,6 +4955,11 @@ parameters: count: 1 path: src/Controllers/Table/IndexesController.php + - + message: "#^Parameter \\#1 \\$oldIndexName of method PhpMyAdmin\\\\Table\\\\Indexes\\:\\:getSqlQueryForIndexCreateOrEdit\\(\\) expects string\\|null, mixed given\\.$#" + count: 1 + path: src/Controllers/Table/IndexesController.php + - message: "#^Parameter \\#1 \\$params of static method PhpMyAdmin\\\\Url\\:\\:getCommon\\(\\) expects array\\, mixed given\\.$#" count: 1 @@ -15170,11 +15175,6 @@ parameters: count: 1 path: src/Table/Indexes.php - - - message: "#^Parameter \\#1 \\$identifier of static method PhpMyAdmin\\\\Util\\:\\:backquote\\(\\) expects string\\|Stringable\\|null, mixed given\\.$#" - count: 1 - path: src/Table/Indexes.php - - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" count: 2 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index e5a783b6a4..b852af6f2a 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -3596,6 +3596,7 @@ + $oldIndex @@ -11462,9 +11463,6 @@ - - $oldIndex - getSubPart()]]> diff --git a/src/Controllers/Table/IndexesController.php b/src/Controllers/Table/IndexesController.php index 784487827b..368d4fd098 100644 --- a/src/Controllers/Table/IndexesController.php +++ b/src/Controllers/Table/IndexesController.php @@ -103,8 +103,18 @@ class IndexesController extends AbstractController if (isset($_POST['do_save_data'])) { $previewSql = $request->hasBodyParam('preview_sql'); + if (isset($_POST['old_index'])) { + $oldIndex = is_array($_POST['old_index']) ? $_POST['old_index']['Key_name'] : $_POST['old_index']; + } else { + $oldIndex = null; + } - $sqlQuery = $this->indexes->getSqlQueryForIndexCreateOrEdit(Current::$database, Current::$table, $index); + $sqlQuery = $this->indexes->getSqlQueryForIndexCreateOrEdit( + $oldIndex, + $index, + Current::$database, + Current::$table, + ); // If there is a request for SQL previewing. if ($previewSql) { diff --git a/src/Table/Indexes.php b/src/Table/Indexes.php index 6887cfe6be..cd22adf816 100644 --- a/src/Table/Indexes.php +++ b/src/Table/Indexes.php @@ -15,7 +15,6 @@ use PhpMyAdmin\Util; use function __; use function implode; use function in_array; -use function is_array; use function sprintf; final class Indexes @@ -36,8 +35,12 @@ final class Indexes * * @param Index $index current index */ - public function getSqlQueryForIndexCreateOrEdit(string $dbName, string $tableName, Index $index): string - { + public function getSqlQueryForIndexCreateOrEdit( + string|null $oldIndexName, + Index $index, + string $dbName, + string $tableName, + ): string { // $sql_query is the one displayed in the query box $sqlQuery = sprintf( 'ALTER TABLE %s.%s', @@ -46,14 +49,13 @@ final class Indexes ); // Drops the old index - if (isset($_POST['old_index'])) { - $oldIndex = is_array($_POST['old_index']) ? $_POST['old_index']['Key_name'] : $_POST['old_index']; - if ($oldIndex === 'PRIMARY') { + if ($oldIndexName !== null) { + if ($oldIndexName === 'PRIMARY') { $sqlQuery .= ' DROP PRIMARY KEY,'; } else { $sqlQuery .= sprintf( ' DROP INDEX %s,', - Util::backquote($oldIndex), + Util::backquote($oldIndexName), ); } } @@ -147,7 +149,7 @@ final class Indexes public function getSqlQueryForRename(string $oldIndexName, Index $index, string $db, string $table): string { if (! Compatibility::isCompatibleRenameIndex($this->dbi->getVersion())) { - return $this->getSqlQueryForIndexCreateOrEdit($db, $table, $index); + return $this->getSqlQueryForIndexCreateOrEdit($oldIndexName, $index, $db, $table); } if ($oldIndexName === 'PRIMARY') { diff --git a/tests/classes/Table/IndexesTest.php b/tests/classes/Table/IndexesTest.php index 0f146b041c..cada27e4ba 100644 --- a/tests/classes/Table/IndexesTest.php +++ b/tests/classes/Table/IndexesTest.php @@ -70,15 +70,14 @@ class IndexesTest extends AbstractTestCase $sqlQueryExpected = 'ALTER TABLE `pma_db`.`pma_table` DROP PRIMARY KEY, ADD PRIMARY KEY (`id`);'; $_POST['old_index'] = 'PRIMARY'; - $this->assertEquals($sqlQueryExpected, $indexes->getSqlQueryForIndexCreateOrEdit($db, $table, $index)); - - $_POST['old_index'] = []; - $_POST['old_index']['Key_name'] = 'PRIMARY'; - $this->assertEquals($sqlQueryExpected, $indexes->getSqlQueryForIndexCreateOrEdit($db, $table, $index)); + $this->assertEquals( + $sqlQueryExpected, + $indexes->getSqlQueryForIndexCreateOrEdit('PRIMARY', $index, $db, $table), + ); // Error message $index->setName('NOT PRIMARY'); // Cannot rename primary so the operation should fail - $indexes->getSqlQueryForIndexCreateOrEdit($db, $table, $index); + $indexes->getSqlQueryForIndexCreateOrEdit('PRIMARY', $index, $db, $table); $this->assertInstanceOf(Message::class, $indexes->getError()); } } From 01407167253250ea59d29b90d574f7dcae25c615 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Fri, 29 Dec 2023 00:10:10 +0100 Subject: [PATCH 6/8] Add error message to match the behaviour Signed-off-by: Kamil Tekiela --- src/Table/Indexes.php | 6 ++++++ tests/classes/Table/IndexesTest.php | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Table/Indexes.php b/src/Table/Indexes.php index cd22adf816..e4489b6dee 100644 --- a/src/Table/Indexes.php +++ b/src/Table/Indexes.php @@ -162,6 +162,12 @@ final class Indexes } } + if ($index->getName() === 'PRIMARY') { + $this->error = Message::error( + __('Can\'t rename index to PRIMARY!'), + ); + } + return QueryGenerator::getSqlQueryForIndexRename( $db, $table, diff --git a/tests/classes/Table/IndexesTest.php b/tests/classes/Table/IndexesTest.php index cada27e4ba..d55c2ad589 100644 --- a/tests/classes/Table/IndexesTest.php +++ b/tests/classes/Table/IndexesTest.php @@ -48,7 +48,13 @@ class IndexesTest extends AbstractTestCase // Error message $index->setName('NOT PRIMARY'); // Cannot rename primary so the operation should fail $indexes->getSqlQueryForRename('PRIMARY', $index, Current::$database, Current::$table); - $this->assertInstanceOf(Message::class, $indexes->getError()); + $error = $indexes->getError(); + $this->assertInstanceOf(Message::class, $error); + + $index->setName('PRIMARY'); // The new name cannot be PRIMARY so the operation should fail + $indexes->getSqlQueryForRename('NOT PRIMARY', $index, Current::$database, Current::$table); + $error = $indexes->getError(); + $this->assertInstanceOf(Message::class, $error); } public function testGetSqlQueryForIndexCreateOrEdit(): void From 9925ba6a6af7a7d6cf2afcb5d8b36dc4d6ff29ae Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Sun, 31 Dec 2023 17:25:43 +0100 Subject: [PATCH 7/8] Fix issues after rebase Signed-off-by: Kamil Tekiela --- phpstan-baseline.neon | 2 +- tests/classes/Controllers/Table/IndexRenameControllerTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 2e3ece07e6..89ad2074db 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -15377,7 +15377,7 @@ parameters: - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 19 + count: 17 path: src/Table/Table.php - diff --git a/tests/classes/Controllers/Table/IndexRenameControllerTest.php b/tests/classes/Controllers/Table/IndexRenameControllerTest.php index c8966680ed..dfa7e45fe5 100644 --- a/tests/classes/Controllers/Table/IndexRenameControllerTest.php +++ b/tests/classes/Controllers/Table/IndexRenameControllerTest.php @@ -100,7 +100,7 @@ HTML; ->withQueryParams(['db' => 'test_db', 'table' => 'test_table']) ->withParsedBody([ 'old_index' => 'old_name', - 'index' => ['Key_name' => 'new_name'], + 'index' => 'new_name', 'do_save_data' => '1', 'preview_sql' => '1', ]); @@ -111,7 +111,7 @@ HTML; $responseRenderer, $template, $dbi, - new Indexes($responseRenderer, $template, $dbi), + new Indexes($dbi), new DbTableExists($dbi), ); $controller($request); From f55e1d58a688e64f4b143d7d049e7643a12e7923 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Sun, 31 Dec 2023 22:54:02 +0100 Subject: [PATCH 8/8] Fix failing unit test Signed-off-by: Kamil Tekiela --- .../Table/IndexRenameControllerTest.php | 24 +++++++++---------- tests/classes/Stubs/DbiDummy.php | 10 ++++++++ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/tests/classes/Controllers/Table/IndexRenameControllerTest.php b/tests/classes/Controllers/Table/IndexRenameControllerTest.php index dfa7e45fe5..d536c23623 100644 --- a/tests/classes/Controllers/Table/IndexRenameControllerTest.php +++ b/tests/classes/Controllers/Table/IndexRenameControllerTest.php @@ -24,24 +24,24 @@ class IndexRenameControllerTest extends AbstractTestCase public function testIndexRenameController(): void { Current::$database = 'test_db'; - Current::$table = 'test_table'; + Current::$table = 'test_table_index_rename'; $GLOBALS['lang'] = 'en'; $dummyDbi = $this->createDbiDummy(); $dummyDbi->addSelectDb('test_db'); $dummyDbi->addSelectDb('test_db'); - $dummyDbi->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); + $dummyDbi->addResult('SELECT 1 FROM `test_db`.`test_table_index_rename` LIMIT 1;', [['1']]); $dbi = $this->createDatabaseInterface($dummyDbi); DatabaseInterface::$instance = $dbi; $template = new Template(); $expected = $template->render('table/index_rename_form', [ 'index' => new Index(['Key_name' => 'index']), - 'form_params' => ['db' => 'test_db', 'table' => 'test_table', 'old_index' => 'index'], + 'form_params' => ['db' => 'test_db', 'table' => 'test_table_index_rename', 'old_index' => 'index'], ]); $request = ServerRequestFactory::create()->createServerRequest('GET', 'http://example.com/') - ->withQueryParams(['db' => 'test_db', 'table' => 'test_table']) + ->withQueryParams(['db' => 'test_db', 'table' => 'test_table_index_rename']) ->withParsedBody(['index' => 'index']); $response = new ResponseRenderer(); @@ -63,9 +63,9 @@ class IndexRenameControllerTest extends AbstractTestCase Config::getInstance()->selectedServer['DisableIS'] = true; Current::$database = 'test_db'; - Current::$table = 'test_table'; + Current::$table = 'test_table_index_rename'; $_POST['db'] = 'test_db'; - $_POST['table'] = 'test_table'; + $_POST['table'] = 'test_table_index_rename'; $_POST['old_index'] = 'old_name'; $_POST['index'] = ['Key_name' => 'new_name']; $_POST['do_save_data'] = '1'; @@ -73,12 +73,12 @@ class IndexRenameControllerTest extends AbstractTestCase $dbiDummy = $this->createDbiDummy(); $dbiDummy->addSelectDb('test_db'); - $dbiDummy->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']], ['1']); + $dbiDummy->addResult('SELECT 1 FROM `test_db`.`test_table_index_rename` LIMIT 1;', [['1']], ['1']); $dbiDummy->addResult( - 'SHOW INDEXES FROM `test_db`.`test_table`', + 'SHOW INDEXES FROM `test_db`.`test_table_index_rename`', [ - ['test_table', '0', 'PRIMARY', 'id', 'BTREE'], - ['test_table', '1', 'old_name', 'name', 'BTREE'], + ['test_table_index_rename', '0', 'PRIMARY', 'id', 'BTREE'], + ['test_table_index_rename', '1', 'old_name', 'name', 'BTREE'], ], ['Table', 'Non_unique', 'Key_name', 'Column_name', 'Index_type'], ); @@ -90,14 +90,14 @@ class IndexRenameControllerTest extends AbstractTestCase $expected = <<<'HTML'
-ALTER TABLE `test_db`.`test_table` DROP INDEX `old_name`, ADD INDEX `new_name` (`name`) USING BTREE;
+ALTER TABLE `test_db`.`test_table_index_rename` DROP INDEX `old_name`, ADD INDEX `new_name` (`name`) USING BTREE;
 
HTML; $request = ServerRequestFactory::create()->createServerRequest('GET', 'http://example.com/') - ->withQueryParams(['db' => 'test_db', 'table' => 'test_table']) + ->withQueryParams(['db' => 'test_db', 'table' => 'test_table_index_rename']) ->withParsedBody([ 'old_index' => 'old_name', 'index' => 'new_name', diff --git a/tests/classes/Stubs/DbiDummy.php b/tests/classes/Stubs/DbiDummy.php index e1c9a23623..73219b23d3 100644 --- a/tests/classes/Stubs/DbiDummy.php +++ b/tests/classes/Stubs/DbiDummy.php @@ -1651,6 +1651,11 @@ class DbiDummy implements DbiExtension 'columns' => ['Name', 'Engine', 'Rows'], 'result' => [['test_table', 'InnoDB', '3']], ], + [ + 'query' => 'SHOW TABLE STATUS FROM `test_db` WHERE `Name` LIKE \'test\\\\_table\\\\_index\\\\_rename%\'', + 'columns' => ['Name', 'Engine', 'Rows'], + 'result' => [['test_table_index_rename', 'InnoDB', '3']], + ], [ 'query' => 'SHOW TABLE STATUS FROM `test_db` WHERE Name = \'test_table\'', 'columns' => ['Name', 'Engine', 'Rows'], @@ -1661,6 +1666,11 @@ class DbiDummy implements DbiExtension 'columns' => ['Table', 'Non_unique', 'Key_name', 'Column_name'], 'result' => [['test_table', '0', 'PRIMARY', 'id']], ], + [ + 'query' => 'SHOW INDEXES FROM `test_db`.`test_table_index_rename`', + 'columns' => ['Table', 'Non_unique', 'Key_name', 'Column_name'], + 'result' => [['test_table_index_rename', '0', 'PRIMARY', 'id']], + ], [ 'query' => 'SHOW INDEX FROM `test_table`;', 'columns' => ['Table', 'Non_unique', 'Key_name', 'Column_name'],