diff --git a/libraries/classes/Controllers/Table/PartitionController.php b/libraries/classes/Controllers/Table/PartitionController.php new file mode 100644 index 0000000000..6e5388c6a7 --- /dev/null +++ b/libraries/classes/Controllers/Table/PartitionController.php @@ -0,0 +1,211 @@ +model = $partition; + } + + public function analyze(): void + { + $partitionName = $_POST['partition_name'] ?? ''; + + if (strlen($partitionName) === 0) { + return; + } + + [$rows, $query] = $this->model->analyze($this->db, $this->table, $partitionName); + + $message = Generator::getMessage( + __('Your SQL query has been executed successfully.'), + $query, + 'success' + ); + + $this->render('table/partition/analyze', [ + 'partition_name' => $partitionName, + 'message' => $message, + 'rows' => $rows, + ]); + } + + public function check(): void + { + $partitionName = $_POST['partition_name'] ?? ''; + + if (strlen($partitionName) === 0) { + return; + } + + [$rows, $query] = $this->model->check($this->db, $this->table, $partitionName); + + $message = Generator::getMessage( + __('Your SQL query has been executed successfully.'), + $query, + 'success' + ); + + $this->render('table/partition/check', [ + 'partition_name' => $partitionName, + 'message' => $message, + 'rows' => $rows, + ]); + } + + public function drop(): void + { + $partitionName = $_POST['partition_name'] ?? ''; + + if (strlen($partitionName) === 0) { + return; + } + + [$result, $query] = $this->model->drop($this->db, $this->table, $partitionName); + + if ($result) { + $message = Generator::getMessage( + __('Your SQL query has been executed successfully.'), + $query, + 'success' + ); + } else { + $message = Generator::getMessage( + __('Error'), + $query, + 'error' + ); + } + + $this->render('table/partition/drop', [ + 'partition_name' => $partitionName, + 'message' => $message, + ]); + } + + public function optimize(): void + { + $partitionName = $_POST['partition_name'] ?? ''; + + if (strlen($partitionName) === 0) { + return; + } + + [$rows, $query] = $this->model->optimize($this->db, $this->table, $partitionName); + + $message = Generator::getMessage( + __('Your SQL query has been executed successfully.'), + $query, + 'success' + ); + + $this->render('table/partition/optimize', [ + 'partition_name' => $partitionName, + 'message' => $message, + 'rows' => $rows, + ]); + } + + public function rebuild(): void + { + $partitionName = $_POST['partition_name'] ?? ''; + + if (strlen($partitionName) === 0) { + return; + } + + [$result, $query] = $this->model->rebuild($this->db, $this->table, $partitionName); + + if ($result) { + $message = Generator::getMessage( + __('Your SQL query has been executed successfully.'), + $query, + 'success' + ); + } else { + $message = Generator::getMessage( + __('Error'), + $query, + 'error' + ); + } + + $this->render('table/partition/rebuild', [ + 'partition_name' => $partitionName, + 'message' => $message, + ]); + } + + public function repair(): void + { + $partitionName = $_POST['partition_name'] ?? ''; + + if (strlen($partitionName) === 0) { + return; + } + + [$rows, $query] = $this->model->repair($this->db, $this->table, $partitionName); + + $message = Generator::getMessage( + __('Your SQL query has been executed successfully.'), + $query, + 'success' + ); + + $this->render('table/partition/repair', [ + 'partition_name' => $partitionName, + 'message' => $message, + 'rows' => $rows, + ]); + } + + public function truncate(): void + { + $partitionName = $_POST['partition_name'] ?? ''; + + if (strlen($partitionName) === 0) { + return; + } + + [$result, $query] = $this->model->truncate($this->db, $this->table, $partitionName); + + if ($result) { + $message = Generator::getMessage( + __('Your SQL query has been executed successfully.'), + $query, + 'success' + ); + } else { + $message = Generator::getMessage( + __('Error'), + $query, + 'error' + ); + } + + $this->render('table/partition/truncate', [ + 'partition_name' => $partitionName, + 'message' => $message, + ]); + } +} diff --git a/libraries/classes/Controllers/Table/StructureController.php b/libraries/classes/Controllers/Table/StructureController.php index 5308e83284..519df6f9a6 100644 --- a/libraries/classes/Controllers/Table/StructureController.php +++ b/libraries/classes/Controllers/Table/StructureController.php @@ -805,19 +805,6 @@ class StructureController extends AbstractController public function partitioning(): void { - global $containerBuilder, $reload; - - if (isset($_POST['partition_maintenance'])) { - /** @var SqlController $controller */ - $controller = $containerBuilder->get(SqlController::class); - $controller->index(); - - $reload = true; - $this->index(); - - return; - } - if (isset($_POST['save_partitioning'])) { $this->dbi->selectDb($this->db); $this->updatePartitioning(); diff --git a/libraries/classes/Table/Partition.php b/libraries/classes/Table/Partition.php new file mode 100644 index 0000000000..b64f41f027 --- /dev/null +++ b/libraries/classes/Table/Partition.php @@ -0,0 +1,138 @@ +dbi = $dbi; + } + + public function analyze(string $db, string $table, string $partition): array + { + $query = sprintf( + 'ALTER TABLE %s ANALYZE PARTITION %s;', + Util::backquote($table), + Util::backquote($partition) + ); + + $this->dbi->selectDb($db); + $result = $this->dbi->fetchResult($query); + + $rows = []; + foreach ($result as $row) { + $rows[$row['Table']][] = $row; + } + + return [$rows, $query]; + } + + public function check(string $db, string $table, string $partition): array + { + $query = sprintf( + 'ALTER TABLE %s CHECK PARTITION %s;', + Util::backquote($table), + Util::backquote($partition) + ); + + $this->dbi->selectDb($db); + $result = $this->dbi->fetchResult($query); + + $rows = []; + foreach ($result as $row) { + $rows[$row['Table']][] = $row; + } + + return [$rows, $query]; + } + + public function drop(string $db, string $table, string $partition): array + { + $query = sprintf( + 'ALTER TABLE %s DROP PARTITION %s;', + Util::backquote($table), + Util::backquote($partition) + ); + + $this->dbi->selectDb($db); + $result = $this->dbi->tryQuery($query); + + return [(bool) $result, $query]; + } + + public function optimize(string $db, string $table, string $partition): array + { + $query = sprintf( + 'ALTER TABLE %s OPTIMIZE PARTITION %s;', + Util::backquote($table), + Util::backquote($partition) + ); + + $this->dbi->selectDb($db); + $result = $this->dbi->fetchResult($query); + + $rows = []; + foreach ($result as $row) { + $rows[$row['Table']][] = $row; + } + + return [$rows, $query]; + } + + public function rebuild(string $db, string $table, string $partition): array + { + $query = sprintf( + 'ALTER TABLE %s REBUILD PARTITION %s;', + Util::backquote($table), + Util::backquote($partition) + ); + + $this->dbi->selectDb($db); + $result = $this->dbi->tryQuery($query); + + return [(bool) $result, $query]; + } + + public function repair(string $db, string $table, string $partition): array + { + $query = sprintf( + 'ALTER TABLE %s REPAIR PARTITION %s;', + Util::backquote($table), + Util::backquote($partition) + ); + + $this->dbi->selectDb($db); + $result = $this->dbi->fetchResult($query); + + $rows = []; + foreach ($result as $row) { + $rows[$row['Table']][] = $row; + } + + return [$rows, $query]; + } + + public function truncate(string $db, string $table, string $partition): array + { + $query = sprintf( + 'ALTER TABLE %s TRUNCATE PARTITION %s;', + Util::backquote($table), + Util::backquote($partition) + ); + + $this->dbi->selectDb($db); + $result = $this->dbi->tryQuery($query); + + return [(bool) $result, $query]; + } +} diff --git a/libraries/routes.php b/libraries/routes.php index 8b7581a04e..a047aad606 100644 --- a/libraries/routes.php +++ b/libraries/routes.php @@ -80,6 +80,7 @@ use PhpMyAdmin\Controllers\Table\ImportController as TableImportController; use PhpMyAdmin\Controllers\Table\IndexesController; use PhpMyAdmin\Controllers\Table\MaintenanceController; use PhpMyAdmin\Controllers\Table\OperationsController as TableOperationsController; +use PhpMyAdmin\Controllers\Table\PartitionController; use PhpMyAdmin\Controllers\Table\RecentFavoriteController; use PhpMyAdmin\Controllers\Table\RelationController; use PhpMyAdmin\Controllers\Table\ReplaceController; @@ -291,6 +292,15 @@ return static function (RouteCollector $routes): void { $routes->post('/optimize', [MaintenanceController::class, 'optimize']); $routes->post('/repair', [MaintenanceController::class, 'repair']); }); + $routes->addGroup('/partition', static function (RouteCollector $routes): void { + $routes->post('/analyze', [PartitionController::class, 'analyze']); + $routes->post('/check', [PartitionController::class, 'check']); + $routes->post('/drop', [PartitionController::class, 'drop']); + $routes->post('/optimize', [PartitionController::class, 'optimize']); + $routes->post('/rebuild', [PartitionController::class, 'rebuild']); + $routes->post('/repair', [PartitionController::class, 'repair']); + $routes->post('/truncate', [PartitionController::class, 'truncate']); + }); $routes->addRoute(['GET', 'POST'], '/operations', [TableOperationsController::class, 'index']); $routes->addRoute(['GET', 'POST'], '/recent-favorite', [RecentFavoriteController::class, 'index']); $routes->addRoute(['GET', 'POST'], '/relation', [RelationController::class, 'index']); diff --git a/libraries/services.php b/libraries/services.php index 7146afc967..c445a8ff71 100644 --- a/libraries/services.php +++ b/libraries/services.php @@ -184,6 +184,10 @@ return [ 'class' => PhpMyAdmin\Table\Maintenance::class, 'arguments' => ['$dbi' => '@dbi'], ], + 'table_partition' => [ + 'class' => PhpMyAdmin\Table\Partition::class, + 'arguments' => ['$dbi' => '@dbi'], + ], 'table_search' => [ 'class' => PhpMyAdmin\Table\Search::class, 'arguments' => ['$dbi' => '@dbi'], diff --git a/libraries/services_controllers.php b/libraries/services_controllers.php index ccb3af9dc5..d391ccf896 100644 --- a/libraries/services_controllers.php +++ b/libraries/services_controllers.php @@ -706,6 +706,16 @@ return [ '$model' => '@table_maintenance', ], ], + PhpMyAdmin\Controllers\Table\PartitionController::class => [ + 'class' => PhpMyAdmin\Controllers\Table\PartitionController::class, + 'arguments' => [ + '$response' => '@response', + '$template' => '@template', + '$db' => '%db%', + '$table' => '%table%', + '$partition' => '@table_partition', + ], + ], PhpMyAdmin\Controllers\Table\OperationsController::class => [ 'class' => PhpMyAdmin\Controllers\Table\OperationsController::class, 'arguments' => [ diff --git a/templates/table/partition/analyze.twig b/templates/table/partition/analyze.twig new file mode 100644 index 0000000000..9a95cbf2aa --- /dev/null +++ b/templates/table/partition/analyze.twig @@ -0,0 +1,36 @@ +