Plugin fixes
* Added vertical rendering to com.noccy.pdo.shell * Added missing Log classes for com.noccy.apiclient
This commit is contained in:
		
							
								
								
									
										79
									
								
								plugins/com.noccy.apiclient/Log/LogIterator.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								plugins/com.noccy.apiclient/Log/LogIterator.php
									
									
									
									
									
										Normal 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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										76
									
								
								plugins/com.noccy.apiclient/Log/RequestData.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								plugins/com.noccy.apiclient/Log/RequestData.php
									
									
									
									
									
										Normal 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,
 | 
			
		||||
            ]
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								plugins/com.noccy.apiclient/Log/RequestLog.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								plugins/com.noccy.apiclient/Log/RequestLog.php
									
									
									
									
									
										Normal 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);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
 | 
			
		||||
namespace SparkPlug\Com\Noccy\Pdo\Shell\Shell;
 | 
			
		||||
 | 
			
		||||
use Attribute;
 | 
			
		||||
use SparkPlug\Com\Noccy\Pdo\PdoResource;
 | 
			
		||||
use Spark\Commands\Command;
 | 
			
		||||
use Spark\SparkApplication;
 | 
			
		||||
@@ -28,6 +29,7 @@ class PdoShell {
 | 
			
		||||
 | 
			
		||||
    private ?array $lastQuery = null;
 | 
			
		||||
 | 
			
		||||
    #[EnumSetting('output', [ 'table', 'vertical', 'dump' ])]
 | 
			
		||||
    private array $defaultOptions = [
 | 
			
		||||
        'output' => 'table',
 | 
			
		||||
        'table.maxwidth' => 40,
 | 
			
		||||
@@ -338,5 +340,31 @@ class PdoShell {
 | 
			
		||||
        $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)
 | 
			
		||||
    {
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user