Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored table formatting with /cli endpoint #84

Merged
merged 6 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 141 additions & 18 deletions src/ManticoreSearch/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,36 @@ class Response {
*/
protected Struct $result;

/** @var bool */
protected bool $isRaw = false;

/**
* @var array<string,mixed> $columns
*/
protected array $columns;
protected array $columns = [];

/**
* @var array<string,mixed> $data
*/
protected array $data;
protected array $data = [];

/** @var bool */
protected bool $hasData = false;

/**
* @var string $error
*/
protected string $error = '';

/**
* @var ?string $error
* @var string $warning
*/
protected ?string $error;
protected string $warning = '';

/**
* @var int $total
*/
protected int $total = 0;

/**
* @var array<string,string> $meta
Expand All @@ -55,10 +71,17 @@ private function __construct(
/**
* @return ?string
*/
public function getError(): string|null {
public function getError(): ?string {
return $this->error;
}

/**
* @return ?string
*/
public function getWarning(): ?string {
return $this->warning;
}

/**
* @return string
*/
Expand All @@ -70,8 +93,36 @@ public function getBody(): string {
* @param callable $fn
* @return static
*/
public function filterResult(callable $fn): static {
$this->result->map($fn);
public function mapData(callable $fn): static {
$this->data = array_map($fn, $this->data);
return $this;
}

/**
* @param callable $fn
* @return static
*/
public function filterData(callable $fn): static {
$this->data = array_filter($this->data, $fn);
return $this;
}

/**
* @param array<string,mixed> $data
* @return static
*/
public function extendData(array $data): static {
$this->data = array_merge($this->data, $data);
return $this;
}

/**
* Apply some function to the whole result
* @param callable $fn
* @return static
*/
public function apply(callable $fn): static {
$this->result = $fn($this->result);
return $this;
}

Expand All @@ -83,9 +134,42 @@ public function getResult(): Struct {
if (!isset($this->result)) {
throw new ManticoreSearchResponseError('Trying to access result with no response created');
}
// We should replace data as result of applying modifier functions
// like filter, map or whatever
// @phpstan-ignore-next-line
if (isset($this->result[0]['data'])) {
$item = $this->result[0];
// @phpstan-ignore-next-line
$item['data'] = $this->data;
$result[0] = $item;
} else {
$this->result['data'] = $this->data;
}

return $this->result;
}

/**
* @return array<string,mixed>
*/
public function getData(): array {
return $this->data;
}

/**
* @return array<string,mixed>
*/
public function getColumns(): array {
return $this->columns;
}

/**
* @return int
*/
public function getTotal(): int {
return $this->total;
}

/**
* @param array<string,string> $meta
* @return static
Expand All @@ -108,7 +192,22 @@ public function getMeta(): array {
* @return bool
*/
public function hasError(): bool {
return isset($this->error);
return !!$this->error;
}

/**
* Check if we had warning on performing our request
* @return bool
*/
public function hasWarning(): bool {
return !!$this->warning;
}

/**
* @return bool
*/
public function hasData(): bool {
return $this->hasData;
}

/**
Expand Down Expand Up @@ -148,17 +247,41 @@ protected function parse(): void {
$data = $struct[0];
$struct = Struct::fromData($data, $struct->getBigIntFields());
}
if ($struct->hasKey('error') && is_string($struct['error']) && $struct['error'] !== '') {
$this->error = $struct['error'];
} else {
$this->error = null;
}
foreach (['columns', 'data'] as $prop) {
if (!$struct->hasKey($prop) || !is_array($struct[$prop])) {
continue;
}
$this->$prop = $struct[$prop];

$this->assign($struct, 'error')
->assign($struct, 'warning')
->assign($struct, 'total')
->assign($struct, 'data')
->assign($struct, 'columns');

// A bit tricky but we need to know if we have data or not
// For table formatter in current architecture
$this->hasData = $struct->hasKey('data');

// Check if this is type of response that is not our scheme
// in this case we just may proxy it as is without any extra
$this->isRaw = !$struct->hasKey('warning') &&
!$struct->hasKey('error') &&
!$struct->hasKey('total');
}

/**
* @return bool
*/
public function isRaw(): bool {
return $this->isRaw;
}

/**
* @param Struct<int|string, mixed> $struct
* @param string $key
* @return static
*/
public function assign(Struct $struct, string $key): static {
if ($struct->hasKey($key)) {
$this->$key = $struct[$key];
}
return $this;
}

/**
Expand Down
17 changes: 17 additions & 0 deletions src/Network/OutputFormat.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?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 3 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\Core\Network;

enum OutputFormat {
case Table;
case Raw;
}
51 changes: 31 additions & 20 deletions src/Network/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
use Ds\Vector;
use Manticoresearch\Buddy\Core\Error\InvalidNetworkRequestError;
use Manticoresearch\Buddy\Core\Error\QueryParseError;
use Manticoresearch\Buddy\Core\ManticoreSearch\Endpoint as ManticoreEndpoint;
use Manticoresearch\Buddy\Core\ManticoreSearch\Endpoint;
use Manticoresearch\Buddy\Core\ManticoreSearch\MySQLTool;
use Manticoresearch\Buddy\Core\ManticoreSearch\RequestFormat;
use Manticoresearch\Buddy\Core\ManticoreSearch\Settings as ManticoreSettings;
use Manticoresearch\Buddy\Core\ManticoreSearch\Settings;
use Manticoresearch\Buddy\Core\Tool\Buddy;

final class Request {
Expand All @@ -33,9 +33,9 @@ final class Request {
public string $id;
public float $time;

public ManticoreEndpoint $endpointBundle;
public Endpoint $endpointBundle;
public RequestFormat $format;
public ManticoreSettings $settings;
public Settings $settings;
public string $path;
public string $error;
/** @var array<mixed> $errorBody */
Expand All @@ -61,9 +61,9 @@ public static function default(string $id = '0'): static {
$self = new static;
$self->id = $id;
$self->time = microtime(true);
$self->endpointBundle = ManticoreEndpoint::Sql;
$self->settings = ManticoreSettings::fromVector(new Vector());
$self->path = ManticoreEndpoint::Sql->value;
$self->endpointBundle = Endpoint::Sql;
$self->settings = Settings::fromVector(new Vector());
$self->path = Endpoint::Sql->value;
$self->format = RequestFormat::JSON;
$self->error = '';
$self->errorBody = [];
Expand Down Expand Up @@ -96,7 +96,7 @@ public static function fromString(string $data, string $id = '0'): static {
* payload:string,
* version:int,
* format:RequestFormat,
* endpointBundle:ManticoreEndpoint,
* endpointBundle:Endpoint,
* path:string
* } $data
* @param string $id
Expand Down Expand Up @@ -193,24 +193,24 @@ protected function parseOrFail(array $payload): static {
$path = '_bulk';
}
if (static::isElasticPath($path)) {
$endpointBundle = ManticoreEndpoint::Elastic;
$endpointBundle = Endpoint::Elastic;
} elseif (str_contains($path, '/_doc/') || str_contains($path, '/_create/')
|| str_ends_with($path, '/_doc')) {
// We don't differentiate elastic-like insert and replace queries here
// since this is irrelevant for the following Buddy processing logic
$endpointBundle = ManticoreEndpoint::Insert;
$endpointBundle = Endpoint::Insert;
} elseif (str_contains($path, '/_update/')) {
$endpointBundle = ManticoreEndpoint::Update;
$endpointBundle = Endpoint::Update;
} else {
$endpointBundle = match ($path) {
'bulk', '_bulk' => ManticoreEndpoint::Bulk,
'cli' => ManticoreEndpoint::Cli,
'cli_json' => ManticoreEndpoint::CliJson,
'search' => ManticoreEndpoint::Search,
'sql?mode=raw', 'sql', '' => ManticoreEndpoint::Sql,
'insert', 'replace' => ManticoreEndpoint::Insert,
'_license' => ManticoreEndpoint::Elastic,
'autocomplete' => ManticoreEndpoint::Autocomplete,
'bulk', '_bulk' => Endpoint::Bulk,
'cli' => Endpoint::Cli,
'cli_json' => Endpoint::CliJson,
'search' => Endpoint::Search,
'sql?mode=raw', 'sql', '' => Endpoint::Sql,
'insert', 'replace' => Endpoint::Insert,
'_license' => Endpoint::Elastic,
'autocomplete' => Endpoint::Autocomplete,
default => throw new InvalidNetworkRequestError(
"Do not know how to handle '{$payload['message']['path_query']}' path_query"
),
Expand All @@ -227,7 +227,7 @@ protected function parseOrFail(array $payload): static {
$this->format = $format;
$this->endpointBundle = $endpointBundle;
$this->mySQLTool = static::detectMySQLTool($payload['message']['body']);
$this->payload = (in_array($endpointBundle, [ManticoreEndpoint::Elastic, ManticoreEndpoint::Bulk]))
$this->payload = (in_array($endpointBundle, [Endpoint::Elastic, Endpoint::Bulk]))
? trim($payload['message']['body'])
: static::removeComments($payload['message']['body']);
$this->error = $payload['error']['message'];
Expand Down Expand Up @@ -339,4 +339,15 @@ static function (array $matches): string {
/** @var string $query */
return trim($query);
}

/**
* Validate if we should format the output in the Table way
* @return OutputFormat
*/
public function getOutputFormat(): OutputFormat {
return match ($this->endpointBundle) {
Endpoint::Cli => OutputFormat::Table,
default => OutputFormat::Raw,
};
}
}
10 changes: 0 additions & 10 deletions src/Network/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use Manticoresearch\Buddy\Core\Error\GenericError;
use Manticoresearch\Buddy\Core\ManticoreSearch\RequestFormat;
use Manticoresearch\Buddy\Core\Plugin\TableFormatter;
use Manticoresearch\Buddy\Core\Task\TaskResult;
use Manticoresearch\Buddy\Core\Tool\Buddy;

/** @package Manticoresearch\Buddy\Core\Network */
Expand Down Expand Up @@ -54,15 +53,6 @@ private static function checkForError(mixed $message): bool {
|| (is_string($message) && str_starts_with($message, TableFormatter::ERROR_PREFIX));
}

/**
* @param TaskResult $result
* @param RequestFormat $format
* @return static
*/
public static function fromResult(TaskResult $result, RequestFormat $format = RequestFormat::JSON): static {
return static::fromMessageAndMeta($result->getStruct(), $result->getMeta(), $format);
}

/**
* Create response from the message when we have no error and success in respond
* @see static::fromStringAndError()
Expand Down
Loading