Files
michaelschiemer/.archive/StreamWrapper/Wrappers/DatabaseStreamWrapper.php

206 lines
6.4 KiB
PHP

<?php
declare(strict_types=1);
namespace Archive\StreamWrapper\Wrappers;
use App\Framework\Database\DatabaseManager;
use App\Framework\StreamWrapper\Helper\StreamWrapperHelper;
use Archive\StreamWrapper\Context\StreamContext;
use Archive\StreamWrapper\StreamWrapperInterface;
/**
* Stream-Wrapper für Database-Operationen
* Syntax: db://connection/table/operation?params
*/
class DatabaseStreamWrapper implements StreamWrapperInterface
{
public $context;
private string $content = '';
private int $position = 0;
private string $mode = 'r';
private array $parsedUrl = [];
private ?StreamContext $streamContext = null;
private DatabaseManager $database;
private string $connection;
private string $table;
private string $operation;
private array $params = [];
public function stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool
{
$this->streamContext = StreamWrapperHelper::initializeContext($this->context);
$this->parsedUrl = StreamWrapperHelper::parseUrl($path);
$this->mode = $mode;
$this->connection = $this->parsedUrl['host'] ?: 'default';
$pathParts = explode('/', $this->parsedUrl['path']);
$this->table = $pathParts[0] ?? '';
$this->operation = $pathParts[1] ?? 'select';
// Query-Parameter parsen
if ($this->parsedUrl['query']) {
parse_str($this->parsedUrl['query'], $this->params);
}
// Database-Manager initialisieren
$this->database = new DatabaseManager();
// Bei Lese-Operationen Query ausführen
if (str_contains($mode, 'r') || str_contains($mode, '+')) {
$this->content = $this->loadContent($this->operation);
}
return true;
}
public function stream_read(int $count): string|false
{
return StreamWrapperHelper::streamRead($this->content, $this->position, $count);
}
public function stream_write(string $data): int|false
{
return StreamWrapperHelper::streamWrite($this->content, $this->position, $data);
}
public function stream_tell(): int|false
{
return $this->position;
}
public function stream_eof(): bool
{
return $this->position >= strlen($this->content);
}
public function stream_seek(int $offset, int $whence = SEEK_SET): bool
{
return StreamWrapperHelper::streamSeek($this->content, $this->position, $offset, $whence);
}
public function stream_close(): void
{
// Bei Schreib-Modi Operation ausführen
if (str_contains($this->mode, 'w') || str_contains($this->mode, 'a') || str_contains($this->mode, '+')) {
$this->saveContent($this->operation, $this->content);
}
$this->content = '';
$this->position = 0;
}
public function stream_stat(): array|false
{
return StreamWrapperHelper::streamStat($this->content);
}
public function url_stat(string $path, int $flags): array|false
{
return StreamWrapperHelper::createDefaultStat(strlen($this->content));
}
// Nicht unterstützte Operationen
public function mkdir(string $path, int $mode, int $options): bool { return false; }
public function rmdir(string $path, int $options): bool { return false; }
public function dir_opendir(string $path, int $options): bool { return false; }
public function dir_readdir(): string|false { return false; }
public function dir_rewinddir(): bool { return false; }
public function dir_closedir(): bool { return false; }
public function rename(string $path_from, string $path_to): bool { return false; }
public function unlink(string $path): bool { return false; }
private function loadContent(string $operation): string
{
$connection = $this->streamContext?->getOption('db', 'connection', $this->connection);
$result = match($operation) {
'select', 'all' => $this->executeSelect(),
'count' => $this->executeCount(),
'exists' => $this->executeExists(),
default => []
};
return json_encode($result);
}
private function saveContent(string $operation, string $content): bool
{
$data = json_decode($content, true);
return match($operation) {
'insert' => $this->executeInsert($data),
'update' => $this->executeUpdate($data),
'delete' => $this->executeDelete($data),
'bulk-insert' => $this->executeBulkInsert($data),
default => false
};
}
private function executeSelect(): array
{
$query = $this->database->connection($this->connection)->table($this->table);
foreach ($this->params as $key => $value) {
if ($key === 'id') {
$query->where('id', $value);
} elseif (str_starts_with($key, 'where_')) {
$field = substr($key, 6);
$query->where($field, $value);
}
}
return $query->get()->toArray();
}
private function executeCount(): array
{
$count = $this->database->connection($this->connection)->table($this->table)->count();
return ['count' => $count];
}
private function executeExists(): array
{
$exists = $this->database->connection($this->connection)->table($this->table);
if (isset($this->params['id'])) {
$exists->where('id', $this->params['id']);
}
return ['exists' => $exists->exists()];
}
private function executeInsert(array $data): bool
{
return $this->database->connection($this->connection)->table($this->table)->insert($data);
}
private function executeUpdate(array $data): bool
{
$query = $this->database->connection($this->connection)->table($this->table);
if (isset($this->params['id'])) {
$query->where('id', $this->params['id']);
}
return $query->update($data) > 0;
}
private function executeDelete(array $data): bool
{
$query = $this->database->connection($this->connection)->table($this->table);
if (isset($this->params['id'])) {
$query->where('id', $this->params['id']);
}
return $query->delete() > 0;
}
private function executeBulkInsert(array $data): bool
{
return $this->database->connection($this->connection)->table($this->table)->insert($data);
}
}