Plugin fixes

* Added vertical rendering to com.noccy.pdo.shell
* Added missing Log classes for com.noccy.apiclient
This commit is contained in:
Chris 2021-12-22 03:03:16 +01:00
parent 80c7c894ab
commit 9050c74a08
4 changed files with 246 additions and 0 deletions

View File

@ -0,0 +1,79 @@
<?php
namespace SparkPlug\Com\Noccy\ApiClient\Log;
use JsonSerializable;
use Psr\Http\Message\ResponseInterface;
use SparkPlug\Com\Noccy\ApiClient\Log\RequestData as LogRequestData;
use SparkPlug\Com\Noccy\ApiClient\Request\Request;
class LogIterator implements \Iterator
{
private ?string $lastLog = null;
private string $filename;
private array $log = [];
private ?int $index = null;
private ?int $lindex = null;
public function __construct(string $logfile)
{
$this->filename = $logfile;
}
private function readLog(string $filename)
{
if (!file_exists($filename)) {
$this->lastLog = null;
$this->log = [];
$this->index = null;
$this->lindex = null;
return;
}
$log = json_decode(file_get_contents($filename), true);
$this->lastLog = $log['lastlog']??null;
$this->log = $log['events'];
$this->lindex = 0;
if ($this->index === null) {
$this->index = 0;
}
}
public function rewind(): void
{
$this->index = null;
$this->readLog($this->filename);
}
public function current()
{
return $this->log[$this->lindex];
}
public function key()
{
return $this->index;
}
public function next(): void
{
$this->index++;
$this->lindex++;
if ($this->lindex >= count($this->log)) {
if ($this->lastLog) {
$this->readLog($this->lastLog);
} else {
$this->lindex = null;
}
}
}
public function valid(): bool
{
return $this->lindex !== null;
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace SparkPlug\Com\Noccy\ApiClient\Log;
use JsonSerializable;
use Psr\Http\Message\ResponseInterface;
use SparkPlug\Com\Noccy\ApiClient\Log\RequestData as LogRequestData;
use SparkPlug\Com\Noccy\ApiClient\Request\Request;
class RequestData implements JsonSerializable
{
private ?string $method = null;
private array $params = [];
private ?int $timestamp = null;
private ?string $requestUrl = null;
private array $requestInfo = [];
private array $requestHeaders = [];
private ?string $responseBody = null;
private ?int $responseStatus = null;
private array $responseHeaders = [];
public static function fromRequestResponse(Request $request, ResponseInterface $response, ?string $method=null, array $params=[]): RequestData
{
$rd = new RequestData();
$rd->method = $method;
$rd->params = $params;
$rd->timestamp = time();
$rd->requestInfo = $request->getInfo();
$rd->requestHeaders = $request->getHeaders();
$rd->responseBody = (string)$response->getBody();
$rd->responseHeaders = $response->getHeaders();
return $rd;
}
public static function fromArray(array $array): RequestData
{
$rd = new RequestData();
$rd->method = $array['method']??'n/a';
$rd->params = $array['params']??[];
$rd->timestamp = $array['request']['timestamp']??null;
$rd->requestInfo = $array['request']['info']??[];
$rd->requestHeaders = $array['request']['headers']??[];
$rd->responseBody = $array['response']['body']??null;
$rd->responseHeaders = $array['response']['headers']??[];
return $rd;
}
public function jsonSerialize(): mixed
{
return [
'method' => $this->method,
'params' => $this->params,
'request' => [
'url' => $this->requestUrl,
'timestamp' => $this->timestamp,
'info' => $this->requestInfo,
'headers' => $this->requestHeaders,
],
'response' => [
'status' => $this->responseStatus,
'headers' => $this->responseHeaders,
'body' => $this->responseBody,
]
];
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace SparkPlug\Com\Noccy\ApiClient\Log;
use JsonSerializable;
use Psr\Http\Message\ResponseInterface;
use SparkPlug\Com\Noccy\ApiClient\Log\RequestData as LogRequestData;
use SparkPlug\Com\Noccy\ApiClient\Request\Request;
class RequestLog
{
private ?string $lastLog = null;
private string $filename;
private array $append = [];
const MAX_EVENTS_PER_FILE = 100;
public function __construct(string $logfile)
{
$this->filename = $logfile;
}
public function append(RequestData $request)
{
$this->append[] = $request;
}
public function flush()
{
if (file_exists($this->filename)) {
$log = json_decode(file_get_contents($this->filename), true);
} else {
$log = [
'lastlog' => null,
'events' => []
];
}
while (count($this->append) > 0) {
$append = array_shift($this->append);
array_push($log['events'], $append);
$json = json_encode($log, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
if (count($log['events']) >= self::MAX_EVENTS_PER_FILE) {
do {
$newlog = sprintf("%s.%04x", $this->filename, rand(0,65535));
} while (file_exists($newlog));
file_put_contents($newlog, $json);
$log['lastlog'] = basename($newlog);
$log['events'] = [];
} else {
file_put_contents($this->filename."~", $json);
if (filesize($this->filename."~") > 0) {
rename($this->filename."~", $this->filename);
} else {
fprintf(STDERR, "error: Null size log writing requestlog %s\n", $this->filename);
}
}
}
}
}

View File

@ -2,6 +2,7 @@
namespace SparkPlug\Com\Noccy\Pdo\Shell\Shell; namespace SparkPlug\Com\Noccy\Pdo\Shell\Shell;
use Attribute;
use SparkPlug\Com\Noccy\Pdo\PdoResource; use SparkPlug\Com\Noccy\Pdo\PdoResource;
use Spark\Commands\Command; use Spark\Commands\Command;
use Spark\SparkApplication; use Spark\SparkApplication;
@ -28,6 +29,7 @@ class PdoShell {
private ?array $lastQuery = null; private ?array $lastQuery = null;
#[EnumSetting('output', [ 'table', 'vertical', 'dump' ])]
private array $defaultOptions = [ private array $defaultOptions = [
'output' => 'table', 'output' => 'table',
'table.maxwidth' => 40, 'table.maxwidth' => 40,
@ -338,5 +340,31 @@ class PdoShell {
$table->render(); $table->render();
} }
private function dumpQueryVertical(array $res)
{
if (count($res) == 0) return;
$names = array_keys(reset($res));
$nameWidth = max(array_map("strlen", $names)) + 4;
foreach ($res as $row) {
foreach ($row as $k=>$v) {
$this->output->writeln(
sprintf("<info>%{$nameWidth}s</>: %s",$k, $v)
);
}
if ($row != end($res)) {
$this->output->writeln(str_repeat("-", $nameWidth));
}
}
}
} }
#[Attribute(Attribute::TARGET_PROPERTY)]
class EnumSetting
{
public function __construct(string $property, array $valid)
{
}
}