117 lines
3.4 KiB
PHP
117 lines
3.4 KiB
PHP
|
|
<?php
|
|||
|
|
|
|||
|
|
namespace app\service\DataSource;
|
|||
|
|
|
|||
|
|
use app\service\DataSource\Adapter\MySQLAdapter;
|
|||
|
|
use app\service\DataSource\Adapter\MongoDBAdapter;
|
|||
|
|
use app\utils\LoggerHelper;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 数据源适配器工厂
|
|||
|
|
*
|
|||
|
|
* 职责:
|
|||
|
|
* - 根据数据源类型创建对应的适配器实例
|
|||
|
|
* - 管理适配器实例(单例模式,避免重复创建连接)
|
|||
|
|
*/
|
|||
|
|
class DataSourceAdapterFactory
|
|||
|
|
{
|
|||
|
|
/**
|
|||
|
|
* 适配器实例缓存(单例模式)
|
|||
|
|
*
|
|||
|
|
* @var array<string, DataSourceAdapterInterface>
|
|||
|
|
*/
|
|||
|
|
private static array $instances = [];
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 创建数据源适配器
|
|||
|
|
*
|
|||
|
|
* @param string $type 数据源类型(mysql、postgresql、mongodb 等)
|
|||
|
|
* @param array<string, mixed> $config 数据源配置
|
|||
|
|
* @return DataSourceAdapterInterface 适配器实例
|
|||
|
|
* @throws \InvalidArgumentException 不支持的数据源类型
|
|||
|
|
*/
|
|||
|
|
public static function create(string $type, array $config): DataSourceAdapterInterface
|
|||
|
|
{
|
|||
|
|
// 生成缓存键(基于类型和配置)
|
|||
|
|
$cacheKey = self::generateCacheKey($type, $config);
|
|||
|
|
|
|||
|
|
// 如果已存在实例,直接返回
|
|||
|
|
if (isset(self::$instances[$cacheKey])) {
|
|||
|
|
$adapter = self::$instances[$cacheKey];
|
|||
|
|
// 检查连接是否有效
|
|||
|
|
if ($adapter->isConnected()) {
|
|||
|
|
return $adapter;
|
|||
|
|
}
|
|||
|
|
// 连接已断开,重新创建
|
|||
|
|
unset(self::$instances[$cacheKey]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 根据类型创建适配器
|
|||
|
|
$adapter = match (strtolower($type)) {
|
|||
|
|
'mysql' => new MySQLAdapter(),
|
|||
|
|
'mongodb' => new MongoDBAdapter(),
|
|||
|
|
// 'postgresql' => new PostgreSQLAdapter(),
|
|||
|
|
default => throw new \InvalidArgumentException("不支持的数据源类型: {$type}"),
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 建立连接
|
|||
|
|
if (!$adapter->connect($config)) {
|
|||
|
|
throw new \RuntimeException("无法连接到数据源: {$type}");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 缓存实例
|
|||
|
|
self::$instances[$cacheKey] = $adapter;
|
|||
|
|
|
|||
|
|
LoggerHelper::logBusiness('data_source_adapter_created', [
|
|||
|
|
'type' => $type,
|
|||
|
|
'cache_key' => $cacheKey,
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
return $adapter;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 生成缓存键
|
|||
|
|
*
|
|||
|
|
* @param string $type 数据源类型
|
|||
|
|
* @param array<string, mixed> $config 数据源配置
|
|||
|
|
* @return string 缓存键
|
|||
|
|
*/
|
|||
|
|
private static function generateCacheKey(string $type, array $config): string
|
|||
|
|
{
|
|||
|
|
// 基于类型、主机、端口、数据库名生成唯一键
|
|||
|
|
$host = $config['host'] ?? 'unknown';
|
|||
|
|
$port = $config['port'] ?? 'unknown';
|
|||
|
|
$database = $config['database'] ?? 'unknown';
|
|||
|
|
return md5("{$type}:{$host}:{$port}:{$database}");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 清除所有适配器实例(用于测试或重新连接)
|
|||
|
|
*
|
|||
|
|
* @return void
|
|||
|
|
*/
|
|||
|
|
public static function clearInstances(): void
|
|||
|
|
{
|
|||
|
|
foreach (self::$instances as $adapter) {
|
|||
|
|
try {
|
|||
|
|
$adapter->disconnect();
|
|||
|
|
} catch (\Throwable $e) {
|
|||
|
|
LoggerHelper::logError($e, ['component' => 'DataSourceAdapterFactory', 'action' => 'clearInstances']);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
self::$instances = [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取所有已创建的适配器实例
|
|||
|
|
*
|
|||
|
|
* @return array<string, DataSourceAdapterInterface>
|
|||
|
|
*/
|
|||
|
|
public static function getInstances(): array
|
|||
|
|
{
|
|||
|
|
return self::$instances;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|