chore: complete update
This commit is contained in:
332
src/Framework/Database/DatabaseFactory.php
Normal file
332
src/Framework/Database/DatabaseFactory.php
Normal file
@@ -0,0 +1,332 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Database;
|
||||
|
||||
use App\Framework\Cache\Cache;
|
||||
use App\Framework\Database\Cache\CacheStrategy;
|
||||
use App\Framework\Database\ConnectionInterface;
|
||||
use App\Framework\Database\Driver\Driver;
|
||||
use App\Framework\Database\Driver\DriverConfig;
|
||||
use App\Framework\Database\Driver\DriverType;
|
||||
use App\Framework\Database\Driver\MysqlDriver;
|
||||
use App\Framework\Database\Driver\PostgresDriver;
|
||||
use App\Framework\Database\Driver\SqliteDriver;
|
||||
use App\Framework\Database\Exception\DatabaseException;
|
||||
use App\Framework\Database\Middleware\MiddlewarePipeline;
|
||||
use App\Framework\Database\Middleware\CacheMiddleware;
|
||||
use App\Framework\Database\Middleware\RetryMiddleware;
|
||||
use App\Framework\Database\Middleware\HealthCheckMiddleware;
|
||||
use App\Framework\Database\Cache\CacheAdapterStrategy;
|
||||
use App\Framework\Database\Cache\SimpleCacheStrategy;
|
||||
use Pdo\Mysql;
|
||||
use Pdo\Pgsql;
|
||||
use Pdo\Sqlite;
|
||||
|
||||
final readonly class DatabaseFactory
|
||||
{
|
||||
public static function createConnection(
|
||||
array|DriverConfig $config,
|
||||
array $middlewareConfig = []
|
||||
): ConnectionInterface {
|
||||
$lazy = $middlewareConfig['lazy'] ?? false;
|
||||
$retry = $middlewareConfig['retry'] ?? false;
|
||||
$healthCheck = $middlewareConfig['health_check'] ?? false;
|
||||
$cache = $middlewareConfig['cache'] ?? false;
|
||||
|
||||
if (!$lazy && !$retry && !$healthCheck && !$cache) {
|
||||
// Keine Middleware - direkte Verbindung
|
||||
return self::createDirectConnection($config);
|
||||
}
|
||||
|
||||
// Base Connection erstellen
|
||||
if ($lazy) {
|
||||
$baseConnection = LazyConnectionFactory::createLazyGhost($config);
|
||||
} else {
|
||||
$baseConnection = self::createDirectConnection($config);
|
||||
}
|
||||
|
||||
// Middleware-Pipeline erstellen
|
||||
$pipeline = new MiddlewarePipeline();
|
||||
|
||||
if ($cache) {
|
||||
$cacheConfig = is_array($cache) ? $cache : [];
|
||||
$cacheStrategy = self::createCacheStrategy($cacheConfig);
|
||||
|
||||
$pipeline->add(new CacheMiddleware(
|
||||
$cacheStrategy,
|
||||
$cacheConfig['ttl'] ?? 300,
|
||||
$cacheConfig['enabled'] ?? true,
|
||||
$cacheConfig['cacheable_operations'] ?? ['query', 'queryOne', 'queryColumn', 'queryScalar']
|
||||
));
|
||||
}
|
||||
|
||||
if ($retry) {
|
||||
$retryConfig = is_array($retry) ? $retry : [];
|
||||
$pipeline->add(new RetryMiddleware(
|
||||
$retryConfig['max_retries'] ?? 3,
|
||||
$retryConfig['delay_ms'] ?? 100,
|
||||
$retryConfig['retryable_exceptions'] ?? [\PDOException::class, DatabaseException::class]
|
||||
));
|
||||
}
|
||||
|
||||
if ($healthCheck) {
|
||||
$healthConfig = is_array($healthCheck) ? $healthCheck : [];
|
||||
$pipeline->add(new HealthCheckMiddleware(
|
||||
$healthConfig['interval'] ?? 30,
|
||||
$healthConfig['enabled'] ?? true
|
||||
));
|
||||
}
|
||||
|
||||
// Wenn Pipeline leer ist, gib direkt die Base Connection zurück
|
||||
if (empty($pipeline->getMiddleware())) {
|
||||
return $baseConnection;
|
||||
}
|
||||
|
||||
return new MiddlewareConnection($baseConnection, $pipeline);
|
||||
}
|
||||
|
||||
public static function createDirectConnection(array|DriverConfig $config): ConnectionInterface
|
||||
{
|
||||
if(is_array($config)) {
|
||||
$config = DriverConfig::fromArray($config);
|
||||
}
|
||||
|
||||
$driver = self::createDriver($config);
|
||||
$pdo = self::createPdo($driver);
|
||||
|
||||
return new PdoConnection($pdo);
|
||||
}
|
||||
|
||||
public static function createLazyConnection(
|
||||
array|DriverConfig $config,
|
||||
array $additionalMiddleware = []
|
||||
): ConnectionInterface {
|
||||
return self::createConnection($config, array_merge(
|
||||
['lazy' => true],
|
||||
$additionalMiddleware
|
||||
));
|
||||
}
|
||||
|
||||
public static function createRetryableConnection(
|
||||
array|DriverConfig $config,
|
||||
int $maxRetries = 3,
|
||||
int $retryDelayMs = 100
|
||||
): ConnectionInterface {
|
||||
return self::createConnection($config, [
|
||||
'retry' => [
|
||||
'max_retries' => $maxRetries,
|
||||
'delay_ms' => $retryDelayMs
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
public static function createRobustConnection(
|
||||
array|DriverConfig $config,
|
||||
array $middlewareConfig = []
|
||||
): ConnectionInterface {
|
||||
// Standard "robuste" Konfiguration
|
||||
$defaultConfig = [
|
||||
'lazy' => true,
|
||||
'retry' => [
|
||||
'max_retries' => 3,
|
||||
'delay_ms' => 100
|
||||
],
|
||||
'health_check' => [
|
||||
'interval' => 30,
|
||||
'enabled' => true
|
||||
]
|
||||
];
|
||||
|
||||
return self::createConnection($config, array_merge($defaultConfig, $middlewareConfig));
|
||||
}
|
||||
|
||||
public static function createPureLazyConnection(array|DriverConfig $config): ConnectionInterface
|
||||
{
|
||||
// Reine LazyGhost-Connection ohne zusätzliche Middleware
|
||||
return LazyConnectionFactory::createLazyGhost($config);
|
||||
}
|
||||
|
||||
public static function isLazyConnection(ConnectionInterface $connection): bool
|
||||
{
|
||||
if ($connection instanceof MiddlewareConnection) {
|
||||
$baseConnection = $connection->getBaseConnection();
|
||||
return LazyConnectionFactory::isLazyGhost($baseConnection);
|
||||
}
|
||||
|
||||
return LazyConnectionFactory::isLazyGhost($connection);
|
||||
}
|
||||
|
||||
public static function forceLazyInitialization(ConnectionInterface $connection): void
|
||||
{
|
||||
if ($connection instanceof MiddlewareConnection) {
|
||||
$baseConnection = $connection->getBaseConnection();
|
||||
if (LazyConnectionFactory::isLazyGhost($baseConnection)) {
|
||||
LazyConnectionFactory::initializeLazyGhost($baseConnection);
|
||||
}
|
||||
} elseif (LazyConnectionFactory::isLazyGhost($connection)) {
|
||||
LazyConnectionFactory::initializeLazyGhost($connection);
|
||||
}
|
||||
}
|
||||
|
||||
private static function createCacheStrategy(array $config): CacheStrategy
|
||||
{
|
||||
// Verwende direktes CacheInterface oder fallback zu ArrayCache
|
||||
$keyPrefix = $config['prefix'] ?? 'db_query:';
|
||||
$tags = $config['tags'] ?? ['database_query'];
|
||||
|
||||
// Wenn eine CacheInterface-Instanz direkt übergeben wird
|
||||
if (isset($config['cache_instance']) && $config['cache_instance'] instanceof Cache) {
|
||||
return new CacheAdapterStrategy($config['cache_instance'], $keyPrefix);
|
||||
}
|
||||
|
||||
// Fallback zu einfacher Array-basierter Implementierung
|
||||
return new SimpleCacheStrategy($keyPrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstelle Cache-Strategy mit direkter CacheInterface-Instanz
|
||||
*/
|
||||
public static function createCacheStrategyFromCache(
|
||||
Cache $cache,
|
||||
string $keyPrefix = 'db_query:',
|
||||
array $tags = ['database_query']
|
||||
): CacheStrategy {
|
||||
return CacheAdapterStrategy::withTags($cache, $tags, $keyPrefix);
|
||||
}
|
||||
|
||||
public static function createCachedConnection(
|
||||
array|DriverConfig $config,
|
||||
array $cacheConfig = []
|
||||
): ConnectionInterface {
|
||||
return self::createConnection($config, [
|
||||
'cache' => array_merge([
|
||||
'ttl' => 300,
|
||||
'enabled' => true,
|
||||
'prefix' => 'db_query:',
|
||||
'tags' => ['database_query']
|
||||
], $cacheConfig)
|
||||
]);
|
||||
}
|
||||
|
||||
public static function createCachedConnectionWithCache(
|
||||
array|DriverConfig $config,
|
||||
Cache $cache,
|
||||
array $additionalConfig = []
|
||||
): ConnectionInterface {
|
||||
return self::createCachedConnection($config, array_merge([
|
||||
'cache_instance' => $cache
|
||||
], $additionalConfig));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstelle Connection mit externem Cache-System
|
||||
*/
|
||||
public static function createConnectionWithCustomCache(
|
||||
array|DriverConfig $config,
|
||||
Cache $cache,
|
||||
string $keyPrefix = 'db_query:',
|
||||
int $ttl = 300
|
||||
): ConnectionInterface {
|
||||
return self::createConnection($config, [
|
||||
'cache' => [
|
||||
'cache_instance' => $cache,
|
||||
'prefix' => $keyPrefix,
|
||||
'ttl' => $ttl,
|
||||
'enabled' => true
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
public static function createFullFeaturedConnection(
|
||||
array|DriverConfig $config,
|
||||
array $middlewareConfig = []
|
||||
): ConnectionInterface {
|
||||
// "Alles dabei" - Connection mit allen Features
|
||||
$defaultConfig = [
|
||||
'lazy' => true,
|
||||
'cache' => [
|
||||
'ttl' => 300,
|
||||
'enabled' => true,
|
||||
'prefix' => 'db_query:',
|
||||
'tags' => ['database_query']
|
||||
],
|
||||
'retry' => [
|
||||
'max_retries' => 3,
|
||||
'delay_ms' => 100
|
||||
],
|
||||
'health_check' => [
|
||||
'interval' => 30,
|
||||
'enabled' => true
|
||||
]
|
||||
];
|
||||
|
||||
return self::createConnection($config, array_merge($defaultConfig, $middlewareConfig));
|
||||
}
|
||||
|
||||
public static function createProductionConnection(
|
||||
array|DriverConfig $config,
|
||||
?Cache $cache = null,
|
||||
array $middlewareConfig = []
|
||||
): ConnectionInterface {
|
||||
// Production-optimierte Konfiguration
|
||||
$defaultConfig = [
|
||||
'lazy' => true,
|
||||
'cache' => [
|
||||
'ttl' => 1800,
|
||||
'enabled' => true,
|
||||
'prefix' => 'prod_db:',
|
||||
'tags' => ['database_query', 'production']
|
||||
],
|
||||
'retry' => [
|
||||
'max_retries' => 5,
|
||||
'delay_ms' => 200
|
||||
],
|
||||
'health_check' => [
|
||||
'interval' => 60,
|
||||
'enabled' => true
|
||||
]
|
||||
];
|
||||
|
||||
// Wenn externe Cache-Instanz übergeben wird
|
||||
if ($cache !== null) {
|
||||
$defaultConfig['cache']['cache_instance'] = $cache;
|
||||
}
|
||||
|
||||
return self::createConnection($config, array_merge($defaultConfig, $middlewareConfig));
|
||||
}
|
||||
|
||||
private static function createDriver(DriverConfig $config): Driver
|
||||
{
|
||||
return match($config->driverType) {
|
||||
DriverType::MYSQL => new MysqlDriver($config),
|
||||
DriverType::PGSQL => new PostgresDriver($config),
|
||||
DriverType::SQLITE => new SqliteDriver($config),
|
||||
};
|
||||
}
|
||||
|
||||
private static function createPdo(Driver $driver): \PDO
|
||||
{
|
||||
return match($driver->config->driverType) {
|
||||
DriverType::MYSQL => new Mysql(
|
||||
$driver->dsn,
|
||||
$driver->config->username,
|
||||
$driver->config->password,
|
||||
$driver->options
|
||||
),
|
||||
DriverType::PGSQL => new Pgsql(
|
||||
$driver->dsn,
|
||||
$driver->config->username,
|
||||
$driver->config->password,
|
||||
$driver->options
|
||||
),
|
||||
DriverType::SQLITE => new Sqlite(
|
||||
$driver->dsn,
|
||||
$driver->config->username,
|
||||
$driver->config->password,
|
||||
$driver->options
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user