config = Config::getInstance(); $this->maxConnections = $this->config->get('database.max_connections', 10); $this->minConnections = $this->config->get('database.min_connections', 3); $this->initPool(); } public static function getInstance() { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; } private function initPool() { for ($i = 0; $i < $this->minConnections; $i++) { $this->connections[] = $this->createConnection(); } } private function createConnection() { $dbConfig = $this->config->get('database'); $host = $dbConfig['host']; $port = $dbConfig['port']; $database = $dbConfig['database']; $username = $dbConfig['username']; $password = $dbConfig['password']; $charset = $dbConfig['charset']; $dsn = "mysql:host={$host};port={$port};charset={$charset}"; $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_PERSISTENT => true ]; $pdo = new PDO($dsn, $username, $password, $options); $pdo->exec("CREATE DATABASE IF NOT EXISTS `$database` CHARACTER SET $charset COLLATE {$dbConfig['collation']}"); $pdo->exec("USE `$database`"); return $pdo; } private function getConnection() { if (count($this->connections) > 0) { $pdo = array_pop($this->connections); if (!$this->isValid($pdo)) { $pdo = $this->createConnection(); } $this->inUse[] = $pdo; return $pdo; } if (count($this->inUse) < $this->maxConnections) { $pdo = $this->createConnection(); $this->inUse[] = $pdo; return $pdo; } usleep(1000); return $this->getConnection(); } private function release($pdo) { $key = array_search($pdo, $this->inUse); if ($key !== false) { unset($this->inUse[$key]); if ($this->isValid($pdo)) { $this->connections[] = $pdo; } } } private function isValid($pdo) { try { $pdo->query("SELECT 1"); return true; } catch (PDOException $e) { return false; } } public function fetchAll($sql, $params = []) { $pdo = $this->getConnection(); try { $stmt = $pdo->prepare($sql); $stmt->execute($params); return $stmt->fetchAll(); } finally { $this->release($pdo); } } public function fetchOne($sql, $params = []) { $pdo = $this->getConnection(); try { $stmt = $pdo->prepare($sql); $stmt->execute($params); return $stmt->fetch(); } finally { $this->release($pdo); } } public function query($sql, $params = []) { $pdo = $this->getConnection(); try { $stmt = $pdo->prepare($sql); $stmt->execute($params); return $stmt; } finally { $this->release($pdo); } } public function insert($sql, $params = []) { $pdo = $this->getConnection(); try { $stmt = $pdo->prepare($sql); $stmt->execute($params); return $pdo->lastInsertId(); } finally { $this->release($pdo); } } public function update($sql, $params = []) { $pdo = $this->getConnection(); try { $stmt = $pdo->prepare($sql); $stmt->execute($params); return $stmt->rowCount(); } finally { $this->release($pdo); } } public function delete($sql, $params = []) { $pdo = $this->getConnection(); try { $stmt = $pdo->prepare($sql); $stmt->execute($params); return $stmt->rowCount(); } finally { $this->release($pdo); } } public function beginTransaction() { $pdo = $this->getConnection(); $pdo->beginTransaction(); return $pdo; } public function commit($pdo = null) { if ($pdo) { $pdo->commit(); $this->release($pdo); } } public function rollback($pdo = null) { if ($pdo) { $pdo->rollBack(); $this->release($pdo); } } public function isConnected() { $pdo = $this->getConnection(); try { $pdo->query("SELECT 1"); return true; } catch (PDOException $e) { return false; } finally { $this->release($pdo); } } public function getPoolStatus() { return [ 'total_connections' => count($this->connections) + count($this->inUse), 'available_connections' => count($this->connections), 'in_use_connections' => count($this->inUse), 'max_connections' => $this->maxConnections ]; } }