From bd44c1986f30536a85bc22e150fe526ce857ddd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=93=AD=E6=98=95?= <715557344@qq.com> Date: Sat, 6 Oct 2018 14:40:26 +0800 Subject: [PATCH] feat: Added strict mode and fetch mode for Mysql client (https://github.com/swoft-cloud/swoft-component/pull/208) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 增加DB严格模式配置 * 增加配置读取单测 * Update SqlTest.php * Update DbPoolProperties.php * Remoe useless comments. --- src/Driver/Mysql/MysqlConnection.php | 31 +++++++++++++++++------- src/Driver/Mysql/SyncMysqlConnection.php | 10 ++++++++ src/Pool/Config/DbPoolConfig.php | 12 +++++++++ src/Pool/Config/DbPoolProperties.php | 30 +++++++++++++++++------ src/Pool/Config/DbSlavePoolConfig.php | 12 +++++++++ test/Cases/Mysql/SqlTest.php | 17 +++++++++++++ test/Cases/PoolTest.php | 8 ++++++ test/Testing/Pool/OtherDbConfig.php | 6 +++++ test/Testing/Pool/OtherDbSlaveConfig.php | 6 +++++ test/config/properties/db.php | 2 ++ 10 files changed, 118 insertions(+), 16 deletions(-) diff --git a/src/Driver/Mysql/MysqlConnection.php b/src/Driver/Mysql/MysqlConnection.php index 754faea..72c3fe0 100644 --- a/src/Driver/Mysql/MysqlConnection.php +++ b/src/Driver/Mysql/MysqlConnection.php @@ -14,6 +14,7 @@ use Swoft\Db\AbstractDbConnection; use Swoft\Db\Bean\Annotation\Connection; use Swoft\Db\Exception\MysqlException; +use Swoft\Db\Pool\Config\DbPoolProperties; use Swoole\Coroutine\Mysql; /** @@ -59,17 +60,29 @@ public function createConnection() $options = $this->parseUri($uri); $options['timeout'] = $this->pool->getTimeout(); + /** @var DbPoolProperties $config */ + $config = $this->pool->getPoolConfig(); + $strictType = $config->isStrictType(); + $fetchMode = $config->isFetchMode(); + + $serverConfig = [ + 'host' => $options['host'], + 'port' => $options['port'], + 'user' => $options['user'], + 'password' => $options['password'], + 'database' => $options['database'], + 'timeout' => $options['timeout'], + 'charset' => $options['charset'], + 'strict_type' => $strictType, + ]; + + if (version_compare(swoole_version(), '4.0', '>=')) { + $serverConfig['fetch_mode'] = $fetchMode; + } + // init $mysql = new MySQL(); - $mysql->connect([ - 'host' => $options['host'], - 'port' => $options['port'], - 'user' => $options['user'], - 'password' => $options['password'], - 'database' => $options['database'], - 'timeout' => $options['timeout'], - 'charset' => $options['charset'], - ]); + $mysql->connect($serverConfig); // error if ($mysql->connected === false) { diff --git a/src/Driver/Mysql/SyncMysqlConnection.php b/src/Driver/Mysql/SyncMysqlConnection.php index 034bfd3..2d8b2f8 100644 --- a/src/Driver/Mysql/SyncMysqlConnection.php +++ b/src/Driver/Mysql/SyncMysqlConnection.php @@ -15,6 +15,7 @@ use Swoft\Db\Bean\Annotation\Connection; use Swoft\Db\Driver\DriverType; use Swoft\Db\Exception\MysqlException; +use Swoft\Db\Pool\Config\DbPoolProperties; /** * Mysql sync connection @@ -47,6 +48,9 @@ public function createConnection() $options = $this->parseUri($uri); $options['timeout'] = $this->pool->getTimeout(); + /** @var DbPoolProperties $config */ + $config = $this->pool->getPoolConfig(); + $user = $options['user']; $passwd = $options['password']; $host = $options['host']; @@ -60,6 +64,12 @@ public function createConnection() \PDO::ATTR_TIMEOUT => $timeout, \PDO::ATTR_PERSISTENT => true, ]; + + if ($config->isStrictType()) { + $pdoOptions[\PDO::ATTR_STRINGIFY_FETCHES] = false; + $pdoOptions[\PDO::ATTR_EMULATE_PREPARES] = false; + } + $dsn = "mysql:host=$host;port=$port;dbname=$dbName;charset=$charset"; $this->connection = new \PDO($dsn, $user, $passwd, $pdoOptions); $this->connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); diff --git a/src/Pool/Config/DbPoolConfig.php b/src/Pool/Config/DbPoolConfig.php index 40e1737..78d9969 100644 --- a/src/Pool/Config/DbPoolConfig.php +++ b/src/Pool/Config/DbPoolConfig.php @@ -108,4 +108,16 @@ class DbPoolConfig extends DbPoolProperties * @var string */ protected $driver = Driver::MYSQL; + + /** + * @Value(name="${config.db.master.strictType}", env="${DB_STRICT_TYPE}") + * @var bool + */ + protected $strictType = false; + + /** + * @Value(name="${config.db.master.fetchMode}", env="${DB_FETCH_MODE}") + * @var bool + */ + protected $fetchMode = true; } diff --git a/src/Pool/Config/DbPoolProperties.php b/src/Pool/Config/DbPoolProperties.php index 1c9956f..b7912de 100644 --- a/src/Pool/Config/DbPoolProperties.php +++ b/src/Pool/Config/DbPoolProperties.php @@ -14,12 +14,6 @@ /** * The pool properties of database - * - * @uses DbPoolProperties - * @version 2018年01月27日 - * @author stelin - * @copyright Copyright 2010-2016 swoft software - * @license PHP Version 7.x {@link http://www.php.net/license/3_0.txt} */ class DbPoolProperties extends PoolProperties { @@ -31,10 +25,32 @@ class DbPoolProperties extends PoolProperties protected $driver = Driver::MYSQL; /** - * @return string + * 开启严格模式,返回的字段将自动转为数字类型 + * + * @var bool */ + protected $strictType = false; + + /** + * 开启 Fetch 模式, 可类似于 PDO 一样使用 fetch/fetchAll 逐行获取或获取全部结果集 + * + * @since Swoole 4.0 + * @var bool + */ + protected $fetchMode = true; + public function getDriver(): string { return $this->driver; } + + public function isStrictType(): bool + { + return $this->strictType; + } + + public function isFetchMode(): bool + { + return $this->fetchMode; + } } diff --git a/src/Pool/Config/DbSlavePoolConfig.php b/src/Pool/Config/DbSlavePoolConfig.php index 513e8a6..01a391e 100644 --- a/src/Pool/Config/DbSlavePoolConfig.php +++ b/src/Pool/Config/DbSlavePoolConfig.php @@ -108,4 +108,16 @@ class DbSlavePoolConfig extends DbPoolProperties * @var string */ protected $driver = Driver::MYSQL; + + /** + * @Value(name="${config.db.slave.strictType}", env="${DB_SLAVE_STRICT_TYPE}") + * @var bool + */ + protected $strictType = false; + + /** + * @Value(name="${config.db.slave.fetchMode}", env="${DB_SLAVE_FETCH_MODE}") + * @var bool + */ + protected $fetchMode = true; } diff --git a/test/Cases/Mysql/SqlTest.php b/test/Cases/Mysql/SqlTest.php index d923741..39c5eb1 100644 --- a/test/Cases/Mysql/SqlTest.php +++ b/test/Cases/Mysql/SqlTest.php @@ -194,4 +194,21 @@ public function testTableNameIsDbKeywordByCo() $this->testTableNameIsDbKeyword(); }); } + + public function testSqlQueryStrictType() + { + $result = Db::query('SELECT * FROM user LIMIT 1;', [], 'other')->getResult(); + $id = $result[0]['id']; + $name = $result[0]['name']; + + $this->assertTrue(is_int($id)); + $this->assertTrue(is_string($name)); + } + + public function testSqlQueryStrictTypeByCo() + { + go(function () { + $this->testSqlQueryStrictType(); + }); + } } diff --git a/test/Cases/PoolTest.php b/test/Cases/PoolTest.php index de7eb22..b6bf51e 100644 --- a/test/Cases/PoolTest.php +++ b/test/Cases/PoolTest.php @@ -14,6 +14,7 @@ use SwoftTest\Db\Testing\Pool\DbPptPoolConfig; use SwoftTest\Db\Testing\Pool\DbSlaveEnvPoolConfig; use SwoftTest\Db\Testing\Pool\DbSlavePptConfig; +use SwoftTest\Db\Testing\Pool\OtherDbConfig; use SwoftTest\Db\Testing\Pool\OtherDbPool; /** @@ -91,6 +92,13 @@ public function testDbSlaveEnv() $this->assertEquals($pConfig->getMaxWait(), 10); } + public function testOtherConfig() + { + $config = bean(OtherDbConfig::class); + $this->assertTrue($config->isStrictType()); + $this->assertTrue($config->isFetchMode()); + } + public function testMaxIdleTime() { $pool = App::getPool('idle.master'); diff --git a/test/Testing/Pool/OtherDbConfig.php b/test/Testing/Pool/OtherDbConfig.php index 6702700..217e409 100644 --- a/test/Testing/Pool/OtherDbConfig.php +++ b/test/Testing/Pool/OtherDbConfig.php @@ -85,4 +85,10 @@ class OtherDbConfig extends DbPoolProperties * @var string */ protected $driver = Driver::MYSQL; + + /** + * @Value(name="${config.db.other.master.strictType}", env="${DB_OTHER_STRICT_TYPE}") + * @var bool + */ + protected $strictType = false; } diff --git a/test/Testing/Pool/OtherDbSlaveConfig.php b/test/Testing/Pool/OtherDbSlaveConfig.php index 3853cbd..d07e192 100644 --- a/test/Testing/Pool/OtherDbSlaveConfig.php +++ b/test/Testing/Pool/OtherDbSlaveConfig.php @@ -85,4 +85,10 @@ class OtherDbSlaveConfig extends DbPoolProperties * @var string */ protected $driver = Driver::MYSQL; + + /** + * @Value(name="${config.db.other.slave.strictType}", env="${DB_OTHER_SLAVE_STRICT_TYPE}") + * @var bool + */ + protected $strictType = false; } diff --git a/test/config/properties/db.php b/test/config/properties/db.php index d203508..8be2806 100644 --- a/test/config/properties/db.php +++ b/test/config/properties/db.php @@ -49,6 +49,7 @@ 'maxActive' => 1, 'maxWait' => 1, 'timeout' => 1, + 'strictType' => true, ], 'slave' => [ @@ -61,6 +62,7 @@ 'maxActive' => 1, 'maxWait' => 1, 'timeout' => 1, + 'strictType' => true, ], ], ];