Skip to content

Commit

Permalink
Feat/rename table (#260)
Browse files Browse the repository at this point in the history
* Alter rename

---------

Co-authored-by: djklim87 <klim@manticoresearch.com>
  • Loading branch information
djklim87 and djklim87 committed May 10, 2024
1 parent 441025d commit 0d69023
Show file tree
Hide file tree
Showing 3 changed files with 294 additions and 0 deletions.
131 changes: 131 additions & 0 deletions src/Plugin/AlterRenameTable/Handler.php
@@ -0,0 +1,131 @@
<?php declare(strict_types=1);

/*
Copyright (c) 2024, Manticore Software LTD (https://manticoresearch.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 or any later
version. You should have received a copy of the GPL license along with this
program; if you did not, you can find it at http://www.gnu.org/
*/

namespace Manticoresearch\Buddy\Base\Plugin\AlterRenameTable;

use Manticoresearch\Buddy\Core\Error\GenericError;
use Manticoresearch\Buddy\Core\Error\ManticoreSearchClientError;
use Manticoresearch\Buddy\Core\ManticoreSearch\Client;
use Manticoresearch\Buddy\Core\Plugin\BaseHandlerWithClient;
use Manticoresearch\Buddy\Core\Task\Task;
use Manticoresearch\Buddy\Core\Task\TaskResult;
use RuntimeException;

final class Handler extends BaseHandlerWithClient
{

/**
* Initialize the executor
*
* @param Payload $payload
* @return void
*/
public function __construct(public Payload $payload) {
}

/**
* Process the request
*
* @return Task
* @throws RuntimeException
*/
public function run(): Task {
$taskFn = static function (Payload $payload, Client $client): TaskResult {

if (!$client->hasTable($payload->sourceTableName)) {
throw GenericError::create("Source table $payload->sourceTableName not exists");
}

if ($client->hasTable($payload->destinationTableName)) {
throw GenericError::create("Destination table $payload->destinationTableName already exists");
}
self::createTableLike($payload->sourceTableName, $payload->destinationTableName, $client);

$result = (array)self::attachTable($payload->sourceTableName, $payload->destinationTableName, $client);

self::dropTable($payload->sourceTableName, $client);

return TaskResult::raw($result);
};

return Task::create(
$taskFn, [$this->payload, $this->manticoreClient]
)->run();
}


/**
* @param string $sourceTableName
* @param string $destinationTableName
* @param Client $client
* @return void
* @throws GenericError
* @throws ManticoreSearchClientError
*/
private static function createTableLike(
string $sourceTableName,
string $destinationTableName,
Client $client
): void {

$sql = /** @lang ManticoreSearch */
"create table $destinationTableName like $sourceTableName";
$result = $client->sendRequest($sql);
if ($result->hasError()) {
throw GenericError::create(
"Can't create $destinationTableName table like $sourceTableName. " .
'Reason: ' . $result->getError()
);
}
}


/**
* @param string $sourceTableName
* @param string $destinationTableName
* @param Client $client
* @return mixed
* @throws GenericError
* @throws ManticoreSearchClientError
*/
private static function attachTable(
string $sourceTableName,
string $destinationTableName,
Client $client
): mixed {

$sql = /** @lang ManticoreSearch */
"ATTACH TABLE $sourceTableName TO TABLE $destinationTableName";
$result = $client->sendRequest($sql);
if ($result->hasError()) {
throw GenericError::create(
"Can't attach $sourceTableName table to $destinationTableName. " .
'Reason: ' . $result->getError()
);
}
return $result->getResult();
}


/**
* @param string $tableName
* @param Client $client
* @throws GenericError
* @throws ManticoreSearchClientError
*/
private static function dropTable(string $tableName, Client $client): void {
$sql = /** @lang ManticoreSearch */
"drop table $tableName";
$result = $client->sendRequest($sql);
if ($result->hasError()) {
throw GenericError::create("Can't drop table $tableName. Reason: " . $result->getError());
}
}
}
162 changes: 162 additions & 0 deletions src/Plugin/AlterRenameTable/Payload.php
@@ -0,0 +1,162 @@
<?php declare(strict_types=1);

/*
Copyright (c) 2024, Manticore Software LTD (https://manticoresearch.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 or any later
version. You should have received a copy of the GPL license along with this
program; if you did not, you can find it at http://www.gnu.org/
*/

namespace Manticoresearch\Buddy\Base\Plugin\AlterRenameTable;

use Manticoresearch\Buddy\Core\Error\GenericError;
use Manticoresearch\Buddy\Core\Network\Request;
use Manticoresearch\Buddy\Core\Plugin\BasePayload;

/**
* This is simple do nothing request that handle empty queries
* which can be as a result of only comments in it that we strip
* @extends BasePayload<array>
*/
final class Payload extends BasePayload {
public string $path;

public string $destinationTableName;
public string $sourceTableName;

public string $type;

/**
* Get description for this plugin
* @return string
*/
public static function getInfo(): string {
return 'Enables alter table rename';
}

/**
* @param Request $request
* @return static
*/
public static function fromRequest(Request $request): static {
$self = new static();
/** phpstan fix */
unset($request);
/**
* @phpstan-var array{
* ALTER: array{
* expr_type: string,
* base_expr: string,
* sub_tree: array<
* array{
* expr_type: string,
* base_expr: string
* }>
* },
* TABLE: array{
* base_expr: string,
* name: string,
* no_quotes: array{
* delim: bool,
* parts: array<string>
* },
* create-def: bool,
* options: bool
* },
* RENAME: array{
* expr_type: string,
* sub_tree: array<
* array{
* destination: array{
* expr_type: string,
* table: string,
* no_quotes: array{
* delim: bool,
* parts: array<string>
* },
* base_expr: string
* }
* }>
* }
* } $payload
*/
$payload = Payload::$sqlQueryParser::getParsedPayload();

$self->destinationTableName = $payload['RENAME']['sub_tree'][0]['destination']['no_quotes']['parts'][0];
$self->sourceTableName = $payload['TABLE']['no_quotes']['parts'][0];
return $self;
}

/**
* @param Request $request
* @return bool
* @throws GenericError
*/
public static function hasMatch(Request $request): bool {

/**
* @phpstan-var array{
* ALTER: array{
* expr_type: string,
* base_expr?: string,
* sub_tree: array<
* array{
* expr_type: string,
* base_expr: string
* }>
* },
* TABLE?: array{
* base_expr: string,
* name: string,
* no_quotes: array{
* delim: bool,
* parts: array<string>
* },
* create-def: bool,
* options: bool
* },
* RENAME?: array{
* expr_type: string,
* sub_tree: array<
* array{
* destination: array{
* expr_type: string,
* table: string,
* no_quotes: array{
* delim: bool,
* parts: array<string>
* },
* base_expr: string
* }
* }>
* }
* }|false $payload
*/

$payload = Payload::$sqlQueryParser::parse(
$request->payload,
fn(Request $request) => (
strpos($request->error, 'P03: syntax error, unexpected tablename') === 0
&& stripos($request->payload, 'alter') !== false
&& stripos($request->payload, 'table') !== false
&& stripos($request->payload, 'rename') !== false
),
$request
);

if (!$payload) {
return false;
}

if (isset($payload['ALTER']['base_expr'])
&& isset($payload['TABLE']['no_quotes']['parts'][0])
&& isset($payload['RENAME']['sub_tree'][0]['destination']['no_quotes']['parts'][0])
&& $payload['ALTER']['base_expr'] === 'TABLE'
) {
return true;
}

return false;
}
}
1 change: 1 addition & 0 deletions src/init.php
Expand Up @@ -62,6 +62,7 @@
'manticoresoftware/buddy-plugin-cli-table',
'manticoresoftware/buddy-plugin-plugin',
'manticoresoftware/buddy-plugin-test',
'manticoresoftware/buddy-plugin-alter-rename-table',
'manticoresoftware/buddy-plugin-modify-table',
'manticoresoftware/buddy-plugin-knn',
'manticoresoftware/buddy-plugin-replace',
Expand Down

0 comments on commit 0d69023

Please sign in to comment.