chore: complete update

This commit is contained in:
2025-07-17 16:24:20 +02:00
parent 899227b0a4
commit 64a7051137
1300 changed files with 85570 additions and 2756 deletions

View File

@@ -0,0 +1,233 @@
<?php
declare(strict_types=1);
namespace App\Framework\Database\HealthCheck;
use App\Framework\Database\ConnectionInterface;
use App\Framework\Database\Exception\DatabaseException;
final readonly class ConnectionHealthChecker
{
public function __construct(
private int $timeoutSeconds = 5,
private array $customQueries = []
) {}
/**
* Führt einen einfachen Health Check aus
*/
public function checkHealth(ConnectionInterface $connection): HealthCheckResult
{
$startTime = microtime(true);
try {
// Einfacher SELECT zum Testen der Verbindung
$result = $connection->queryScalar('SELECT 1');
$responseTime = (microtime(true) - $startTime) * 1000; // in Millisekunden
if ($result != 1) {
return HealthCheckResult::unhealthy(
$responseTime,
'Unexpected result from health check query',
null,
['expected' => 1, 'actual' => $result]
);
}
return HealthCheckResult::healthy($responseTime, 'Connection is healthy');
} catch (\Throwable $e) {
$responseTime = (microtime(true) - $startTime) * 1000;
return HealthCheckResult::error($e, $responseTime);
}
}
/**
* Führt einen Health Check mit Timeout aus
*/
public function checkHealthWithTimeout(ConnectionInterface $connection): HealthCheckResult
{
$startTime = time();
while ((time() - $startTime) < $this->timeoutSeconds) {
$result = $this->checkHealth($connection);
if ($result->isHealthy) {
return $result;
}
// Kurz warten vor nächstem Versuch
usleep(100000); // 100ms
}
return HealthCheckResult::timeout($this->timeoutSeconds * 1000);
}
/**
* Führt erweiterte Health Checks aus
*/
public function checkDetailedHealth(ConnectionInterface $connection): HealthCheckResult
{
$startTime = microtime(true);
$additionalData = [];
try {
// 1. Basis Health Check
$basicResult = $this->checkHealth($connection);
if (!$basicResult->isHealthy) {
return $basicResult;
}
$additionalData['basic_check'] = $basicResult->toArray();
// 2. PDO-Status prüfen
$pdoStatus = $this->checkPdoStatus($connection);
$additionalData['pdo_status'] = $pdoStatus;
// 3. Custom Queries ausführen
if (!empty($this->customQueries)) {
$customResults = $this->executeCustomQueries($connection);
$additionalData['custom_queries'] = $customResults;
}
// 4. Connection Attributes prüfen
$attributes = $this->getConnectionAttributes($connection);
$additionalData['connection_attributes'] = $attributes;
$responseTime = (microtime(true) - $startTime) * 1000;
return HealthCheckResult::healthy(
$responseTime,
'Detailed health check passed',
$additionalData
);
} catch (\Throwable $e) {
$responseTime = (microtime(true) - $startTime) * 1000;
return HealthCheckResult::error($e, $responseTime)->withAdditionalData('partial_data', $additionalData);
}
}
/**
* Prüft ob die Connection noch lebendig ist (schneller Check)
*/
public function checkConnectionAlive(ConnectionInterface $connection): bool
{
try {
$pdo = $connection->getPdo();
// Prüfe ob die PDO-Verbindung noch aktiv ist
$stmt = $pdo->query('SELECT 1');
return $stmt !== false;
} catch (\Throwable) {
return false;
}
}
/**
* Prüft den PDO-Status
*/
private function checkPdoStatus(ConnectionInterface $connection): array
{
try {
$pdo = $connection->getPdo();
return [
'connection_status' => $pdo->getAttribute(\PDO::ATTR_CONNECTION_STATUS),
'server_info' => $pdo->getAttribute(\PDO::ATTR_SERVER_INFO),
'driver_name' => $pdo->getAttribute(\PDO::ATTR_DRIVER_NAME),
'client_version' => $pdo->getAttribute(\PDO::ATTR_CLIENT_VERSION),
'server_version' => $pdo->getAttribute(\PDO::ATTR_SERVER_VERSION),
'in_transaction' => $connection->inTransaction(),
];
} catch (\Throwable $e) {
return ['error' => $e->getMessage()];
}
}
/**
* Führt benutzerdefinierte Queries aus
*/
private function executeCustomQueries(ConnectionInterface $connection): array
{
$results = [];
foreach ($this->customQueries as $name => $query) {
try {
$startTime = microtime(true);
$result = $connection->queryScalar($query);
$responseTime = (microtime(true) - $startTime) * 1000;
$results[$name] = [
'success' => true,
'result' => $result,
'response_time_ms' => round($responseTime, 2),
];
} catch (\Throwable $e) {
$results[$name] = [
'success' => false,
'error' => $e->getMessage(),
'response_time_ms' => 0,
];
}
}
return $results;
}
/**
* Sammelt Connection-Attribute
*/
private function getConnectionAttributes(ConnectionInterface $connection): array
{
try {
$pdo = $connection->getPdo();
$attributes = [];
$attributesToCheck = [
'AUTOCOMMIT' => \PDO::ATTR_AUTOCOMMIT,
'ERRMODE' => \PDO::ATTR_ERRMODE,
'CASE' => \PDO::ATTR_CASE,
'NULL_TO_STRING' => \PDO::ATTR_NULL_TO_STRING,
'STRINGIFY_FETCHES' => \PDO::ATTR_STRINGIFY_FETCHES,
'STATEMENT_CLASS' => \PDO::ATTR_STATEMENT_CLASS,
'TIMEOUT' => \PDO::ATTR_TIMEOUT,
'EMULATE_PREPARES' => \PDO::ATTR_EMULATE_PREPARES,
'DEFAULT_FETCH_MODE' => \PDO::ATTR_DEFAULT_FETCH_MODE,
];
foreach ($attributesToCheck as $name => $constant) {
try {
$attributes[$name] = $pdo->getAttribute($constant);
} catch (\Throwable) {
$attributes[$name] = 'Not supported';
}
}
return $attributes;
} catch (\Throwable $e) {
return ['error' => $e->getMessage()];
}
}
/**
* Factory-Methoden für verschiedene Health Check-Konfigurationen
*/
public static function quick(int $timeoutSeconds = 2): self
{
return new self($timeoutSeconds);
}
public static function detailed(int $timeoutSeconds = 10, array $customQueries = []): self
{
return new self($timeoutSeconds, $customQueries);
}
public static function withCustomQueries(array $customQueries, int $timeoutSeconds = 5): self
{
return new self($timeoutSeconds, $customQueries);
}
}