From e9b6965678b44d7173be872f584c3f980b4bd152 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 27 Aug 2022 19:39:02 +0800 Subject: [PATCH 1/5] remove redundant library --- bin/phpunit-zm | 13 ++++++++++++- composer.json | 3 +-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/bin/phpunit-zm b/bin/phpunit-zm index 73049fcd..b6e68c7b 100755 --- a/bin/phpunit-zm +++ b/bin/phpunit-zm @@ -31,6 +31,17 @@ $ob_event_provider = new EventProvider(); // 注册一个最低级别的 WorkerStart 事件,用于在框架的事件初始化之后开始运行 PHPUnit ob_event_provider()->addEventListener(WorkerStartEvent::getName(), function () { + register_shutdown_function(function () { + $error = error_get_last(); + // 下面这段代码的作用就是,不是错误引发的退出时照常退出即可 + if (($error['type'] ?? 0) != 0) { + logger()->emergency(zm_internal_errcode('E00027') . 'Internal fatal error: ' . $error['message'] . ' at ' . $error['file'] . "({$error['line']})"); + } + ob_dump($error); + ob_dump(func_get_args()); + ob_dump(debug_backtrace()); + Framework::getInstance()->stop(); + }); try { // 不退出,而是返回 code $retcode = Command::main(false); @@ -43,7 +54,7 @@ ob_event_provider()->addEventListener(WorkerStartEvent::getName(), function () { try { $options = ServerStartCommand::exportOptionArray(); - $options['driver'] = DIRECTORY_SEPARATOR === '/' ? 'swoole' : 'workerman'; + $options['driver'] = 'workerman'; $options['worker-num'] = 1; $options['private-mode'] = true; (new Framework($options))->init()->start(); diff --git a/composer.json b/composer.json index ca0c8537..c6294e0e 100644 --- a/composer.json +++ b/composer.json @@ -26,8 +26,7 @@ "symfony/polyfill-ctype": "^1.19", "symfony/polyfill-mbstring": "^1.19", "symfony/polyfill-php80": "^1.16", - "symfony/routing": "~6.0 || ~5.0 || ~4.0", - "zhamao/logger": "dev-master" + "symfony/routing": "~6.0 || ~5.0 || ~4.0" }, "require-dev": { "brainmaestro/composer-git-hooks": "^2.8", From 085472a12c4c19d92c906ff9974aabe48cf4e683 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 27 Aug 2022 19:45:23 +0800 Subject: [PATCH 2/5] refactor MySQL component to support SQLite at the same time --- .../DBConnection.php} | 36 ++-- src/ZM/Store/Database/DBException.php | 11 ++ .../MySQLPool.php => Database/DBPool.php} | 59 +++--- .../DBQueryBuilder.php} | 10 +- .../DBStatement.php} | 4 +- .../DBStatementWrapper.php} | 62 +++---- .../DBWrapper.php} | 168 ++++++++++-------- src/ZM/Store/MySQL/MySQLException.php | 9 - 8 files changed, 199 insertions(+), 160 deletions(-) rename src/ZM/Store/{MySQL/MySQLConnection.php => Database/DBConnection.php} (70%) create mode 100644 src/ZM/Store/Database/DBException.php rename src/ZM/Store/{MySQL/MySQLPool.php => Database/DBPool.php} (54%) rename src/ZM/Store/{MySQL/MySQLQueryBuilder.php => Database/DBQueryBuilder.php} (72%) rename src/ZM/Store/{MySQL/MySQLStatement.php => Database/DBStatement.php} (97%) rename src/ZM/Store/{MySQL/MySQLStatementWrapper.php => Database/DBStatementWrapper.php} (71%) rename src/ZM/Store/{MySQL/MySQLWrapper.php => Database/DBWrapper.php} (79%) delete mode 100644 src/ZM/Store/MySQL/MySQLException.php diff --git a/src/ZM/Store/MySQL/MySQLConnection.php b/src/ZM/Store/Database/DBConnection.php similarity index 70% rename from src/ZM/Store/MySQL/MySQLConnection.php rename to src/ZM/Store/Database/DBConnection.php index 9c8c2134..827fdf7c 100644 --- a/src/ZM/Store/MySQL/MySQLConnection.php +++ b/src/ZM/Store/Database/DBConnection.php @@ -4,14 +4,14 @@ declare(strict_types=1); -namespace ZM\Store\MySQL; +namespace ZM\Store\Database; use Doctrine\DBAL\Driver\Connection; use Doctrine\DBAL\ParameterType; use PDO; use PDOException; -class MySQLConnection implements Connection +class DBConnection implements Connection { /** @var PDO */ private $conn; @@ -21,20 +21,20 @@ class MySQLConnection implements Connection public function __construct($params) { logger()->debug('Constructing...'); - $this->conn = MySQLPool::pool($params['dbName'])->get(); + $this->conn = DBPool::pool($params['dbName'])->get(); $this->pool_name = $params['dbName']; } public function __destruct() { logger()->debug('Destructing!!!'); - MySQLPool::pool($this->pool_name)->put($this->conn); + DBPool::pool($this->pool_name)->put($this->conn); } /** - * @param mixed $sql - * @param mixed $options - * @throws MySQLException + * @param mixed $sql + * @param mixed $options + * @throws DBException */ public function prepare($sql, $options = []) { @@ -43,13 +43,13 @@ class MySQLConnection implements Connection $statement = $this->conn->prepare($sql, $options); assert($statement !== false); } catch (PDOException $exception) { - throw new MySQLException($exception->getMessage(), $exception->getCode(), $exception); + throw new DBException($exception->getMessage(), 0, $exception); } - return new MySQLStatement($statement); + return new DBStatement($statement); } /** - * @throws MySQLException + * @throws DBException */ public function query(...$args) { @@ -57,9 +57,9 @@ class MySQLConnection implements Connection $statement = $this->conn->query(...$args); assert($statement !== false); } catch (PDOException $exception) { - throw new MySQLException($exception->getMessage(), $exception->getCode(), $exception); + throw new DBException($exception->getMessage(), 0, $exception); } - return new MySQLStatement($statement); + return new DBStatement($statement); } public function quote($value, $type = ParameterType::STRING) @@ -68,8 +68,8 @@ class MySQLConnection implements Connection } /** - * @param mixed $sql - * @throws MySQLException + * @param mixed $sql + * @throws DBException */ public function exec($sql) { @@ -79,20 +79,20 @@ class MySQLConnection implements Connection assert($statement !== false); return $statement; } catch (PDOException $exception) { - throw new MySQLException($exception->getMessage(), $exception->getCode(), $exception); + throw new DBException($exception->getMessage(), 0, $exception); } } /** - * @param null|mixed $name - * @throws MySQLException + * @param null|mixed $name + * @throws DBException */ public function lastInsertId($name = null) { try { return $name === null ? $this->conn->lastInsertId() : $this->conn->lastInsertId($name); } catch (PDOException $exception) { - throw new MySQLException($exception->getMessage(), $exception->getCode(), $exception); + throw new DBException($exception->getMessage(), 0, $exception); } } diff --git a/src/ZM/Store/Database/DBException.php b/src/ZM/Store/Database/DBException.php new file mode 100644 index 00000000..01a9b4f8 --- /dev/null +++ b/src/ZM/Store/Database/DBException.php @@ -0,0 +1,11 @@ + 连接池列表 @@ -25,26 +26,44 @@ class MySQLPool /** * 通过配置文件创建一个 MySQL 连接池 * - * @throws MySQLException + * @throws DBException */ public static function create(string $name, array $config) { - $size = $config['pool_size'] ?? 128; - $connect_str = 'mysql:host={host};port={port};dbname={dbname};charset={charset}'; - $table = [ - '{host}' => $config['host'], - '{port}' => $config['port'], - '{dbname}' => $config['dbname'], - '{charset}' => $config['charset'] ?? 'utf8mb4', - ]; - $connect_str = str_replace(array_keys($table), array_values($table), $connect_str); - self::checkExtension(); + $size = $config['pool_size'] ?? 64; + switch ($config['type']) { + case 'mysql': + $connect_str = 'mysql:host={host};port={port};dbname={dbname};charset={charset}'; + $table = [ + '{host}' => $config['host'], + '{port}' => $config['port'], + '{dbname}' => $config['dbname'], + '{charset}' => $config['charset'] ?? 'utf8mb4', + ]; + $connect_str = str_replace(array_keys($table), array_values($table), $connect_str); + $args = [$config['username'], $config['password'], $config['options'] ?? []]; + self::checkMysqlExtension(); + break; + case 'sqlite': + $connect_str = 'sqlite:{dbname}'; + if (FileSystem::isRelativePath($config['dbname'])) { + $config['dbname'] = zm_dir(SOURCE_ROOT_DIR . '/' . $config['dbname']); + } + $table = [ + '{dbname}' => $config['dbname'], + ]; + $args = []; + $connect_str = str_replace(array_keys($table), array_values($table), $connect_str); + break; + default: + throw new DBException('type ' . $config['type'] . ' not supported yet'); + } switch (Driver::getActiveDriverClass()) { case WorkermanDriver::class: - self::$pools[$name] = new WorkermanObjectPool($size, PDO::class, $connect_str, $config['username'], $config['password'], $config['options'] ?? []); + self::$pools[$name] = new WorkermanObjectPool($size, PDO::class, $connect_str, ...$args); break; case SwooleDriver::class: - self::$pools[$name] = new SwooleObjectPool($size, PDO::class, $connect_str, $config['username'], $config['password'], $config['options'] ?? []); + self::$pools[$name] = new SwooleObjectPool($size, PDO::class, $connect_str, ...$args); } } @@ -56,10 +75,10 @@ class MySQLPool */ public static function pool(string $name) { - if (!isset(self::$pools[$name])) { + if (!isset(self::$pools[$name]) && count(self::$pools) !== 1) { throw new RuntimeException("Pool {$name} not found"); } - return self::$pools[$name]; + return self::$pools[$name] ?? self::$pools[array_key_first(self::$pools)]; } /** @@ -85,9 +104,9 @@ class MySQLPool /** * 检查数据库启动必要的依赖扩展,如果不符合要求则抛出异常 * - * @throws MySQLException + * @throws DBException */ - public static function checkExtension() + public static function checkMysqlExtension() { ob_start(); phpinfo(); // 这个phpinfo是有用的,不能删除 @@ -102,7 +121,7 @@ class MySQLPool continue; } if (mb_strpos($v, 'pdo_mysql') === false) { - throw new MySQLException(zm_internal_errcode('E00028') . '未安装 mysqlnd php-mysql扩展。'); + throw new DBException(zm_internal_errcode('E00028') . '未安装 mysqlnd php-mysql扩展。'); } } } diff --git a/src/ZM/Store/MySQL/MySQLQueryBuilder.php b/src/ZM/Store/Database/DBQueryBuilder.php similarity index 72% rename from src/ZM/Store/MySQL/MySQLQueryBuilder.php rename to src/ZM/Store/Database/DBQueryBuilder.php index 3eff9a9d..ac6383ac 100644 --- a/src/ZM/Store/MySQL/MySQLQueryBuilder.php +++ b/src/ZM/Store/Database/DBQueryBuilder.php @@ -2,16 +2,16 @@ declare(strict_types=1); -namespace ZM\Store\MySQL; +namespace ZM\Store\Database; use Doctrine\DBAL\Query\QueryBuilder; -use ZM\Store\MySQL\MySQLException as DbException; +use ZM\Store\Database\DBException as DbException; -class MySQLQueryBuilder extends QueryBuilder +class DBQueryBuilder extends QueryBuilder { private $wrapper; - public function __construct(MySQLWrapper $wrapper) + public function __construct(DBWrapper $wrapper) { parent::__construct($wrapper->getConnection()); $this->wrapper = $wrapper; @@ -19,7 +19,7 @@ class MySQLQueryBuilder extends QueryBuilder /** * @throws DbException - * @return int|MySQLStatementWrapper + * @return DBStatementWrapper|int */ public function execute() { diff --git a/src/ZM/Store/MySQL/MySQLStatement.php b/src/ZM/Store/Database/DBStatement.php similarity index 97% rename from src/ZM/Store/MySQL/MySQLStatement.php rename to src/ZM/Store/Database/DBStatement.php index ea192d7c..092215df 100644 --- a/src/ZM/Store/MySQL/MySQLStatement.php +++ b/src/ZM/Store/Database/DBStatement.php @@ -6,7 +6,7 @@ declare(strict_types=1); -namespace ZM\Store\MySQL; +namespace ZM\Store\Database; use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\ParameterType; @@ -15,7 +15,7 @@ use PDO; use PDOStatement; use Traversable; -class MySQLStatement implements IteratorAggregate, Statement +class DBStatement implements IteratorAggregate, Statement { /** @var PDOStatement */ private $statement; diff --git a/src/ZM/Store/MySQL/MySQLStatementWrapper.php b/src/ZM/Store/Database/DBStatementWrapper.php similarity index 71% rename from src/ZM/Store/MySQL/MySQLStatementWrapper.php rename to src/ZM/Store/Database/DBStatementWrapper.php index 9304f478..dd6774f1 100644 --- a/src/ZM/Store/MySQL/MySQLStatementWrapper.php +++ b/src/ZM/Store/Database/DBStatementWrapper.php @@ -7,16 +7,16 @@ declare(strict_types=1); -namespace ZM\Store\MySQL; +namespace ZM\Store\Database; use Doctrine\DBAL\Driver\ResultStatement; use Doctrine\DBAL\ForwardCompatibility\Result; use Throwable; use Traversable; -class MySQLStatementWrapper +class DBStatementWrapper { - public $stmt; + public ?Result $stmt; public function __construct(?Result $stmt) { @@ -45,7 +45,7 @@ class MySQLStatementWrapper /** * wrapper method - * @throws MySQLException + *@throws DBException * @return array|false|mixed */ public function fetchNumeric() @@ -53,13 +53,13 @@ class MySQLStatementWrapper try { return $this->stmt->fetchNumeric(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + *@throws DBException * @return array|false|mixed */ public function fetchAssociative() @@ -67,13 +67,13 @@ class MySQLStatementWrapper try { return $this->stmt->fetchAssociative(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + *@throws DBException * @return false|mixed */ public function fetchOne() @@ -81,143 +81,143 @@ class MySQLStatementWrapper try { return $this->stmt->fetchOne(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + * @throws DBException */ public function fetchAllNumeric(): array { try { return $this->stmt->fetchAllNumeric(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + * @throws DBException */ public function fetchAllAssociative(): array { try { return $this->stmt->fetchAllAssociative(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + * @throws DBException */ public function fetchAllKeyValue(): array { try { return $this->stmt->fetchAllKeyValue(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + * @throws DBException */ public function fetchAllAssociativeIndexed(): array { try { return $this->stmt->fetchAllAssociativeIndexed(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + * @throws DBException */ public function fetchFirstColumn(): array { try { return $this->stmt->fetchFirstColumn(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + * @throws DBException */ public function iterateNumeric(): Traversable { try { return $this->stmt->iterateNumeric(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + * @throws DBException */ public function iterateAssociative(): Traversable { try { return $this->stmt->iterateAssociative(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + * @throws DBException */ public function iterateKeyValue(): Traversable { try { return $this->stmt->iterateKeyValue(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + * @throws DBException */ public function iterateAssociativeIndexed(): Traversable { try { return $this->stmt->iterateAssociativeIndexed(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + * @throws DBException */ public function iterateColumn(): Traversable { try { return $this->stmt->iterateColumn(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws MySQLException + * @throws DBException * @return int */ public function rowCount() @@ -225,7 +225,7 @@ class MySQLStatementWrapper try { return $this->stmt->rowCount(); } catch (Throwable $e) { - throw new MySQLException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } diff --git a/src/ZM/Store/MySQL/MySQLWrapper.php b/src/ZM/Store/Database/DBWrapper.php similarity index 79% rename from src/ZM/Store/MySQL/MySQLWrapper.php rename to src/ZM/Store/Database/DBWrapper.php index 1314a0a6..e4d53fdc 100644 --- a/src/ZM/Store/MySQL/MySQLWrapper.php +++ b/src/ZM/Store/Database/DBWrapper.php @@ -2,11 +2,7 @@ declare(strict_types=1); -/** - * @noinspection PhpUnused - */ - -namespace ZM\Store\MySQL; +namespace ZM\Store\Database; use Closure; use Doctrine\DBAL\Cache\QueryCacheProfile; @@ -16,23 +12,29 @@ use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\Types\Type; use Throwable; use Traversable; -use ZM\Store\MySQL\MySQLException as DbException; -class MySQLWrapper +class DBWrapper { - /** @var Connection */ - private $connection; + private Connection $connection; /** - * MySQLWrapper constructor. - * @throws DbException + * DBWrapper constructor. + * @throws DBException */ public function __construct(string $name) { try { - $this->connection = DriverManager::getConnection(['driverClass' => MySQLDriver::class, 'dbName' => $name]); + $db_list = config()->get('global.database'); + if (isset($db_list[$name]) || count($db_list) === 1) { + if ($name === '') { + $name = array_key_first($db_list); + } + $this->connection = DriverManager::getConnection(['driverClass' => $this->getConnectionClass($db_list[$name]['type']), 'dbName' => $name]); + } else { + throw new DBException('Cannot find database config named "' . $name . '" !'); + } } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -67,7 +69,7 @@ class MySQLWrapper /** * wrapper method - * @throws DbException + * @throws DBException * @return array|false */ public function fetchAssociative(string $query, array $params = [], array $types = []) @@ -75,13 +77,13 @@ class MySQLWrapper try { return $this->connection->fetchAssociative($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), intval($e->getCode()), $e); } } /** * wrapper method - * @throws DbException + * @throws DBException * @return array|false */ public function fetchNumeric(string $query, array $params = [], array $types = []) @@ -89,12 +91,12 @@ class MySQLWrapper try { return $this->connection->fetchNumeric($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** - * @throws DbException + * @throws DBException * @return false|mixed */ public function fetchOne(string $query, array $params = [], array $types = []) @@ -102,7 +104,7 @@ class MySQLWrapper try { return $this->connection->fetchOne($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -116,14 +118,14 @@ class MySQLWrapper /** * @param string $table 表 - * @throws DbException + * @throws DBException */ public function delete(string $table, array $criteria, array $types = []): int { try { return $this->connection->delete($table, $criteria, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -147,28 +149,28 @@ class MySQLWrapper /** * wrapper method * @param string $table 表名 - * @throws DbException + * @throws DBException */ public function update(string $table, array $data, array $criteria, array $types = []): int { try { return $this->connection->update($table, $data, $criteria, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method * @param string $table 表名 - * @throws DbException + * @throws DBException */ public function insert(string $table, array $data, array $types = []): int { try { return $this->connection->insert($table, $data, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -197,7 +199,7 @@ class MySQLWrapper * @param array|array $params Query parameters * @param array|array $types Parameter types * - * @throws DbException + * @throws DBException * @return array> */ public function fetchAllNumeric(string $query, array $params = [], array $types = []): array @@ -205,7 +207,7 @@ class MySQLWrapper try { return $this->connection->fetchAllNumeric($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -215,7 +217,7 @@ class MySQLWrapper * @param array|array $params Query parameters * @param array|array $types Parameter types * - * @throws DbException + * @throws DBException * @return array> */ public function fetchAllAssociative(string $query, array $params = [], array $types = []): array @@ -223,7 +225,7 @@ class MySQLWrapper try { return $this->connection->fetchAllAssociative($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -233,14 +235,14 @@ class MySQLWrapper * @param array|array $params Query parameters * @param array|array $types Parameter types * - * @throws DbException + * @throws DBException */ public function fetchAllKeyValue(string $query, array $params = [], array $types = []): array { try { return $this->connection->fetchAllKeyValue($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -250,7 +252,7 @@ class MySQLWrapper * @param array|array $params Query parameters * @param array|array $types Parameter types * - * @throws DbException + * @throws DBException * @return array> */ public function fetchAllAssociativeIndexed(string $query, array $params = [], array $types = []): array @@ -258,7 +260,7 @@ class MySQLWrapper try { return $this->connection->fetchAllAssociativeIndexed($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -268,7 +270,7 @@ class MySQLWrapper * @param array|array $params Query parameters * @param array|array $types Parameter types * - * @throws DbException + * @throws DBException * @return array */ public function fetchFirstColumn(string $query, array $params = [], array $types = []): array @@ -276,7 +278,7 @@ class MySQLWrapper try { return $this->connection->fetchFirstColumn($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -286,7 +288,7 @@ class MySQLWrapper * @param array|array $params Query parameters * @param array|array $types Parameter types * - * @throws DbException + * @throws DBException * @return Traversable> */ public function iterateNumeric(string $query, array $params = [], array $types = []): Traversable @@ -294,7 +296,7 @@ class MySQLWrapper try { return $this->connection->iterateNumeric($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -304,7 +306,7 @@ class MySQLWrapper * @param array|array $params Query parameters * @param array|array $types Parameter types * - * @throws DbException + * @throws DBException * @return Traversable> */ public function iterateAssociative(string $query, array $params = [], array $types = []): Traversable @@ -312,7 +314,7 @@ class MySQLWrapper try { return $this->connection->iterateAssociative($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -322,7 +324,7 @@ class MySQLWrapper * @param array|array $params Query parameters * @param array|array $types Parameter types * - * @throws DbException + * @throws DBException * @return Traversable */ public function iterateKeyValue(string $query, array $params = [], array $types = []): Traversable @@ -330,7 +332,7 @@ class MySQLWrapper try { return $this->connection->iterateKeyValue($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -340,7 +342,7 @@ class MySQLWrapper * @param array|array $params Query parameters * @param array|array $types Parameter types * - * @throws DbException + * @throws DBException * @return Traversable> */ public function iterateAssociativeIndexed(string $query, array $params = [], array $types = []): Traversable @@ -348,7 +350,7 @@ class MySQLWrapper try { return $this->connection->iterateAssociativeIndexed($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -358,7 +360,7 @@ class MySQLWrapper * @param array|array $params Query parameters * @param array|array $types Parameter types * - * @throws DbException + * @throws DBException * @return Traversable */ public function iterateColumn(string $query, array $params = [], array $types = []): Traversable @@ -366,7 +368,7 @@ class MySQLWrapper try { return $this->connection->iterateColumn($query, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -376,15 +378,16 @@ class MySQLWrapper * @param array|array $params Query parameters * @param array|array $types Parameter types * - * @throws DbException + * @throws DBException */ - public function executeQuery(string $sql, array $params = [], array $types = [], ?QueryCacheProfile $qcp = null): MySQLStatementWrapper + public function executeQuery(string $sql, array $params = [], array $types = [], ?QueryCacheProfile $qcp = null): DBStatementWrapper { try { $query = $this->connection->executeQuery($sql, $params, $types, $qcp); - return new MySQLStatementWrapper($query); + return new DBStatementWrapper($query); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw $e; + // throw new DBException($e->getMessage(), intval($e->getCode()), $e); } } @@ -393,15 +396,15 @@ class MySQLWrapper * @param string $sql SQL query * @param array|array $params Query parameters * @param array|array $types Parameter types - * @throws DbException + * @throws DBException */ - public function executeCacheQuery(string $sql, array $params, array $types, QueryCacheProfile $qcp): MySQLStatementWrapper + public function executeCacheQuery(string $sql, array $params, array $types, QueryCacheProfile $qcp): DBStatementWrapper { try { $query = $this->connection->executeCacheQuery($sql, $params, $types, $qcp); - return new MySQLStatementWrapper($query); + return new DBStatementWrapper($query); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -411,7 +414,7 @@ class MySQLWrapper * @param array|array $params Statement parameters * @param array|array $types Parameter types * - * @throws DbException + * @throws DBException * @return int|string the number of affected rows */ public function executeStatement(string $sql, array $params = [], array $types = []) @@ -419,7 +422,7 @@ class MySQLWrapper try { return $this->connection->executeStatement($sql, $params, $types); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -443,7 +446,7 @@ class MySQLWrapper /** * overwrite method to $this->connection->transactional() - * @throws DbException + * @throws DBException * @return mixed */ public function transactional(Closure $func) @@ -455,20 +458,20 @@ class MySQLWrapper return $res; } catch (Throwable $e) { $this->rollBack(); - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws DbException + * @throws DBException */ public function setNestTransactionsWithSavepoints(bool $nest_transactions_with_savepoints) { try { $this->connection->setNestTransactionsWithSavepoints($nest_transactions_with_savepoints); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } @@ -490,108 +493,123 @@ class MySQLWrapper /** * wrapper method - * @throws DbException + * @throws DBException */ public function commit(): bool { try { return $this->connection->commit(); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws DbException + * @throws DBException */ public function rollBack(): bool { try { return $this->connection->rollBack(); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method * @param string $savepoint the name of the savepoint to create - * @throws DbException + * @throws DBException */ public function createSavepoint(string $savepoint) { try { $this->connection->createSavepoint($savepoint); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method * @param string $savepoint the name of the savepoint to release - * @throws DbException + * @throws DBException */ public function releaseSavepoint(string $savepoint) { try { $this->connection->releaseSavepoint($savepoint); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method * @param string $savepoint the name of the savepoint to rollback to - * @throws DbException + * @throws DBException */ public function rollbackSavepoint(string $savepoint) { try { $this->connection->rollbackSavepoint($savepoint); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws DbException + * @throws DBException */ public function setRollbackOnly() { try { $this->connection->setRollbackOnly(); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * wrapper method - * @throws DbException + * @throws DBException */ public function isRollbackOnly(): bool { try { return $this->connection->isRollbackOnly(); } catch (Throwable $e) { - throw new DbException($e->getMessage(), $e->getCode(), $e); + throw new DBException($e->getMessage(), $e->getCode(), $e); } } /** * overwrite method to $this->connection->createQueryBuilder */ - public function createQueryBuilder(): MySQLQueryBuilder + public function createQueryBuilder(): DBQueryBuilder { - return new MySQLQueryBuilder($this); + return new DBQueryBuilder($this); } public function getConnection(): Connection { return $this->connection; } + + /** + * @throws DBException + */ + private function getConnectionClass(string $type): string + { + switch ($type) { + case 'mysql': + return MySQLDriver::class; + case 'sqlite': + return SQLiteDriver::class; + default: + throw new DBException('Unknown database type: ' . $type); + } + } } diff --git a/src/ZM/Store/MySQL/MySQLException.php b/src/ZM/Store/MySQL/MySQLException.php deleted file mode 100644 index ec11f4fd..00000000 --- a/src/ZM/Store/MySQL/MySQLException.php +++ /dev/null @@ -1,9 +0,0 @@ - Date: Sat, 27 Aug 2022 19:47:45 +0800 Subject: [PATCH 3/5] add SQLiteDriver.php and change MySQLDriver.php --- src/Globals/global_functions.php | 16 ++++---- src/ZM/Event/Listener/WorkerEventListener.php | 33 +++++++-------- .../Store/{MySQL => Database}/MySQLDriver.php | 16 +++----- src/ZM/Store/Database/SQLiteDriver.php | 41 +++++++++++++++++++ 4 files changed, 68 insertions(+), 38 deletions(-) rename src/ZM/Store/{MySQL => Database}/MySQLDriver.php (63%) create mode 100644 src/ZM/Store/Database/SQLiteDriver.php diff --git a/src/Globals/global_functions.php b/src/Globals/global_functions.php index 862741d1..a7288823 100644 --- a/src/Globals/global_functions.php +++ b/src/Globals/global_functions.php @@ -13,8 +13,8 @@ use ZM\Container\ContainerInterface; use ZM\Context\Context; use ZM\Logger\ConsoleLogger; use ZM\Middleware\MiddlewareHandler; -use ZM\Store\MySQL\MySQLException; -use ZM\Store\MySQL\MySQLWrapper; +use ZM\Store\Database\DBException; +use ZM\Store\Database\DBWrapper; // 防止重复引用引发报错 if (function_exists('zm_internal_errcode')) { @@ -172,21 +172,21 @@ function app(string $abstract = null, array $parameters = []) /** * 获取 MySQL 调用的类 * - * @throws MySQLException + * @throws DBException */ -function mysql(string $name = '') +function db(string $name = '') { - return new MySQLWrapper($name); + return new DBWrapper($name); } /** * 获取构建 MySQL 的类 * - * @throws MySQLException + * @throws DBException */ -function mysql_builder(string $name = '') +function sql_builder(string $name = '') { - return (new MySQLWrapper($name))->createQueryBuilder(); + return (new DBWrapper($name))->createQueryBuilder(); } /** diff --git a/src/ZM/Event/Listener/WorkerEventListener.php b/src/ZM/Event/Listener/WorkerEventListener.php index 2df8156b..e9e219c9 100644 --- a/src/ZM/Event/Listener/WorkerEventListener.php +++ b/src/ZM/Event/Listener/WorkerEventListener.php @@ -12,12 +12,11 @@ use ZM\Annotation\AnnotationMap; use ZM\Annotation\AnnotationParser; use ZM\Annotation\Framework\Init; use ZM\Container\ContainerServicesProvider; -use ZM\Exception\ConfigException; use ZM\Exception\ZMKnownException; use ZM\Framework; use ZM\Process\ProcessStateManager; -use ZM\Store\MySQL\MySQLException; -use ZM\Store\MySQL\MySQLPool; +use ZM\Store\Database\DBException; +use ZM\Store\Database\DBPool; use ZM\Utils\ZMUtil; class WorkerEventListener @@ -99,6 +98,10 @@ class WorkerEventListener if (DIRECTORY_SEPARATOR !== '\\') { ProcessStateManager::removeProcessState(ZM_PROCESS_WORKER, ProcessManager::getProcessId()); } + // 清空 MySQL 的连接池 + foreach (DBPool::getAllPools() as $name => $pool) { + DBPool::destroyPool($name); + } } /** @@ -149,29 +152,21 @@ class WorkerEventListener * * TODO:未来新增其他db的连接池 * - * @throws ConfigException - * @throws MySQLException + * @throws DBException */ private function initConnectionPool() { // 清空 MySQL 的连接池 - foreach (MySQLPool::getAllPools() as $name => $pool) { - MySQLPool::destroyPool($name); + foreach (DBPool::getAllPools() as $name => $pool) { + DBPool::destroyPool($name); } // 读取 MySQL 配置文件 - $conf = config('global.mysql'); - if (is_array($conf) && !is_assoc_array($conf)) { - // 如果有多个数据库连接,则遍历 - foreach ($conf as $conn_conf) { - if ($conn_conf['host'] !== '') { - MySQLPool::create($conn_conf['pool_name'], $conn_conf); - } - } - } elseif (is_assoc_array($conf)) { - // 这种情况也支持,但是不推荐 - if ($conf['host'] !== '') { - MySQLPool::create($conf['pool_name'], $conf); + $conf = config('global.database'); + // 如果有多个数据库连接,则遍历 + foreach ($conf as $name => $conn_conf) { + if (($conn_conf['enable'] ?? true) !== false) { + DBPool::create($name, $conn_conf); } } } diff --git a/src/ZM/Store/MySQL/MySQLDriver.php b/src/ZM/Store/Database/MySQLDriver.php similarity index 63% rename from src/ZM/Store/MySQL/MySQLDriver.php rename to src/ZM/Store/Database/MySQLDriver.php index 68815d0b..4c6e3c9c 100644 --- a/src/ZM/Store/MySQL/MySQLDriver.php +++ b/src/ZM/Store/Database/MySQLDriver.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace ZM\Store\MySQL; +namespace ZM\Store\Database; use Doctrine\DBAL\Driver as DoctrineDriver; use Doctrine\DBAL\Platforms\MySqlPlatform; @@ -13,10 +13,10 @@ class MySQLDriver implements DoctrineDriver public function connect(array $params, $username = null, $password = null, array $driverOptions = []) { logger()->debug('Requiring new connection'); - return new MySQLConnection($params); + return new DBConnection($params); } - public function getDatabasePlatform(): MySqlPlatform + public function getDatabasePlatform() { return new MySqlPlatform(); } @@ -33,14 +33,8 @@ class MySQLDriver implements DoctrineDriver public function getDatabase($conn) { - $conf = config('global.mysql'); - - if ($conn instanceof MySQLConnection) { - foreach ($conf as $v) { - if (($v['name'] ?? $v['dbname']) === $conn->getPoolName()) { - return $v['dbname']; - } - } + if ($conn instanceof DBConnection) { + return config('database')[$conn->getPoolName()]['dbname'] ?? ''; } return ''; } diff --git a/src/ZM/Store/Database/SQLiteDriver.php b/src/ZM/Store/Database/SQLiteDriver.php new file mode 100644 index 00000000..f2bfbab7 --- /dev/null +++ b/src/ZM/Store/Database/SQLiteDriver.php @@ -0,0 +1,41 @@ +debug('Requiring new connection'); + return new DBConnection($params); + } + + public function getDatabasePlatform() + { + return new SqlitePlatform(); + } + + public function getSchemaManager($conn) + { + return new SqliteSchemaManager($conn); + } + + public function getName() + { + return 'pdo_sqlite_pool'; + } + + public function getDatabase($conn) + { + if ($conn instanceof DBConnection) { + return config('database')[$conn->getPoolName()]['dbname'] ?? ''; + } + return ''; + } +} From 84f84dad40cdc68df84ed737e2dd81e9eef6b5f2 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 27 Aug 2022 19:50:40 +0800 Subject: [PATCH 4/5] add sqlite extensions for github action --- .github/workflows/integration-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 53de9450..d14f8f72 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -36,7 +36,7 @@ jobs: uses: "shivammathur/setup-php@v2" with: php-version: ${{ matrix.php-versions }} - extensions: swoole, posix, json, mbstring + extensions: swoole, posix, json, mbstring, pdo, sqlite3, pdo_sqlite env: SWOOLE_CONFIGURE_OPTS: --enable-openssl From 6413567353f78d4a023059a841ec4564a3ee7439 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 27 Aug 2022 19:51:09 +0800 Subject: [PATCH 5/5] change global config for database --- config/global.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/config/global.php b/config/global.php index 8a3a3a9e..167848f9 100644 --- a/config/global.php +++ b/config/global.php @@ -80,11 +80,18 @@ $config['file_server'] = [ ], ]; -/* MySQL 数据库连接配置,框架将自动生成连接池,支持多个连接池 */ -$config['mysql'] = [ - [ - 'pool_name' => '', // 默认只有一个空名称的连接池,如果需要多个连接池,请复制此段配置并修改参数和名称 - 'host' => '', // 填写数据库服务器地址后才会创建数据库连接 +/* MySQL 和 SQLite3 数据库连接配置,框架将自动生成连接池,支持多个连接池 */ +$config['database'] = [ + 'sqlite_db1' => [ + 'enable' => false, + 'type' => 'sqlite', + 'dbname' => 'a.db', + 'pool_size' => 10, + ], + 'zm' => [ + 'enable' => false, + 'type' => 'mysql', + 'host' => '127.0.0.1', // 填写数据库服务器地址后才会创建数据库连接 'port' => 3306, 'username' => 'root', 'password' => 'ZhamaoTEST',