From a215317e081cf733478bf5380207fa03b0c4e91c Mon Sep 17 00:00:00 2001 From: lilin <794774870@qq.com> Date: Wed, 28 Mar 2018 00:15:15 +0800 Subject: [PATCH 01/27] refactor db --- src/AbstractDbConnection.php | 8 - .../Annotation/{Builder.php => Statement.php} | 2 +- src/Bean/Collector/BuilderCollector.php | 48 --- src/Bean/Collector/StatementCollector.php | 47 +++ src/Bean/Parser/BuilderParser.php | 33 -- src/Bean/Parser/StatementParser.php | 35 ++ ...uilderWrapper.php => StatementWrapper.php} | 10 +- src/Db.php | 155 +++++--- src/DbCoResult.php | 90 +---- src/DbDataResult.php | 25 +- src/DbResult.php | 80 ++++ src/Driver/Mysql/MysqlConnection.php | 15 +- src/Driver/Mysql/MysqlStatement.php | 13 + src/Driver/Mysql/QueryBuilder.php | 155 -------- src/EntityManager.php | 337 ---------------- src/EntityManagerInterface.php | 31 -- src/Executor.php | 177 +++------ src/Helper/DbHelper.php | 34 +- src/Helper/EntityHelper.php | 26 +- src/Model.php | 98 ++--- src/Pool.php | 2 + src/Query.php | 24 ++ src/QueryBuilder.php | 291 +++++++++----- src/Statement.php | 250 ++++++------ src/StatementInterface.php | 11 + test/Cases/AbstractDbTestCase.php | 373 ------------------ test/Cases/AbstractMysqlCase.php | 51 +++ test/Cases/AbstractTestCase.php | 2 +- test/Cases/BugMysqlTest.php | 207 ---------- test/Cases/EntityTest.php | 82 ++-- test/Cases/MysqlArTest.php | 202 ---------- test/Cases/MysqlEmTest.php | 181 --------- test/Cases/MysqlTest.php | 270 +++++++++++++ test/Cases/QueryTest.php | 59 +++ test/Cases/SqlMysqlTest.php | 136 +++---- test/Cases/TrasactionTest.php | 11 + test/Cases/TsTest.php | 122 ------ 37 files changed, 1282 insertions(+), 2411 deletions(-) rename src/Bean/Annotation/{Builder.php => Statement.php} (97%) delete mode 100644 src/Bean/Collector/BuilderCollector.php create mode 100644 src/Bean/Collector/StatementCollector.php delete mode 100644 src/Bean/Parser/BuilderParser.php create mode 100644 src/Bean/Parser/StatementParser.php rename src/Bean/Wrapper/{BuilderWrapper.php => StatementWrapper.php} (78%) create mode 100644 src/DbResult.php create mode 100644 src/Driver/Mysql/MysqlStatement.php delete mode 100644 src/Driver/Mysql/QueryBuilder.php create mode 100644 src/Query.php create mode 100644 src/StatementInterface.php delete mode 100644 test/Cases/AbstractDbTestCase.php create mode 100644 test/Cases/AbstractMysqlCase.php delete mode 100644 test/Cases/BugMysqlTest.php delete mode 100644 test/Cases/MysqlArTest.php delete mode 100644 test/Cases/MysqlEmTest.php create mode 100644 test/Cases/MysqlTest.php create mode 100644 test/Cases/QueryTest.php create mode 100644 test/Cases/TrasactionTest.php delete mode 100644 test/Cases/TsTest.php diff --git a/src/AbstractDbConnection.php b/src/AbstractDbConnection.php index 4aafcd7..7fa98c3 100644 --- a/src/AbstractDbConnection.php +++ b/src/AbstractDbConnection.php @@ -12,14 +12,6 @@ */ abstract class AbstractDbConnection extends AbstractConnection implements DbConnectInterface { - - /** - * - */ - public function fetch() - { - } - /** * @return string */ diff --git a/src/Bean/Annotation/Builder.php b/src/Bean/Annotation/Statement.php similarity index 97% rename from src/Bean/Annotation/Builder.php rename to src/Bean/Annotation/Statement.php index fa5349f..a1b2266 100644 --- a/src/Bean/Annotation/Builder.php +++ b/src/Bean/Annotation/Statement.php @@ -8,7 +8,7 @@ * @Annotation * @Target("CLASS") */ -class Builder +class Statement { /** * @var string diff --git a/src/Bean/Collector/BuilderCollector.php b/src/Bean/Collector/BuilderCollector.php deleted file mode 100644 index 2cd2e8f..0000000 --- a/src/Bean/Collector/BuilderCollector.php +++ /dev/null @@ -1,48 +0,0 @@ -getDriver(); - self::$builders[$driver] = $className; - } - } - - /** - * @return array - */ - public static function getCollector() - { - return self::$builders; - } -} \ No newline at end of file diff --git a/src/Bean/Collector/StatementCollector.php b/src/Bean/Collector/StatementCollector.php new file mode 100644 index 0000000..8b80516 --- /dev/null +++ b/src/Bean/Collector/StatementCollector.php @@ -0,0 +1,47 @@ +getDriver(); + self::$statements[$driver] = $className; + } + } + + /** + * @return array + */ + public static function getCollector() + { + return self::$statements; + } +} \ No newline at end of file diff --git a/src/Bean/Parser/BuilderParser.php b/src/Bean/Parser/BuilderParser.php deleted file mode 100644 index e51a34e..0000000 --- a/src/Bean/Parser/BuilderParser.php +++ /dev/null @@ -1,33 +0,0 @@ -getPool(); + /* @var DbPoolProperties $poolConfig */ + $poolConfig = $pool->getPoolConfig(); + $profileKey = $poolConfig->getDriver(); + + if (App::isCoContext()) { + $connection->setDefer(); + } + $connection->prepare($sql); + $result = $connection->execute($params); + + $dbResult = self::getResult($result, $connection, $profileKey); + $dbResult->setType($type); - return new $queryBuilderClassName($group, $sql); + return $dbResult; } + /** - * @param string $group + * @param string $instance + * @param string $node + * @param int $type * - * @return \Swoft\Db\QueryBuilder + * @return array */ - public static function delete(string $group = Pool::GROUP) + private static function getInstanceAndNodeByType(string $instance, string $node, int $type): array + { + if (!empty($node)) { + return [$instance, $node]; + } + + if ($type === Db::RESULT_ROWS || $type == Db::RESULT_INSERTID) { + return [$instance, Pool::MASTER]; + } + + return [$instance, Pool::SLAVE]; + } + + public static function beginTransaction() + { + + } + + public static function rollback() + { + + } + + public static function commit() { - $queryBuilderClassName = DbHelper::getQueryClassNameByGroup($group); - /* @var \Swoft\Db\QueryBuilder $queryBuidler */ - $queryBuidler = new $queryBuilderClassName($group); - $queryBuidler->delete(); - return $queryBuidler; } /** - * @param string $tableName - * @param string $group - * - * @return \Swoft\Db\QueryBuilder + * @return ConnectionInterface */ - public static function insert(string $tableName, string $group = Pool::GROUP) + private static function getConnection(string $instance, string $node): ConnectionInterface { - $queryBuilderClassName = DbHelper::getQueryClassNameByGroup($group); - /* @var \Swoft\Db\QueryBuilder $queryBuidler */ - $queryBuidler = new $queryBuilderClassName($group); - $queryBuidler->insert($tableName); + $contextTsKey = PoolHelper::getContextTsKey(); + $contextCntKey = PoolHelper::getContextCntKey(); + $instanceKey = PoolHelper::getTsInstanceKey($instance); + + /* @var \SplStack $tsStack */ + $tsStack = RequestContext::getContextDataByChildKey($contextTsKey, $instanceKey, new \SplStack()); + if (!$tsStack->isEmpty()) { + $cntId = $tsStack->offsetGet(0); + $connection = RequestContext::getContextDataByChildKey($contextCntKey, $cntId, null); - return $queryBuidler; + return $connection; + } + + $pool = DbHelper::getPool($instance, $node); + + return $pool->getConnection(); } /** - * @param string $tableName - * @param string $group + * @param string $sql * - * @return \Swoft\Db\QueryBuilder + * @return string */ - public static function update(string $tableName, string $group = Pool::GROUP) + private static function getOperation(string $sql): string { - $queryBuilderClassName = DbHelper::getQueryClassNameByGroup($group); - /* @var \Swoft\Db\QueryBuilder $queryBuidler */ - $queryBuidler = new $queryBuilderClassName($group); - $queryBuidler->update($tableName); + $sql = trim($sql); + $sql = strtoupper($sql); + + if (strpos($sql, 'INSERT') === 0) { + return self::RESULT_INSERTID; + } - return $queryBuidler; + if (strpos($sql, 'UPDATE') === 0 || strpos($sql, 'DELETE') === 0) { + return self::RESULT_ROWS; + } + + if (strpos($sql, 'SELECT') === 0 && strpos($sql, 'LIMIT 0,1')) { + return self::RESULT_ONE; + } + + return self::RESULT_FETCH; } /** - * @param mixed $column - * @param string|null $alias - * @param string $group + * @param mixed $result + * @param ConnectionInterface $connection + * @param string $profileKey * - * @return \Swoft\Db\QueryBuilder + * @return \Swoft\Db\DbResult */ - public static function select($column, string $alias = null, string $group = Pool::GROUP) + private static function getResult($result, ConnectionInterface $connection = null, string $profileKey = '') { - $queryBuilderClassName = DbHelper::getQueryClassNameByGroup($group); - /* @var \Swoft\Db\QueryBuilder $queryBuidler */ - $queryBuidler = new $queryBuilderClassName($group); - $queryBuidler->select($column, $alias); + if (App::isCoContext()) { + return new DbCoResult($result, $connection, $profileKey); + } - return $queryBuidler; + return new DbDataResult($result, $connection, $profileKey); } + } \ No newline at end of file diff --git a/src/DbCoResult.php b/src/DbCoResult.php index 3839af9..5c62eaf 100644 --- a/src/DbCoResult.php +++ b/src/DbCoResult.php @@ -2,37 +2,13 @@ namespace Swoft\Db; -use Swoft\App; -use Swoft\Core\AbstractCoResult; -use Swoft\Db\Helper\EntityHelper; - /** * Class DbCoResult * * @package Swoft\Db */ -class DbCoResult extends AbstractCoResult +class DbCoResult extends DbResult { - /** - * Is insert operation - * - * @var bool - */ - private $insert = false; - - /** - * Is update or delete operation - * - * @var bool - */ - private $updateOrDelete = false; - - /** - * Is find one entity operation - * - * @var bool - */ - private $findOne = false; /** * @param array ...$params @@ -41,67 +17,9 @@ class DbCoResult extends AbstractCoResult */ public function getResult(...$params) { - $className = ''; - if (!empty($params)) { - list($className) = $params; - } - - $result = $this->recv(true); - $result = $this->transferResult($result); - - // Logger - list(, $sqlId) = explode('.', $this->profileKey); - App::debug("SQL语句执行结果(defer) sqlId=$sqlId result=" . json_encode($result)); - - // Fill data to Entity - if (\is_array($result) && !empty($className)) { - $result = EntityHelper::resultToEntity($result, $className); - } - - return $result; - } - - /** - * @param bool $insert - */ - public function setInsert(bool $insert) - { - $this->insert = $insert; - } - - /** - * @param bool $updateOrDelete - */ - public function setUpdateOrDelete(bool $updateOrDelete) - { - $this->updateOrDelete = $updateOrDelete; - } - - /** - * @param bool $findOne - */ - public function setFindOne(bool $findOne) - { - $this->findOne = $findOne; - } - - /** - * 转换结果 - * - * @param mixed $result 查询结果 - * - * @return mixed - */ - private function transferResult($result) - { - if ($this->insert && $result !== false) { - $result = $this->connection->getInsertId(); - } elseif ($this->updateOrDelete && $result !== false) { - $result = $this->connection->getAffectedRows(); - } elseif ($this->findOne && $result !== false) { - $result = $result[0] ?? []; - } - + list($className) = array_pad($params, 1, ''); + $this->recv(true); + $result = $this->getResultByClass($className); return $result; } } \ No newline at end of file diff --git a/src/DbDataResult.php b/src/DbDataResult.php index e7e9c9f..aebe8c9 100644 --- a/src/DbDataResult.php +++ b/src/DbDataResult.php @@ -2,15 +2,10 @@ namespace Swoft\Db; -use Swoft\Core\AbstractDataResult; -use Swoft\Db\Helper\EntityHelper; - /** - * Class DbDataResult - * - * @package Swoft\Db + * DbDataResult */ -class DbDataResult extends AbstractDataResult +class DbDataResult extends DbResult { /** * @param array ...$params @@ -19,20 +14,8 @@ class DbDataResult extends AbstractDataResult */ public function getResult(...$params) { - $className = ''; - $result = $this->data; - if (!empty($params)) { - list($className) = $params; - } - - // Fill data to Entity - if (\is_array($result) && !empty($result) && !empty($className)) { - $result = EntityHelper::resultToEntity($result, $className); - } - - if (empty($result) && !empty($className)) { - return null; - } + list($className) = array_pad($params, 1, ''); + $result = $this->getResultByClass($className); $this->release(); diff --git a/src/DbResult.php b/src/DbResult.php new file mode 100644 index 0000000..eeb5952 --- /dev/null +++ b/src/DbResult.php @@ -0,0 +1,80 @@ +type = $type; + } + + /** + * @param string $className + * + * @return mixed + */ + protected function getResultByClass(string $className) + { + $result = $this->getResultByType(); + if (isset($result[0]) && !empty($className)) { + $result = EntityHelper::listToEntity($result, $className); + } + + if (is_array($result) && !empty($result) && !empty($className)) { + $result = EntityHelper::arrayToEntity($result, $className); + } + + if (!empty($className) && $this->type == Db::RESULT_FETCH && empty($result)) { + return []; + } + + if (!empty($className) && $this->type == Db::RESULT_ONE && empty($result)) { + return null; + } + + return $result; + } + + /** + * @return mixed + */ + private function getResultByType() + { + /* @var AbstractDbConnection $connection */ + $connection = $this->connection; + + if ($this->type == Db::RESULT_INSERTID) { + return $this->connection->getInsertId(); + } + + if ($this->type == Db::RESULT_ROWS) { + return $connection->getAffectedRows(); + } + + if ($this->type == Db::RESULT_FETCH) { + return $connection->fetch(); + } + + $result = $connection->fetch(); + $result = $result[0]??[]; + + return $result; + } +} \ No newline at end of file diff --git a/src/Driver/Mysql/MysqlConnection.php b/src/Driver/Mysql/MysqlConnection.php index 1094aa6..8bcf115 100644 --- a/src/Driver/Mysql/MysqlConnection.php +++ b/src/Driver/Mysql/MysqlConnection.php @@ -25,6 +25,11 @@ class MysqlConnection extends AbstractDbConnection */ private $sql = ''; + /** + * @var mixed + */ + private $result; + /** * Prepare * @@ -61,11 +66,20 @@ public function receive() { $result = $this->connection->recv(); $this->connection->setDefer(false); + $this->recv = true; + $this->result = $result; return $result; } + /** + * @return mixed + */ + public function fetch() + { + return $this->result; + } /** * @return mixed @@ -152,7 +166,6 @@ public function setDefer($defer = true) $this->connection->setDefer($defer); } - /** * @return void */ diff --git a/src/Driver/Mysql/MysqlStatement.php b/src/Driver/Mysql/MysqlStatement.php new file mode 100644 index 0000000..4efaa08 --- /dev/null +++ b/src/Driver/Mysql/MysqlStatement.php @@ -0,0 +1,13 @@ +getCorResult(); - } - - return $this->getSyncResult(); - } - - /** - * @return DbDataResult - */ - private function getSyncResult() - { - $sql = $this->getStatement(); - list($sqlId, $profileKey) = $this->getSqlIdAndProfileKey($sql); - - App::profileStart($profileKey); - - /* @var AbstractDbConnection $connection*/ - $connection = $this->selectConnection(); - $connection->prepare($sql); - $result = $connection->execute($this->parameters); - - App::profileEnd($profileKey); - App::debug(sprintf('sql execute sqlId=%s, result=%s, sql=%s', $sqlId, JsonHelper::encode($result, JSON_UNESCAPED_UNICODE), $sql)); - - $isFindOne = isset($this->limit['limit']) && $this->limit['limit'] === 1; - if ($this->isSqlOperation($sql, 'insert')) { - $result = $connection->getInsertId(); - } elseif ($this->isSqlOperation($sql, 'update') || $this->isSqlOperation($sql, 'delete')) { - $result = $connection->getAffectedRows(); - } else { - $result = $connection->fetch(); - } - - $result = $this->transferResult($connection, $result); - - if (is_array($result) && !empty($className)) { - $result = EntityHelper::resultToEntity($result, $className); - } - $syncData = new DbDataResult($result, $connection); - - return $syncData; - } - - /** - * @return ResultInterface - */ - private function getCorResult() - { - $sql = $this->getStatement(); - list($sqlId, $profileKey) = $this->getSqlIdAndProfileKey($sql); - - /* @var AbstractDbConnection $connection */ - $connection = $this->selectConnection(); - $connection->setDefer(); - $connection->prepare($sql); - $result = $connection->execute($this->parameters); - - App::debug(sprintf('sql execute sqlId=%s, sql=%s', $sqlId, $sql)); - $isInsert = $this->isSqlOperation($sql, 'insert'); - $isUpdateOrDelete = $this->isSqlOperation($sql, 'delete') || $this->isSqlOperation($sql, 'update'); - $isFindOne = $this->isSelect() && isset($this->limit['limit']) && $this->limit['limit'] === 1; - $corResult = new DbCoResult($connection, $profileKey); - - // 结果转换参数 - $corResult->setInsert($isInsert); - $corResult->setUpdateOrDelete($isUpdateOrDelete); - $corResult->setFindOne($isFindOne); - - return $corResult; - } - - /** - * @param string $sql - * - * @return array - */ - private function getSqlIdAndProfileKey(string $sql) - { - $sqlId = md5($sql); - $profileKey = sprintf('%s.%s', $sqlId, $this->profilePrefix); - - return [$sqlId, $profileKey]; - } - - /** - * 转换结果 - * - * @param AbstractDbConnection $connection - * @param mixed $result - * - * @return mixed - */ - private function transferResult(AbstractDbConnection $connection, $result) - { - $isFindOne = isset($this->limit['limit']) && $this->limit['limit'] === 1; - $isUpdateOrDelete = $this->isDelete() || $this->isUpdate(); - if ($result !== false && $this->isInsert()) { - $result = $connection->getInsertId(); - } elseif ($result !== false && $isUpdateOrDelete) { - $result = $connection->getAffectedRows(); - } elseif ($isFindOne && $result !== false && $this->isSelect()) { - $result = $result[0] ?? []; - } - - return $result; - } - - /** - * @param mixed $key - * - * @return string - */ - protected function formatParamsKey($key): string - { - if (\is_string($key) && strpos($key, ':') === false) { - return ':' . $key; - } - if (is_int($key) && App::isCoContext()) { - return '?' . $key; - } - - return $key; - } -} diff --git a/src/EntityManager.php b/src/EntityManager.php index 11626b1..f39312f 100644 --- a/src/EntityManager.php +++ b/src/EntityManager.php @@ -2,15 +2,6 @@ namespace Swoft\Db; -use Swoft\Core\Coroutine; -use Swoft\Core\RequestContext; -use Swoft\Core\ResultInterface; -use Swoft\Db\Bean\Collector\EntityCollector; -use Swoft\Db\Exception\DbException; -use Swoft\Db\Helper\DbHelper; -use Swoft\Helper\PoolHelper; -use Swoft\Pool\PoolInterface; - /** * Class EntityManager * @@ -18,333 +9,5 @@ */ class EntityManager implements EntityManagerInterface { - /** - * Db connection - * - * @var \Swoft\Db\AbstractDbConnection - */ - private $connection; - - /** - * Connection pool - * - * @var PoolInterface - */ - private $pool = null; - - /** - * Is this EntityManager closed ? - * - * @var bool - */ - private $isClose = false; - - /** - * @var bool - */ - private $isTransaction = false; - - /** - * @var string - */ - private $group; - - /** - * EntityManager constructor. - * - * @param PoolInterface $pool - * @param string $group - */ - private function __construct(PoolInterface $pool, string $group) - { - $this->pool = $pool; - $this->group = $group; - $this->connection = $pool->getConnection(); - $this->connection->setAutoRelease(false); - } - - /** - * Create a EntityManager - * - * @param string $group - * @param string $node - * - * @return EntityManager - */ - public static function create(string $group = Pool::GROUP, $node = Pool::MASTER): EntityManager - { - $pool = DbHelper::getPool($group, $node); - - return new EntityManager($pool, $group); - } - - /** - * Create a Query Builder - * - * @param string $sql - * - * @return QueryBuilder - * @throws \Swoft\Db\Exception\DbException - */ - public function createQuery(string $sql = ''): QueryBuilder - { - $this->checkStatus(); - $className = DbHelper::getQueryClassNameByConnection($this->connection); - - return new $className($this->group, $sql, null, $this->connection); - } - - /** - * Create a QueryBuild for ActiveRecord - * - * @param string $className Entity class name - * @param string $group Group id, master node will be used as defaults - * - * @return QueryBuilder - */ - public static function getQuery(string $className, $group): QueryBuilder - { - $entities = EntityCollector::getCollector(); - $tableName = $entities[$className]['table']['name']; - $queryClassName = DbHelper::getQueryClassNameByGroup($group); - - /* @var QueryBuilder $query */ - $query = new $queryClassName($group, '', $tableName); - - return $query; - } - - /** - * Save Entity - * - * @param object $entity - * - * @return ResultInterface - * @throws \Swoft\Db\Exception\DbException - */ - public function save($entity) - { - $this->checkStatus(); - $executor = $this->getExecutor(); - - return $executor->save($entity); - } - - /** - * Delete Entity - * - * @param object $entity - * - * @return ResultInterface - */ - public function delete($entity) - { - $this->checkStatus(); - $executor = $this->getExecutor(); - - return $executor->delete($entity); - } - - /** - * @param $entity - * - * @return ResultInterface - */ - public function update($entity): ResultInterface - { - $this->checkStatus(); - $executor = $this->getExecutor(); - - return $executor->update($entity); - } - - /** - * Delete Entity by ID - * - * @param string $className Entity class nane - * @param mixed $id - * - * @return ResultInterface - */ - public function deleteById($className, $id) - { - $this->checkStatus(); - $executor = $this->getExecutor(); - - return $executor->deleteById($className, $id); - } - - /** - * Delete Entities by Ids - * - * @param string $className Entity class name - * @param array $ids ID collection - * - * @return ResultInterface - */ - public function deleteByIds($className, array $ids) - { - $this->checkStatus(); - $executor = $this->getExecutor(); - - return $executor->deleteByIds($className, $ids); - } - - /** - * Find by Entity - * - * @param object $entity - * - * @return ResultInterface - */ - public function find($entity): ResultInterface - { - $this->checkStatus(); - $executor = $this->getExecutor(); - - return $executor->find($entity); - } - - /** - * Find Entity by ID - * - * @param string $className Entity class name - * @param mixed $id - * - * @return ResultInterface - */ - public function findById($className, $id): ResultInterface - { - $this->checkStatus(); - $executor = $this->getExecutor(); - - return $executor->findById($className, $id); - } - - /** - * Find Entites by IDs - * - * @param string $className transaction - * @param array $ids - * - * @return ResultInterface - */ - public function findByIds($className, array $ids): ResultInterface - { - $this->checkStatus(); - $executor = $this->getExecutor(); - - return $executor->findByIds($className, $ids); - } - - /** - * Begin transaction - * - * @throws \Swoft\Db\Exception\DbException - */ - public function beginTransaction() - { - $this->checkStatus(); - $this->connection->beginTransaction(); - $this->beginTransactionContext(); - $this->isTransaction = true; - } - - /** - * Rollback transaction - * - * @throws \Swoft\Db\Exception\DbException - */ - public function rollback() - { - $this->checkStatus(); - $this->connection->rollback(); - $this->isTransaction = false; - $this->closetTransactionContext(); - } - - /** - * Commit transaction - * - * @throws \Swoft\Db\Exception\DbException - */ - public function commit() - { - $this->checkStatus(); - $this->connection->commit(); - $this->isTransaction = false; - $this->closetTransactionContext(); - } - - /** - * Close current EntityManager, and release the connection - */ - public function close() - { - if ($this->isTransaction) { - $this->rollback(); - } - if (!$this->connection->isRecv()) { - $this->connection->receive(); - } - $this->isClose = true; - $this->pool->release($this->connection); - } - - /** - * Check the EntityManager status - * - * @throws DbException - */ - private function checkStatus() - { - if ($this->isClose) { - throw new DbException('EntityManager was closed, no operation anymore'); - } - } - - /** - * Get an Executor - * - * @return Executor - * @throws \Swoft\Db\Exception\DbException - */ - private function getExecutor(): Executor - { - $query = $this->createQuery(); - - return new Executor($query); - } - - /** - * Begin transaction context - */ - private function beginTransactionContext() - { - $cntId = $this->connection->getConnectionId(); - $contextTsKey = PoolHelper::getContextTsKey(); - $groupKey = PoolHelper::getGroupKey($this->group); - - /* @var \SplStack $tsStack */ - $tsStack = RequestContext::getContextDataByChildKey($contextTsKey, $groupKey, new \SplStack()); - $tsStack->push($cntId); - - RequestContext::setContextDataByChildKey($contextTsKey, $groupKey, $tsStack); - } - - /** - * Close transaction context - */ - private function closetTransactionContext() - { - $cid = Coroutine::id(); - $contextTsKey = PoolHelper::getContextTsKey(); - $groupKey = PoolHelper::getGroupKey($this->group); - - /* @var \SplStack $tsStack */ - $tsStack = RequestContext::getContextDataByChildKey($contextTsKey, $groupKey, new \SplStack()); - $tsStack->pop(); - RequestContext::setContextDataByChildKey($contextTsKey, $groupKey, $tsStack); - } } diff --git a/src/EntityManagerInterface.php b/src/EntityManagerInterface.php index 002d912..951ed7d 100644 --- a/src/EntityManagerInterface.php +++ b/src/EntityManagerInterface.php @@ -9,36 +9,5 @@ */ interface EntityManagerInterface { - /** - * Create a EntityManager instance - * - * @param string $poolId - * @return EntityManager - */ - public static function create(string $poolId): EntityManager; - - /** - * Rollback transaction - */ - public function rollback(); - - /** - * Begin transaction - */ - public function beginTransaction(); - - /** - * Commit transaction - */ - public function commit(); - - - /** - * Create a Query Builder - * - * @param string $sql - * @return QueryBuilder - */ - public function createQuery(string $sql = ''): QueryBuilder; } diff --git a/src/Executor.php b/src/Executor.php index 1b3569b..9043a24 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -15,195 +15,147 @@ class Executor { /** - * 查询器 - * - * @var QueryBuilder - */ - private $queryBuilder; - - /** - * Executor constructor. - * - * @param QueryBuilder $queryBuilder - */ - public function __construct(QueryBuilder $queryBuilder) - { - $this->queryBuilder = $queryBuilder; - } - - /** - * insert实体数据 - * - * @param object $entity 实体 + * @param object $entity * * @return ResultInterface */ - public function save($entity): ResultInterface + public static function save($entity): ResultInterface { - // 实体映射信息处理 - list($table, , , $fields) = $this->getFields($entity, 1); + list($table, , , $fields) = self::getFields($entity, 1); - // 构建insert查询器 - $this->queryBuilder->insert($table); + $query = Query::table($table)->insert(); foreach ($fields ?? [] as $column => $value) { - $this->queryBuilder->set($column, $value); + $query = $query->set($column, $value); } - return $this->getResult(); + + return $query->execute(); } /** - * 按实体信息删除数据 - * - * @param object $entity 实体 + * @param object $entity * * @return ResultInterface */ - public function delete($entity): ResultInterface + public static function delete($entity): ResultInterface { - // 实体映射数据 - list($table, , , $fields) = $this->getFields($entity, 3); + list($table, , , $fields) = self::getFields($entity, 3); - // 构建delete查询器 - $this->queryBuilder->delete()->from($table); + $query = Query::table($table)->delete(); foreach ($fields ?? [] as $column => $value) { - $this->queryBuilder->where($column, $value); + $query->where($column, $value); } - return $this->getResult(); + return $query->execute(); } /** - * 根据ID删除数据 - * - * @param string $className 实体类名 - * @param mixed $id 删除ID + * @param string $className + * @param mixed $id * * @return ResultInterface */ - public function deleteById($className, $id): ResultInterface + public static function deleteById($className, $id): ResultInterface { - // 实体映射数据 - list($table, , $idColumn) = $this->getTable($className); + list($table, , $idColumn) = self::getTable($className); + $query = Query::table($table)->delete()->where($idColumn, $id); - // 构建delete查询器 - $this->queryBuilder->delete()->from($table)->where($idColumn, $id); - return $this->getResult(); + return $query->execute(); } /** - * 根据ID删除数据 - * - * @param string $className 实体类名 - * @param array $ids ID集合 + * @param string $className + * @param array $ids * * @return ResultInterface */ - public function deleteByIds($className, array $ids): ResultInterface + public static function deleteByIds($className, array $ids): ResultInterface { - // 实体映射数据 - list($table, , $idColumn) = $this->getTable($className); + list($table, , $idColumn) = self::getTable($className); + $query = Query::table($table)->delete()->whereIn($idColumn, $ids); - // 构建delete查询器 - $this->queryBuilder->delete()->from($table)->whereIn($idColumn, $ids); - return $this->getResult(); + return $query->execute(); } /** - * 按实体更新信息(默认按照主键) - * - * @param object $entity 具体实体实例 + * @param object $entity * * @return ResultInterface */ - public function update($entity): ResultInterface + public static function update($entity): ResultInterface { // 实体映射数据 - list($table, $idColumn, $idValue, $fields) = $this->getFields($entity, 2); + list($table, $idColumn, $idValue, $fields) = self::getFields($entity, 2); if (empty($fields)) { - $pool = $this->queryBuilder->getConnection(); - $connection = $this->queryBuilder->getConnection(); - return new DbDataResult(0, $connection); + return new DbDataResult(0); } // 构建update查询器 - $this->queryBuilder->update($table)->where($idColumn, $idValue); + $query = Query::table($table)->update()->where($idColumn, $idValue); foreach ($fields ?? [] as $column => $value) { - $this->queryBuilder->set($column, $value); + $query->set($column, $value); } - return $this->getResult(); + + return $query->execute(); } /** - * 按实体信息查找 - * - * @param object $entity 实体实例 + * @param object $entity * * @return ResultInterface */ - public function find($entity): ResultInterface + public static function find($entity): ResultInterface { - // 实体映射数据 - list($tableName, , , $fields) = $this->getFields($entity, 3); + list($tableName, , , $fields) = self::getFields($entity, 3); - // 构建find查询器 - $this->queryBuilder->select('*')->from($tableName); + $query = Query::table($tableName)->select('*'); foreach ($fields ?? [] as $column => $value) { - $this->queryBuilder->where($column, $value); + $query->where($column, $value); } - return $this->queryBuilder->execute(); + + return $query->execute(); } /** - * 根据ID查找 - * - * @param string $className 实体类名 - * @param mixed $id ID + * @param string $className + * @param mixed $id * * @return ResultInterface */ - public function findById($className, $id): ResultInterface + public static function findById($className, $id): ResultInterface { - // 实体映射数据 - list($tableName, , $columnId) = $this->getTable($className); + list($tableName, , $columnId) = self::getTable($className); + $query = Query::table($tableName)->select("*")->where($columnId, $id)->limit(1); - // 构建find查询器 - $query = $this->queryBuilder->select("*")->from($tableName)->where($columnId, $id)->limit(1); return $query->execute(); } /** - * 根据ids查找 - * - * @param string $className 类名 + * @param string $className * @param array $ids * * @return ResultInterface */ - public function findByIds($className, array $ids): ResultInterface + public static function findByIds($className, array $ids): ResultInterface { - // 实体映射数据 - list($tableName, , $columnId) = $this->getTable($className); + list($tableName, , $columnId) = self::getTable($className); + $query = Query::table($tableName)->select("*")->whereIn($columnId, $ids); - // 构建find查询器 - $query = $this->queryBuilder->select("*")->from($tableName)->whereIn($columnId, $ids); return $query->execute(); } /** - * 获取实体映射结构 - * * @param object $entity 实体对象 * @param int $type 类型,1=insert 3=delete|find 2=update * * @return array * @throws \Swoft\Exception\ValidatorException */ - private function getFields($entity, $type = 1): array + private static function getFields($entity, $type = 1): array { $changeFields = []; // 实体表结构信息 - list($table, $id, $idColumn, $fields) = $this->getClassMetaData($entity); + list($table, $id, $idColumn, $fields) = self::getClassMetaData($entity); // 实体映射字段、值处理以及验证处理 $idValue = null; @@ -212,7 +164,7 @@ private function getFields($entity, $type = 1): array $default = $proAry['default']; // 实体属性对应值 - $proValue = $this->getEntityProValue($entity, $proName); + $proValue = self::getEntityProValue($entity, $proName); // insert逻辑 if ($type === 1 && $id === $proName && $default === $proValue) { @@ -230,7 +182,7 @@ private function getFields($entity, $type = 1): array } // 属性值验证 - $this->validate($proAry, $proValue); + self::validate($proAry, $proValue); // id值赋值 if ($idColumn === $column) { @@ -274,7 +226,7 @@ private function validate(array $columnAry, $propertyValue) // 类型验证器 $validator = [ 'name' => ucfirst($type), - 'value' => [$length] + 'value' => [$length], ]; // 所有验证器 @@ -324,14 +276,12 @@ private function getEntityProValue($entity, string $proName) } /** - * 实例映射信息 - * * @param object $entity * * @return array * @throws \InvalidArgumentException */ - private function getClassMetaData($entity): array + private static function getClassMetaData($entity): array { // 不是对象 if (!\is_object($entity) && !class_exists($entity)) { @@ -345,33 +295,22 @@ private function getClassMetaData($entity): array throw new \InvalidArgumentException('对象不是实体对象,className=' . $className); } - return $this->getTable($className); + return self::getTable($className); } /** - * 实体表映射结构 - * * @param string $className * * @return array */ - private function getTable(string $className): array + private static function getTable(string $className): array { $entities = EntityCollector::getCollector(); $fields = $entities[$className]['field']; $idProperty = $entities[$className]['table']['id']; $tableName = $entities[$className]['table']['name']; $idColumn = $entities[$className]['column'][$idProperty]; - return [$tableName, $idProperty, $idColumn, $fields]; - } - /** - * 获取执行结果 - * - * @return ResultInterface - */ - private function getResult() - { - return $this->queryBuilder->execute(); + return [$tableName, $idProperty, $idColumn, $fields]; } } diff --git a/src/Helper/DbHelper.php b/src/Helper/DbHelper.php index 95a7f90..bfc7b64 100644 --- a/src/Helper/DbHelper.php +++ b/src/Helper/DbHelper.php @@ -4,10 +4,12 @@ use Swoft\App; use Swoft\Db\Bean\Collector\BuilderCollector; +use Swoft\Db\Bean\Collector\StatementCollector; use Swoft\Db\Exception\MysqlException; use Swoft\Db\Pool; use Swoft\Pool\ConnectionInterface; use Swoft\Pool\PoolInterface; +use Swoft\Db\Pool\Config\DbPoolProperties; /** * DbHelper @@ -46,23 +48,47 @@ public static function getPool(string $group, string $node): PoolInterface return App::getPool($poolName); } + public static function getStatementClassNameByInstance(string $instance): string + { + $pool = DbHelper::getPool($instance, Pool::MASTER); + /* @var \Swoft\Db\Pool\Config\DbPoolProperties $poolConfig */ + $poolConfig = $pool->getPoolConfig(); + $driver = $poolConfig->getDriver(); + + $collector = StatementCollector::getCollector(); + if (!isset($collector[$driver])) { + throw new MysqlException(sprintf('The Statement of %s is not exist!', $driver)); + } + return $collector[$driver]; + } + + public static function getDriverByInstance(string $instance): string + { + $pool = DbHelper::getPool($instance, Pool::MASTER); + /* @var DbPoolProperties $poolConfig */ + $poolConfig = $pool->getPoolConfig(); + + return $poolConfig->getDriver(); + } + /** * @param string $group * * @throws \Swoft\Db\Exception\MysqlException * @return string */ - public static function getQueryClassNameByGroup(string $group):string + public static function getQueryClassNameByGroup(string $group): string { $pool = DbHelper::getPool($group, Pool::MASTER); - /* @var \Swoft\Db\Pool\Config\DbPoolProperties $poolConfig*/ + /* @var \Swoft\Db\Pool\Config\DbPoolProperties $poolConfig */ $poolConfig = $pool->getPoolConfig(); - $driver = $poolConfig->getDriver(); + $driver = $poolConfig->getDriver(); $collector = BuilderCollector::getCollector(); - if(!isset($collector[$driver])){ + if (!isset($collector[$driver])) { throw new MysqlException(sprintf('The queryBuilder of %s is not exist!', $driver)); } + return $collector[$driver]; } diff --git a/src/Helper/EntityHelper.php b/src/Helper/EntityHelper.php index 901980b..ab1350d 100644 --- a/src/Helper/EntityHelper.php +++ b/src/Helper/EntityHelper.php @@ -6,7 +6,7 @@ use Swoft\Db\Types; /** - * The helper of entity + * EntityHelper */ class EntityHelper { @@ -14,19 +14,16 @@ class EntityHelper * @param array $result * @param string $className * - * @return mixed + * @return array */ - public static function resultToEntity(array $result, string $className) + public static function listToEntity(array $result, string $className): array { - if (!isset($result[0])) { - return self::arrayToEntity($result, $className); - } $entities = []; - foreach ($result as $entityData) { - if (!\is_array($entityData)) { + foreach ($result as $data) { + if (!\is_array($data)) { continue; } - $entities[] = self::arrayToEntity($entityData, $className); + $entities[] = self::arrayToEntity($data, $className); } return $entities; @@ -36,17 +33,14 @@ public static function resultToEntity(array $result, string $className) * @param array $data * @param string $className * - * @return mixed + * @return object */ public static function arrayToEntity(array $data, string $className) { - + $attrs = []; + $object = new $className(); $entities = EntityCollector::getCollector(); - if (!isset($className)) { - return $data; - } - $attrs = []; - $object = new $className(); + foreach ($data as $col => $value) { if (!isset($entities[$className]['column'][$col])) { continue; diff --git a/src/Model.php b/src/Model.php index c6744b2..c39e969 100644 --- a/src/Model.php +++ b/src/Model.php @@ -6,12 +6,12 @@ use Swoft\Db\Bean\Collector\EntityCollector; /** - * The model of activerecord + * Activerecord */ class Model implements \ArrayAccess, \Iterator { /** - * The data of old + * Old data * * @var array */ @@ -30,144 +30,100 @@ public function __construct(array $attributes = []) /** * Insert data to db * - * @param string $group - * * @return ResultInterface */ - public function save(string $group = Pool::GROUP) + public function save() { - $executor = self::getExecutor($group); - - return $executor->save($this); + return Executor::save($this); } /** * Delete data from db * - * @param string $group - * * @return ResultInterface */ - public function delete(string $group = Pool::GROUP) + public function delete() { - $executor = self::getExecutor($group); - return $executor->delete($this); + return Executor::delete($this); } /** * Delete data by id * - * @param mixed $id ID - * @param string $group + * @param mixed $id ID * * @return ResultInterface */ - public static function deleteById($id, string $group = Pool::GROUP) + public static function deleteById($id) { - $executor = self::getExecutor($group); - - return $executor->deleteById(static::class, $id); + return Executor::deleteById(static::class, $id); } /** * Delete by ids * - * @param array $ids - * @param string $group + * @param array $ids * * @return ResultInterface */ - public static function deleteByIds(array $ids, string $group = Pool::GROUP) + public static function deleteByIds(array $ids) { - $executor = self::getExecutor($group); - - return $executor->deleteByIds(static::class, $ids); + return Executor::deleteByIds(static::class, $ids); } /** * Update data * - * @param string $group - * * @return ResultInterface */ - public function update(string $group = Pool::GROUP) + public function update() { - $executor = self::getExecutor($group); - - return $executor->update($this); + return Executor::update($this); } /** * Find data from db * - * @param string $group - * * @return ResultInterface */ - public function find(string $group = Pool::GROUP) + public function find() { - $executor = self::getExecutor($group); - - return $executor->find($this); + return Executor::find($this); } /** * Find by id * - * @param mixed $id - * @param string $group + * @param mixed $id * * @return ResultInterface */ - public static function findById($id, string $group = Pool::GROUP) + public static function findById($id) { - $executor = self::getExecutor($group); - - return $executor->findById(static::class, $id); + return Executor::findById(static::class, $id); } /** * Find by ids * - * @param array $ids - * @param string $group + * @param array $ids * * @return ResultInterface */ - public static function findByIds(array $ids, string $group = Pool::GROUP) + public static function findByIds(array $ids) { - $executor = self::getExecutor($group); - - return $executor->findByIds(static::class, $ids); + return Executor::findByIds(static::class, $ids); } /** * Get the QueryBuilder * - * @param string $group - * * @return QueryBuilder */ - public static function query(string $group = Pool::GROUP): QueryBuilder + public static function query(): QueryBuilder { - return EntityManager::getQuery(static::class, $group); - } - - /** - * Get the exeutor - * - * @param string $group - * - * @return Executor - */ - private static function getExecutor(string $group = Pool::GROUP): Executor - { - $queryBuilder = EntityManager::getQuery(static::class, $group); - $executor = new Executor($queryBuilder, $group); - - return $executor; + return Query::table(static::class); } /** @@ -192,6 +148,7 @@ public function setAttrs(array $attrs) * $attributes = [ * 'name' => $value * ] + * @return \Swoft\Db\Model */ public function fill(array $attributes) { @@ -201,6 +158,7 @@ public function fill(array $attributes) $this->$methodName($value); } } + return $this; } /** @@ -302,6 +260,7 @@ public function current() /** * Move forward to next element + * * @return void Any returned value is ignored. */ public function next() @@ -311,6 +270,7 @@ public function next() /** * Return the key of the current element + * * @return mixed scalar on success, or null on failure. */ public function key() @@ -320,6 +280,7 @@ public function key() /** * Checks if current position is valid + * * @return boolean The return value will be casted to boolean and then evaluated. * Returns true on success or false on failure. */ @@ -330,6 +291,7 @@ public function valid() /** * Rewind the Iterator to the first element + * * @return void Any returned value is ignored. */ public function rewind() diff --git a/src/Pool.php b/src/Pool.php index e84c623..23e72c4 100644 --- a/src/Pool.php +++ b/src/Pool.php @@ -12,6 +12,8 @@ class Pool */ const GROUP = 'default'; + const INSTANCE = 'default'; + /** * The master */ diff --git a/src/Query.php b/src/Query.php new file mode 100644 index 0000000..0dfb4f7 --- /dev/null +++ b/src/Query.php @@ -0,0 +1,24 @@ +table($tableName); + + return $query; + } + +} \ No newline at end of file diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index aaaf3da..f0aa70b 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -3,19 +3,17 @@ namespace Swoft\Db; use Swoft\App; -use Swoft\Core\RequestContext; use Swoft\Db\Bean\Collector\EntityCollector; use Swoft\Db\Exception\DbException; use Swoft\Db\Exception\MysqlException; use Swoft\Db\Helper\DbHelper; use Swoft\Db\Helper\EntityHelper; -use Swoft\Helper\PoolHelper; -use Swoft\Pool\ConnectionInterface; +use Swoft\Core\ResultInterface; /** * 查询器 */ -abstract class QueryBuilder implements QueryBuilderInterface +class QueryBuilder implements QueryBuilderInterface { /** * 升序 @@ -132,24 +130,19 @@ abstract class QueryBuilder implements QueryBuilderInterface */ const IS_NOT = 'IS NOT'; - /** - * SQL语句 - */ - use Statement; - /** * 插入表名 * * @var string */ - private $insert; + private $insert = ''; /** * 更新表名 * * @var string */ - private $update; + private $update = ''; /** * 是否是delete @@ -229,13 +222,6 @@ abstract class QueryBuilder implements QueryBuilderInterface */ protected $parameters = []; - /** - * sql语句 - * - * @var string - */ - protected $sql = ''; - /** * @var AbstractDbConnection */ @@ -246,62 +232,46 @@ abstract class QueryBuilder implements QueryBuilderInterface */ protected $lastSql; + /** + * @var array + */ + protected $table = []; + /** * @var string */ - protected $table; + protected $instance = Pool::INSTANCE; /** * @var string */ - protected $group = Pool::GROUP; + protected $node = ''; /** - * QueryBuilder constructor. + * Selected database * - * @param string $group - * @param string $sql - * @param string $table - * @param ConnectionInterface $connection + * @var string */ - public function __construct(string $group = Pool::GROUP, string $sql = '', string $table = null, ConnectionInterface $connection = null) - { - if ($table != null) { - $this->from($table); - } - $this->sql = $sql; - $this->table = $table; - $this->group = $group; - - $this->connection = $connection; - } + protected $db = ''; /** - * insert语句 - * - * @param string $tableName - * * @return QueryBuilder - * @throws \Swoft\Db\Exception\DbException + * @throws DbException */ - public function insert(string $tableName = null): QueryBuilder + public function insert(): QueryBuilder { - $this->insert = $this->getTableName($tableName); + $this->insert = $this->getTableName(); return $this; } /** - * update语句 - * - * @param string $tableName - * * @return QueryBuilder - * @throws \Swoft\Db\Exception\DbException + * @throws DbException */ - public function update(string $tableName = null): QueryBuilder + public function update(): QueryBuilder { - $this->update = $this->getTableName($tableName); + $this->update = $this->getTableName(); return $this; } @@ -321,7 +291,7 @@ public function delete(): QueryBuilder /** * select语句 * - * @param mixed $column + * @param mixed $column * @param string $alias * * @return QueryBuilder @@ -356,20 +326,16 @@ public function selects(array $columns): QueryBuilder return $this; } - /** - * from语句 - * - * @param string $table - * @param string|null $alias + * @param string $table + * @param string $alias * * @return QueryBuilder - * @throws \Swoft\Db\Exception\DbException */ - public function from(string $table, string $alias = null): QueryBuilder + public function table(string $table, string $alias = null) { - $this->from['table'] = $this->getTableNameByClassName($table); - $this->from['alias'] = $alias; + $this->table['table'] = $this->getTableNameByClassName($table); + $this->table['alias'] = $alias; return $this; } @@ -930,6 +896,60 @@ private function criteria( return $this; } + /** + * @param string $db + */ + public function selectDb(string $db) + { + $this->db = $db; + } + + /** + * @param string $node + */ + public function selectNode(string $node = Pool::MASTER) + { + $this->node = $node; + } + + /** + * @param string $instance + */ + public function selectInstance(string $instance) + { + $this->instance = $instance; + } + + public function force(bool $master = true) + { + if ($master) { + $this->node = Pool::MASTER; + } + } + + /** + * @return ResultInterface + */ + public function execute() + { + $statementClassName = DbHelper::getStatementClassNameByInstance($this->instance); + /* @var StatementInterface $statement */ + $statement = new $statementClassName($this); + $sql = $statement->getStatement(); + $instanceName = $this->getInstanceName(); + + return Db::query($sql, $this->parameters, $instanceName); + } + + /** + * @return string + */ + private function getInstanceName() + { + return sprintf('%s.%s.%s', $this->instance, $this->node, $this->db); + } + + /** * 实体类名获取表名 * @@ -981,53 +1001,142 @@ private function transferParameter($key, $value, $type): array } /** - * @return ConnectionInterface + * @return string + * @throws \Swoft\Db\Exception\MysqlException */ - protected function selectConnection(): ConnectionInterface + private function getTableName(): string { - if (!empty($this->connection)) { - return $this->connection; + if (empty($this->table)) { + throw new MysqlException('Table name must be setted!'); } + $table = $this->table['table']; - $contextTsKey = PoolHelper::getContextTsKey(); - $contextCntKey = PoolHelper::getContextCntKey(); - $groupKey = PoolHelper::getGroupKey($this->group); - - /* @var \SplStack $tsStack */ - $tsStack = RequestContext::getContextDataByChildKey($contextTsKey, $groupKey, new \SplStack()); - if (!$tsStack->isEmpty()) { - $cntId = $tsStack->offsetGet(0); - $connection = RequestContext::getContextDataByChildKey($contextCntKey, $cntId, null); + return $table; + } - return $connection; + /** + * @param mixed $key + * + * @return string + */ + private function formatParamsKey($key): string + { + if (\is_string($key) && strpos($key, ':') === false) { + return ':' . $key; } - - $node = Pool::SLAVE; - if ($this->isInsert() || $this->isDelete() || $this->isUpdate()) { - $node = Pool::MASTER; + if (is_int($key) && App::isCoContext()) { + return '?' . $key; } - $pool = DbHelper::getPool($this->group, $node); + return $key; + } - return $pool->getConnection(); + /** + * @return string + */ + public function getInsert(): string + { + return $this->insert; } /** - * @param string $tableName - * * @return string - * @throws \Swoft\Db\Exception\MysqlException */ - private function getTableName(string $tableName = null): string + public function getUpdate(): string { - if ($tableName != null) { - return $this->getTableNameByClassName($tableName); - } - if ($this->table != null) { - return $this->table; + return $this->update; + } + + /** + * @return bool + */ + public function isDelete(): bool + { + return $this->delete; + } + + /** + * @return array + */ + public function getSelect(): array + { + return $this->select; + } + + /** + * @return array + */ + public function getSet(): array + { + return $this->set; + } + + /** + * @return array + * @throws MysqlException + */ + public function getFrom(): array + { + if (empty($this->table)) { + throw new MysqlException('Table name must be setted!'); } - throw new MysqlException('Table name must be setted by use insert()!'); + + return $this->table; + } + + /** + * @return array + */ + public function getJoin(): array + { + return $this->join; + } + + /** + * @return array + */ + public function getWhere(): array + { + return $this->where; } - abstract protected function formatParamsKey($key): string; + /** + * @return array + */ + public function getGroupBy(): array + { + return $this->groupBy; + } + + /** + * @return array + */ + public function getHaving(): array + { + return $this->having; + } + + /** + * @return array + */ + public function getOrderBy(): array + { + return $this->orderBy; + } + + /** + * @return array + */ + public function getLimit(): array + { + return $this->limit; + } + + /** + * @return array + */ + public function getParameters(): array + { + return $this->parameters; + } } diff --git a/src/Statement.php b/src/Statement.php index 3ac28ea..0706dc4 100644 --- a/src/Statement.php +++ b/src/Statement.php @@ -3,16 +3,20 @@ namespace Swoft\Db; /** - * SQL语句组装 - * - * @uses Statement - * @version 2017年09月07日 - * @author stelin - * @copyright Copyright 2010-2016 swoft software - * @license PHP Version 7.x {@link http://www.php.net/license/3_0.txt} + * Statement */ -trait Statement +class Statement implements StatementInterface { + /** + * @var QueryBuilder + */ + protected $builder; + + public function __construct(QueryBuilder $queryBuilder) + { + $this->builder = $queryBuilder; + } + /** * 组拼SQL * @@ -21,9 +25,7 @@ trait Statement public function getStatement(): string { $statement = ''; - if ($this->isQuerySql()) { - $statement = $this->sql; - } elseif ($this->isSelect()) { + if ($this->isSelect()) { $statement = $this->getSelectStatement(); } elseif ($this->isInsert()) { $statement = $this->getInsertStatement(); @@ -32,6 +34,7 @@ public function getStatement(): string } elseif ($this->isDelete()) { $statement = $this->getDeleteStatement(); } + return $statement; } @@ -43,7 +46,7 @@ public function getStatement(): string protected function getSelectStatement(): string { $statement = ''; - if (! $this->isSelect()) { + if (!$this->isSelect()) { return $statement; } @@ -51,32 +54,32 @@ protected function getSelectStatement(): string $statement .= $this->getSelectString(); // from语句 - if ($this->from) { + if ($this->builder->getFrom()) { $statement .= ' ' . $this->getFromString(); } // where语句 - if ($this->where) { + if ($this->builder->getWhere()) { $statement .= ' ' . $this->getWhereString(); } // groupBy语句 - if ($this->groupBy) { + if ($this->builder->getGroupBy()) { $statement .= ' ' . $this->getGroupByString(); } // having语句 - if ($this->having) { + if ($this->builder->getHaving()) { $statement .= ' ' . $this->getHavingString(); } // orderBy语句 - if ($this->orderBy) { + if ($this->builder->getOrderBy()) { $statement .= ' ' . $this->getOrderByString(); } // limit语句 - if ($this->limit) { + if ($this->builder->getLimit()) { $statement .= ' ' . $this->getLimitString(); } @@ -91,7 +94,7 @@ protected function getSelectStatement(): string protected function getInsertStatement(): string { $statement = ''; - if (! $this->isInsert()) { + if (!$this->isInsert()) { return $statement; } @@ -99,7 +102,7 @@ protected function getInsertStatement(): string $statement .= $this->getInsertString(); // set语句 - if ($this->set) { + if ($this->builder->getSet()) { $statement .= ' ' . $this->getSetString(); } @@ -114,7 +117,7 @@ protected function getInsertStatement(): string protected function getUpdateStatement(): string { $statement = ''; - if (! $this->isUpdate()) { + if (!$this->isUpdate()) { return $statement; } @@ -122,22 +125,22 @@ protected function getUpdateStatement(): string $statement .= $this->getUpdateString(); // set语句 - if ($this->set) { + if ($this->builder->getSet()) { $statement .= ' ' . $this->getSetString(); } // where语句 - if ($this->where) { + if ($this->builder->getWhere()) { $statement .= ' ' . $this->getWhereString(); } // orderBy语句 - if ($this->orderBy) { + if ($this->builder->getOrderBy()) { $statement .= ' ' . $this->getOrderByString(); } // limit语句 - if ($this->limit) { + if ($this->builder->getLimit()) { $statement .= ' ' . $this->getLimitString(); } @@ -152,7 +155,7 @@ protected function getUpdateStatement(): string protected function getDeleteStatement(): string { $statement = ''; - if (! $this->isDelete()) { + if (!$this->isDelete()) { return $statement; } @@ -160,22 +163,22 @@ protected function getDeleteStatement(): string $statement .= $this->getDeleteString(); // from语句 - if ($this->from) { + if ($this->builder->getFrom()) { $statement .= ' ' . $this->getFromString(); } // where语句 - if ($this->where) { + if ($this->builder->getWhere()) { $statement .= ' ' . $this->getWhereString(); } // orderBy语句 - if ($this->orderBy) { + if ($this->builder->getOrderBy()) { $statement .= ' ' . $this->getOrderByString(); } // limit语句 - if ($this->limit) { + if ($this->builder->getLimit()) { $statement .= ' ' . $this->getLimitString(); } @@ -190,12 +193,13 @@ protected function getDeleteStatement(): string protected function getSelectString(): string { $statement = ''; - if (empty($this->select)) { + $select = $this->builder->getSelect(); + if (empty($select)) { return $statement; } // 字段组拼 - foreach ($this->select as $column => $alias) { + foreach ($select as $column => $alias) { $statement .= $column; if ($alias !== null) { $statement .= ' AS ' . $alias; @@ -205,7 +209,7 @@ protected function getSelectString(): string //select组拼 $statement = substr($statement, 0, -2); - if (! empty($statement)) { + if (!empty($statement)) { $statement = 'SELECT ' . $statement; } @@ -220,7 +224,7 @@ protected function getSelectString(): string public function getFromString(): string { $statement = ''; - if (empty($this->from)) { + if (empty($this->builder->getFrom())) { return $statement; } @@ -235,7 +239,7 @@ public function getFromString(): string $statement .= ' ' . $this->getJoinString(); $statement = rtrim($statement); - if (! empty($statement)) { + if (!empty($statement)) { $statement = 'FROM ' . $statement; } @@ -250,12 +254,13 @@ public function getFromString(): string protected function getJoinString(): string { $statement = ''; - foreach ($this->join as $i => $join) { + $join = $this->builder->getJoin(); + foreach ($join as $i => $join) { // join信息 - $type = $join['type']; - $table = $join['table']; - $alias = $join['alias']; + $type = $join['type']; + $table = $join['table']; + $alias = $join['alias']; $criteria = $join['criteria']; // join类型 @@ -274,6 +279,7 @@ protected function getJoinString(): string } $statement = trim($statement); + return $statement; } @@ -284,6 +290,7 @@ protected function getJoinString(): string * @param string $table * @param string $statement * @param array $criteria + * * @return string */ protected function getJoinCriteria(int $joinIndex, string $table, string $statement, array $criteria): string @@ -302,6 +309,7 @@ protected function getJoinCriteria(int $joinIndex, string $table, string $statem } $statement .= $criterion; } + return $statement; } @@ -311,11 +319,12 @@ protected function getJoinCriteria(int $joinIndex, string $table, string $statem * @param int $joinIndex * @param string $table * @param string $column + * * @return string */ protected function getJoinCriteriaUsingPreviousTable(int $joinIndex, string $table, string $column): string { - $joinCriteria = ''; + $joinCriteria = ''; $previousJoinIndex = $joinIndex - 1; if (array_key_exists($previousJoinIndex, $this->join)) { @@ -327,7 +336,7 @@ protected function getJoinCriteriaUsingPreviousTable(int $joinIndex, string $tab } elseif ($this->isSelect()) { // 查询 $previousTable = $this->getFrom(); - $alias = $this->getFromAlias(); + $alias = $this->getFromAlias(); if (!empty($alias)) { $previousTable = $alias; } @@ -343,7 +352,7 @@ protected function getJoinCriteriaUsingPreviousTable(int $joinIndex, string $tab $joinCriteria .= $previousTable . '.'; } - $joinCriteria .= $column . ' ' . self::OPERATOR_EQ . ' ' . $table . '.' . $column; + $joinCriteria .= $column . ' ' . QueryBuilder::OPERATOR_EQ . ' ' . $table . '.' . $column; return $joinCriteria; } @@ -355,9 +364,10 @@ protected function getJoinCriteriaUsingPreviousTable(int $joinIndex, string $tab */ protected function getWhereString(): string { - $statement = $this->getCriteriaString($this->where); + $where = $this->builder->getWhere(); + $statement = $this->getCriteriaString($where); - if (! empty($statement)) { + if (!empty($statement)) { $statement = 'WHERE ' . $statement; } @@ -368,17 +378,18 @@ protected function getWhereString(): string * where条件 * * @param array $criteria + * * @return string */ protected function getCriteriaString(array &$criteria): string { - $statement = ''; + $statement = ''; $useConnector = false; foreach ($criteria as $i => $criterion) { // 是括号符 if (array_key_exists('bracket', $criterion)) { - if (strcmp($criterion['bracket'], self::BRACKET_OPEN) === 0) { + if (strcmp($criterion['bracket'], QueryBuilder::BRACKET_OPEN) === 0) { if ($useConnector) { $statement .= ' ' . $criterion['connector'] . ' '; } @@ -397,9 +408,10 @@ protected function getCriteriaString(array &$criteria): string // 没有括号 $useConnector = true; - $value = $this->getCriteriaWithoutBracket($criterion['operator'], $criterion['value'], $criterion['column']); - $statement .= $criterion['column'] . ' ' . $criterion['operator'] . ' ' . $value; + $value = $this->getCriteriaWithoutBracket($criterion['operator'], $criterion['value'], $criterion['column']); + $statement .= $criterion['column'] . ' ' . $criterion['operator'] . ' ' . $value; } + return $statement; } @@ -408,31 +420,32 @@ protected function getCriteriaString(array &$criteria): string * * @param string $operator * @param mixed $criterionVaue + * * @return bool|string */ protected function getCriteriaWithoutBracket(string $operator, $criterionVaue, $columnName) { switch ($operator) { - case self::BETWEEN: - case self::NOT_BETWEEN: - $end = $this->getQuoteValue($criterionVaue[1]); + case QueryBuilder::BETWEEN: + case QueryBuilder::NOT_BETWEEN: + $end = $this->getQuoteValue($criterionVaue[1]); $start = $this->getQuoteValue($criterionVaue[0]); - $value = $start . ' ' . self::LOGICAL_AND . ' ' . $end; + $value = $start . ' ' . QueryBuilder::LOGICAL_AND . ' ' . $end; break; - case self::IN: - case self::NOT_IN: - $value = self::BRACKET_OPEN; + case QueryBuilder::IN: + case QueryBuilder::NOT_IN: + $value = QueryBuilder::BRACKET_OPEN; // 数组处理 foreach ($criterionVaue ?? [] as $criterionValue) { $criterionValue = $this->getQuoteValue($criterionValue); - $value .= $criterionValue . ', '; + $value .= $criterionValue . ', '; } $value = substr($value, 0, -2); - $value .= self::BRACKET_CLOSE; + $value .= QueryBuilder::BRACKET_CLOSE; break; - case self::IS: - case self::IS_NOT: + case QueryBuilder::IS: + case QueryBuilder::IS_NOT: $value = $criterionVaue; $value = $this->getQuoteValue($value); break; @@ -441,6 +454,7 @@ protected function getCriteriaWithoutBracket(string $operator, $criterionVaue, $ $value = $this->getQuoteValue($value); break; } + return $value; } @@ -452,7 +466,8 @@ protected function getCriteriaWithoutBracket(string $operator, $criterionVaue, $ protected function getGroupByString(): string { $statement = ''; - foreach ($this->groupBy as $groupBy) { + $groupBys = $this->builder->getGroupBy(); + foreach ($groupBys as $groupBy) { $statement .= $groupBy['column']; if ($groupBy['order']) { $statement .= ' ' . $groupBy['order']; @@ -461,7 +476,7 @@ protected function getGroupByString(): string } $statement = substr($statement, 0, -2); - if (! empty($statement)) { + if (!empty($statement)) { $statement = 'GROUP BY ' . $statement; } @@ -475,10 +490,12 @@ protected function getGroupByString(): string */ protected function getHavingString(): string { - $statement = $this->getCriteriaString($this->having); - if (! empty($statement)) { + $having = $this->builder->getHaving(); + $statement = $this->getCriteriaString($having); + if (!empty($statement)) { $statement = 'HAVING ' . $statement; } + return $statement; } @@ -490,12 +507,13 @@ protected function getHavingString(): string protected function getOrderByString(): string { $statement = ''; - foreach ($this->orderBy as $orderBy) { + $orderBys = $this->builder->getOrderBy(); + foreach ($orderBys as $orderBy) { $statement .= $orderBy['column'] . ' ' . $orderBy['order'] . ', '; } $statement = substr($statement, 0, -2); - if (! empty($statement)) { + if (!empty($statement)) { $statement = 'ORDER BY ' . $statement; } @@ -510,19 +528,14 @@ protected function getOrderByString(): string protected function getLimitString(): string { $statement = ''; - if (! $this->limit) { + $limit = $this->builder->getLimit(); + if (!$limit) { return $statement; } - $statement .= $this->limit['limit']; - - if ($this->limit['offset'] !== 0) { - $statement .= ' OFFSET ' . $this->limit['offset']; - } - - if (! empty($statement)) { - $statement = 'LIMIT ' . $statement; - } + $limit = $limit['limit']; + $offset = $limit['offset']; + $statement = sprintf('LIMIT %d,%d', $offset, $limit); return $statement; } @@ -534,12 +547,13 @@ protected function getLimitString(): string protected function getSetString(): string { $statement = ''; - foreach ($this->set as $set) { - $statement .= $set['column'] . ' ' . self::OPERATOR_EQ . ' ' . $this->getQuoteValue($set['value']) . ', '; + $sets = $this->builder->getSet(); + foreach ($sets as $set) { + $statement .= $set['column'] . ' ' . QueryBuilder::OPERATOR_EQ . ' ' . $this->getQuoteValue($set['value']) . ', '; } $statement = substr($statement, 0, -2); - if (! empty($statement)) { + if (!empty($statement)) { $statement = 'SET ' . $statement; } @@ -554,12 +568,12 @@ protected function getSetString(): string protected function getInsertString(): string { $statement = ''; - if (! $this->insert) { + if (!$this->builder->getInsert()) { return $statement; } $statement .= $this->getInsert(); - if (! empty($statement)) { + if (!empty($statement)) { $statement = 'INSERT ' . $statement; } @@ -574,7 +588,7 @@ protected function getInsertString(): string protected function getUpdateString(): string { $statement = ''; - if (! $this->update) { + if (!$this->builder->getUpdate()) { return $statement; } @@ -583,7 +597,7 @@ protected function getUpdateString(): string // join条件 $statement .= ' ' . $this->getJoinString(); $statement = rtrim($statement); - if (! empty($statement)) { + if (!empty($statement)) { $statement = 'UPDATE ' . $statement; } @@ -599,32 +613,21 @@ protected function getDeleteString(): string { $statement = ''; - if (! $this->delete && ! $this->isDeleteTableFrom()) { + $delete = $this->builder->isDelete(); + if (!$delete && !$this->isDeleteTableFrom()) { return $statement; } - if (\is_array($this->delete)) { - $statement .= implode(', ', $this->delete); + if (\is_array($delete)) { + $statement .= implode(', ', $delete); } if ($statement || $this->isDeleteTableFrom()) { $statement = 'DELETE ' . $statement; $statement = trim($statement); } - return $statement; - } - /** - * 字符串转换 - * - * @param $value - * @return string - */ - protected function getQuoteValue($value): string - { - $key = uniqid(); - $this->setParameter($key, $value); - return ":{$key}"; + return $statement; } /** @@ -634,7 +637,7 @@ protected function getQuoteValue($value): string */ protected function hasParameter($key): bool { - return array_key_exists($key, $this->parameters); + return array_key_exists($key, $this->builder->getParameters()); } /** @@ -644,7 +647,7 @@ protected function hasParameter($key): bool */ protected function getInsert(): string { - return $this->insert; + return $this->builder->getInsert(); } /** @@ -654,7 +657,7 @@ protected function getInsert(): string */ protected function getUpdate() { - return $this->update; + return $this->builder->getUpdate(); } /** @@ -664,17 +667,7 @@ protected function getUpdate() */ protected function isSelect(): bool { - return ! empty($this->select); - } - - /** - * 是否是查询SQL - * - * @return bool - */ - protected function isQuerySql(): bool - { - return ! empty($this->sql); + return !empty($this->builder->getSelect()); } /** @@ -684,7 +677,7 @@ protected function isQuerySql(): bool */ protected function isInsert(): bool { - return ! empty($this->insert); + return !empty($this->builder->getInsert()); } /** @@ -694,7 +687,7 @@ protected function isInsert(): bool */ protected function isDelete(): bool { - return ! empty($this->delete); + return !empty($this->builder->isDelete()); } /** @@ -704,7 +697,9 @@ protected function isDelete(): bool */ protected function isDeleteTableFrom(): bool { - return $this->delete === true; + $delete = $this->builder->isDelete(); + + return $delete === true; } /** @@ -714,7 +709,7 @@ protected function isDeleteTableFrom(): bool */ protected function isUpdate(): bool { - return ! empty($this->update); + return !empty($this->builder->getUpdate()); } /** @@ -724,7 +719,8 @@ protected function isUpdate(): bool */ protected function getFrom(): string { - $table = $this->from['table']??''; + $from = $this->builder->getFrom(); + $table = $from['table']??''; return $table; } @@ -736,24 +732,22 @@ protected function getFrom(): string */ protected function getFromAlias(): string { - $alias = $this->from['alias']??''; + $from = $this->builder->getFrom(); + $alias = $from['alias']??''; return $alias; } /** - * @param string $sql - * @param string $operation + * 字符串转换 * - * @return bool + * @param $value + * @return string */ - protected function isSqlOperation(string $sql, $operation = 'update'): bool + protected function getQuoteValue($value): string { - $sql = trim($sql); - $sql = strtolower($sql); - if(strpos($sql, $operation) === 0){ - return true; - } - return false; + $key = uniqid(); + $this->builder->setParameter($key, $value); + return ":{$key}"; } } diff --git a/src/StatementInterface.php b/src/StatementInterface.php new file mode 100644 index 0000000..8a2d641 --- /dev/null +++ b/src/StatementInterface.php @@ -0,0 +1,11 @@ +setName('stelin'); - $user->setSex(1); - $user->setDesc('this my desc'); - $user->setAge(mt_rand(1, 100)); - - $id = $user->save($group)->getResult(); - $reuslt = $id > 0; - $this->assertTrue($reuslt); - } - - /** - * @param int $id - * @param string $group - */ - public function arDelete(int $id, string $group = Pool::GROUP) - { - /* @var User $user */ - $user = User::findById($id, $group)->getResult(User::class); - $result = $user->delete($group)->getResult(); - $this->assertEquals(1, $result); - } - - /** - * @param int $id - * @param string $group - */ - public function arDeleteById(int $id, string $group = Pool::GROUP) - { - $result = User::deleteById($id, $group)->getResult(); - $this->assertEquals(1, $result); - } - - /** - * @param array $ids - * @param string $group - */ - public function arDeleteByIds(array $ids, string $group = Pool::GROUP) - { - $result = User::deleteByIds($ids, $group)->getResult(); - $this->assertEquals($result, 2); - } - - /** - * @param int $id - * @param string $group - */ - public function arUpdate(int $id, string $group = Pool::GROUP) - { - $newName = 'swoft framewrok'; - - /* @var User $user */ - $user = User::findById($id, $group)->getResult(User::class); - $user->setName($newName); - $user->update($group)->getResult(); - - /* @var User $newUser */ - $newUser = User::findById($id, $group)->getResult(User::class); - $this->assertEquals($newName, $newUser->getName()); - } - - /** - * @param int $id - * @param string $group - */ - public function arFindById(int $id, string $group = Pool::GROUP) - { - $user = User::findById($id, $group)->getResult(); - $this->assertEquals($id, $user['id']); - } - - /** - * @param int $id - * @param string $group - */ - public function arFindByIdClass(int $id, string $group = Pool::GROUP) - { - /* @var User $user */ - $user = User::findById($id, $group)->getResult(User::class); - $this->assertEquals($id, $user->getId()); - } - - /** - * @param array $ids - * @param string $group - */ - public function arFindByIds(array $ids, string $group = Pool::GROUP) - { - $users = User::findByIds($ids, $group)->getResult(); - - $resultIds = []; - foreach ($users as $user) { - $resultIds[] = $user['id']; - } - $this->assertEquals(sort($resultIds), sort($ids)); - } - - /** - * @param array $ids - * @param string $group - */ - public function arFindByIdsByClass(array $ids, string $group = Pool::GROUP) - { - $users = User::findByIds($ids, $group)->getResult(User::class); - - $resultIds = []; - /* @var User $user */ - foreach ($users as $user) { - $resultIds[] = $user->getId(); - } - $this->assertEquals(sort($resultIds), sort($ids)); - } - - public function arQuery(array $ids, string $group = Pool::GROUP) - { - $result = User::query($group) - ->select('*') - ->orderBy('id', QueryBuilder::ORDER_BY_DESC) - ->limit(2) - ->execute() - ->getResult(); - $this->assertCount(2, $result); - } - - public function emSave(string $group = Pool::GROUP) - { - $user = new User(); - $user->setName('stelin'); - $user->setSex(1); - $user->setDesc('this my desc'); - $user->setAge(mt_rand(1, 100)); - - $em = EntityManager::create($group); - $id = $em->save($user)->getResult(); - $em->close(); - - $reuslt = $id > 0; - $this->assertTrue($reuslt); - } - - /** - * @param int $id - * @param string $group - */ - public function emDelete(int $id, string $group = Pool::GROUP) - { - - /* @var User $user */ - $user = User::findById($id, $group)->getResult(User::class); - $em = EntityManager::create($group); - $result = $em->delete($user)->getResult(); - $em->close(); - - $this->assertEquals(1, $result); - } - - /** - * @param int $id - * @param string $group - */ - public function emDeleteById(int $id, string $group = Pool::GROUP) - { - $em = EntityManager::create($group); - $result = $em->deleteById(User::class, $id)->getResult(); - $em->close(); - - $this->assertEquals(1, $result); - } - - /** - * @param array $ids - * @param string $group - */ - public function emDeleteByIds(array $ids, string $group = Pool::GROUP) - { - $em = EntityManager::create($group); - $result = $em->deleteByIds(User::class, $ids)->getResult(); - $em->close(); - - $this->assertEquals($result, 2); - } - - /** - * @param int $id - * @param string $group - */ - public function emUpdate(int $id, string $group = Pool::GROUP) - { - $newName = 'swoft framewrok'; - - /* @var User $user */ - $user = User::findById($id, $group)->getResult(User::class); - $user->setName($newName); - $user->update($group)->getResult(); - - $em = EntityManager::create($group); - $em->update($user); - $em->close(); - - /* @var User $newUser */ - $newUser = User::findById($id, $group)->getResult(User::class); - $this->assertEquals($newName, $newUser->getName()); - } - - /** - * @param int $id - * @param string $group - */ - public function emFindById(int $id, string $group = Pool::GROUP) - { - $em = EntityManager::create($group); - $user = $em->findById(User::class, $id)->getResult(); - $em->close(); - - $this->assertEquals($id, $user['id']); - } - - /** - * @param array $ids - * @param string $group - */ - public function emFindByIds(array $ids, string $group = Pool::GROUP) - { - $em = EntityManager::create($group); - $users = $em->findByIds(User::class, $ids)->getResult(); - $em->close(); - - $resultIds = []; - foreach ($users as $user) { - $resultIds[] = $user['id']; - } - $this->assertEquals(sort($resultIds), sort($ids)); - } - - - public function emQuery(array $ids, string $group = Pool::GROUP) - { - $em = EntityManager::create($group); - $result = $em->createQuery() - ->select('*') - ->from(User::class) - ->orderBy('id', QueryBuilder::ORDER_BY_DESC) - ->limit(2) - ->execute() - ->getResult(); - $em->close(); - - $this->assertCount(2, $result); - } - - public function emSql(array $ids, string $group = Pool::GROUP) - { - $em = EntityManager::create($group); - $result = $em->createQuery('select * from user where id in(?, ?) and name = ? order by id desc limit 2') - ->setParameter(0, $ids[0]) - ->setParameter(1, $ids[1]) - ->setParameter(2, 'stelin') - ->execute() - ->getResult(); - $em->close(); - - $em = EntityManager::create($group); - $result2 = $em->createQuery('select * from user where id in(?, ?) and name = ? order by id desc limit 2') - ->setParameter(0, $ids[0]) - ->setParameter(1, $ids[1]) - ->setParameter(2, 'stelin', Types::STRING) - ->execute() - ->getResult(); - $em->close(); - - $em = EntityManager::create($group); - $result3 = $em->createQuery('select * from user where id in(?, ?) and name = ? order by id desc limit 2') - ->setParameters([$ids[0], $ids[1], 'stelin']) - ->execute() - ->getResult(); - $em->close(); - - $em = EntityManager::create($group); - $result4 = $em->createQuery('select * from user where id in(:id1, :id2) and name = :name order by id desc limit 2') - ->setParameter(':id1', $ids[0]) - ->setParameter('id2', $ids[1]) - ->setParameter('name', 'stelin') - ->execute() - ->getResult(); - $em->close(); - - $em = EntityManager::create($group); - $result5 = $em->createQuery('select * from user where id in(:id1, :id2) and name = :name order by id desc limit 2') - ->setParameters([ - 'id1' => $ids[0], - ':id2' => $ids[1], - 'name' => 'stelin' - ]) - ->execute() - ->getResult(); - $em->close(); - - - $em = EntityManager::create($group); - $result6 = $em->createQuery('select * from user where id in(:id1, :id2) and name = :name order by id desc limit 2') - ->setParameters([ - ['id1', $ids[0]], - [':id2', $ids[1], Types::INT], - ['name', 'stelin', Types::STRING], - ]) - ->execute() - ->getResult(); - $em->close(); - - $this->assertCount(2, $result); - $this->assertCount(2, $result2); - $this->assertCount(2, $result3); - $this->assertCount(2, $result4); - $this->assertCount(2, $result5); - $this->assertCount(2, $result6); - } - - public function addUsers(string $group = Pool::GROUP) - { - $user = new User(); - $user->setName('stelin'); - $user->setSex(1); - $user->setDesc('this my desc'); - $user->setAge(mt_rand(1, 100)); - $id = $user->save($group)->getResult(); - $id2 = $user->save($group)->getResult(); - - return [ - [[$id, $id2]], - ]; - } - - public function addUser(string $group = Pool::GROUP) - { - $user = new User(); - $user->setName('stelin'); - $user->setSex(1); - $user->setDesc('this my desc'); - $user->setAge(mt_rand(1, 100)); - $id = $user->save($group)->getResult(); - - return [ - [$id], - ]; - } - - public function mysqlProviders() - { - return $this->addUsers(); - } - - public function mysqlProvider() - { - return $this->addUser(); - } -} diff --git a/test/Cases/AbstractMysqlCase.php b/test/Cases/AbstractMysqlCase.php new file mode 100644 index 0000000..d5abc63 --- /dev/null +++ b/test/Cases/AbstractMysqlCase.php @@ -0,0 +1,51 @@ +setName('stelin'); + $user->setSex(1); + $user->setDesc('this my desc'); + $user->setAge(mt_rand(1, 100)); + $id = $user->save()->getResult(); + $id2 = $user->save()->getResult(); + + return [ + [[$id, $id2]], + ]; + } + + public function addUser() + { + $user = new User(); + $user->setName('stelin'); + $user->setSex(1); + $user->setDesc('this my desc'); + $user->setAge(mt_rand(1, 100)); + $id = $user->save()->getResult(); + + return [ + [$id], + ]; + } + + public function mysqlProviders() + { + return $this->addUsers(); + } + + public function mysqlProvider() + { + return $this->addUser(); + } +} diff --git a/test/Cases/AbstractTestCase.php b/test/Cases/AbstractTestCase.php index 31c4aa6..d358c3e 100644 --- a/test/Cases/AbstractTestCase.php +++ b/test/Cases/AbstractTestCase.php @@ -14,7 +14,7 @@ abstract class AbstractTestCase extends TestCase protected function tearDown() { parent::tearDown(); - swoole_event_exit(); +// swoole_event_exit(); } } \ No newline at end of file diff --git a/test/Cases/BugMysqlTest.php b/test/Cases/BugMysqlTest.php deleted file mode 100644 index 55f720f..0000000 --- a/test/Cases/BugMysqlTest.php +++ /dev/null @@ -1,207 +0,0 @@ -query($id); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testCo(int $id) - { - go(function () use ($id) { - $this->query($id); - }); - } - - public function query($id) - { - $query = User::query()->select('name,id')->where('id', $id)->limit(1)->execute(); - - $result = $query->getResult(); - $this->assertCount(2, $result); - $this->assertFalse(empty(get_last_sql())); - } - - public function testAttrs() - { - $this->attr(); - } - - public function testCoAttr() - { - go(function () { - $this->attr(); - }); - } - - public function attr() - { - $attrs = [ - 'name' => 'stelin3', - 'sex' => 1, - 'desc' => 'this is my desc2', - 'age' => 99, - ]; - $user = new User(); - $user->fill($attrs); - $result = $user->save()->getResult(); - - /* @var User $user */ - $user = User::findById($result)->getResult(User::class); - - $this->assertEquals($user->getName(), 'stelin3'); - $this->assertEquals($user->getSex(), 1); - $this->assertEquals($user->getDesc(), 'this is my desc2'); - $this->assertEquals($user->getAge(), 99); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testModelSelect(int $id) - { - $this->modelSelect($id); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testModelCoSelect(int $id) - { - go(function () use ($id) { - $this->modelSelect($id); - }); - } - - public function modelSelect($id) - { - $result = User::query()->select('*')->where('id', $id)->limit(1)->execute()->getResult(); - $this->assertEquals($id, (int)$result['id']); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testModelDelete(int $id) - { - $this->modelDelete($id); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testModelCoDelete(int $id) - { - go(function () use ($id) { - $this->modelDelete($id); - }); - } - - public function modelDelete(int $id) - { - $result = User::query()->delete()->where('id', $id)->limit(1)->execute()->getResult(); - $this->assertEquals(1, $result); - - $user = User::findById($id)->getResult(); - $this->assertEmpty($user); - } - - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testModelUpdate(int $id) - { - $this->modelUpdate($id); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testModelCoUpdate(int $id) - { - go(function () use ($id) { - $this->modelUpdate($id); - }); - } - - public function modelUpdate(int $id) - { - $data = [ - 'name' => 'stelin7872', - 'sex' => 18, - 'description' => 'descc', - 'age' => 100, - ]; - - $result = User::query()->update()->set($data)->where('id', $id)->execute()->getResult(); - $this->assertEquals(1, $result); - - /* @var User $user */ - $user = User::findById($id)->getResult(User::class); - $this->assertEquals($user->getName(), 'stelin7872'); - $this->assertEquals($user->getSex(), 18); - $this->assertEquals($user->getDesc(), 'descc'); - $this->assertEquals($user->getAge(), 100); - } - - /** - */ - public function testModelInsert() - { - $this->modelInsert(); - } - - /** - */ - public function testModelCoInsert() - { - go(function () { - $this->modelInsert(); - }); - } - - /** - */ - public function modelInsert() - { - $data = [ - 'name' => 'stelin666', - 'sex' => 19, - 'description' => '1212', - 'age' => 100, - ]; - - $id = User::query()->insert()->set($data)->execute()->getResult(); - $this->assertFalse(empty($id)); - - /* @var User $user */ - $user = User::findById($id)->getResult(User::class); - $this->assertEquals($user->getName(), 'stelin666'); - $this->assertEquals($user->getSex(), 19); - $this->assertEquals($user->getDesc(), '1212'); - $this->assertEquals($user->getAge(), 100); - } -} \ No newline at end of file diff --git a/test/Cases/EntityTest.php b/test/Cases/EntityTest.php index ecb69ea..2b2a493 100644 --- a/test/Cases/EntityTest.php +++ b/test/Cases/EntityTest.php @@ -2,12 +2,11 @@ namespace Swoft\Db\Test\Cases; -use Swoft\Db\Db; use Swoft\Db\Test\Testing\Entity\User; /** */ -class EntityTest extends AbstractDbTestCase +class EntityTest extends AbstractMysqlCase { public function testToArray() { @@ -22,11 +21,11 @@ public function testToArray() $array = $user->toArray(); $data = [ - 'id' => 12, - 'name' => 'stelin', - 'sex' => 1, + 'id' => 12, + 'name' => 'stelin', + 'sex' => 1, 'desc' => 'this my desc', - 'age' => $age, + 'age' => $age, ]; $this->assertEquals($data, $array); } @@ -73,59 +72,44 @@ public function testIterator($id) { $user = User::findById($id)->getResult(User::class); $data = []; - foreach ($user as $key => $value){ + foreach ($user as $key => $value) { $data[$key] = $value; } $this->assertEquals($data, $user->toArray()); } - /** - * @dataProvider mysqlProvider - * - * @param int $id - */ - public function testDbSelect(int $id) + public function testArrayAttr() { - $result = Db::select('*')->from(User::class)->where('id', $id)->limit(1)->execute()->getResult(); - $this->assertEquals($id, $result['id']); - } + $data = [ + 'name' => 'stelin', + 'sex' => 1, + 'desc' => 'desc2', + 'age' => 100, + ]; - /** - * @dataProvider mysqlProvider - * - * @param int $id - */ - public function testDbDelete(int $id) - { - $result = Db::delete()->from(User::class)->where('id', $id)->execute()->getResult(); - $this->assertEquals(1, $result); - } + $user = new User(); + $result = $user->fill($data)->save()->getResult(); - /** - * @dataProvider mysqlProvider - * - * @param int $id - */ - public function testDbUpdate(int $id) - { - $result = Db::update(User::class)->set(['name' => 'stelin666'])->where('id', $id)->execute()->getResult(); - $user = User::findById($id)->getResult(); - $this->assertEquals('stelin666', $user['name']); - } + $resultUser = User::findById($result)->getResult(); + $this->assertEquals('stelin', $resultUser['name']); + $this->assertEquals(1, $resultUser['sex']); + $this->assertEquals('desc2', $resultUser['description']); + $this->assertEquals(100, $resultUser['age']); - public function testDbInsert() - { - $values = [ - 'name' => 'stelin', - 'sex' => 1, - 'description' => 'this my desc', - 'age' => 99, - ]; - $result = Db::insert(User::class)->set($values)->execute()->getResult(); - $user = User::findById($result)->getResult(); - $this->assertCount(5, $user); - } + $user2 = new User(); + $user2['name'] = 'stelin2'; + $user2['sex'] = 1; + $user2['desc'] = 'this my desc9'; + $user2['age'] = 99; + + $result2 = $user2->save()->getResult(); + $resultUser2 = User::findById($result2)->getResult(); + $this->assertEquals('stelin2', $resultUser2['name']); + $this->assertEquals(1, $resultUser2['sex']); + $this->assertEquals('this my desc9', $resultUser2['description']); + $this->assertEquals(99, $resultUser2['age']); + } } \ No newline at end of file diff --git a/test/Cases/MysqlArTest.php b/test/Cases/MysqlArTest.php deleted file mode 100644 index 1fa1b1e..0000000 --- a/test/Cases/MysqlArTest.php +++ /dev/null @@ -1,202 +0,0 @@ -arSave(); - } - - public function testCoSave() - { - go(function () { - $this->arSave(); - }); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testDelete(int $id) - { - $this->arDelete($id); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testCoDelete(int $id) - { - go(function () use ($id) { - $this->arDelete($id); - }); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testDeleteById(int $id) - { - $this->arDeleteById($id); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testCoDeleteById(int $id) - { - go(function () use ($id) { - $this->arDeleteById($id); - }); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testDeleteByIds(array $ids) - { - $this->arDeleteByIds($ids); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testCoDeleteByIds(array $ids) - { - go(function () use ($ids) { - $this->arDeleteByIds($ids); - }); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testUpdate(int $id) - { - $this->arUpdate($id); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testCoUpdate(int $id) - { - go(function () use ($id) { - $this->arUpdate($id); - }); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testFindById(int $id) - { - $this->arFindById($id); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testCoFindById(int $id) - { - go(function () use ($id) { - $this->arFindById($id); - }); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testFindByIdClass(int $id) - { - $this->arFindByIdClass($id); - } - - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testCoFindByIdClass(int $id) - { - go(function () use ($id) { - $this->arFindByIdClass($id); - }); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testFindByIds(array $ids) - { - $this->arFindByIds($ids); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testCoFindByIds(array $ids) - { - go(function () use ($ids) { - $this->arFindByIds($ids); - }); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testFindByIdsByClass(array $ids) - { - $this->arFindByIdsByClass($ids); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testCoFindByIdsByClass(array $ids) - { - go(function () use ($ids) { - $this->arFindByIdsByClass($ids); - }); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testQuery(array $ids) - { - $this->arQuery($ids); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testCoQuery(array $ids) - { - go(function () use ($ids) { - $this->arQuery($ids); - }); - } -} \ No newline at end of file diff --git a/test/Cases/MysqlEmTest.php b/test/Cases/MysqlEmTest.php deleted file mode 100644 index 71ce2ae..0000000 --- a/test/Cases/MysqlEmTest.php +++ /dev/null @@ -1,181 +0,0 @@ -emSave(); - } - - public function testCoSave() - { - go(function () { - $this->emSave(); - }); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testDelete(int $id) - { - $this->emDelete($id); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testCoDelete(int $id) - { - go(function () use ($id) { - $this->emDelete($id); - }); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testDeleteById(int $id) - { - $this->emDeleteById($id); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testCoDeleteById(int $id) - { - go(function () use ($id) { - $this->emDeleteById($id); - }); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testDeleteByIds(array $ids) - { - $this->emDeleteByIds($ids); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testCoDeleteByIds(array $ids) - { - go(function () use ($ids) { - $this->emDeleteByIds($ids); - }); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testUpdate(int $id) - { - $this->emUpdate($id); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testCoUpdate(int $id) - { - go(function () use ($id) { - $this->emUpdate($id); - }); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testFindById(int $id) - { - $this->emFindById($id); - } - - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testCoFindById(int $id) - { - go(function () use ($id) { - $this->emFindById($id); - }); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testFindByIds(array $ids) - { - $this->emFindByIds($ids); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testCoFindByIds(array $ids) - { - go(function () use ($ids) { - $this->emFindByIds($ids); - }); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testQuery(array $ids) - { - $this->emQuery($ids); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testSql(array $ids) - { - $this->emSql($ids); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testCoSql(array $ids) - { - go(function () use ($ids) { - $this->emSql($ids); - }); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testCoQuery(array $ids) - { - go(function () use ($ids) { - $this->emQuery($ids); - }); - } -} \ No newline at end of file diff --git a/test/Cases/MysqlTest.php b/test/Cases/MysqlTest.php new file mode 100644 index 0000000..3fc067d --- /dev/null +++ b/test/Cases/MysqlTest.php @@ -0,0 +1,270 @@ +setName('stelin'); + $user->setSex(1); + $user->setDesc('this my desc'); + $user->setAge(mt_rand(1, 100)); + + $id = $user->save()->getResult(); + $reuslt = $id > 0; + $this->assertTrue($reuslt); + } + + public function testSaveByCo() + { + go(function () { + $this->testSave(); + }); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testDelete(int $id) + { + /* @var User $user */ + $user = User::findById($id)->getResult(User::class); + $result = $user->delete()->getResult(); + $this->assertEquals(1, $result); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testDeleteByCo(int $id) + { + go(function () use ($id) { + $this->testDelete($id); + }); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testDeleteById(int $id) + { + $result = User::deleteById($id)->getResult(); + $this->assertEquals(1, $result); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testDeleteByIdByCo(int $id) + { + go(function () use ($id) { + $this->testDeleteById($id); + }); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testDeleteByIds(array $ids) + { + $result = User::deleteByIds($ids)->getResult(); + $this->assertEquals($result, 2); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testDeleteByIdsByCo(array $ids) + { + go(function () use ($ids) { + $this->testDeleteByIds($ids); + }); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testUpdate(int $id) + { + $newName = 'swoft framewrok'; + + /* @var User $user */ + $user = User::findById($id)->getResult(User::class); + $user->setName($newName); + $user->update()->getResult(); + + /* @var User $newUser */ + $newUser = User::findById($id)->getResult(User::class); + $this->assertEquals($newName, $newUser->getName()); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testUpdateByCo(int $id) + { + go(function () use ($id) { + $this->testUpdate($id); + }); + } + + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testFindById(int $id) + { + $user = User::findById($id)->getResult(); + $userEmpty = User::findById(99999999999)->getResult(); + $this->assertEquals($id, $user['id']); + $this->assertEquals($userEmpty, []); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testFindByIdByCo(int $id) + { + go(function () use ($id) { + $this->testFindById($id); + }); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testFindByIdClass(int $id) + { + /* @var User $user */ + $user = User::findById($id)->getResult(User::class); + $userEmpty = User::findById(99999999999)->getResult(User::class); + $this->assertEquals($id, $user->getId()); + $this->assertEquals($userEmpty, null); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testFindByIdClassByCo(int $id) + { + go(function () use ($id) { + $this->testFindByIdClass($id); + }); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testFindByIds(array $ids) + { + $users = User::findByIds($ids)->getResult(); + $userEmpty = User::findByIds([999999999999])->getResult(); + + $resultIds = []; + foreach ($users as $user) { + $resultIds[] = $user['id']; + } + $this->assertEquals(sort($resultIds), sort($ids)); + $this->assertEquals($userEmpty, []); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testFindByIdsByCo(array $ids) + { + go(function () use ($ids) { + $this->testFindByIds($ids); + }); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testFindByIdsByClass(array $ids) + { + $users = User::findByIds($ids)->getResult(User::class); + $userEmpty = User::findByIds([999999999999])->getResult(User::class); + + $resultIds = []; + /* @var User $user */ + foreach ($users as $user) { + $resultIds[] = $user->getId(); + } + $this->assertEquals(sort($resultIds), sort($ids)); + $this->assertEquals($userEmpty, []); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testFindByIdsByClassByCo(array $ids) + { + go(function () use ($ids) { + $this->testFindByIdsByClass($ids); + }); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testQuery(array $ids) + { + $result = User::query()->select('*')->orderBy('id', QueryBuilder::ORDER_BY_DESC)->limit(2)->execute()->getResult(); + $this->assertCount(2, $result); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testQueryByCo(array $ids) + { + go(function () use ($ids) { + $this->testQuery($ids); + }); + } +} \ No newline at end of file diff --git a/test/Cases/QueryTest.php b/test/Cases/QueryTest.php new file mode 100644 index 0000000..406e37b --- /dev/null +++ b/test/Cases/QueryTest.php @@ -0,0 +1,59 @@ +select('*')->where('id', $id)->limit(1)->execute()->getResult(); + $this->assertEquals($id, $result['id']); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testDbDelete(int $id) + { + $result = Query::table(User::class)->delete()->where('id', $id)->execute()->getResult(); + $this->assertEquals(1, $result); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testDbUpdate(int $id) + { + $result = Query::table(User::class)->update()->set(['name' => 'stelin666'])->where('id', $id)->execute()->getResult(); + $user = User::findById($id)->getResult(); + $this->assertEquals('stelin666', $user['name']); + } + + public function testDbInsert() + { + $values = [ + 'name' => 'stelin', + 'sex' => 1, + 'description' => 'this my desc', + 'age' => 99, + ]; + $result = Query::table(User::class)->insert()->set($values)->execute()->getResult(); + $user = User::findById($result)->getResult(); + $this->assertCount(5, $user); + } +} \ No newline at end of file diff --git a/test/Cases/SqlMysqlTest.php b/test/Cases/SqlMysqlTest.php index 8e7ea38..48e8882 100644 --- a/test/Cases/SqlMysqlTest.php +++ b/test/Cases/SqlMysqlTest.php @@ -8,125 +8,105 @@ /** * SqlMysqlTest */ -class SqlMysqlTest extends AbstractDbTestCase +class SqlMysqlTest extends AbstractMysqlCase { - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testUpdate(int $id) + public function testInsert() { - $this->update($id); + $name = "swoft insert"; + $result = Db::query('insert into user(name, sex,description, age) values("' . $name . '", 1, "xxxx", 99)')->getResult(); + $user = User::findById($result)->getResult(); + + $this->assertEquals($user['name'], $name); + + $result = Db::query('INSERT into user(name, sex,description, age) values("' . $name . '", 1, "xxxx", 99)')->getResult(); + $user = User::findById($result)->getResult(); + $this->assertEquals($user['name'], $name); } - /** - * @dataProvider mysqlProvider - * @param int $id - */ - public function testDelete(int $id) + public function testInsertByCo() { - $this->delete($id); + go(function () { + $this->testInsert(); + }); } /** * @dataProvider mysqlProvider - * @param int $id + * + * @param $id */ - public function testCoDelete(int $id) + public function testSelect($id) { - go(function () use ($id) { - $result = Db::query('DELETE from user where id=' . $id)->execute()->getResult(); - $this->assertEquals(1, $result); - }); - } + $result = Db::query('select * from user where id=' . $id)->getResult(); + $this->assertCount(1, $result); + $result = Db::query('SELECT * from user where id=' . $id)->getResult(); + $this->assertCount(1, $result); + } /** * @dataProvider mysqlProvider - * @param int $id + * + * @param $id */ - public function testCoUpdate(int $id) + public function testSelectByCo($id) { go(function () use ($id) { - $this->update($id); + $this->testSelect($id); }); } /** * @dataProvider mysqlProvider - * @param int $id + * + * @param $id */ - public function testSelect(int $id) + public function testDelete($id) { - $this->select($id); + $result = Db::query('delete from user where id=' . $id)->getResult(); + $this->assertEquals(1, $result); } /** * @dataProvider mysqlProvider - * @param int $id + * + * @param $id */ - public function testCoSelect(int $id) + public function testDeleteByCo($id) { go(function () use ($id) { - $this->select($id); - }); - } - - public function testInsert() - { - $this->insert(); - } - - public function testCoInsert() - { - go(function () { - $this->insert(); + $this->testDelete($id); }); } - private function insert() - { - $name = "swoft insert"; - $result = Db::query('insert into user(name, sex,description, age) values("' . $name . '", 1, "xxxx", 99)') - ->execute() - ->getResult(); - $user = User::findById($result)->getResult(); - - $this->assertEquals($user['name'], $name); - - $result = Db::query('INSERT into user(name, sex,description, age) values("' . $name . '", 1, "xxxx", 99)') - ->execute() - ->getResult(); - $user = User::findById($result)->getResult(); - $this->assertEquals($user['name'], $name); - } - - private function select($id) - { - $result = Db::query('select * from user where id=' . $id)->execute()->getResult(); - $this->assertCount(1, $result); - - $result = Db::query('SELECT * from user where id=' . $id)->execute()->getResult(); - $this->assertCount(1, $result); - } - - private function delete($id) - { - $result = Db::query('delete from user where id=' . $id)->execute()->getResult(); - $this->assertEquals(1, $result); - } - - private function update($id) + /** + * @dataProvider mysqlProvider + * + * @param $id + */ + public function testUpdate($id) { - $name = 'update name1'; - $result = Db::query('update user set name="' . $name . '" where id=' . $id)->execute()->getResult(); + $name = 'update name1'; + $result = Db::query('update user set name="' . $name . '" where id=' . $id)->getResult(); $this->assertEquals(1, $result); - $name = 'update name 协程框架'; - $result = Db::query('UPDATE user set name="' . $name . '" where id=' . $id)->execute()->getResult(); + $name = 'update name 协程框架'; + $result = Db::query('UPDATE user set name="' . $name . '" where id=' . $id)->getResult(); $this->assertEquals(1, $result); $user = User::findById($id)->getResult(); $this->assertEquals($name, $user['name']); } + + /** + * @dataProvider mysqlProvider + * + * @param $id + */ + public function testUpdateByCo($id) + { + go(function () use ($id) { + $this->testUpdate($id); + }); + } } \ No newline at end of file diff --git a/test/Cases/TrasactionTest.php b/test/Cases/TrasactionTest.php new file mode 100644 index 0000000..336d949 --- /dev/null +++ b/test/Cases/TrasactionTest.php @@ -0,0 +1,11 @@ +assertTrue(true); + } +} \ No newline at end of file diff --git a/test/Cases/TsTest.php b/test/Cases/TsTest.php deleted file mode 100644 index d73bd6a..0000000 --- a/test/Cases/TsTest.php +++ /dev/null @@ -1,122 +0,0 @@ -rollback(); - go(function () { - $this->rollback(); - }); - } - - public function rollback() - { - $user = new User(); - $user->setName('stelin'); - $user->setSex(1); - $user->setDesc('this my desc'); - $user->setAge(mt_rand(1, 100)); - - $em = EntityManager::create(); - $em->beginTransaction(); - $uid = $em->save($user)->getResult(); - $uid2 = $user->save()->getResult(); - $em->rollback(); - - $user1 = User::findById($uid); - $user2 = User::findById($uid2); - - $user1 = $user1->getResult(); - $user2 = $user2->getResult(); - - $this->assertTrue(empty($user1)); - $this->assertTrue(empty($user2)); - } - - public function testTsCommit() - { - $this->commit(); - go(function () { - $this->commit(); - }); - } - - public function commit() - { - $user = new User(); - $user->setName('stelin'); - $user->setSex(1); - $user->setDesc('this my desc'); - $user->setAge(mt_rand(1, 100)); - - $em = EntityManager::create(); - $em->beginTransaction(); - $uid = $em->save($user)->getResult(); - $uid2 = $user->save()->getResult(); - $em->commit(); - - $user1 = User::findById($uid); - $user2 = User::findById($uid2); - - $user1Id = $user1->getResult(); - $user2Id = $user2->getResult(); - - $this->assertEquals($uid, $user1Id['id']); - $this->assertEquals($uid2, $user2Id['id']); - } - - /** - * @dataProvider mysqlProviders - * @param array $ids - */ - public function testDbBuilder(array $ids) - { - $this->builder(); - - go(function () { - $this->builder(); - }); - } - - public function testNull() - { - $user = User::findById(12122223)->getResult(User::class); - $this->assertEquals($user, null); - } - - public function builder() - { - $result = Db::query('select * from user order by id desc limit 2')->execute()->getResult(); - $result2 = Db::query('select * from user order by id desc limit 2')->execute()->getResult(User::class); - - $result3 = Db::query() - ->select('*') - ->from(User::class) - ->where('name', 'stelin') - ->orderBy('id', 'DESC') - ->limit(1) - ->execute() - ->getResult(); - $result4 = Db::query() - ->select('*') - ->from(User::class) - ->where('name', 'stelin') - ->orderBy('id', 'DESC') - ->limit(1) - ->execute() - ->getResult(User::class); - - $this->assertCount(2, $result); - $this->assertCount(2, $result2); - $this->assertCount(5, $result3); - $this->assertEquals('stelin', $result4->getName()); - } - -} \ No newline at end of file From 819697a5d6016e7f33fd24b00659e2d64b1281e7 Mon Sep 17 00:00:00 2001 From: lilin <794774870@qq.com> Date: Thu, 29 Mar 2018 00:36:35 +0800 Subject: [PATCH 02/27] ts --- src/Bean/Annotation/Entity.php | 35 +++- src/Bean/Collector/EntityCollector.php | 18 +- src/Bean/Parser/EntityParser.php | 8 +- src/Db.php | 187 ++++++++++++++---- src/DbResult.php | 10 +- src/Driver/Mysql/MysqlConnection.php | 2 +- ....php => ResourceReleaseBeforeListener.php} | 23 ++- src/Executor.php | 42 +++- src/Helper/DbHelper.php | 47 ++--- src/Pool.php | 10 +- src/QueryBuilder.php | 17 ++ 11 files changed, 276 insertions(+), 123 deletions(-) rename src/Event/Listeners/{TransactionReleaseListener.php => ResourceReleaseBeforeListener.php} (59%) diff --git a/src/Bean/Annotation/Entity.php b/src/Bean/Annotation/Entity.php index 7c16aba..3ae4ab6 100644 --- a/src/Bean/Annotation/Entity.php +++ b/src/Bean/Annotation/Entity.php @@ -2,18 +2,41 @@ namespace Swoft\Db\Bean\Annotation; +use Swoft\Db\Pool; + /** * 实体注解 * * @Annotation * @Target("CLASS") - * - * @uses Entity - * @version 2017年08月31日 - * @author stelin - * @copyright Copyright 2010-2016 swoft software - * @license PHP Version 7.x {@link http://www.php.net/license/3_0.txt} */ class Entity { + /** + * @var string + */ + private $instance = Pool::INSTANCE; + + /** + * Inject constructor. + * + * @param array $values + */ + public function __construct(array $values) + { + if (isset($values['value'])) { + $this->instance = $values['value']; + } + if (isset($values['instance'])) { + $this->instance = $values['instance']; + } + } + + /** + * @return string + */ + public function getInstance(): string + { + return $this->instance; + } } diff --git a/src/Bean/Collector/EntityCollector.php b/src/Bean/Collector/EntityCollector.php index 5a05eac..6af64b8 100644 --- a/src/Bean/Collector/EntityCollector.php +++ b/src/Bean/Collector/EntityCollector.php @@ -25,18 +25,20 @@ class EntityCollector implements CollectorInterface * @param string $propertyName * @param string $methodName * @param null $propertyValue + * + * @return void */ public static function collect( string $className, $objectAnnotation = null, - string $propertyName = "", - string $methodName = "", + string $propertyName = '', + string $methodName = '', $propertyValue = null ) { if ($objectAnnotation instanceof Column) { self::collectColumn($objectAnnotation, $className, $propertyName, $propertyValue); } elseif ($objectAnnotation instanceof Entity) { - self::collectEntity($className); + self::collectEntity($objectAnnotation, $className); } elseif ($objectAnnotation instanceof Id) { self::collectId($className, $propertyName); } elseif ($objectAnnotation instanceof Required) { @@ -76,11 +78,13 @@ private static function collectId(string $className, string $propertyName) } /** + * @param Entity $objectAnnotationstring * @param string $className */ - private static function collectEntity(string $className) + private static function collectEntity(Entity $objectAnnotationstring, string $className) { - self::$entities[$className] = []; + $instance = $objectAnnotationstring->getInstance(); + self::$entities[$className]['instance'] = $instance; } /** @@ -97,14 +101,14 @@ private static function collectColumn( ) { $columnName = $objectAnnotation->getName(); - $entity = [ + $entity = [ 'type' => $objectAnnotation->getType(), 'length' => $objectAnnotation->getLength(), 'column' => $columnName, 'default' => $propertyValue, ]; self::$entities[$className]['field'][$propertyName] = $entity; - self::$entities[$className]['column'][$columnName] = $propertyName; + self::$entities[$className]['column'][$columnName] = $propertyName; } /** diff --git a/src/Bean/Parser/EntityParser.php b/src/Bean/Parser/EntityParser.php index dcc26af..11ab88c 100644 --- a/src/Bean/Parser/EntityParser.php +++ b/src/Bean/Parser/EntityParser.php @@ -7,13 +7,7 @@ use Swoft\Db\Bean\Collector\EntityCollector; /** - * Entity注解解析器 - * - * @uses EntityParser - * @version 2017年09月04日 - * @author stelin - * @copyright Copyright 2010-2016 swoft software - * @license PHP Version 7.x {@link http://www.php.net/license/3_0.txt} + * EntityParser */ class EntityParser extends AbstractParser { diff --git a/src/Db.php b/src/Db.php index b8cbc18..732e7bd 100644 --- a/src/Db.php +++ b/src/Db.php @@ -5,6 +5,7 @@ use Swoft\App; use Swoft\Core\RequestContext; use Swoft\Core\ResultInterface; +use Swoft\Db\Exception\DbException; use Swoft\Db\Helper\DbHelper; use Swoft\Helper\PoolHelper; use Swoft\Pool\ConnectionInterface; @@ -16,11 +17,35 @@ */ class Db { - const RESULT_ONE = 1; - const RESULT_ROWS = 2; - const RESULT_FETCH = 3; - const RESULT_INSERTID = 4; + /** + * Return one + */ + const RETURN_ONE = 1; + + /** + * Return rows + */ + const RETURN_ROWS = 2; + + /** + * Return fetch + */ + const RETURN_FETCH = 3; + + /** + * Return insertid + */ + const RETURN_INSERTID = 4; + /** + * Query by sql + * + * @param string $sql + * @param array $params + * @param string $instance + * + * @return ResultInterface + */ public static function query(string $sql, array $params = [], string $instance = Pool::INSTANCE): ResultInterface { $type = self::getOperation($sql); @@ -30,6 +55,7 @@ public static function query(string $sql, array $params = [], string $instance = list($instance, $node) = self::getInstanceAndNodeByType($instance, $node, $type); /* @var AbstractDbConnection $connection */ $connection = self::getConnection($instance, $node); + /* @var DbPool $pool */ $pool = $connection->getPool(); /* @var DbPoolProperties $poolConfig */ @@ -48,6 +74,52 @@ public static function query(string $sql, array $params = [], string $instance = return $dbResult; } + /** + * @param string $instance + */ + public static function beginTransaction(string $instance = Pool::INSTANCE) + { + /* @var AbstractDbConnection $connection */ + $connection = self::getConnection($instance, Pool::MASTER, 'ts'); + $connection->setAutoRelease(false); + $connection->beginTransaction(); + + self::beginTransactionContext($connection, $instance); + } + + /** + * @param string $instance + * + * @throws DbException + */ + public static function rollback(string $instance = Pool::INSTANCE) + { + /* @var AbstractDbConnection $connection */ + $connection = self::getTransactionConnection($instance); + if ($connection === null) { + throw new DbException('No transaction needs to be rollbacked'); + } + + $connection->rollback(); + self::closetTransactionContext($connection, $instance); + } + + /** + * @param string $instance + * + * @throws DbException + */ + public static function commit(string $instance = Pool::INSTANCE) + { + /* @var AbstractDbConnection $connection */ + $connection = self::getTransactionConnection($instance); + if ($connection === null) { + throw new DbException('No transaction needs to be committed'); + } + + $connection->commit(); + self::closetTransactionContext($connection, $instance); + } /** * @param string $instance @@ -62,44 +134,48 @@ private static function getInstanceAndNodeByType(string $instance, string $node, return [$instance, $node]; } - if ($type === Db::RESULT_ROWS || $type == Db::RESULT_INSERTID) { + if ($type === Db::RETURN_ROWS || $type == Db::RETURN_INSERTID) { return [$instance, Pool::MASTER]; } return [$instance, Pool::SLAVE]; } - public static function beginTransaction() + /** + * @param string $sql + * + * @return string + */ + private static function getOperation(string $sql): string { + $sql = trim($sql); + $sql = strtoupper($sql); - } - - public static function rollback() - { + if (strpos($sql, 'INSERT') === 0) { + return self::RETURN_INSERTID; + } - } + if (strpos($sql, 'UPDATE') === 0 || strpos($sql, 'DELETE') === 0) { + return self::RETURN_ROWS; + } - public static function commit() - { + if (strpos($sql, 'SELECT') === 0 && strpos($sql, 'LIMIT 0,1')) { + return self::RETURN_ONE; + } + return self::RETURN_FETCH; } - /** + * @param string $instance + * @param string $node + * * @return ConnectionInterface */ - private static function getConnection(string $instance, string $node): ConnectionInterface + private static function getConnection(string $instance, string $node, $ts = 'query'): ConnectionInterface { - $contextTsKey = PoolHelper::getContextTsKey(); - $contextCntKey = PoolHelper::getContextCntKey(); - $instanceKey = PoolHelper::getTsInstanceKey($instance); - - /* @var \SplStack $tsStack */ - $tsStack = RequestContext::getContextDataByChildKey($contextTsKey, $instanceKey, new \SplStack()); - if (!$tsStack->isEmpty()) { - $cntId = $tsStack->offsetGet(0); - $connection = RequestContext::getContextDataByChildKey($contextCntKey, $cntId, null); - - return $connection; + $transactionConnection = self::getTransactionConnection($instance); + if ($transactionConnection !== null) { + return $transactionConnection; } $pool = DbHelper::getPool($instance, $node); @@ -108,28 +184,57 @@ private static function getConnection(string $instance, string $node): Connectio } /** - * @param string $sql + * @param string $instance * - * @return string + * @return mixed */ - private static function getOperation(string $sql): string + private static function getTransactionConnection(string $instance) { - $sql = trim($sql); - $sql = strtoupper($sql); - - if (strpos($sql, 'INSERT') === 0) { - return self::RESULT_INSERTID; + $contextTsKey = DbHelper::getContextTsKey(); + $contextCntKey = PoolHelper::getContextCntKey(); + $instanceKey = DbHelper::getTsInstanceKey($instance); + /* @var \SplStack $tsStack */ + $tsStack = RequestContext::getContextDataByChildKey($contextTsKey, $instanceKey, new \SplStack()); + if ($tsStack->isEmpty()) { + return null; } + $cntId = $tsStack->offsetGet(0); + $connection = RequestContext::getContextDataByChildKey($contextCntKey, $cntId, null); + return $connection; + } - if (strpos($sql, 'UPDATE') === 0 || strpos($sql, 'DELETE') === 0) { - return self::RESULT_ROWS; - } + /** + * @param ConnectionInterface $connection + * @param string $instance + */ + private static function beginTransactionContext(ConnectionInterface $connection, string $instance = Pool::INSTANCE) + { + $cntId = $connection->getConnectionId(); + $contextTsKey = DbHelper::getContextTsKey(); + $instanceKey = DbHelper::getTsInstanceKey($instance); - if (strpos($sql, 'SELECT') === 0 && strpos($sql, 'LIMIT 0,1')) { - return self::RESULT_ONE; - } + /* @var \SplStack $tsStack */ + $tsStack = RequestContext::getContextDataByChildKey($contextTsKey, $instanceKey, new \SplStack()); + $tsStack->push($cntId); + RequestContext::setContextDataByChildKey($contextTsKey, $instanceKey, $tsStack); + } - return self::RESULT_FETCH; + /** + * @param AbstractDbConnection $connection + * @param string $instance + */ + private static function closetTransactionContext(AbstractDbConnection $connection, string $instance = Pool::INSTANCE) + { + $contextTsKey = DbHelper::getContextTsKey(); + $instanceKey = DbHelper::getTsInstanceKey($instance); + + /* @var \SplStack $tsStack */ + $tsStack = RequestContext::getContextDataByChildKey($contextTsKey, $instanceKey, new \SplStack()); + if (!$tsStack->isEmpty()) { + $tsStack->pop(); + } + RequestContext::setContextDataByChildKey($contextTsKey, $instanceKey, $tsStack); + $connection->release(true); } /** diff --git a/src/DbResult.php b/src/DbResult.php index eeb5952..7c6db44 100644 --- a/src/DbResult.php +++ b/src/DbResult.php @@ -41,11 +41,11 @@ protected function getResultByClass(string $className) $result = EntityHelper::arrayToEntity($result, $className); } - if (!empty($className) && $this->type == Db::RESULT_FETCH && empty($result)) { + if (!empty($className) && $this->type == Db::RETURN_FETCH && empty($result)) { return []; } - if (!empty($className) && $this->type == Db::RESULT_ONE && empty($result)) { + if (!empty($className) && $this->type == Db::RETURN_ONE && empty($result)) { return null; } @@ -60,15 +60,15 @@ private function getResultByType() /* @var AbstractDbConnection $connection */ $connection = $this->connection; - if ($this->type == Db::RESULT_INSERTID) { + if ($this->type == Db::RETURN_INSERTID) { return $this->connection->getInsertId(); } - if ($this->type == Db::RESULT_ROWS) { + if ($this->type == Db::RETURN_ROWS) { return $connection->getAffectedRows(); } - if ($this->type == Db::RESULT_FETCH) { + if ($this->type == Db::RETURN_FETCH) { return $connection->fetch(); } diff --git a/src/Driver/Mysql/MysqlConnection.php b/src/Driver/Mysql/MysqlConnection.php index 8bcf115..8d23402 100644 --- a/src/Driver/Mysql/MysqlConnection.php +++ b/src/Driver/Mysql/MysqlConnection.php @@ -163,7 +163,7 @@ public function createConnection() public function setDefer($defer = true) { $this->recv = false; - $this->connection->setDefer($defer); + $result = $this->connection->setDefer($defer); } /** diff --git a/src/Event/Listeners/TransactionReleaseListener.php b/src/Event/Listeners/ResourceReleaseBeforeListener.php similarity index 59% rename from src/Event/Listeners/TransactionReleaseListener.php rename to src/Event/Listeners/ResourceReleaseBeforeListener.php index 38de0bd..9a9f601 100644 --- a/src/Event/Listeners/TransactionReleaseListener.php +++ b/src/Event/Listeners/ResourceReleaseBeforeListener.php @@ -3,29 +3,37 @@ namespace Swoft\Db\Event\Listeners; use Swoft\Bean\Annotation\Listener; +use Swoft\Core\RequestContext; use Swoft\Db\AbstractDbConnection; +use Swoft\Db\Helper\DbHelper; use Swoft\Event\AppEvent; use Swoft\Event\EventHandlerInterface; use Swoft\Event\EventInterface; -use Swoft\Event\Events\TransactionReleaseEvent; +use Swoft\Helper\PoolHelper; use Swoft\Log\Log; /** * TransactionRelease * - * @Listener(AppEvent::TRANSACTION_RELEASE) + * @Listener(AppEvent::RESOURCE_RELEASE_BEFORE) */ -class TransactionReleaseListener implements EventHandlerInterface +class ResourceReleaseBeforeListener implements EventHandlerInterface { + /** + * @param \Swoft\Event\EventInterface $event + */ public function handle(EventInterface $event) { - if (!($event instanceof TransactionReleaseEvent)) { + $contextTsKey = DbHelper::getContextTsKey(); + $contextCntKey = PoolHelper::getContextCntKey(); + $transactions = RequestContext::getContextDataByKey($contextTsKey, []); + $connections = RequestContext::getContextDataByKey($contextCntKey, []); + + if (empty($connections) || empty($transactions)) { return; } - $tsStacks = $event->getTsStacks(); - $connections = $event->getConnections(); - foreach ($tsStacks as $tsStack) { + foreach ($transactions as $instance => $tsStack) { if (!($tsStack instanceof \SplStack)) { continue; } @@ -37,7 +45,6 @@ public function handle(EventInterface $event) $connection = $connections[$connectId]; if ($connection instanceof AbstractDbConnection) { $connection->rollback(); - $connections[$connectId] = $connection; Log::error(sprintf('%s transaction is not committed or rollbacked', get_class($connection))); } diff --git a/src/Executor.php b/src/Executor.php index 9043a24..59834f3 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -22,8 +22,9 @@ class Executor public static function save($entity): ResultInterface { list($table, , , $fields) = self::getFields($entity, 1); + $instance = self::getInstance(get_class($entity)); - $query = Query::table($table)->insert(); + $query = Query::table($table)->insert()->selectInstance($instance); foreach ($fields ?? [] as $column => $value) { $query = $query->set($column, $value); } @@ -39,8 +40,9 @@ public static function save($entity): ResultInterface public static function delete($entity): ResultInterface { list($table, , , $fields) = self::getFields($entity, 3); + $instance = self::getInstance(get_class($entity)); - $query = Query::table($table)->delete(); + $query = Query::table($table)->delete()->selectInstance($instance); foreach ($fields ?? [] as $column => $value) { $query->where($column, $value); } @@ -57,7 +59,9 @@ public static function delete($entity): ResultInterface public static function deleteById($className, $id): ResultInterface { list($table, , $idColumn) = self::getTable($className); - $query = Query::table($table)->delete()->where($idColumn, $id); + $instance = self::getInstance($className); + + $query = Query::table($table)->delete()->where($idColumn, $id)->selectInstance($instance); return $query->execute(); } @@ -71,7 +75,9 @@ public static function deleteById($className, $id): ResultInterface public static function deleteByIds($className, array $ids): ResultInterface { list($table, , $idColumn) = self::getTable($className); - $query = Query::table($table)->delete()->whereIn($idColumn, $ids); + $instance = self::getInstance($className); + + $query = Query::table($table)->delete()->whereIn($idColumn, $ids)->selectInstance($instance); return $query->execute(); } @@ -90,7 +96,8 @@ public static function update($entity): ResultInterface return new DbDataResult(0); } // 构建update查询器 - $query = Query::table($table)->update()->where($idColumn, $idValue); + $instance = self::getInstance(get_class($entity)); + $query = Query::table($table)->update()->where($idColumn, $idValue)->selectInstance($instance); foreach ($fields ?? [] as $column => $value) { $query->set($column, $value); } @@ -106,8 +113,9 @@ public static function update($entity): ResultInterface public static function find($entity): ResultInterface { list($tableName, , , $fields) = self::getFields($entity, 3); + $instance = self::getInstance(get_class($entity)); - $query = Query::table($tableName)->select('*'); + $query = Query::table($tableName)->select('*')->selectInstance($instance); foreach ($fields ?? [] as $column => $value) { $query->where($column, $value); } @@ -124,7 +132,9 @@ public static function find($entity): ResultInterface public static function findById($className, $id): ResultInterface { list($tableName, , $columnId) = self::getTable($className); - $query = Query::table($tableName)->select("*")->where($columnId, $id)->limit(1); + $instance = self::getInstance($className); + + $query = Query::table($tableName)->select("*")->where($columnId, $id)->limit(1)->selectInstance($instance); return $query->execute(); } @@ -138,7 +148,9 @@ public static function findById($className, $id): ResultInterface public static function findByIds($className, array $ids): ResultInterface { list($tableName, , $columnId) = self::getTable($className); - $query = Query::table($tableName)->select("*")->whereIn($columnId, $ids); + $instance = self::getInstance($className); + + $query = Query::table($tableName)->select("*")->whereIn($columnId, $ids)->selectInstance($instance); return $query->execute(); } @@ -313,4 +325,18 @@ private static function getTable(string $className): array return [$tableName, $idProperty, $idColumn, $fields]; } + + /** + * @param string $className + * + * @return string + */ + private static function getInstance(string $className):string + { + $collector = EntityCollector::getCollector(); + if(!isset($collector[$className]['instance'])){ + return Pool::INSTANCE; + } + return $collector[$className]['instance']; + } } diff --git a/src/Helper/DbHelper.php b/src/Helper/DbHelper.php index bfc7b64..e90c308 100644 --- a/src/Helper/DbHelper.php +++ b/src/Helper/DbHelper.php @@ -62,52 +62,31 @@ public static function getStatementClassNameByInstance(string $instance): string return $collector[$driver]; } - public static function getDriverByInstance(string $instance): string - { - $pool = DbHelper::getPool($instance, Pool::MASTER); - /* @var DbPoolProperties $poolConfig */ - $poolConfig = $pool->getPoolConfig(); - - return $poolConfig->getDriver(); - } - /** - * @param string $group - * - * @throws \Swoft\Db\Exception\MysqlException * @return string */ - public static function getQueryClassNameByGroup(string $group): string + public static function getContextTsKey(): string { - $pool = DbHelper::getPool($group, Pool::MASTER); - /* @var \Swoft\Db\Pool\Config\DbPoolProperties $poolConfig */ - $poolConfig = $pool->getPoolConfig(); - $driver = $poolConfig->getDriver(); - - $collector = BuilderCollector::getCollector(); - if (!isset($collector[$driver])) { - throw new MysqlException(sprintf('The queryBuilder of %s is not exist!', $driver)); - } - - return $collector[$driver]; + return sprintf('transactions'); } /** - * Get the class name of QueryBuilder - * - * @param \Swoft\Pool\ConnectionInterface $connect + * @param string $instance * * @return string */ - public static function getQueryClassNameByConnection(ConnectionInterface $connect): string + public static function getTsInstanceKey(string $instance): string + { + return $instance; + } + + public static function getDriverByInstance(string $instance): string { - $connectClassName = \get_class($connect); - $classNameTmp = str_replace('\\', '/', $connectClassName); - $namespaceDir = \dirname($classNameTmp); - $namespace = str_replace('/', '\\', $namespaceDir); - $namespace = sprintf('%s\\QueryBuilder', $namespace); + $pool = DbHelper::getPool($instance, Pool::MASTER); + /* @var DbPoolProperties $poolConfig */ + $poolConfig = $pool->getPoolConfig(); - return $namespace; + return $poolConfig->getDriver(); } /** diff --git a/src/Pool.php b/src/Pool.php index 23e72c4..0f973c2 100644 --- a/src/Pool.php +++ b/src/Pool.php @@ -3,24 +3,22 @@ namespace Swoft\Db; /** - * The type of pool + * Pool */ class Pool { /** - * Default group + * Default instance */ - const GROUP = 'default'; - const INSTANCE = 'default'; /** - * The master + * Master */ const MASTER = 'master'; /** - * The slave + * Slave */ const SLAVE = 'slave'; diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index f0aa70b..ce338c1 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -898,33 +898,50 @@ private function criteria( /** * @param string $db + * + * @return QueryBuilder */ public function selectDb(string $db) { $this->db = $db; + return $this; } /** * @param string $node + * + * @return QueryBuilder */ public function selectNode(string $node = Pool::MASTER) { $this->node = $node; + + return $this; } /** * @param string $instance + * + * @return QueryBuilder */ public function selectInstance(string $instance) { $this->instance = $instance; + + return $this; } + /** + * @param bool $master + * + * @return QueryBuilder + */ public function force(bool $master = true) { if ($master) { $this->node = Pool::MASTER; } + return $this; } /** From f861b7df5eb92c372ef981c9d08c9147eff2f928 Mon Sep 17 00:00:00 2001 From: lilin <794774870@qq.com> Date: Thu, 29 Mar 2018 14:53:13 +0800 Subject: [PATCH 03/27] select db --- src/AbstractDbConnection.php | 23 ++++++- src/Db.php | 4 ++ src/DbCoResult.php | 4 +- ...nterface.php => DbConnectionInterface.php} | 9 ++- src/DbResult.php | 2 +- src/Driver/Mysql/MysqlConnection.php | 68 +++++++++++-------- src/Driver/Mysql/SyncMysqlConnection.php | 8 +++ 7 files changed, 87 insertions(+), 31 deletions(-) rename src/{DbConnectInterface.php => DbConnectionInterface.php} (84%) diff --git a/src/AbstractDbConnection.php b/src/AbstractDbConnection.php index 7fa98c3..e44b980 100644 --- a/src/AbstractDbConnection.php +++ b/src/AbstractDbConnection.php @@ -10,8 +10,18 @@ /** * Abstract database connection */ -abstract class AbstractDbConnection extends AbstractConnection implements DbConnectInterface +abstract class AbstractDbConnection extends AbstractConnection implements DbConnectionInterface { + /** + * @var string + */ + protected $originDb = ''; + + /** + * @var string + */ + protected $currentDb = ''; + /** * @return string */ @@ -20,6 +30,17 @@ public function getDriver(): string return $this->pool->getDriver(); } + /** + * @param bool $release + */ + public function release($release = false) + { + if(!empty($this->currentDb) && $this->currentDb != $this->originDb){ + $this->selectDb($this->originDb); + } + parent::release($release); + } + /** * Parse uri * diff --git a/src/Db.php b/src/Db.php index 732e7bd..42ca8b3 100644 --- a/src/Db.php +++ b/src/Db.php @@ -56,6 +56,10 @@ public static function query(string $sql, array $params = [], string $instance = /* @var AbstractDbConnection $connection */ $connection = self::getConnection($instance, $node); + if(!empty($db)){ + $connection->selectDb($db); + } + /* @var DbPool $pool */ $pool = $connection->getPool(); /* @var DbPoolProperties $poolConfig */ diff --git a/src/DbCoResult.php b/src/DbCoResult.php index 5c62eaf..2401dd3 100644 --- a/src/DbCoResult.php +++ b/src/DbCoResult.php @@ -18,8 +18,10 @@ class DbCoResult extends DbResult public function getResult(...$params) { list($className) = array_pad($params, 1, ''); - $this->recv(true); + $this->recv(true, false); $result = $this->getResultByClass($className); + $this->release(); + return $result; } } \ No newline at end of file diff --git a/src/DbConnectInterface.php b/src/DbConnectionInterface.php similarity index 84% rename from src/DbConnectInterface.php rename to src/DbConnectionInterface.php index 5de7c0d..56560e4 100644 --- a/src/DbConnectInterface.php +++ b/src/DbConnectionInterface.php @@ -5,7 +5,7 @@ /** * Database interface */ -interface DbConnectInterface +interface DbConnectionInterface { /** * @param string $sql @@ -49,6 +49,13 @@ public function rollback(); */ public function commit(); + /** + * @param string $db + * + * @return void + */ + public function selectDb(string $db); + /** * Destory */ diff --git a/src/DbResult.php b/src/DbResult.php index 7c6db44..989fb40 100644 --- a/src/DbResult.php +++ b/src/DbResult.php @@ -61,7 +61,7 @@ private function getResultByType() $connection = $this->connection; if ($this->type == Db::RETURN_INSERTID) { - return $this->connection->getInsertId(); + return $this->connection->getInsertId();; } if ($this->type == Db::RETURN_ROWS) { diff --git a/src/Driver/Mysql/MysqlConnection.php b/src/Driver/Mysql/MysqlConnection.php index 8d23402..d3e8379 100644 --- a/src/Driver/Mysql/MysqlConnection.php +++ b/src/Driver/Mysql/MysqlConnection.php @@ -6,6 +6,7 @@ use Swoft\Db\Bean\Annotation\Connection; use Swoft\Db\AbstractDbConnection; use Swoft\Db\Exception\MysqlException; +use Swoft\Log\Log; use Swoole\Coroutine\Mysql; /** @@ -40,6 +41,38 @@ public function prepare(string $sql) $this->sql = $sql; } + /** + * Create connection + * + * @throws \InvalidArgumentException + */ + public function createConnection() + { + $uri = $this->pool->getConnectionAddress(); + $options = $this->parseUri($uri); + $options['timeout'] = $this->pool->getTimeout(); + + // 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'], + ]); + + // error + if ($mysql->connected === false) { + throw new MysqlException('Database connection error,error=' . $mysql->connect_error); + } + + $this->originDb = $options['database']; + $this->connection = $mysql; + } + /** * Execute * @@ -111,7 +144,8 @@ public function beginTransaction() public function rollback() { if (!$this->recv) { - throw new MysqlException('You forget to getResult() before rollback !'); + $this->receive(); + App::error('You forget to getResult() before rollback !'); } $this->connection->query('rollback;'); } @@ -122,39 +156,19 @@ public function rollback() public function commit() { if (!$this->recv) { - throw new MysqlException('You forget to getResult() before commit !'); + $this->receive(); + App::error('You forget to getResult() before commit !'); } $this->connection->query('commit;'); } /** - * Create connection - * - * @throws \InvalidArgumentException + * @param string $db */ - public function createConnection() + public function selectDb(string $db) { - $uri = $this->pool->getConnectionAddress(); - $options = $this->parseUri($uri); - $options['timeout'] = $this->pool->getTimeout(); - - // 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'], - ]); - - // error - if ($mysql->connected === false) { - throw new MysqlException('Database connection error,error=' . $mysql->connect_error); - } - $this->connection = $mysql; + $this->connection->query(sprintf('use %s', $db)); + $this->currentDb = $db; } /** diff --git a/src/Driver/Mysql/SyncMysqlConnection.php b/src/Driver/Mysql/SyncMysqlConnection.php index 1726244..8afaa2b 100644 --- a/src/Driver/Mysql/SyncMysqlConnection.php +++ b/src/Driver/Mysql/SyncMysqlConnection.php @@ -133,6 +133,14 @@ public function beginTransaction() $this->connection->beginTransaction(); } + /** + * @param string $db + */ + public function selectDb(string $db) + { + $this->connection->exec(sprintf('use %s', $db)); + } + /** * @return mixed */ From cd0384eb0749732c9a3b60ee63ca0ef51f674c94 Mon Sep 17 00:00:00 2001 From: lilin <794774870@qq.com> Date: Sun, 1 Apr 2018 23:00:33 +0800 Subject: [PATCH 04/27] batchInsert and Simplified operation --- .travis.yml | 2 +- src/Driver/Mysql/SyncMysqlConnection.php | 2 + src/Executor.php | 145 +++++++++++--- src/Model.php | 5 + src/QueryBuilder.php | 241 ++++++++++++++++++----- src/Statement.php | 99 ++++++++-- test/.env | 21 ++ test/Cases/AggregateTest.php | 132 +++++++++++++ test/Cases/MysqlTest.php | 2 +- test/Cases/QueryTest.php | 114 ++++++++++- test/Cases/StelinTest.php | 25 +++ test/Cases/TrasactionTest.php | 70 ++++++- test/Testing/Entity/OtherUser.php | 165 ++++++++++++++++ test/Testing/Pool/OtherDbConfig.php | 81 ++++++++ test/Testing/Pool/OtherDbPool.php | 21 ++ test/Testing/Pool/OtherDbSlaveConfig.php | 80 ++++++++ test/Testing/Pool/OtherDbSlavePool.php | 22 +++ test/config/properties/db.php | 30 ++- 18 files changed, 1154 insertions(+), 103 deletions(-) create mode 100644 test/Cases/AggregateTest.php create mode 100644 test/Cases/StelinTest.php create mode 100644 test/Testing/Entity/OtherUser.php create mode 100644 test/Testing/Pool/OtherDbConfig.php create mode 100644 test/Testing/Pool/OtherDbPool.php create mode 100644 test/Testing/Pool/OtherDbSlaveConfig.php create mode 100644 test/Testing/Pool/OtherDbSlavePool.php diff --git a/.travis.yml b/.travis.yml index c9edd55..9db0c95 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ services: - mysql before_install: - - mysql -e 'CREATE DATABASE IF NOT EXISTS test;use test;CREATE TABLE IF NOT EXISTS `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,`sex` int(1) NOT NULL DEFAULT '0',`age` int(1) NOT NULL DEFAULT '0',`description` varchar(240) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;' + - mysql -e 'CREATE DATABASE IF NOT EXISTS test;use test;CREATE TABLE IF NOT EXISTS `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,`sex` int(1) NOT NULL DEFAULT '0',`age` int(1) NOT NULL DEFAULT '0',`description` varchar(240) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;CREATE TABLE `user2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `sex` int(1) NOT NULL DEFAULT '0', `age` int(1) NOT NULL DEFAULT '0', `description` varchar(240) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;CREATE DATABASE IF NOT EXISTS test2;use test2;CREATE TABLE IF NOT EXISTS `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,`sex` int(1) NOT NULL DEFAULT '0',`age` int(1) NOT NULL DEFAULT '0',`description` varchar(240) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;' install: - wget https://github.com/redis/hiredis/archive/v0.13.3.tar.gz -O hiredis.tar.gz && mkdir -p hiredis && tar -xf hiredis.tar.gz -C hiredis --strip-components=1 && cd hiredis && sudo make -j$(nproc) && sudo make install && sudo ldconfig && cd .. diff --git a/src/Driver/Mysql/SyncMysqlConnection.php b/src/Driver/Mysql/SyncMysqlConnection.php index 8afaa2b..e615413 100644 --- a/src/Driver/Mysql/SyncMysqlConnection.php +++ b/src/Driver/Mysql/SyncMysqlConnection.php @@ -54,6 +54,7 @@ public function createConnection() $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); + $this->originDb = $dbName; } /** @@ -139,6 +140,7 @@ public function beginTransaction() public function selectDb(string $db) { $this->connection->exec(sprintf('use %s', $db)); + $this->currentDb = $db; } /** diff --git a/src/Executor.php b/src/Executor.php index 59834f3..541844a 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -10,7 +10,7 @@ use Swoft\Exception\ValidatorException; /** - * The executor of db + * Executor */ class Executor { @@ -24,12 +24,10 @@ public static function save($entity): ResultInterface list($table, , , $fields) = self::getFields($entity, 1); $instance = self::getInstance(get_class($entity)); - $query = Query::table($table)->insert()->selectInstance($instance); - foreach ($fields ?? [] as $column => $value) { - $query = $query->set($column, $value); - } + $fields = $fields ?? []; + $query = Query::table($table)->selectInstance($instance); - return $query->execute(); + return $query->insert($fields); } /** @@ -42,12 +40,12 @@ public static function delete($entity): ResultInterface list($table, , , $fields) = self::getFields($entity, 3); $instance = self::getInstance(get_class($entity)); - $query = Query::table($table)->delete()->selectInstance($instance); + $query = Query::table($table)->selectInstance($instance); foreach ($fields ?? [] as $column => $value) { $query->where($column, $value); } - return $query->execute(); + return $query->delete(); } /** @@ -61,9 +59,9 @@ public static function deleteById($className, $id): ResultInterface list($table, , $idColumn) = self::getTable($className); $instance = self::getInstance($className); - $query = Query::table($table)->delete()->where($idColumn, $id)->selectInstance($instance); + $query = Query::table($table)->where($idColumn, $id)->selectInstance($instance); - return $query->execute(); + return $query->delete(); } /** @@ -77,9 +75,33 @@ public static function deleteByIds($className, array $ids): ResultInterface list($table, , $idColumn) = self::getTable($className); $instance = self::getInstance($className); - $query = Query::table($table)->delete()->whereIn($idColumn, $ids)->selectInstance($instance); + $query = Query::table($table)->whereIn($idColumn, $ids)->selectInstance($instance); - return $query->execute(); + return $query->delete(); + } + + /** + * @param string $className + * @param array $condition + * + * @return ResultInterface + */ + public function deleteOne(string $className, array $condition) + { + $instance = self::getInstance($className); + return Query::table($className)->selectInstance($instance)->condition($condition)->limit(1)->delete(); + } + + /** + * @param string $className + * @param array $condition + * + * @return ResultInterface + */ + public function deleteAll(string $className, array $condition) + { + $instance = self::getInstance($className); + return Query::table($className)->selectInstance($instance)->condition($condition)->delete(); } /** @@ -97,12 +119,36 @@ public static function update($entity): ResultInterface } // 构建update查询器 $instance = self::getInstance(get_class($entity)); - $query = Query::table($table)->update()->where($idColumn, $idValue)->selectInstance($instance); - foreach ($fields ?? [] as $column => $value) { - $query->set($column, $value); - } + $fields = $fields ?? []; + $query = Query::table($table)->where($idColumn, $idValue)->selectInstance($instance); - return $query->execute(); + return $query->update($fields); + } + + /** + * @param string $className + * @param array $attributes + * @param array $condition + * + * @return ResultInterface + */ + public static function updateOne(string $className, array $attributes, array $condition) + { + $instance = self::getInstance($className); + return Query::table($className)->selectInstance($instance)->condition($condition)->limit(1)->update($attributes); + } + + /** + * @param string $className + * @param array $attributes + * @param array $condition + * + * @return ResultInterface + */ + public static function updateAll(string $className, array $attributes, array $condition) + { + $instance = self::getInstance($className); + return Query::table($className)->selectInstance($instance)->condition($condition)->update($attributes); } /** @@ -115,12 +161,12 @@ public static function find($entity): ResultInterface list($tableName, , , $fields) = self::getFields($entity, 3); $instance = self::getInstance(get_class($entity)); - $query = Query::table($tableName)->select('*')->selectInstance($instance); + $query = Query::table($tableName)->selectInstance($instance); foreach ($fields ?? [] as $column => $value) { $query->where($column, $value); } - return $query->execute(); + return $query->get(); } /** @@ -134,9 +180,9 @@ public static function findById($className, $id): ResultInterface list($tableName, , $columnId) = self::getTable($className); $instance = self::getInstance($className); - $query = Query::table($tableName)->select("*")->where($columnId, $id)->limit(1)->selectInstance($instance); + $query = Query::table($tableName)->where($columnId, $id)->limit(1)->selectInstance($instance); - return $query->execute(); + return $query->get(); } /** @@ -150,9 +196,57 @@ public static function findByIds($className, array $ids): ResultInterface list($tableName, , $columnId) = self::getTable($className); $instance = self::getInstance($className); - $query = Query::table($tableName)->select("*")->whereIn($columnId, $ids)->selectInstance($instance); + $query = Query::table($tableName)->whereIn($columnId, $ids)->selectInstance($instance); + + return $query->get(); + } + + /** + * @param string $className + * @param array $condition + * @param array $orderBy + * + * @return \Swoft\Core\ResultInterface + */ + public static function findOne(string $className, array $condition = [], array $orderBy = []) + { + $instance = self::getInstance($className); + $query = Query::table($className)->selectInstance($instance)->delete(); + + if (!empty($condition)) { + $query = $query->condition($condition); + } + + foreach ($orderBy as $column => $order) { + $query = $query->orderBy($column, $order); + } + + return $query->limit(1)->execute(); + } + + /** + * @param string $className + * @param array $condition + * @param array $orderBy + * @param int $limit + * @param int $offset + * + * @return ResultInterface + */ + public function findAll(string $className, array $condition = [], array $orderBy = [], int $limit = 20, int $offset = 0) + { + $instance = self::getInstance($className); + $query = Query::table($className)->selectInstance($instance)->delete(); + + if (!empty($condition)) { + $query = $query->condition($condition); + } + + foreach ($orderBy as $column => $order) { + $query = $query->orderBy($column, $order); + } - return $query->execute(); + return $query->limit($limit, $offset)->execute(); } /** @@ -331,12 +425,13 @@ private static function getTable(string $className): array * * @return string */ - private static function getInstance(string $className):string + private static function getInstance(string $className): string { $collector = EntityCollector::getCollector(); - if(!isset($collector[$className]['instance'])){ + if (!isset($collector[$className]['instance'])) { return Pool::INSTANCE; } + return $collector[$className]['instance']; } } diff --git a/src/Model.php b/src/Model.php index c39e969..9805dc4 100644 --- a/src/Model.php +++ b/src/Model.php @@ -72,6 +72,11 @@ public static function deleteByIds(array $ids) return Executor::deleteByIds(static::class, $ids); } + public function updateOne(array $attributes, array $condition) + { + + } + /** * Update data * diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index ce338c1..caff48a 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -137,6 +137,11 @@ class QueryBuilder implements QueryBuilderInterface */ private $insert = ''; + /** + * @var array + */ + private $insertValues = []; + /** * 更新表名 * @@ -144,6 +149,11 @@ class QueryBuilder implements QueryBuilderInterface */ private $update = ''; + /** + * @var array + */ + private $updateValues = []; + /** * 是否是delete * @@ -222,16 +232,6 @@ class QueryBuilder implements QueryBuilderInterface */ protected $parameters = []; - /** - * @var AbstractDbConnection - */ - protected $connection; - - /** - * @var string - */ - protected $lastSql; - /** * @var array */ @@ -255,37 +255,87 @@ class QueryBuilder implements QueryBuilderInterface protected $db = ''; /** - * @return QueryBuilder + * @var array + */ + protected $aggregate = []; + + /** + * @param array $values + * + * @return ResultInterface * @throws DbException */ - public function insert(): QueryBuilder + public function insert(array $values): ResultInterface + { + $this->insert = $this->getTableName(); + $this->insertValues['columns'] = array_keys($values); + $this->insertValues['values'][] = array_values($values); + + return $this->execute(); + } + + /** + * @param array $rows + * + * @return ResultInterface + * @throws DbException + */ + public function batchInsert(array $rows): ResultInterface { $this->insert = $this->getTableName(); + foreach ($rows as $row) { + ksort($row); + if (!isset($this->insertValues['columns'])) { + $this->insertValues['columns'] = array_keys($row); + } + $this->insertValues['values'][] = array_values($row); + } - return $this; + return $this->execute(); } /** - * @return QueryBuilder + * @param array $values + * + * @return ResultInterface * @throws DbException */ - public function update(): QueryBuilder + public function update(array $values): ResultInterface { - $this->update = $this->getTableName(); + $this->update = $this->getTableName(); + $this->updateValues = $values; - return $this; + return $this->execute(); } /** * delete语句 * - * @return QueryBuilder + * @return ResultInterface */ - public function delete(): QueryBuilder + public function delete(): ResultInterface { $this->delete = true; - return $this; + return $this->execute(); + } + + /** + * @param array $columns + * + * @return ResultInterface + */ + public function get(array $columns = ['*']): ResultInterface + { + foreach ($columns as $column => $alias) { + if (\is_int($column)) { + $this->select[$alias] = null; + continue; + } + $this->select[$column] = $alias; + } + + return $this->execute(); } /** @@ -411,6 +461,41 @@ public function where(string $column, $value, $operator = self::OPERATOR_EQ, $co return $this; } + /** + * The $condition is array + * + * Format `['column1' => value1, 'column2' => value2, ...]` + * - ['name' => 'swoft', 'status' => 1] => ('name'='swoft' and 'status' = 1) + * - ['id' => [1, 2, 3], 'status' => 1] => ('id' in (1, 2, 3) and 'status' = 1) + * - ['status' => null] => ('status' is null) + * + * Format `[operator, operand1, operand2, ...]` + * - ['>', 'id', 12] / ['id' => ['$gt' => xxx ]] + * - ['<', 'id', 13] + * - ['>=', 'id', 13] + * - ['<=', 'id', 13] + * - ['<>', 'id', 13] + * + * - ['in', 'id', [1, 2, 3]] + * - ['not in', 'id', [1, 2, 3]] + * + * - ['between', 'id', 2, 3] + * - ['not between', 'id', 2, 3] + * + * - ['like', 'name', '%swoft%'] + * - ['not like', 'name', '%swoft%'] + * + * + * @param mixed $condition + * @param string $connector + * + * @return \Swoft\Db\QueryBuilder + */ + public function condition($condition, $connector = self::LOGICAL_AND) + { + return $this; + } + /** * where and 语句 * @@ -720,32 +805,6 @@ public function limit(int $limit, $offset = 0): QueryBuilder return $this; } - /** - * set语句 - * - * @param mixed $column - * @param mixed $value - * - * @return QueryBuilder - */ - public function set($column, $value = null): QueryBuilder - { - if (!\is_array($column)) { - $this->set[] = array( - 'column' => $column, - 'value' => $value, - ); - - return $this; - } - - foreach ($column as $columnName => $columnValue) { - $this->set($columnName, $columnValue); - } - - return $this; - } - /** * 设置参数 * @@ -813,14 +872,6 @@ public function setParameters(array $parameters) return $this; } - /** - * @return \Swoft\Db\AbstractDbConnection - */ - public function getConnection(): \Swoft\Db\AbstractDbConnection - { - return $this->connection; - } - /** * 括号条件组拼 * @@ -904,6 +955,7 @@ private function criteria( public function selectDb(string $db) { $this->db = $db; + return $this; } @@ -941,6 +993,63 @@ public function force(bool $master = true) if ($master) { $this->node = Pool::MASTER; } + + return $this; + } + + /** + * @param string $column + * @param string $alias + * + * @return QueryBuilder + */ + public function count(string $column = '*', string $alias = 'count') + { + $this->aggregate['count'] = [$column, $alias]; + $this->limit(1); + + return $this; + } + + /** + * @param string $column + * @param string $alias + * + * @return QueryBuilder + */ + public function max(string $column, string $alias = 'max') + { + $this->aggregate['max'] = [$column, $alias]; + $this->limit(1); + + return $this; + } + + /** + * @param string $column + * @param string $alias + * + * @return QueryBuilder + */ + public function avg(string $column, string $alias = 'avg') + { + $this->aggregate['avg'] = [$column, $alias]; + $this->limit(1); + + return $this; + } + + /** + * @param string $column + * @param string $alias + * + * @return QueryBuilder + */ + public function sum(string $column, string $alias = 'sum') + { + $this->aggregate['sum'] = [$column, $alias]; + $this->limit(1); + return $this; } @@ -1156,4 +1265,28 @@ public function getParameters(): array { return $this->parameters; } + + /** + * @return array + */ + public function getAggregate(): array + { + return $this->aggregate; + } + + /** + * @return array + */ + public function getInsertValues(): array + { + return $this->insertValues; + } + + /** + * @return array + */ + public function getUpdateValues(): array + { + return $this->updateValues; + } } diff --git a/src/Statement.php b/src/Statement.php index 0706dc4..12efe73 100644 --- a/src/Statement.php +++ b/src/Statement.php @@ -12,6 +12,11 @@ class Statement implements StatementInterface */ protected $builder; + /** + * Statement constructor. + * + * @param \Swoft\Db\QueryBuilder $queryBuilder + */ public function __construct(QueryBuilder $queryBuilder) { $this->builder = $queryBuilder; @@ -25,7 +30,7 @@ public function __construct(QueryBuilder $queryBuilder) public function getStatement(): string { $statement = ''; - if ($this->isSelect()) { + if ($this->isSelect() || $this->isAggregate()) { $statement = $this->getSelectStatement(); } elseif ($this->isInsert()) { $statement = $this->getInsertStatement(); @@ -46,7 +51,7 @@ public function getStatement(): string protected function getSelectStatement(): string { $statement = ''; - if (!$this->isSelect()) { + if (!$this->isSelect() && !$this->isAggregate()) { return $statement; } @@ -101,9 +106,9 @@ protected function getInsertStatement(): string // insert语句 $statement .= $this->getInsertString(); - // set语句 - if ($this->builder->getSet()) { - $statement .= ' ' . $this->getSetString(); + // values + if ($this->builder->getInsertValues()) { + $statement .= ' ' . $this->getInsertValuesString(); } return $statement; @@ -125,8 +130,8 @@ protected function getUpdateStatement(): string $statement .= $this->getUpdateString(); // set语句 - if ($this->builder->getSet()) { - $statement .= ' ' . $this->getSetString(); + if ($this->builder->getUpdateValues()) { + $statement .= ' ' . $this->getUpdateValuesString(); } // where语句 @@ -194,10 +199,13 @@ protected function getSelectString(): string { $statement = ''; $select = $this->builder->getSelect(); - if (empty($select)) { + $aggregate = $this->builder->getAggregate(); + if (empty($select) && empty($aggregate)) { return $statement; } + $select = $this->getAggregateStatement($select, $aggregate); + // 字段组拼 foreach ($select as $column => $alias) { $statement .= $column; @@ -216,6 +224,38 @@ protected function getSelectString(): string return $statement; } + /** + * @param array $select + * @param array $aggregate + * @return array + */ + protected function getAggregateStatement(array $select, array $aggregate): array + { + foreach ($aggregate as $func => $value) { + list($column, $alias) = $value; + switch ($func) { + case 'count': + $column = sprintf('count(%s)', $column); + break; + case 'max': + $column = sprintf('max(%s)', $column); + break; + case 'min': + $column = sprintf('min(%s)', $column); + break; + case 'avg': + $column = sprintf('avg(%s)', $column); + break; + case 'sum': + $column = sprintf('sum(%s)', $column); + break; + } + $select[$column] = $alias; + } + + return $select; + } + /** * from语句 * @@ -540,18 +580,38 @@ protected function getLimitString(): string } /** - * set语句 - * * @return string */ - protected function getSetString(): string + protected function getInsertValuesString(): string { - $statement = ''; - $sets = $this->builder->getSet(); - foreach ($sets as $set) { - $statement .= $set['column'] . ' ' . QueryBuilder::OPERATOR_EQ . ' ' . $this->getQuoteValue($set['value']) . ', '; + $statement = ' '; + $values = $this->builder->getInsertValues(); + $columns = $values['columns']; + $columnValues = $values['values']; + + $statement .= sprintf('(%s)', implode(',', $columns)); + $statement .= ' values '; + foreach ($columnValues as $row) { + foreach ($row as &$rowValue) { + $rowValue = $this->getQuoteValue($rowValue); + } + $statement .= sprintf('(%s)', implode(',', $row)) . ', '; } + $statement = substr($statement, 0, -2); + return $statement; + } + + /** + * @return string + */ + protected function getUpdateValuesString(): string + { + $statement = ''; + $values = $this->builder->getUpdateValues(); + foreach ($values as $column => $value) { + $statement .= $column . ' ' . QueryBuilder::OPERATOR_EQ . ' ' . $this->getQuoteValue($value) . ', '; + } $statement = substr($statement, 0, -2); if (!empty($statement)) { $statement = 'SET ' . $statement; @@ -670,6 +730,14 @@ protected function isSelect(): bool return !empty($this->builder->getSelect()); } + /** + * @return bool + */ + protected function isAggregate(): bool + { + return !empty($this->builder->getAggregate()); + } + /** * 是否是insert * @@ -748,6 +816,7 @@ protected function getQuoteValue($value): string { $key = uniqid(); $this->builder->setParameter($key, $value); + return ":{$key}"; } } diff --git a/test/.env b/test/.env index 6dbcea5..b5b0d13 100644 --- a/test/.env +++ b/test/.env @@ -36,6 +36,27 @@ DB_SLAVE_BALANCER=random DB_SLAVE_PROVIDER=consul2 +# the pool of master nodes pool +DB_OTHER_NAME=master2 +DB_OTHER_URI=127.0.0.1:3306/test?user=root&password=&charset=utf8,127.0.0.1:3306/test?user=root&password=&charset=utf8 +DB_OTHER_MIN_ACTIVE=1 +DB_OTHER_MAX_ACTIVE=30 +DB_OTHER_MAX_WAIT=10 +DB_OTHER_MAX_WAIT_TIME=10 +DB_OTHER_MAX_IDLE_TIME=60 +DB_OTHER_TIMEOUT=2 + +# the pool of slave nodes pool +DB_OTHER_SLAVE_NAME=slave2 +DB_OTHER_SLAVE_URI=127.0.0.1:3306/test?user=root&password=&charset=utf8,127.0.0.1:3306/test?user=root&password=&charset=utf8 +DB_OTHER_SLAVE_MIN_ACTIVE=1 +DB_OTHER_SLAVE_MAX_ACTIVE=30 +DB_OTHER_SLAVE_MAX_WAIT=10 +DB_OTHER_SLAVE_MAX_WAIT_TIME=10 +DB_OTHER_SLAVE_MAX_IDLE_TIME=60 +DB_OTHER_SLAVE_TIMEOUT=3 + + # the pool of redis REDIS_NAME=redis2 diff --git a/test/Cases/AggregateTest.php b/test/Cases/AggregateTest.php new file mode 100644 index 0000000..7c2119e --- /dev/null +++ b/test/Cases/AggregateTest.php @@ -0,0 +1,132 @@ +count('id', 'userCount')->execute()->getResult(); + $countNum = $count['userCount']; + $this->assertTrue($countNum >= 2); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testCountByCo(array $ids) + { + go(function () use ($ids){ + $this->testCount($ids); + }); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testSum(array $ids) + { + $ageNum = Query::table(User::class)->sum('age', 'ageNum')->execute()->getResult(); + $ageNum = $ageNum['ageNum']; + $this->assertTrue($ageNum >= 0); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testSumByCo(array $ids) + { + go(function () use ($ids){ + $this->testSum($ids); + }); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testMax(array $ids) + { + $maxAge = Query::table(User::class)->max('age', 'maxAge')->execute()->getResult(); + $maxAge = $maxAge['maxAge']; + $this->assertTrue($maxAge >= 0); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testMaxByCo(array $ids) + { + go(function () use ($ids){ + $this->testMax($ids); + }); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testMin(array $ids) + { + $minAge = Query::table(User::class)->max('age', 'minAge')->execute()->getResult(); + $minAge = $minAge['minAge']; + $this->assertTrue($minAge >= 0); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testMinByCo(array $ids) + { + go(function () use ($ids){ + $this->testMin($ids); + }); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testAvg(array $ids) + { + $avgAge = Query::table(User::class)->avg('age', 'avgAge')->execute()->getResult(); + $avgAge = $avgAge['avgAge']; + $this->assertTrue($avgAge >= 0); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testAvgByCo(array $ids) + { + go(function () use ($ids){ + $this->testAvg($ids); + }); + } +} \ No newline at end of file diff --git a/test/Cases/MysqlTest.php b/test/Cases/MysqlTest.php index 3fc067d..61a2fa3 100644 --- a/test/Cases/MysqlTest.php +++ b/test/Cases/MysqlTest.php @@ -252,7 +252,7 @@ public function testFindByIdsByClassByCo(array $ids) */ public function testQuery(array $ids) { - $result = User::query()->select('*')->orderBy('id', QueryBuilder::ORDER_BY_DESC)->limit(2)->execute()->getResult(); + $result = User::query()->orderBy('id', QueryBuilder::ORDER_BY_DESC)->limit(2)->get()->getResult(); $this->assertCount(2, $result); } diff --git a/test/Cases/QueryTest.php b/test/Cases/QueryTest.php index 406e37b..6089bd2 100644 --- a/test/Cases/QueryTest.php +++ b/test/Cases/QueryTest.php @@ -3,6 +3,7 @@ namespace Swoft\Db\Test\Cases; use Swoft\Db\Query; +use Swoft\Db\Test\Testing\Entity\OtherUser; use Swoft\Db\Test\Testing\Entity\User; /** @@ -17,10 +18,22 @@ class QueryTest extends AbstractMysqlCase */ public function testDbSelect(int $id) { - $result = Query::table(User::class)->select('*')->where('id', $id)->limit(1)->execute()->getResult(); + $result = Query::table(User::class)->where('id', $id)->limit(1)->get()->getResult(); $this->assertEquals($id, $result['id']); } + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testDbSelectByCo(int $id) + { + go(function ()use ($id){ + $this->testDbSelect($id); + }); + } + /** * @dataProvider mysqlProvider * @@ -28,10 +41,22 @@ public function testDbSelect(int $id) */ public function testDbDelete(int $id) { - $result = Query::table(User::class)->delete()->where('id', $id)->execute()->getResult(); + $result = Query::table(User::class)->where('id', $id)->delete()->getResult(); $this->assertEquals(1, $result); } + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testDbDeleteByCo(int $id) + { + go(function () use ($id) { + $this->testDbDelete($id); + }); + } + /** * @dataProvider mysqlProvider * @@ -39,11 +64,23 @@ public function testDbDelete(int $id) */ public function testDbUpdate(int $id) { - $result = Query::table(User::class)->update()->set(['name' => 'stelin666'])->where('id', $id)->execute()->getResult(); + $result = Query::table(User::class)->where('id', $id)->update(['name' => 'stelin666'])->getResult(); $user = User::findById($id)->getResult(); $this->assertEquals('stelin666', $user['name']); } + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testDbUpdateByCo(int $id) + { + go(function ()use ($id){ + $this->testDbUpdate($id); + }); + } + public function testDbInsert() { $values = [ @@ -52,8 +89,77 @@ public function testDbInsert() 'description' => 'this my desc', 'age' => 99, ]; - $result = Query::table(User::class)->insert()->set($values)->execute()->getResult(); + $result = Query::table(User::class)->insert($values)->getResult(); $user = User::findById($result)->getResult(); $this->assertCount(5, $user); } + + + public function testDbInsertByCo() + { + go(function (){ + $this->testDbInsert(); + }); + } + + public function testSelectDb() + { + $data = [ + 'name' => 'stelin', + 'sex' => 1, + 'description' => 'this my desc table', + 'age' => mt_rand(1, 100), + ]; + $userid = Query::table(User::class)->selectDb('test2')->insert($data)->getResult(); + + $user = User::findById($userid)->getResult(User::class); + $user2 = Query::table(User::class)->selectDb('test2')->where('id', $userid)->limit(1)->get()->getResult(); + + $this->assertEquals($user2['description'], 'this my desc table'); + $this->assertEquals($user2['id'], $userid); + } + public function testSelectDbByCo() + { + go(function (){ + $this->testSelectDb(); + }); + } + + public function testSelectTable() + { + $data = [ + 'name' => 'stelin', + 'sex' => 1, + 'description' => 'this my desc', + 'age' => mt_rand(1, 100), + ]; + $result = Query::table('user2')->insert($data)->getResult(); + + /* @var User $user2 */ + $user2 = Query::table('user2')->where('id', $result)->limit(1)->get()->getResult(User::class); + $this->assertEquals($user2->getId(), $result); + } + + public function testSelectTableByCo() + { + go(function (){ + $this->testSelectTable(); + }); + } + + public function testSelectinstance() + { + $data = [ + 'name' => 'stelin', + 'sex' => 1, + 'description' => 'this my desc instance', + 'age' => mt_rand(1, 100), + ]; + $userid = Query::table(User::class)->selectInstance('other')->insert($data)->getResult(); + + $user = OtherUser::findById($userid)->getResult(User::class); + $user2 = Query::table(User::class)->selectInstance('other')->where('id', $userid)->limit(1)->get()->getResult(); + $this->assertEquals($user2['description'], 'this my desc instance'); + $this->assertEquals($user2['id'], $userid); + } } \ No newline at end of file diff --git a/test/Cases/StelinTest.php b/test/Cases/StelinTest.php new file mode 100644 index 0000000..d7a35c2 --- /dev/null +++ b/test/Cases/StelinTest.php @@ -0,0 +1,25 @@ + 'stelin', +// 'sex' => 1, +// 'description' => 'this my desc', +// 'age' => 99, +// ]; +// $result = Query::table(User::class)->insert($values)->execute()->getResult(); +// var_dump(get_last_sql()); +// $user = User::findById($result)->getResult(); +// $this->assertCount(5, $user); + } +} \ No newline at end of file diff --git a/test/Cases/TrasactionTest.php b/test/Cases/TrasactionTest.php index 336d949..2b942cf 100644 --- a/test/Cases/TrasactionTest.php +++ b/test/Cases/TrasactionTest.php @@ -2,10 +2,78 @@ namespace Swoft\Db\Test\Cases; +use Swoft\Db\Db; +use Swoft\Db\Test\Testing\Entity\User; + class TrasactionTest extends AbstractMysqlCase { public function testCommit() { - $this->assertTrue(true); + $data = [ + 'name' => 'stelin', + 'sex' => 1, + 'desc' => 'desc2', + 'age' => 100, + ]; + + Db::beginTransaction(); + + $user = new User(); + $user->fill($data); + $id = $user->save()->getResult(); + + $user2 = new User(); + $user2->fill($data); + $id2 = $user2->save()->getResult(); + Db::commit(); + + + $fid = User::findById($id)->getResult()['id']; + $fid2 = User::findById($id2)->getResult()['id']; + + $this->assertEquals($id, $fid); + $this->assertEquals($id2, $fid2); + } + + public function testCommitByCo() + { + go(function (){ + $this->testCommit(); + }); + } + + public function testRollback() + { + $data = [ + 'name' => 'stelin', + 'sex' => 1, + 'desc' => 'desc2', + 'age' => 100, + ]; + + Db::beginTransaction(); + + $user = new User(); + $user->fill($data); + $id = $user->save()->getResult(); + + $user2 = new User(); + $user2->fill($data); + $id2 = $user2->save()->getResult(); + Db::rollback(); + + + $fid = User::findById($id)->getResult(); + $fid2 = User::findById($id2)->getResult(); + + $this->assertTrue(empty($fid)); + $this->assertTrue(empty($fid2)); + } + + public function testRollbackByCo() + { + go(function (){ + $this->testRollback(); + }); } } \ No newline at end of file diff --git a/test/Testing/Entity/OtherUser.php b/test/Testing/Entity/OtherUser.php new file mode 100644 index 0000000..03aa2f7 --- /dev/null +++ b/test/Testing/Entity/OtherUser.php @@ -0,0 +1,165 @@ +id; + } + + /** + * @param int|null $id + */ + public function setId($id) + { + $this->id = $id; + } + + /** + * @return null|string + */ + public function getName() + { + return $this->name; + } + + /** + * @param null|string $name + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * @return int + */ + public function getAge(): int + { + return $this->age; + } + + /** + * @param int $age + */ + public function setAge(int $age) + { + $this->age = $age; + } + + /** + * @return int + */ + public function getSex(): int + { + return $this->sex; + } + + /** + * @param int $sex + */ + public function setSex(int $sex) + { + $this->sex = $sex; + } + + /** + * @return string + */ + public function getDesc(): string + { + return $this->desc; + } + + /** + * @param string $desc + */ + public function setDesc(string $desc) + { + $this->desc = $desc; + } + + /** + * @return mixed + */ + public function getOtherProperty() + { + return $this->otherProperty; + } + + /** + * @param mixed $otherProperty + */ + public function setOtherProperty($otherProperty) + { + $this->otherProperty = $otherProperty; + } +} diff --git a/test/Testing/Pool/OtherDbConfig.php b/test/Testing/Pool/OtherDbConfig.php new file mode 100644 index 0000000..85b2858 --- /dev/null +++ b/test/Testing/Pool/OtherDbConfig.php @@ -0,0 +1,81 @@ + + * [ + * '127.0.0.1:88', + * '127.0.0.1:88' + * ] + * + * + * @Value(name="${config.db.other.master.uri}", env="${DB_OTHER_URI}") + * @var array + */ + protected $uri = []; + + /** + * the default driver is consul mysql + * + * @Value(name="${config.db.other.master.driver}", env="${DB_OTHER_DRIVER}") + * @var string + */ + protected $driver = Driver::MYSQL; +} \ No newline at end of file diff --git a/test/Testing/Pool/OtherDbPool.php b/test/Testing/Pool/OtherDbPool.php new file mode 100644 index 0000000..6eeeef6 --- /dev/null +++ b/test/Testing/Pool/OtherDbPool.php @@ -0,0 +1,21 @@ + + * [ + * '127.0.0.1:88', + * '127.0.0.1:88' + * ] + * + * + * @Value(name="${config.db.other.slave.uri}", env="${DB_OTHER_SLAVE_URI}") + * @var array + */ + protected $uri = []; + + /** + * the default driver is mysql + * + * @Value(name="${config.db.other.slave.driver}", env="${DB_OTHER_SLAVE_DRIVER}") + * @var string + */ + protected $driver = Driver::MYSQL; +} \ No newline at end of file diff --git a/test/Testing/Pool/OtherDbSlavePool.php b/test/Testing/Pool/OtherDbSlavePool.php new file mode 100644 index 0000000..78daefa --- /dev/null +++ b/test/Testing/Pool/OtherDbSlavePool.php @@ -0,0 +1,22 @@ + [ - 'name' => 'master1', + 'name' => 'master1', "uri" => [ '127.0.0.1:3301', '127.0.0.1:3301', @@ -16,7 +16,7 @@ ], 'slave' => [ - 'name' => 'slave1', + 'name' => 'slave1', "uri" => [ '127.0.0.1:3301', '127.0.0.1:3301', @@ -29,4 +29,30 @@ "useProvider" => true, 'provider' => 'consul1', ], + + 'other' => [ + 'master' => [ + 'name' => 'master2', + "uri" => [ + '127.0.0.1:3301', + '127.0.0.1:3301', + ], + "maxIdel" => 1, + "maxActive" => 1, + "maxWait" => 1, + "timeout" => 1, + ], + + 'slave' => [ + 'name' => 'slave3', + "uri" => [ + '127.0.0.1:3301', + '127.0.0.1:3301', + ], + "maxIdel" => 1, + "maxActive" => 1, + "maxWait" => 1, + "timeout" => 1, + ], + ], ]; From 8c95fb6f154ef2d19ea90a9e93c9246d41cac4c4 Mon Sep 17 00:00:00 2001 From: lilin <794774870@qq.com> Date: Sun, 1 Apr 2018 23:20:24 +0800 Subject: [PATCH 05/27] add batch unit --- src/Executor.php | 12 ++++++ src/Model.php | 28 +++++++++---- src/QueryBuilder.php | 76 ++++++++++++------------------------ test/Cases/AggregateTest.php | 10 ++--- test/Cases/MysqlTest.php | 29 ++++++++++++++ test/Cases/StelinTest.php | 23 +++++++---- 6 files changed, 107 insertions(+), 71 deletions(-) diff --git a/src/Executor.php b/src/Executor.php index 541844a..c9c3f0e 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -30,6 +30,18 @@ public static function save($entity): ResultInterface return $query->insert($fields); } + /** + * @param string $className + * @param array $rows + * + * @return ResultInterface + */ + public static function batchInsert(string $className, array $rows): ResultInterface + { + $instance = self::getInstance($className); + return Query::table($className)->selectInstance($instance)->batchInsert($rows); + } + /** * @param object $entity * diff --git a/src/Model.php b/src/Model.php index 9805dc4..54b8351 100644 --- a/src/Model.php +++ b/src/Model.php @@ -32,7 +32,7 @@ public function __construct(array $attributes = []) * * @return ResultInterface */ - public function save() + public function save(): ResultInterface { return Executor::save($this); } @@ -42,12 +42,22 @@ public function save() * * @return ResultInterface */ - public function delete() + public function delete(): ResultInterface { return Executor::delete($this); } + /** + * @param array $rows + * + * @return ResultInterface + */ + public static function batchInsert(array $rows): ResultInterface + { + return Executor::batchInsert(static::class, $rows); + } + /** * Delete data by id * @@ -55,7 +65,7 @@ public function delete() * * @return ResultInterface */ - public static function deleteById($id) + public static function deleteById($id): ResultInterface { return Executor::deleteById(static::class, $id); } @@ -67,7 +77,7 @@ public static function deleteById($id) * * @return ResultInterface */ - public static function deleteByIds(array $ids) + public static function deleteByIds(array $ids): ResultInterface { return Executor::deleteByIds(static::class, $ids); } @@ -82,7 +92,7 @@ public function updateOne(array $attributes, array $condition) * * @return ResultInterface */ - public function update() + public function update(): ResultInterface { return Executor::update($this); } @@ -92,7 +102,7 @@ public function update() * * @return ResultInterface */ - public function find() + public function find(): ResultInterface { return Executor::find($this); } @@ -104,7 +114,7 @@ public function find() * * @return ResultInterface */ - public static function findById($id) + public static function findById($id): ResultInterface { return Executor::findById(static::class, $id); } @@ -116,7 +126,7 @@ public static function findById($id) * * @return ResultInterface */ - public static function findByIds(array $ids) + public static function findByIds(array $ids): ResultInterface { return Executor::findByIds(static::class, $ids); } @@ -153,6 +163,7 @@ public function setAttrs(array $attrs) * $attributes = [ * 'name' => $value * ] + * * @return \Swoft\Db\Model */ public function fill(array $attributes) @@ -163,6 +174,7 @@ public function fill(array $attributes) $this->$methodName($value); } } + return $this; } diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index caff48a..cbf2026 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -338,44 +338,6 @@ public function get(array $columns = ['*']): ResultInterface return $this->execute(); } - /** - * select语句 - * - * @param mixed $column - * @param string $alias - * - * @return QueryBuilder - */ - public function select($column, string $alias = null): QueryBuilder - { - if (is_array($column)) { - return $this->selects($column); - } - $this->select[$column] = $alias; - - return $this; - } - - /** - * select语句 - * - * @param array $columns - * - * @return QueryBuilder - */ - public function selects(array $columns): QueryBuilder - { - foreach ($columns as $key => $column) { - if (\is_int($key)) { - $this->select[$column] = null; - continue; - } - $this->select[$key] = $column; - } - - return $this; - } - /** * @param string $table * @param string $alias @@ -1001,56 +963,70 @@ public function force(bool $master = true) * @param string $column * @param string $alias * - * @return QueryBuilder + * @return ResultInterface */ - public function count(string $column = '*', string $alias = 'count') + public function count(string $column = '*', string $alias = 'count'):ResultInterface { $this->aggregate['count'] = [$column, $alias]; $this->limit(1); - return $this; + return $this->execute(); } /** * @param string $column * @param string $alias * - * @return QueryBuilder + * @return ResultInterface */ - public function max(string $column, string $alias = 'max') + public function max(string $column, string $alias = 'max'):ResultInterface { $this->aggregate['max'] = [$column, $alias]; $this->limit(1); - return $this; + return $this->execute(); } /** * @param string $column * @param string $alias * - * @return QueryBuilder + * @return ResultInterface + */ + public function min(string $column, string $alias = 'min'):ResultInterface + { + $this->aggregate['min'] = [$column, $alias]; + $this->limit(1); + + return $this->execute(); + } + + /** + * @param string $column + * @param string $alias + * + * @return ResultInterface */ - public function avg(string $column, string $alias = 'avg') + public function avg(string $column, string $alias = 'avg'):ResultInterface { $this->aggregate['avg'] = [$column, $alias]; $this->limit(1); - return $this; + return $this->execute(); } /** * @param string $column * @param string $alias * - * @return QueryBuilder + * @return ResultInterface */ - public function sum(string $column, string $alias = 'sum') + public function sum(string $column, string $alias = 'sum'):ResultInterface { $this->aggregate['sum'] = [$column, $alias]; $this->limit(1); - return $this; + return $this->execute(); } /** diff --git a/test/Cases/AggregateTest.php b/test/Cases/AggregateTest.php index 7c2119e..00ca679 100644 --- a/test/Cases/AggregateTest.php +++ b/test/Cases/AggregateTest.php @@ -17,7 +17,7 @@ class AggregateTest extends AbstractMysqlCase */ public function testCount(array $ids) { - $count = Query::table(User::class)->count('id', 'userCount')->execute()->getResult(); + $count = Query::table(User::class)->count('id', 'userCount')->getResult(); $countNum = $count['userCount']; $this->assertTrue($countNum >= 2); } @@ -41,7 +41,7 @@ public function testCountByCo(array $ids) */ public function testSum(array $ids) { - $ageNum = Query::table(User::class)->sum('age', 'ageNum')->execute()->getResult(); + $ageNum = Query::table(User::class)->sum('age', 'ageNum')->getResult(); $ageNum = $ageNum['ageNum']; $this->assertTrue($ageNum >= 0); } @@ -65,7 +65,7 @@ public function testSumByCo(array $ids) */ public function testMax(array $ids) { - $maxAge = Query::table(User::class)->max('age', 'maxAge')->execute()->getResult(); + $maxAge = Query::table(User::class)->max('age', 'maxAge')->getResult(); $maxAge = $maxAge['maxAge']; $this->assertTrue($maxAge >= 0); } @@ -89,7 +89,7 @@ public function testMaxByCo(array $ids) */ public function testMin(array $ids) { - $minAge = Query::table(User::class)->max('age', 'minAge')->execute()->getResult(); + $minAge = Query::table(User::class)->min('age', 'minAge')->getResult(); $minAge = $minAge['minAge']; $this->assertTrue($minAge >= 0); } @@ -113,7 +113,7 @@ public function testMinByCo(array $ids) */ public function testAvg(array $ids) { - $avgAge = Query::table(User::class)->avg('age', 'avgAge')->execute()->getResult(); + $avgAge = Query::table(User::class)->avg('age', 'avgAge')->getResult(); $avgAge = $avgAge['avgAge']; $this->assertTrue($avgAge >= 0); } diff --git a/test/Cases/MysqlTest.php b/test/Cases/MysqlTest.php index 61a2fa3..198fc55 100644 --- a/test/Cases/MysqlTest.php +++ b/test/Cases/MysqlTest.php @@ -30,6 +30,35 @@ public function testSaveByCo() }); } + + public function testBatchInsert() + { + $values = [ + [ + 'name' => 'stelin', + 'sex' => 1, + 'description' => 'this my desc', + 'age' => 99, + ], + [ + 'name' => 'stelin2', + 'sex' => 1, + 'description' => 'this my desc2', + 'age' => 100, + ] + ]; + + $result = User::batchInsert($values)->getResult(); + $this->assertTrue($result > 0); + } + + public function testBatchInsertByCo() + { + go(function (){ + $this->testBatchInsert(); + }); + } + /** * @dataProvider mysqlProvider * diff --git a/test/Cases/StelinTest.php b/test/Cases/StelinTest.php index d7a35c2..586d877 100644 --- a/test/Cases/StelinTest.php +++ b/test/Cases/StelinTest.php @@ -12,14 +12,21 @@ class StelinTest extends AbstractTestCase public function testAaa() { // $values = [ -// 'name' => 'stelin', -// 'sex' => 1, -// 'description' => 'this my desc', -// 'age' => 99, +// [ +// 'name' => 'stelin', +// 'sex' => 1, +// 'description' => 'this my desc', +// 'age' => 99, +// ], +// [ +// 'name' => 'stelin2', +// 'sex' => 1, +// 'description' => 'this my desc2', +// 'age' => 100, +// ] // ]; -// $result = Query::table(User::class)->insert($values)->execute()->getResult(); -// var_dump(get_last_sql()); -// $user = User::findById($result)->getResult(); -// $this->assertCount(5, $user); +// +// $result = User::batchInsert($values)->getResult(); +// var_dump($result); } } \ No newline at end of file From 61896acfa8178507436b7a302d3051d88f8114af Mon Sep 17 00:00:00 2001 From: lilin <794774870@qq.com> Date: Sun, 1 Apr 2018 23:25:28 +0800 Subject: [PATCH 06/27] refactor unit --- .../ActiveRecordTest.php} | 5 +++-- test/Cases/{ => Mysql}/AggregateTest.php | 3 ++- .../{QueryTest.php => Mysql/QueryBuildTest.php} | 16 +++++++++------- .../{SqlMysqlTest.php => Mysql/SqlTest.php} | 5 +++-- test/Cases/{ => Mysql}/TrasactionTest.php | 3 ++- 5 files changed, 19 insertions(+), 13 deletions(-) rename test/Cases/{MysqlTest.php => Mysql/ActiveRecordTest.php} (98%) rename test/Cases/{ => Mysql}/AggregateTest.php (97%) rename test/Cases/{QueryTest.php => Mysql/QueryBuildTest.php} (93%) rename test/Cases/{SqlMysqlTest.php => Mysql/SqlTest.php} (95%) rename test/Cases/{ => Mysql}/TrasactionTest.php (95%) diff --git a/test/Cases/MysqlTest.php b/test/Cases/Mysql/ActiveRecordTest.php similarity index 98% rename from test/Cases/MysqlTest.php rename to test/Cases/Mysql/ActiveRecordTest.php index 198fc55..6166e21 100644 --- a/test/Cases/MysqlTest.php +++ b/test/Cases/Mysql/ActiveRecordTest.php @@ -1,14 +1,15 @@ testDbSelect($id); }); } @@ -76,7 +77,7 @@ public function testDbUpdate(int $id) */ public function testDbUpdateByCo(int $id) { - go(function ()use ($id){ + go(function () use ($id) { $this->testDbUpdate($id); }); } @@ -97,7 +98,7 @@ public function testDbInsert() public function testDbInsertByCo() { - go(function (){ + go(function () { $this->testDbInsert(); }); } @@ -118,9 +119,10 @@ public function testSelectDb() $this->assertEquals($user2['description'], 'this my desc table'); $this->assertEquals($user2['id'], $userid); } + public function testSelectDbByCo() { - go(function (){ + go(function () { $this->testSelectDb(); }); } @@ -142,7 +144,7 @@ public function testSelectTable() public function testSelectTableByCo() { - go(function (){ + go(function () { $this->testSelectTable(); }); } diff --git a/test/Cases/SqlMysqlTest.php b/test/Cases/Mysql/SqlTest.php similarity index 95% rename from test/Cases/SqlMysqlTest.php rename to test/Cases/Mysql/SqlTest.php index 48e8882..bedcdfc 100644 --- a/test/Cases/SqlMysqlTest.php +++ b/test/Cases/Mysql/SqlTest.php @@ -1,14 +1,15 @@ Date: Mon, 2 Apr 2018 00:09:01 +0800 Subject: [PATCH 07/27] add condition --- src/QueryBuilder.php | 71 ++++++++++++++++++++++++++++---- test/Cases/AbstractMysqlCase.php | 1 - 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index cbf2026..31ec874 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -432,7 +432,7 @@ public function where(string $column, $value, $operator = self::OPERATOR_EQ, $co * - ['status' => null] => ('status' is null) * * Format `[operator, operand1, operand2, ...]` - * - ['>', 'id', 12] / ['id' => ['$gt' => xxx ]] + * - ['>', 'id', 12] * - ['<', 'id', 13] * - ['>=', 'id', 13] * - ['<=', 'id', 13] @@ -448,16 +448,71 @@ public function where(string $column, $value, $operator = self::OPERATOR_EQ, $co * - ['not like', 'name', '%swoft%'] * * - * @param mixed $condition + * @param array $condition * @param string $connector * * @return \Swoft\Db\QueryBuilder */ - public function condition($condition, $connector = self::LOGICAL_AND) + public function condition(array $condition, $connector = self::LOGICAL_AND) { + $this->openWhere($connector); + foreach ($condition as $key => $value) { + if (\is_int($key)) { + $this->andCondition($condition); + break; + } + $this->operatorCondition($condition); + break; + } + $this->closeWhere(); + return $this; } + /** + * @param array $condition + */ + public function operatorCondition(array $condition) + { + foreach ($condition as $column => $value) { + if (is_array($value)) { + $this->whereIn($column, $value); + continue; + } + $this->andWhere($column, $value); + } + } + + /** + * @param array $condition + */ + public function andCondition(array $condition) + { + list($operator) = $condition; + $operator = strtoupper($operator); + switch ($operator) { + case self::OPERATOR_EQ: + case self::OPERATOR_GT: + case self::OPERATOR_NE: + case self::OPERATOR_LT: + case self::OPERATOR_LTE: + case self::OPERATOR_GTE: + case self::IN: + case self::NOT_IN: + list($operator, $column, $value) = $condition; + $this->andWhere($column, $value, $operator); + break; + case self::BETWEEN: + list(, $column, $min, $max) = $condition; + $this->whereBetween($column, $min, $max); + break; + case self::NOT_BETWEEN: + list(, $column, $min, $max) = $condition; + $this->whereNotBetween($column, $min, $max); + break; + } + } + /** * where and 语句 * @@ -965,7 +1020,7 @@ public function force(bool $master = true) * * @return ResultInterface */ - public function count(string $column = '*', string $alias = 'count'):ResultInterface + public function count(string $column = '*', string $alias = 'count'): ResultInterface { $this->aggregate['count'] = [$column, $alias]; $this->limit(1); @@ -979,7 +1034,7 @@ public function count(string $column = '*', string $alias = 'count'):ResultInter * * @return ResultInterface */ - public function max(string $column, string $alias = 'max'):ResultInterface + public function max(string $column, string $alias = 'max'): ResultInterface { $this->aggregate['max'] = [$column, $alias]; $this->limit(1); @@ -993,7 +1048,7 @@ public function max(string $column, string $alias = 'max'):ResultInterface * * @return ResultInterface */ - public function min(string $column, string $alias = 'min'):ResultInterface + public function min(string $column, string $alias = 'min'): ResultInterface { $this->aggregate['min'] = [$column, $alias]; $this->limit(1); @@ -1007,7 +1062,7 @@ public function min(string $column, string $alias = 'min'):ResultInterface * * @return ResultInterface */ - public function avg(string $column, string $alias = 'avg'):ResultInterface + public function avg(string $column, string $alias = 'avg'): ResultInterface { $this->aggregate['avg'] = [$column, $alias]; $this->limit(1); @@ -1021,7 +1076,7 @@ public function avg(string $column, string $alias = 'avg'):ResultInterface * * @return ResultInterface */ - public function sum(string $column, string $alias = 'sum'):ResultInterface + public function sum(string $column, string $alias = 'sum'): ResultInterface { $this->aggregate['sum'] = [$column, $alias]; $this->limit(1); diff --git a/test/Cases/AbstractMysqlCase.php b/test/Cases/AbstractMysqlCase.php index d5abc63..bc1e338 100644 --- a/test/Cases/AbstractMysqlCase.php +++ b/test/Cases/AbstractMysqlCase.php @@ -2,7 +2,6 @@ namespace Swoft\Db\Test\Cases; -use Swoft\Db\Pool; use Swoft\Db\Test\Testing\Entity\User; /** From 8a4c5062946d73a3bf480c589bd3d44850e09e72 Mon Sep 17 00:00:00 2001 From: lilin <794774870@qq.com> Date: Mon, 9 Apr 2018 17:01:24 +0800 Subject: [PATCH 08/27] remove className --- src/Db.php | 4 +++- src/DbCoResult.php | 3 +-- src/DbDataResult.php | 4 +--- src/DbResult.php | 17 +++++++++++++++-- src/Executor.php | 23 +++++++++++++---------- src/QueryBuilder.php | 19 ++++++++++++++++++- test/Cases/EntityTest.php | 6 +++--- test/Cases/Mysql/ActiveRecordTest.php | 16 ++++++++-------- test/Cases/Mysql/QueryBuildTest.php | 10 ++++------ 9 files changed, 66 insertions(+), 36 deletions(-) diff --git a/src/Db.php b/src/Db.php index 42ca8b3..b1000fe 100644 --- a/src/Db.php +++ b/src/Db.php @@ -43,10 +43,11 @@ class Db * @param string $sql * @param array $params * @param string $instance + * @param string $className * * @return ResultInterface */ - public static function query(string $sql, array $params = [], string $instance = Pool::INSTANCE): ResultInterface + public static function query(string $sql, array $params = [], string $instance = Pool::INSTANCE, string $className = ''): ResultInterface { $type = self::getOperation($sql); $instance = explode('.', $instance); @@ -74,6 +75,7 @@ public static function query(string $sql, array $params = [], string $instance = $dbResult = self::getResult($result, $connection, $profileKey); $dbResult->setType($type); + $dbResult->setClassName($className); return $dbResult; } diff --git a/src/DbCoResult.php b/src/DbCoResult.php index 2401dd3..a2d5d9e 100644 --- a/src/DbCoResult.php +++ b/src/DbCoResult.php @@ -17,9 +17,8 @@ class DbCoResult extends DbResult */ public function getResult(...$params) { - list($className) = array_pad($params, 1, ''); $this->recv(true, false); - $result = $this->getResultByClass($className); + $result = $this->getResultByClassName(); $this->release(); return $result; diff --git a/src/DbDataResult.php b/src/DbDataResult.php index aebe8c9..0333247 100644 --- a/src/DbDataResult.php +++ b/src/DbDataResult.php @@ -14,9 +14,7 @@ class DbDataResult extends DbResult */ public function getResult(...$params) { - list($className) = array_pad($params, 1, ''); - $result = $this->getResultByClass($className); - + $result = $this->getResultByClassName(); $this->release(); return $result; diff --git a/src/DbResult.php b/src/DbResult.php index 989fb40..45f1b29 100644 --- a/src/DbResult.php +++ b/src/DbResult.php @@ -17,6 +17,11 @@ abstract class DbResult extends AbstractResult */ protected $type; + /** + * @var string + */ + protected $className = ''; + /** * @param int $type */ @@ -27,12 +32,20 @@ public function setType(int $type) /** * @param string $className - * + */ + public function setClassName(string $className) + { + $this->className = $className; + } + + /** * @return mixed */ - protected function getResultByClass(string $className) + protected function getResultByClassName() { + $className = $this->className; $result = $this->getResultByType(); + if (isset($result[0]) && !empty($className)) { $result = EntityHelper::listToEntity($result, $className); } diff --git a/src/Executor.php b/src/Executor.php index c9c3f0e..0c25ff3 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -21,8 +21,9 @@ class Executor */ public static function save($entity): ResultInterface { + $className = get_class($entity); list($table, , , $fields) = self::getFields($entity, 1); - $instance = self::getInstance(get_class($entity)); + $instance = self::getInstance($className); $fields = $fields ?? []; $query = Query::table($table)->selectInstance($instance); @@ -49,8 +50,9 @@ public static function batchInsert(string $className, array $rows): ResultInterf */ public static function delete($entity): ResultInterface { + $className = get_class($entity); list($table, , , $fields) = self::getFields($entity, 3); - $instance = self::getInstance(get_class($entity)); + $instance = self::getInstance($className); $query = Query::table($table)->selectInstance($instance); foreach ($fields ?? [] as $column => $value) { @@ -123,14 +125,14 @@ public function deleteAll(string $className, array $condition) */ public static function update($entity): ResultInterface { - // 实体映射数据 + $className = get_class($entity); list($table, $idColumn, $idValue, $fields) = self::getFields($entity, 2); if (empty($fields)) { return new DbDataResult(0); } // 构建update查询器 - $instance = self::getInstance(get_class($entity)); + $instance = self::getInstance($className); $fields = $fields ?? []; $query = Query::table($table)->where($idColumn, $idValue)->selectInstance($instance); @@ -170,10 +172,11 @@ public static function updateAll(string $className, array $attributes, array $co */ public static function find($entity): ResultInterface { + $className = get_class($entity); list($tableName, , , $fields) = self::getFields($entity, 3); - $instance = self::getInstance(get_class($entity)); + $instance = self::getInstance($className); - $query = Query::table($tableName)->selectInstance($instance); + $query = Query::table($tableName)->className($className)->selectInstance($instance); foreach ($fields ?? [] as $column => $value) { $query->where($column, $value); } @@ -192,7 +195,7 @@ public static function findById($className, $id): ResultInterface list($tableName, , $columnId) = self::getTable($className); $instance = self::getInstance($className); - $query = Query::table($tableName)->where($columnId, $id)->limit(1)->selectInstance($instance); + $query = Query::table($tableName)->className($className)->where($columnId, $id)->limit(1)->selectInstance($instance); return $query->get(); } @@ -208,7 +211,7 @@ public static function findByIds($className, array $ids): ResultInterface list($tableName, , $columnId) = self::getTable($className); $instance = self::getInstance($className); - $query = Query::table($tableName)->whereIn($columnId, $ids)->selectInstance($instance); + $query = Query::table($tableName)->className($className)->whereIn($columnId, $ids)->selectInstance($instance); return $query->get(); } @@ -223,7 +226,7 @@ public static function findByIds($className, array $ids): ResultInterface public static function findOne(string $className, array $condition = [], array $orderBy = []) { $instance = self::getInstance($className); - $query = Query::table($className)->selectInstance($instance)->delete(); + $query = Query::table($className)->className($className)->selectInstance($instance)->delete(); if (!empty($condition)) { $query = $query->condition($condition); @@ -248,7 +251,7 @@ public static function findOne(string $className, array $condition = [], array $ public function findAll(string $className, array $condition = [], array $orderBy = [], int $limit = 20, int $offset = 0) { $instance = self::getInstance($className); - $query = Query::table($className)->selectInstance($instance)->delete(); + $query = Query::table($className)->className($className)->selectInstance($instance)->delete(); if (!empty($condition)) { $query = $query->condition($condition); diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 31ec874..d078554 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -259,6 +259,11 @@ class QueryBuilder implements QueryBuilderInterface */ protected $aggregate = []; + /** + * @var string + */ + protected $className = ''; + /** * @param array $values * @@ -988,6 +993,18 @@ public function selectNode(string $node = Pool::MASTER) return $this; } + /** + * @param string $className + * + * @return QueryBuilder + */ + public function className(string $className) + { + $this->className = $className; + + return $this; + } + /** * @param string $instance * @@ -1095,7 +1112,7 @@ public function execute() $sql = $statement->getStatement(); $instanceName = $this->getInstanceName(); - return Db::query($sql, $this->parameters, $instanceName); + return Db::query($sql, $this->parameters, $instanceName, $this->className); } /** diff --git a/test/Cases/EntityTest.php b/test/Cases/EntityTest.php index 2b2a493..21d764c 100644 --- a/test/Cases/EntityTest.php +++ b/test/Cases/EntityTest.php @@ -70,7 +70,7 @@ public function testArrayAccess() */ public function testIterator($id) { - $user = User::findById($id)->getResult(User::class); + $user = User::findById($id)->getResult(); $data = []; foreach ($user as $key => $value) { $data[$key] = $value; @@ -94,7 +94,7 @@ public function testArrayAttr() $resultUser = User::findById($result)->getResult(); $this->assertEquals('stelin', $resultUser['name']); $this->assertEquals(1, $resultUser['sex']); - $this->assertEquals('desc2', $resultUser['description']); + $this->assertEquals('desc2', $resultUser['desc']); $this->assertEquals(100, $resultUser['age']); @@ -109,7 +109,7 @@ public function testArrayAttr() $this->assertEquals('stelin2', $resultUser2['name']); $this->assertEquals(1, $resultUser2['sex']); - $this->assertEquals('this my desc9', $resultUser2['description']); + $this->assertEquals('this my desc9', $resultUser2['desc']); $this->assertEquals(99, $resultUser2['age']); } } \ No newline at end of file diff --git a/test/Cases/Mysql/ActiveRecordTest.php b/test/Cases/Mysql/ActiveRecordTest.php index 6166e21..8f717e7 100644 --- a/test/Cases/Mysql/ActiveRecordTest.php +++ b/test/Cases/Mysql/ActiveRecordTest.php @@ -68,7 +68,7 @@ public function testBatchInsertByCo() public function testDelete(int $id) { /* @var User $user */ - $user = User::findById($id)->getResult(User::class); + $user = User::findById($id)->getResult(); $result = $user->delete()->getResult(); $this->assertEquals(1, $result); } @@ -141,12 +141,12 @@ public function testUpdate(int $id) $newName = 'swoft framewrok'; /* @var User $user */ - $user = User::findById($id)->getResult(User::class); + $user = User::findById($id)->getResult(); $user->setName($newName); $user->update()->getResult(); /* @var User $newUser */ - $newUser = User::findById($id)->getResult(User::class); + $newUser = User::findById($id)->getResult(); $this->assertEquals($newName, $newUser->getName()); } @@ -173,7 +173,7 @@ public function testFindById(int $id) $user = User::findById($id)->getResult(); $userEmpty = User::findById(99999999999)->getResult(); $this->assertEquals($id, $user['id']); - $this->assertEquals($userEmpty, []); + $this->assertEquals($userEmpty, null); } /** @@ -196,8 +196,8 @@ public function testFindByIdByCo(int $id) public function testFindByIdClass(int $id) { /* @var User $user */ - $user = User::findById($id)->getResult(User::class); - $userEmpty = User::findById(99999999999)->getResult(User::class); + $user = User::findById($id)->getResult(); + $userEmpty = User::findById(99999999999)->getResult(); $this->assertEquals($id, $user->getId()); $this->assertEquals($userEmpty, null); } @@ -251,8 +251,8 @@ public function testFindByIdsByCo(array $ids) */ public function testFindByIdsByClass(array $ids) { - $users = User::findByIds($ids)->getResult(User::class); - $userEmpty = User::findByIds([999999999999])->getResult(User::class); + $users = User::findByIds($ids)->getResult(); + $userEmpty = User::findByIds([999999999999])->getResult(); $resultIds = []; /* @var User $user */ diff --git a/test/Cases/Mysql/QueryBuildTest.php b/test/Cases/Mysql/QueryBuildTest.php index f375136..0812935 100644 --- a/test/Cases/Mysql/QueryBuildTest.php +++ b/test/Cases/Mysql/QueryBuildTest.php @@ -113,7 +113,7 @@ public function testSelectDb() ]; $userid = Query::table(User::class)->selectDb('test2')->insert($data)->getResult(); - $user = User::findById($userid)->getResult(User::class); + $user = User::findById($userid)->getResult(); $user2 = Query::table(User::class)->selectDb('test2')->where('id', $userid)->limit(1)->get()->getResult(); $this->assertEquals($user2['description'], 'this my desc table'); @@ -136,10 +136,8 @@ public function testSelectTable() 'age' => mt_rand(1, 100), ]; $result = Query::table('user2')->insert($data)->getResult(); - - /* @var User $user2 */ - $user2 = Query::table('user2')->where('id', $result)->limit(1)->get()->getResult(User::class); - $this->assertEquals($user2->getId(), $result); + $user2 = Query::table('user2')->where('id', $result)->limit(1)->get()->getResult(); + $this->assertEquals($user2['id'], $result); } public function testSelectTableByCo() @@ -159,7 +157,7 @@ public function testSelectinstance() ]; $userid = Query::table(User::class)->selectInstance('other')->insert($data)->getResult(); - $user = OtherUser::findById($userid)->getResult(User::class); + $user = OtherUser::findById($userid)->getResult(); $user2 = Query::table(User::class)->selectInstance('other')->where('id', $userid)->limit(1)->get()->getResult(); $this->assertEquals($user2['description'], 'this my desc instance'); $this->assertEquals($user2['id'], $userid); From 5cd22b0155dbb4b5d865e9562556a6b28ca1eb9f Mon Sep 17 00:00:00 2001 From: lilin <794774870@qq.com> Date: Mon, 9 Apr 2018 20:10:40 +0800 Subject: [PATCH 09/27] add AR --- src/DbResult.php | 4 +- src/Executor.php | 14 +-- src/Model.php | 65 +++++++++++++- src/QueryBuilder.php | 44 +++++----- src/Statement.php | 6 ++ test/Cases/AbstractMysqlCase.php | 4 +- test/Cases/EntityTest.php | 20 ++--- test/Cases/Mysql/ActiveRecordTest.php | 80 ++++++++++++++++- test/Cases/Mysql/QueryBuildTest.php | 119 ++++++++++++++++++++++++-- test/Cases/Mysql/TrasactionTest.php | 4 +- test/Cases/StelinTest.php | 32 ------- 11 files changed, 305 insertions(+), 87 deletions(-) delete mode 100644 test/Cases/StelinTest.php diff --git a/src/DbResult.php b/src/DbResult.php index 45f1b29..9aba53a 100644 --- a/src/DbResult.php +++ b/src/DbResult.php @@ -47,11 +47,11 @@ protected function getResultByClassName() $result = $this->getResultByType(); if (isset($result[0]) && !empty($className)) { - $result = EntityHelper::listToEntity($result, $className); + return EntityHelper::listToEntity($result, $className); } if (is_array($result) && !empty($result) && !empty($className)) { - $result = EntityHelper::arrayToEntity($result, $className); + return EntityHelper::arrayToEntity($result, $className); } if (!empty($className) && $this->type == Db::RETURN_FETCH && empty($result)) { diff --git a/src/Executor.php b/src/Executor.php index 0c25ff3..8ae45ad 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -100,7 +100,7 @@ public static function deleteByIds($className, array $ids): ResultInterface * * @return ResultInterface */ - public function deleteOne(string $className, array $condition) + public static function deleteOne(string $className, array $condition) { $instance = self::getInstance($className); return Query::table($className)->selectInstance($instance)->condition($condition)->limit(1)->delete(); @@ -112,7 +112,7 @@ public function deleteOne(string $className, array $condition) * * @return ResultInterface */ - public function deleteAll(string $className, array $condition) + public static function deleteAll(string $className, array $condition) { $instance = self::getInstance($className); return Query::table($className)->selectInstance($instance)->condition($condition)->delete(); @@ -226,7 +226,7 @@ public static function findByIds($className, array $ids): ResultInterface public static function findOne(string $className, array $condition = [], array $orderBy = []) { $instance = self::getInstance($className); - $query = Query::table($className)->className($className)->selectInstance($instance)->delete(); + $query = Query::table($className)->className($className)->selectInstance($instance); if (!empty($condition)) { $query = $query->condition($condition); @@ -236,7 +236,7 @@ public static function findOne(string $className, array $condition = [], array $ $query = $query->orderBy($column, $order); } - return $query->limit(1)->execute(); + return $query->limit(1)->get(); } /** @@ -248,10 +248,10 @@ public static function findOne(string $className, array $condition = [], array $ * * @return ResultInterface */ - public function findAll(string $className, array $condition = [], array $orderBy = [], int $limit = 20, int $offset = 0) + public static function findAll(string $className, array $condition = [], array $orderBy = [], int $limit = 20, int $offset = 0) { $instance = self::getInstance($className); - $query = Query::table($className)->className($className)->selectInstance($instance)->delete(); + $query = Query::table($className)->className($className)->selectInstance($instance); if (!empty($condition)) { $query = $query->condition($condition); @@ -261,7 +261,7 @@ public function findAll(string $className, array $condition = [], array $orderBy $query = $query->orderBy($column, $order); } - return $query->limit($limit, $offset)->execute(); + return $query->limit($limit, $offset)->get(); } /** diff --git a/src/Model.php b/src/Model.php index 54b8351..dfa41a6 100644 --- a/src/Model.php +++ b/src/Model.php @@ -48,6 +48,26 @@ public function delete(): ResultInterface return Executor::delete($this); } + /** + * @param array $condition + * + * @return ResultInterface + */ + public static function deleteOne(array $condition): ResultInterface + { + return Executor::deleteOne(static::class, $condition); + } + + /** + * @param array $condition + * + * @return ResultInterface + */ + public static function deleteAll(array $condition): ResultInterface + { + return Executor::deleteAll(static::class, $condition); + } + /** * @param array $rows * @@ -82,9 +102,26 @@ public static function deleteByIds(array $ids): ResultInterface return Executor::deleteByIds(static::class, $ids); } - public function updateOne(array $attributes, array $condition) + /** + * @param array $attributes + * @param array $condition + * + * @return ResultInterface + */ + public static function updateOne(array $attributes, array $condition): ResultInterface { + return Executor::updateOne(static::class, $attributes, $condition); + } + /** + * @param array $attributes + * @param array $condition + * + * @return ResultInterface + */ + public static function updateAll(array $attributes, array $condition): ResultInterface + { + return Executor::updateAll(static::class, $attributes, $condition); } /** @@ -107,6 +144,30 @@ public function find(): ResultInterface return Executor::find($this); } + /** + * @param array $condition + * @param array $orderBy + * + * @return ResultInterface + */ + public static function findOne(array $condition, array $orderBy = []): ResultInterface + { + return Executor::findOne(static::class, $condition, $orderBy); + } + + /** + * @param array $condition + * @param array $orderBy + * @param int $limit + * @param int $offset + * + * @return ResultInterface + */ + public static function findAll(array $condition = [], array $orderBy = [], int $limit = 20, int $offset = 0): ResultInterface + { + return Executor::findAll(static::class, $condition, $orderBy, $limit, $offset); + } + /** * Find by id * @@ -138,7 +199,7 @@ public static function findByIds(array $ids): ResultInterface */ public static function query(): QueryBuilder { - return Query::table(static::class); + return Query::table(static::class)->className(static::class); } /** diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index d078554..a542559 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -434,33 +434,30 @@ public function where(string $column, $value, $operator = self::OPERATOR_EQ, $co * Format `['column1' => value1, 'column2' => value2, ...]` * - ['name' => 'swoft', 'status' => 1] => ('name'='swoft' and 'status' = 1) * - ['id' => [1, 2, 3], 'status' => 1] => ('id' in (1, 2, 3) and 'status' = 1) - * - ['status' => null] => ('status' is null) * * Format `[operator, operand1, operand2, ...]` - * - ['>', 'id', 12] - * - ['<', 'id', 13] - * - ['>=', 'id', 13] - * - ['<=', 'id', 13] - * - ['<>', 'id', 13] + * - ['id', '>', 12] + * - ['id', '<', 13] + * - ['id', '>=', 13] + * - ['id', '<=', 13] + * - ['id', '<>', 13] * - * - ['in', 'id', [1, 2, 3]] - * - ['not in', 'id', [1, 2, 3]] + * - ['id', 'in', [1, 2, 3]] + * - ['id', 'not in', [1, 2, 3]] * - * - ['between', 'id', 2, 3] - * - ['not between', 'id', 2, 3] + * - ['id', 'between', 2, 3] + * - ['id', 'not between', 2, 3] * - * - ['like', 'name', '%swoft%'] - * - ['not like', 'name', '%swoft%'] + * - ['name', 'like', '%swoft%'] + * - ['name', 'not like', '%swoft%'] * * * @param array $condition - * @param string $connector * * @return \Swoft\Db\QueryBuilder */ - public function condition(array $condition, $connector = self::LOGICAL_AND) + public function condition(array $condition) { - $this->openWhere($connector); foreach ($condition as $key => $value) { if (\is_int($key)) { $this->andCondition($condition); @@ -469,7 +466,6 @@ public function condition(array $condition, $connector = self::LOGICAL_AND) $this->operatorCondition($condition); break; } - $this->closeWhere(); return $this; } @@ -493,7 +489,7 @@ public function operatorCondition(array $condition) */ public function andCondition(array $condition) { - list($operator) = $condition; + list(, $operator) = $condition; $operator = strtoupper($operator); switch ($operator) { case self::OPERATOR_EQ: @@ -502,17 +498,23 @@ public function andCondition(array $condition) case self::OPERATOR_LT: case self::OPERATOR_LTE: case self::OPERATOR_GTE: + list($column, $operator, $value) = $condition; + $this->andWhere($column, $value, $operator); + break; case self::IN: + list($column, $operator, $value) = $condition; + $this->whereIn($column, $value, $operator); + break; case self::NOT_IN: - list($operator, $column, $value) = $condition; - $this->andWhere($column, $value, $operator); + list($column, $operator, $value) = $condition; + $this->whereNotIn($column, $value, $operator); break; case self::BETWEEN: - list(, $column, $min, $max) = $condition; + list($column, , $min, $max) = $condition; $this->whereBetween($column, $min, $max); break; case self::NOT_BETWEEN: - list(, $column, $min, $max) = $condition; + list($column, , $min, $max) = $condition; $this->whereNotBetween($column, $min, $max); break; } diff --git a/src/Statement.php b/src/Statement.php index 12efe73..657e51f 100644 --- a/src/Statement.php +++ b/src/Statement.php @@ -573,9 +573,15 @@ protected function getLimitString(): string return $statement; } + $isUpdateOrDelete = $this->isDelete() || $this->isUpdate(); + if ($isUpdateOrDelete && $limit['limit']) { + return sprintf('LIMIT %d', $limit['limit']); + } + $limit = $limit['limit']; $offset = $limit['offset']; $statement = sprintf('LIMIT %d,%d', $offset, $limit); + return $statement; } diff --git a/test/Cases/AbstractMysqlCase.php b/test/Cases/AbstractMysqlCase.php index bc1e338..ac1ce9a 100644 --- a/test/Cases/AbstractMysqlCase.php +++ b/test/Cases/AbstractMysqlCase.php @@ -12,7 +12,7 @@ abstract class AbstractMysqlCase extends AbstractTestCase public function addUsers() { $user = new User(); - $user->setName('stelin'); + $user->setName('name'); $user->setSex(1); $user->setDesc('this my desc'); $user->setAge(mt_rand(1, 100)); @@ -27,7 +27,7 @@ public function addUsers() public function addUser() { $user = new User(); - $user->setName('stelin'); + $user->setName('name'); $user->setSex(1); $user->setDesc('this my desc'); $user->setAge(mt_rand(1, 100)); diff --git a/test/Cases/EntityTest.php b/test/Cases/EntityTest.php index 21d764c..a1178b2 100644 --- a/test/Cases/EntityTest.php +++ b/test/Cases/EntityTest.php @@ -13,7 +13,7 @@ public function testToArray() $age = mt_rand(1, 100); $user = new User(); $user->setId(12); - $user->setName('stelin'); + $user->setName('name'); $user->setSex(1); $user->setDesc('this my desc'); $user->setAge($age); @@ -22,7 +22,7 @@ public function testToArray() $data = [ 'id' => 12, - 'name' => 'stelin', + 'name' => 'name', 'sex' => 1, 'desc' => 'this my desc', 'age' => $age, @@ -35,14 +35,14 @@ public function testToJson() $age = mt_rand(1, 100); $user = new User(); $user->setId(12); - $user->setName('stelin'); + $user->setName('name'); $user->setSex(1); $user->setDesc('this my desc'); $user->setAge($age); $json = $user->toJson(); $string = $user->__toString(); - $data = '{"id":12,"name":"stelin","age":' . $age . ',"sex":1,"desc":"this my desc"}'; + $data = '{"id":12,"name":"name","age":' . $age . ',"sex":1,"desc":"this my desc"}'; $this->assertEquals($data, $json); $this->assertEquals($data, $string); } @@ -52,13 +52,13 @@ public function testArrayAccess() $age = mt_rand(1, 100); $user = new User(); $user->setId(12); - $user->setName('stelin'); + $user->setName('name'); $user->setSex(1); $user->setDesc('this my desc'); $user['age'] = $age; - $this->assertEquals('stelin', $user['name']); + $this->assertEquals('name', $user['name']); $this->assertEquals($age, $user['age']); $this->assertTrue(isset($user['sex'])); } @@ -82,7 +82,7 @@ public function testIterator($id) public function testArrayAttr() { $data = [ - 'name' => 'stelin', + 'name' => 'name', 'sex' => 1, 'desc' => 'desc2', 'age' => 100, @@ -92,14 +92,14 @@ public function testArrayAttr() $result = $user->fill($data)->save()->getResult(); $resultUser = User::findById($result)->getResult(); - $this->assertEquals('stelin', $resultUser['name']); + $this->assertEquals('name', $resultUser['name']); $this->assertEquals(1, $resultUser['sex']); $this->assertEquals('desc2', $resultUser['desc']); $this->assertEquals(100, $resultUser['age']); $user2 = new User(); - $user2['name'] = 'stelin2'; + $user2['name'] = 'name2'; $user2['sex'] = 1; $user2['desc'] = 'this my desc9'; $user2['age'] = 99; @@ -107,7 +107,7 @@ public function testArrayAttr() $result2 = $user2->save()->getResult(); $resultUser2 = User::findById($result2)->getResult(); - $this->assertEquals('stelin2', $resultUser2['name']); + $this->assertEquals('name2', $resultUser2['name']); $this->assertEquals(1, $resultUser2['sex']); $this->assertEquals('this my desc9', $resultUser2['desc']); $this->assertEquals(99, $resultUser2['age']); diff --git a/test/Cases/Mysql/ActiveRecordTest.php b/test/Cases/Mysql/ActiveRecordTest.php index 8f717e7..714bd4c 100644 --- a/test/Cases/Mysql/ActiveRecordTest.php +++ b/test/Cases/Mysql/ActiveRecordTest.php @@ -2,6 +2,7 @@ namespace Swoft\Db\Test\Cases\Mysql; +use Swoft\Db\Query; use Swoft\Db\QueryBuilder; use Swoft\Db\Test\Testing\Entity\User; use Swoft\Db\Test\Cases\AbstractMysqlCase; @@ -14,7 +15,7 @@ class ActiveRecordTest extends AbstractMysqlCase public function testSave() { $user = new User(); - $user->setName('stelin'); + $user->setName('name'); $user->setSex(1); $user->setDesc('this my desc'); $user->setAge(mt_rand(1, 100)); @@ -36,13 +37,13 @@ public function testBatchInsert() { $values = [ [ - 'name' => 'stelin', + 'name' => 'name', 'sex' => 1, 'description' => 'this my desc', 'age' => 99, ], [ - 'name' => 'stelin2', + 'name' => 'name2', 'sex' => 1, 'description' => 'this my desc2', 'age' => 100, @@ -297,4 +298,77 @@ public function testQueryByCo(array $ids) $this->testQuery($ids); }); } + + public function testDeleteOne() + { + $user = new User(); + $user['name'] = 'name2testDeleteOne'; + $user['sex'] = 1; + $user['desc'] = 'this my desc9'; + $user['age'] = 99; + + $uid = $user->save()->getResult(); + $result = User::deleteOne(['name' => 'name2testDeleteOne', 'age' => 99, 'id' => $uid])->getResult(); + $this->assertEquals($result, 1); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testDeleteAll(array $ids) + { + $result = User::deleteAll(['name' => 'name', 'id' => $ids])->getResult(); + $this->assertEquals(2,$result); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testUpdateOne(int $id) + { + $result = User::updateOne(['name' => 'testUpdateOne'], ['id' => $id])->getResult(); + $user = User::findById($id)->getResult(); + $this->assertEquals(1, $result); + $this->assertEquals($user['name'], 'testUpdateOne'); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testUpdateAll(array $ids) + { + $result = User::updateAll(['name' => 'testUpdateAll'], ['id' => $ids])->getResult(); + $count = User::findAll(['name' => 'testUpdateAll', 'id' => $ids])->getResult(); + $this->assertEquals(2,$result); + $this->assertCount(2,$count); + } + + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testFindOne(int $id) + { + $user = User::findOne(['id' => $id, 'name' => 'name'], ['id'=> 'desc', 'age' => 'desc'])->getResult(); + $this->assertEquals($id, $user['id']); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testFindAll(array $ids) + { + $result = User::findAll(['name' => 'name', 'id' => $ids], ['id' => 'desc'], 2, 0)->getResult(); + $this->assertCount(2,$result); + } } \ No newline at end of file diff --git a/test/Cases/Mysql/QueryBuildTest.php b/test/Cases/Mysql/QueryBuildTest.php index 0812935..f3905b8 100644 --- a/test/Cases/Mysql/QueryBuildTest.php +++ b/test/Cases/Mysql/QueryBuildTest.php @@ -65,9 +65,9 @@ public function testDbDeleteByCo(int $id) */ public function testDbUpdate(int $id) { - $result = Query::table(User::class)->where('id', $id)->update(['name' => 'stelin666'])->getResult(); + $result = Query::table(User::class)->where('id', $id)->update(['name' => 'name666'])->getResult(); $user = User::findById($id)->getResult(); - $this->assertEquals('stelin666', $user['name']); + $this->assertEquals('name666', $user['name']); } /** @@ -85,7 +85,7 @@ public function testDbUpdateByCo(int $id) public function testDbInsert() { $values = [ - 'name' => 'stelin', + 'name' => 'name', 'sex' => 1, 'description' => 'this my desc', 'age' => 99, @@ -106,7 +106,7 @@ public function testDbInsertByCo() public function testSelectDb() { $data = [ - 'name' => 'stelin', + 'name' => 'name', 'sex' => 1, 'description' => 'this my desc table', 'age' => mt_rand(1, 100), @@ -130,7 +130,7 @@ public function testSelectDbByCo() public function testSelectTable() { $data = [ - 'name' => 'stelin', + 'name' => 'name', 'sex' => 1, 'description' => 'this my desc', 'age' => mt_rand(1, 100), @@ -150,7 +150,7 @@ public function testSelectTableByCo() public function testSelectinstance() { $data = [ - 'name' => 'stelin', + 'name' => 'name', 'sex' => 1, 'description' => 'this my desc instance', 'age' => mt_rand(1, 100), @@ -162,4 +162,111 @@ public function testSelectinstance() $this->assertEquals($user2['description'], 'this my desc instance'); $this->assertEquals($user2['id'], $userid); } + + public function testCondtionAndByF1() + { + $age = mt_rand(1, 100); + $data = [ + 'name' => 'nameQuery', + 'sex' => 1, + 'description' => 'this my desc instance', + 'age' => $age, + ]; + $userid = Query::table(User::class)->insert($data)->getResult(); + $user = Query::table(User::class)->condition(['name' => 'nameQuery', 'age'=> $age])->limit(1)->get()->getResult(); + + $this->assertEquals('nameQuery', $user['name']); + $this->assertEquals($age, $user['age']); + + $user2 = Query::table(User::class)->where('id', $userid)->condition(['name' => 'nameQuery', 'age'=> $age])->limit(1)->get()->getResult(); + $this->assertEquals('nameQuery', $user2['name']); + $this->assertEquals($age, $user2['age']); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testCondtion2AndByF1(array $ids) + { + $users = Query::table(User::class)->condition(['sex' => 1, 'id' => $ids])->get()->getResult(); + $this->assertCount(2, $users); + } + + public function testCondtion1AndByF3() + { + $age = mt_rand(1, 100); + $data = [ + 'name' => 'nameQuery', + 'sex' => 1, + 'description' => 'this my desc instance', + 'age' => $age-1, + ]; + + $userid = Query::table(User::class)->insert($data)->getResult(); + $user = Query::table(User::class)->condition(['age', '<',$age])->limit(1)->orderBy('id', 'desc')->get()->getResult(); + $this->assertEquals($userid, $user['id']); + } + + public function testCondtion2AndByF3() + { + $age = mt_rand(1, 100); + $data = [ + 'name' => 'nameQuery', + 'sex' => 1, + 'description' => 'this my desc instance', + 'age' => $age-1, + ]; + + $userid = Query::table(User::class)->insert($data)->getResult(); + $users = Query::table(User::class)->condition(['age', 'between', $age, $age+1])->orderBy('id', 'desc')->get()->getResult(); + + $this->assertTrue(count($users) > 1); + } + + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testCondtion3AndByF3(int $id) + { + $age = mt_rand(1, 100); + $data = [ + 'name' => 'nameQuery', + 'sex' => 1, + 'description' => 'this my desc instance', + 'age' => $age-1, + ]; + + $userid = Query::table(User::class)->insert($data)->getResult(); + $users = Query::table(User::class)->condition(['age', 'not between', $age, $age+1])->orderBy('id', 'desc')->get()->getResult(); + + $this->assertTrue(count($users) > 1); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testCondtion4AndByF3(array $ids) + { + $users = Query::table(User::class)->condition(['id', 'in', $ids])->orderBy('id', 'desc')->get()->getResult(); + + $this->assertCount(2, $users); + } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testCondtion5AndByF3(array $ids) + { + $users = Query::table(User::class)->condition(['id', 'not in', $ids])->orderBy('id', 'desc')->get()->getResult(); + + $this->assertTrue(count($users) > 2); + } } \ No newline at end of file diff --git a/test/Cases/Mysql/TrasactionTest.php b/test/Cases/Mysql/TrasactionTest.php index 49d85ec..ca82f8c 100644 --- a/test/Cases/Mysql/TrasactionTest.php +++ b/test/Cases/Mysql/TrasactionTest.php @@ -11,7 +11,7 @@ class TrasactionTest extends AbstractMysqlCase public function testCommit() { $data = [ - 'name' => 'stelin', + 'name' => 'name', 'sex' => 1, 'desc' => 'desc2', 'age' => 100, @@ -46,7 +46,7 @@ public function testCommitByCo() public function testRollback() { $data = [ - 'name' => 'stelin', + 'name' => 'name', 'sex' => 1, 'desc' => 'desc2', 'age' => 100, diff --git a/test/Cases/StelinTest.php b/test/Cases/StelinTest.php deleted file mode 100644 index 586d877..0000000 --- a/test/Cases/StelinTest.php +++ /dev/null @@ -1,32 +0,0 @@ - 'stelin', -// 'sex' => 1, -// 'description' => 'this my desc', -// 'age' => 99, -// ], -// [ -// 'name' => 'stelin2', -// 'sex' => 1, -// 'description' => 'this my desc2', -// 'age' => 100, -// ] -// ]; -// -// $result = User::batchInsert($values)->getResult(); -// var_dump($result); - } -} \ No newline at end of file From 5108b80f58ac296381fd5a999d7a3ff66c146656 Mon Sep 17 00:00:00 2001 From: lilin <794774870@qq.com> Date: Mon, 9 Apr 2018 22:24:50 +0800 Subject: [PATCH 10/27] add unit --- .travis.yml | 2 +- src/Query.php | 2 +- test/Cases/AbstractMysqlCase.php | 26 +++++++ test/Cases/Mysql/QueryBuildTest.php | 110 +++++++++++++++++++++++----- test/Cases/Mysql/RelationTest.php | 45 ++++++++++++ test/Testing/Entity/Count.php | 13 ---- test/Testing/Entity/User.php | 17 ----- 7 files changed, 166 insertions(+), 49 deletions(-) create mode 100644 test/Cases/Mysql/RelationTest.php diff --git a/.travis.yml b/.travis.yml index 9db0c95..67e213a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ services: - mysql before_install: - - mysql -e 'CREATE DATABASE IF NOT EXISTS test;use test;CREATE TABLE IF NOT EXISTS `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,`sex` int(1) NOT NULL DEFAULT '0',`age` int(1) NOT NULL DEFAULT '0',`description` varchar(240) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;CREATE TABLE `user2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `sex` int(1) NOT NULL DEFAULT '0', `age` int(1) NOT NULL DEFAULT '0', `description` varchar(240) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;CREATE DATABASE IF NOT EXISTS test2;use test2;CREATE TABLE IF NOT EXISTS `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,`sex` int(1) NOT NULL DEFAULT '0',`age` int(1) NOT NULL DEFAULT '0',`description` varchar(240) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;' + - mysql -e 'CREATE DATABASE IF NOT EXISTS test;use test;CREATE TABLE IF NOT EXISTS `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,`sex` int(1) NOT NULL DEFAULT '0',`age` int(1) NOT NULL DEFAULT '0',`description` varchar(240) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;CREATE TABLE `user2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `sex` int(1) NOT NULL DEFAULT '0', `age` int(1) NOT NULL DEFAULT '0', `description` varchar(240) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;CREATE TABLE `count` (`uid` int(11) NOT NULL,`fans` int(1) NOT NULL DEFAULT '0',`follows` int(1) NOT NULL DEFAULT '0',PRIMARY KEY (`uid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8CREATE DATABASE IF NOT EXISTS test2;use test2;CREATE TABLE IF NOT EXISTS `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,`sex` int(1) NOT NULL DEFAULT '0',`age` int(1) NOT NULL DEFAULT '0',`description` varchar(240) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;' install: - wget https://github.com/redis/hiredis/archive/v0.13.3.tar.gz -O hiredis.tar.gz && mkdir -p hiredis && tar -xf hiredis.tar.gz -C hiredis --strip-components=1 && cd hiredis && sudo make -j$(nproc) && sudo make install && sudo ldconfig && cd .. diff --git a/src/Query.php b/src/Query.php index 0dfb4f7..ba8e4ff 100644 --- a/src/Query.php +++ b/src/Query.php @@ -16,7 +16,7 @@ class Query public static function table(string $tableName, string $alias = null) { $query = new QueryBuilder(); - $query = $query->table($tableName); + $query = $query->table($tableName, $alias); return $query; } diff --git a/test/Cases/AbstractMysqlCase.php b/test/Cases/AbstractMysqlCase.php index ac1ce9a..901d756 100644 --- a/test/Cases/AbstractMysqlCase.php +++ b/test/Cases/AbstractMysqlCase.php @@ -2,6 +2,7 @@ namespace Swoft\Db\Test\Cases; +use Swoft\Db\Test\Testing\Entity\Count; use Swoft\Db\Test\Testing\Entity\User; /** @@ -38,6 +39,26 @@ public function addUser() ]; } + public function addUserAndCount() + { + $user = new User(); + $user->setName('name'); + $user->setSex(1); + $user->setDesc('this my desc'); + $user->setAge(mt_rand(1, 100)); + $id = $user->save()->getResult(); + + $count = new Count(); + $count->setUid($id); + $count->setFans(mt_rand(1000, 10000)); + $count->setFollows(mt_rand(1000, 10000)); + $count->save()->getResult(); + + return [ + [$id], + ]; + } + public function mysqlProviders() { return $this->addUsers(); @@ -47,4 +68,9 @@ public function mysqlProvider() { return $this->addUser(); } + + public function relationProider() + { + return $this->addUserAndCount(); + } } diff --git a/test/Cases/Mysql/QueryBuildTest.php b/test/Cases/Mysql/QueryBuildTest.php index f3905b8..47ad6d6 100644 --- a/test/Cases/Mysql/QueryBuildTest.php +++ b/test/Cases/Mysql/QueryBuildTest.php @@ -3,9 +3,9 @@ namespace Swoft\Db\Test\Cases\Mysql; use Swoft\Db\Query; +use Swoft\Db\Test\Cases\AbstractMysqlCase; use Swoft\Db\Test\Testing\Entity\OtherUser; use Swoft\Db\Test\Testing\Entity\User; -use Swoft\Db\Test\Cases\AbstractMysqlCase; /** * QueryTest @@ -136,7 +136,7 @@ public function testSelectTable() 'age' => mt_rand(1, 100), ]; $result = Query::table('user2')->insert($data)->getResult(); - $user2 = Query::table('user2')->where('id', $result)->limit(1)->get()->getResult(); + $user2 = Query::table('user2')->where('id', $result)->limit(1)->get()->getResult(); $this->assertEquals($user2['id'], $result); } @@ -163,9 +163,16 @@ public function testSelectinstance() $this->assertEquals($user2['id'], $userid); } + public function testSelectinstanceByCo() + { + go(function () { + $this->testSelectinstance(); + }); + } + public function testCondtionAndByF1() { - $age = mt_rand(1, 100); + $age = mt_rand(1, 100); $data = [ 'name' => 'nameQuery', 'sex' => 1, @@ -173,16 +180,23 @@ public function testCondtionAndByF1() 'age' => $age, ]; $userid = Query::table(User::class)->insert($data)->getResult(); - $user = Query::table(User::class)->condition(['name' => 'nameQuery', 'age'=> $age])->limit(1)->get()->getResult(); + $user = Query::table(User::class)->condition(['name' => 'nameQuery', 'age' => $age])->limit(1)->get()->getResult(); $this->assertEquals('nameQuery', $user['name']); $this->assertEquals($age, $user['age']); - $user2 = Query::table(User::class)->where('id', $userid)->condition(['name' => 'nameQuery', 'age'=> $age])->limit(1)->get()->getResult(); + $user2 = Query::table(User::class)->where('id', $userid)->condition(['name' => 'nameQuery', 'age' => $age])->limit(1)->get()->getResult(); $this->assertEquals('nameQuery', $user2['name']); $this->assertEquals($age, $user2['age']); } + public function testCondtionAndByF1ByCo() + { + go(function () { + $this->testCondtionAndByF1(); + }); + } + /** * @dataProvider mysqlProviders * @@ -194,37 +208,63 @@ public function testCondtion2AndByF1(array $ids) $this->assertCount(2, $users); } + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testCondtion2AndByF1ByCo(array $ids) + { + go(function () use ($ids) { + $this->testCondtion2AndByF1($ids); + }); + } + public function testCondtion1AndByF3() { - $age = mt_rand(1, 100); - $data = [ + $age = mt_rand(1, 100); + $data = [ 'name' => 'nameQuery', 'sex' => 1, 'description' => 'this my desc instance', - 'age' => $age-1, + 'age' => $age - 1, ]; $userid = Query::table(User::class)->insert($data)->getResult(); - $user = Query::table(User::class)->condition(['age', '<',$age])->limit(1)->orderBy('id', 'desc')->get()->getResult(); + $user = Query::table(User::class)->condition(['age', '<', $age])->andWhere('id', $userid)->limit(1)->orderBy('id', 'desc')->get()->getResult(); $this->assertEquals($userid, $user['id']); } + public function testCondtion1AndByF3ByCo() + { + go(function () { + $this->testCondtion1AndByF3(); + }); + } + public function testCondtion2AndByF3() { - $age = mt_rand(1, 100); - $data = [ + $age = mt_rand(1, 100); + $data = [ 'name' => 'nameQuery', 'sex' => 1, 'description' => 'this my desc instance', - 'age' => $age-1, + 'age' => $age - 1, ]; $userid = Query::table(User::class)->insert($data)->getResult(); - $users = Query::table(User::class)->condition(['age', 'between', $age, $age+1])->orderBy('id', 'desc')->get()->getResult(); + $users = Query::table(User::class)->condition(['age', 'between', $age, $age + 1])->orderBy('id', 'desc')->get()->getResult(); $this->assertTrue(count($users) > 1); } + public function testCondtion2AndByF3ByCo() + { + go(function (){ + $this->testCondtion2AndByF3(); + }); + } + /** * @dataProvider mysqlProvider * @@ -232,20 +272,32 @@ public function testCondtion2AndByF3() */ public function testCondtion3AndByF3(int $id) { - $age = mt_rand(1, 100); - $data = [ + $age = mt_rand(1, 100); + $data = [ 'name' => 'nameQuery', 'sex' => 1, 'description' => 'this my desc instance', - 'age' => $age-1, + 'age' => $age - 1, ]; $userid = Query::table(User::class)->insert($data)->getResult(); - $users = Query::table(User::class)->condition(['age', 'not between', $age, $age+1])->orderBy('id', 'desc')->get()->getResult(); + $users = Query::table(User::class)->condition(['age', 'not between', $age, $age + 1])->orderBy('id', 'desc')->get()->getResult(); $this->assertTrue(count($users) > 1); } + /** + * @dataProvider mysqlProvider + * + * @param int $id + */ + public function testCondtion3AndByF3ByCo(int $id) + { + go(function ()use ($id){ + $this->testCondtion3AndByF3($id); + }); + } + /** * @dataProvider mysqlProviders * @@ -258,6 +310,18 @@ public function testCondtion4AndByF3(array $ids) $this->assertCount(2, $users); } + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testCondtion4AndByF3ByCo(array $ids) + { + go(function ()use ($ids){ + $this->testCondtion4AndByF3($ids); + }); + } + /** * @dataProvider mysqlProviders * @@ -269,4 +333,16 @@ public function testCondtion5AndByF3(array $ids) $this->assertTrue(count($users) > 2); } + + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testCondtion5AndByF3ByCo(array $ids) + { + go(function ()use ($ids){ + $this->testCondtion5AndByF3($ids); + }); + } } \ No newline at end of file diff --git a/test/Cases/Mysql/RelationTest.php b/test/Cases/Mysql/RelationTest.php new file mode 100644 index 0000000..8f046d7 --- /dev/null +++ b/test/Cases/Mysql/RelationTest.php @@ -0,0 +1,45 @@ +leftJoin(Count::class, 'user.id=count.uid')->andWhere('id', $uid) + ->orderBy('user.id', QueryBuilder::ORDER_BY_DESC)->limit(1)->get(['user.id', 'user.name','count.fans', 'count.follows'])->getResult(); + + $data2 = Query::table(User::class, 'u')->leftJoin(Count::class, 'u.id=c.uid', 'c')->andWhere('id', $uid) + ->orderBy('u.id', QueryBuilder::ORDER_BY_DESC)->limit(1)->get(['u.id'=> 'userid', 'u.name','c.fans', 'c.follows'])->getResult(); + + $this->assertEquals($uid, $data['id']); + $this->assertEquals($uid, $data2['userid']); + } + + /** + * @dataProvider relationProider + * + * @param int $uid + */ + public function testJoinByCo(int $uid) + { + go(function ()use ($uid){ + $this->testJoin($uid); + }); + } + +} \ No newline at end of file diff --git a/test/Testing/Entity/Count.php b/test/Testing/Entity/Count.php index d81f848..9b3de2e 100644 --- a/test/Testing/Entity/Count.php +++ b/test/Testing/Entity/Count.php @@ -10,21 +10,12 @@ use Swoft\Db\Types; /** - * 计数表实体 - * * @Entity() * @Table("count") - * @uses Count - * @version 2017年09月15日 - * @author stelin - * @copyright Copyright 2010-2016 swoft software - * @license PHP Version 7.x {@link http://www.php.net/license/3_0.txt} */ class Count extends Model { /** - * 用户ID - * * @Column(name="uid", type=Types::INT) * @Id() * @var null|int @@ -32,16 +23,12 @@ class Count extends Model private $uid; /** - * 粉丝数 - * * @Column(name="fans", type=Types::NUMBER) * @var int */ private $fans = 0; /** - * 关注数 - * * @Column("follows", type=Types::NUMBER) * @var int */ diff --git a/test/Testing/Entity/User.php b/test/Testing/Entity/User.php index a30e823..bd8aec6 100644 --- a/test/Testing/Entity/User.php +++ b/test/Testing/Entity/User.php @@ -11,21 +11,12 @@ use Swoft\Db\Types; /** - * 用户实体 - * * @Entity() * @Table(name="user") - * @uses User - * @version 2017年08月23日 - * @author stelin - * @copyright Copyright 2010-2016 Swoft software - * @license PHP Version 7.x {@link http://www.php.net/license/3_0.txt} */ class User extends Model { /** - * 主键ID - * * @Id() * @Column(name="id", type=Types::INT) * @var null|int @@ -33,8 +24,6 @@ class User extends Model private $id; /** - * 名称 - * * @Column(name="name", type=Types::STRING, length=20) * @Required() * @var null|string @@ -42,8 +31,6 @@ class User extends Model private $name; /** - * 年龄 - * * @Column(name="age", type=Types::INT) * @var int */ @@ -58,16 +45,12 @@ class User extends Model private $sex = 0; /** - * 描述 - * * @Column(name="description", type="string") * @var string */ private $desc = ""; /** - * 非数据库字段,未定义映射关系 - * * @var mixed */ private $otherProperty; From 3bdb799e52b5042d7bcc5a743dec5390cdda2f44 Mon Sep 17 00:00:00 2001 From: lilin <794774870@qq.com> Date: Mon, 9 Apr 2018 23:12:41 +0800 Subject: [PATCH 11/27] add unit --- src/Db.php | 22 +++++++++++++- src/Driver/Mysql/MysqlConnection.php | 7 ++++- src/Helper/EntityHelper.php | 39 ++++++++++++++++++++++++ src/QueryBuilder.php | 44 +--------------------------- test/Cases/Mysql/SqlTest.php | 25 ++++++++++++++++ 5 files changed, 92 insertions(+), 45 deletions(-) diff --git a/src/Db.php b/src/Db.php index b1000fe..65e6c8f 100644 --- a/src/Db.php +++ b/src/Db.php @@ -7,6 +7,7 @@ use Swoft\Core\ResultInterface; use Swoft\Db\Exception\DbException; use Swoft\Db\Helper\DbHelper; +use Swoft\Db\Helper\EntityHelper; use Swoft\Helper\PoolHelper; use Swoft\Pool\ConnectionInterface; use Swoft\Db\Pool\Config\DbPoolProperties; @@ -57,7 +58,7 @@ public static function query(string $sql, array $params = [], string $instance = /* @var AbstractDbConnection $connection */ $connection = self::getConnection($instance, $node); - if(!empty($db)){ + if (!empty($db)) { $connection->selectDb($db); } @@ -71,6 +72,7 @@ public static function query(string $sql, array $params = [], string $instance = $connection->setDefer(); } $connection->prepare($sql); + $params = self::transferParams($params); $result = $connection->execute($params); $dbResult = self::getResult($result, $connection, $profileKey); @@ -171,6 +173,7 @@ private static function getOperation(string $sql): string return self::RETURN_FETCH; } + /** * @param string $instance * @param string $node @@ -206,6 +209,7 @@ private static function getTransactionConnection(string $instance) } $cntId = $tsStack->offsetGet(0); $connection = RequestContext::getContextDataByChildKey($contextCntKey, $cntId, null); + return $connection; } @@ -259,4 +263,20 @@ private static function getResult($result, ConnectionInterface $connection = nul return new DbDataResult($result, $connection, $profileKey); } + /** + * @param $params + * + * @throws DbException + * @return array + */ + private static function transferParams($params) + { + $newParams = []; + foreach ($params as $key => $value) { + list($nkey, $nvalue) = EntityHelper::transferParameter($key, $value, null); + $newParams[$nkey] = $nvalue; + } + + return $newParams; + } } \ No newline at end of file diff --git a/src/Driver/Mysql/MysqlConnection.php b/src/Driver/Mysql/MysqlConnection.php index d3e8379..93d9bb9 100644 --- a/src/Driver/Mysql/MysqlConnection.php +++ b/src/Driver/Mysql/MysqlConnection.php @@ -223,15 +223,20 @@ private function formatSqlByParams(array $params = null) return; } + $newParams = []; foreach ($params as $key => &$value){ $value = "'{$value}'"; + if(is_int($key)){ + $key = sprintf('?%d', $key); + } + $newParams[$key] = $value; } // ?方式传递参数 if (strpos($this->sql, '?') !== false) { $this->transferQuestionMark(); } - $this->sql = strtr($this->sql, $params); + $this->sql = strtr($this->sql, $newParams); } /** * 格式化?标记 diff --git a/src/Helper/EntityHelper.php b/src/Helper/EntityHelper.php index ab1350d..54bb384 100644 --- a/src/Helper/EntityHelper.php +++ b/src/Helper/EntityHelper.php @@ -3,6 +3,7 @@ namespace Swoft\Db\Helper; use Swoft\Db\Bean\Collector\EntityCollector; +use Swoft\Db\Exception\DbException; use Swoft\Db\Types; /** @@ -84,4 +85,42 @@ public static function trasferTypes($type, $value) return $value; } + + /** + * @param mixed $key + * @param mixed $value + * @param string $type + * + * @throws DbException + * + * @return array + */ + public static function transferParameter($key, $value, $type): array + { + if (!\is_int($key) && !\is_string($key)) { + throw new DbException('Key must to be int Or string! '); + } + $key = self::formatParamsKey($key); + + // 参数值类型转换 + if ($type !== null) { + $value = EntityHelper::trasferTypes($type, $value); + } + + return [$key, $value]; + } + + /** + * @param mixed $key + * + * @return string + */ + private static function formatParamsKey($key): string + { + if (\is_string($key) && strpos($key, ':') === false) { + return ':' . $key; + } + + return $key; + } } \ No newline at end of file diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index a542559..d03b6b3 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -841,7 +841,7 @@ public function limit(int $limit, $offset = 0): QueryBuilder */ public function setParameter($key, $value, $type = null): QueryBuilder { - list($key, $value) = $this->transferParameter($key, $value, $type); + list($key, $value) = EntityHelper::transferParameter($key, $value, $type); $this->parameters[$key] = $value; return $this; @@ -1150,32 +1150,6 @@ private function getTableNameByClassName($tableName): string return $name; } - /** - * 参数个数转换 - * - * @param mixed $key - * @param mixed $value - * @param string $type - * - * @throws DbException - * - * @return array - */ - private function transferParameter($key, $value, $type): array - { - if (!\is_int($key) && !\is_string($key)) { - throw new DbException('参数key,只能是字符串和整数'); - } - $key = $this->formatParamsKey($key); - - // 参数值类型转换 - if ($type !== null) { - $value = EntityHelper::trasferTypes($type, $value); - } - - return [$key, $value]; - } - /** * @return string * @throws \Swoft\Db\Exception\MysqlException @@ -1190,22 +1164,6 @@ private function getTableName(): string return $table; } - /** - * @param mixed $key - * - * @return string - */ - private function formatParamsKey($key): string - { - if (\is_string($key) && strpos($key, ':') === false) { - return ':' . $key; - } - if (is_int($key) && App::isCoContext()) { - return '?' . $key; - } - - return $key; - } /** * @return string diff --git a/test/Cases/Mysql/SqlTest.php b/test/Cases/Mysql/SqlTest.php index bedcdfc..419f93a 100644 --- a/test/Cases/Mysql/SqlTest.php +++ b/test/Cases/Mysql/SqlTest.php @@ -57,6 +57,31 @@ public function testSelectByCo($id) }); } + /** + * @dataProvider mysqlProvider + * + * @param $id + */ + public function testSelect2($id) + { + $result = Db::query('select * from user where id=:id and name=:name', ['id' => $id, ':name'=>'name'])->getResult(); + $result2 = Db::query('select * from user where id=? and name=?', [$id, 'name'])->getResult(); + $this->assertEquals($id, $result[0]['id']); + $this->assertEquals($id, $result2[0]['id']); + } + + /** + * @dataProvider mysqlProvider + * + * @param $id + */ + public function testSelect2ByCo($id) + { + go(function ()use ($id){ + $this->testSelect2($id); + }); + } + /** * @dataProvider mysqlProvider * From 777f31788f4f59fd985b0377b433091a4f9049b8 Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Tue, 10 Apr 2018 14:53:48 +0800 Subject: [PATCH 12/27] Update context key --- src/Db.php | 8 ++++---- src/Event/Listeners/ResourceReleaseBeforeListener.php | 4 ++-- src/Helper/DbHelper.php | 2 +- src/Model.php | 3 ++- test/Cases/Mysql/ActiveRecordTest.php | 3 ++- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Db.php b/src/Db.php index b1000fe..15e72f5 100644 --- a/src/Db.php +++ b/src/Db.php @@ -196,8 +196,8 @@ private static function getConnection(string $instance, string $node, $ts = 'que */ private static function getTransactionConnection(string $instance) { - $contextTsKey = DbHelper::getContextTsKey(); - $contextCntKey = PoolHelper::getContextCntKey(); + $contextTsKey = DbHelper::getContextTransactionsKey(); + $contextCntKey = PoolHelper::getContextConnKey(); $instanceKey = DbHelper::getTsInstanceKey($instance); /* @var \SplStack $tsStack */ $tsStack = RequestContext::getContextDataByChildKey($contextTsKey, $instanceKey, new \SplStack()); @@ -216,7 +216,7 @@ private static function getTransactionConnection(string $instance) private static function beginTransactionContext(ConnectionInterface $connection, string $instance = Pool::INSTANCE) { $cntId = $connection->getConnectionId(); - $contextTsKey = DbHelper::getContextTsKey(); + $contextTsKey = DbHelper::getContextTransactionsKey(); $instanceKey = DbHelper::getTsInstanceKey($instance); /* @var \SplStack $tsStack */ @@ -231,7 +231,7 @@ private static function beginTransactionContext(ConnectionInterface $connection, */ private static function closetTransactionContext(AbstractDbConnection $connection, string $instance = Pool::INSTANCE) { - $contextTsKey = DbHelper::getContextTsKey(); + $contextTsKey = DbHelper::getContextTransactionsKey(); $instanceKey = DbHelper::getTsInstanceKey($instance); /* @var \SplStack $tsStack */ diff --git a/src/Event/Listeners/ResourceReleaseBeforeListener.php b/src/Event/Listeners/ResourceReleaseBeforeListener.php index 9a9f601..4dca4a0 100644 --- a/src/Event/Listeners/ResourceReleaseBeforeListener.php +++ b/src/Event/Listeners/ResourceReleaseBeforeListener.php @@ -24,8 +24,8 @@ class ResourceReleaseBeforeListener implements EventHandlerInterface */ public function handle(EventInterface $event) { - $contextTsKey = DbHelper::getContextTsKey(); - $contextCntKey = PoolHelper::getContextCntKey(); + $contextTsKey = DbHelper::getContextTransactionsKey(); + $contextCntKey = PoolHelper::getContextConnKey(); $transactions = RequestContext::getContextDataByKey($contextTsKey, []); $connections = RequestContext::getContextDataByKey($contextCntKey, []); diff --git a/src/Helper/DbHelper.php b/src/Helper/DbHelper.php index e90c308..091b5cb 100644 --- a/src/Helper/DbHelper.php +++ b/src/Helper/DbHelper.php @@ -65,7 +65,7 @@ public static function getStatementClassNameByInstance(string $instance): string /** * @return string */ - public static function getContextTsKey(): string + public static function getContextTransactionsKey(): string { return sprintf('transactions'); } diff --git a/src/Model.php b/src/Model.php index dfa41a6..17dbde5 100644 --- a/src/Model.php +++ b/src/Model.php @@ -2,13 +2,14 @@ namespace Swoft\Db; +use Swoft\Contract\Arrayable; use Swoft\Core\ResultInterface; use Swoft\Db\Bean\Collector\EntityCollector; /** * Activerecord */ -class Model implements \ArrayAccess, \Iterator +class Model implements \ArrayAccess, \Iterator, Arrayable { /** * Old data diff --git a/test/Cases/Mysql/ActiveRecordTest.php b/test/Cases/Mysql/ActiveRecordTest.php index 714bd4c..b57183d 100644 --- a/test/Cases/Mysql/ActiveRecordTest.php +++ b/test/Cases/Mysql/ActiveRecordTest.php @@ -144,7 +144,8 @@ public function testUpdate(int $id) /* @var User $user */ $user = User::findById($id)->getResult(); $user->setName($newName); - $user->update()->getResult(); + $updateResult = $user->update()->getResult(); + $this->assertGreaterThanOrEqual(1, $updateResult); /* @var User $newUser */ $newUser = User::findById($id)->getResult(); From 5d894a6212e3ccaf9cb37008fcbe1750e5e50eb1 Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Tue, 10 Apr 2018 14:54:00 +0800 Subject: [PATCH 13/27] Fix unit test --- test/Cases/AbstractTestCase.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/Cases/AbstractTestCase.php b/test/Cases/AbstractTestCase.php index d358c3e..b7a81e2 100644 --- a/test/Cases/AbstractTestCase.php +++ b/test/Cases/AbstractTestCase.php @@ -14,7 +14,9 @@ abstract class AbstractTestCase extends TestCase protected function tearDown() { parent::tearDown(); -// swoole_event_exit(); + swoole_timer_after(2 * 1000, function () { + swoole_event_exit(); + }); } } \ No newline at end of file From 4a67ca0080d4721ff02396bc1e7ab719fad884bb Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Tue, 10 Apr 2018 15:02:44 +0800 Subject: [PATCH 14/27] format .travis.yml sql --- .travis.yml | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 67e213a..0896b83 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,12 +3,46 @@ language: php php: - 7.0 - 7.1 + - 7.2 services: - mysql before_install: - - mysql -e 'CREATE DATABASE IF NOT EXISTS test;use test;CREATE TABLE IF NOT EXISTS `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,`sex` int(1) NOT NULL DEFAULT '0',`age` int(1) NOT NULL DEFAULT '0',`description` varchar(240) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;CREATE TABLE `user2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `sex` int(1) NOT NULL DEFAULT '0', `age` int(1) NOT NULL DEFAULT '0', `description` varchar(240) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;CREATE TABLE `count` (`uid` int(11) NOT NULL,`fans` int(1) NOT NULL DEFAULT '0',`follows` int(1) NOT NULL DEFAULT '0',PRIMARY KEY (`uid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8CREATE DATABASE IF NOT EXISTS test2;use test2;CREATE TABLE IF NOT EXISTS `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,`sex` int(1) NOT NULL DEFAULT '0',`age` int(1) NOT NULL DEFAULT '0',`description` varchar(240) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;' + - mysql -e 'CREATE DATABASE IF NOT EXISTS test; + USE test; + CREATE TABLE IF NOT EXISTS `user` ( + `id` INT (11) NOT NULL AUTO_INCREMENT, + `name` VARCHAR (20) DEFAULT NULL, + `sex` INT (1) NOT NULL DEFAULT '0', + `age` INT (1) NOT NULL DEFAULT '0', + `description` VARCHAR (240) DEFAULT NULL, + PRIMARY KEY (`id`) + ) ENGINE = INNODB DEFAULT CHARSET = utf8 ; + CREATE TABLE `user2` ( + `id` INT (11) NOT NULL AUTO_INCREMENT, + `name` VARCHAR (20) DEFAULT NULL, + `sex` INT (1) NOT NULL DEFAULT '0', + `age` INT (1) NOT NULL DEFAULT '0', + `description` VARCHAR (240) DEFAULT NULL, + PRIMARY KEY (`id`) + ) ENGINE = INNODB DEFAULT CHARSET = utf8 ; + CREATE TABLE `count` ( + `uid` INT (11) NOT NULL, + `fans` INT (1) NOT NULL DEFAULT '0', + `follows` INT (1) NOT NULL DEFAULT '0', + PRIMARY KEY (`uid`) + ) ENGINE = INNODB DEFAULT CHARSET = utf8 ;' + - mysql -e 'CREATE DATABASE IF NOT EXISTS test2; + USE test2; + CREATE TABLE IF NOT EXISTS `user` ( + `id` INT (11) NOT NULL AUTO_INCREMENT, + `name` VARCHAR (20) DEFAULT NULL, + `sex` INT (1) NOT NULL DEFAULT '0', + `age` INT (1) NOT NULL DEFAULT '0', + `description` VARCHAR (240) DEFAULT NULL, + PRIMARY KEY (`id`) + ) ENGINE = INNODB DEFAULT CHARSET = utf8 ;' install: - wget https://github.com/redis/hiredis/archive/v0.13.3.tar.gz -O hiredis.tar.gz && mkdir -p hiredis && tar -xf hiredis.tar.gz -C hiredis --strip-components=1 && cd hiredis && sudo make -j$(nproc) && sudo make install && sudo ldconfig && cd .. From 91b7829a15aeab3c7ebdc8d62f0c6901cc9936b9 Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Tue, 10 Apr 2018 15:07:44 +0800 Subject: [PATCH 15/27] add pdo requires and use feature branch framework requires --- composer.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index ad77691..61a19e0 100644 --- a/composer.json +++ b/composer.json @@ -6,12 +6,14 @@ "swoole", "swoft", "db", - "orm" + "orm", + "active record" ], "description": "microservice framework base on swoole", "license": "Apache-2.0", "require": { - "swoft/framework": "^1.0", + "ext-pdo": "*", + "swoft/framework": "dev-feature as 1.0", "swoft/console": "^1.0", "swoft/service-governance": "^1.0" }, From e4ae05d985cf04607a17b9862dc23e5d50a4a139 Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Tue, 10 Apr 2018 15:14:46 +0800 Subject: [PATCH 16/27] fix method type --- src/Executor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Executor.php b/src/Executor.php index 8ae45ad..0b844c4 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -330,7 +330,7 @@ private static function getFields($entity, $type = 1): array * * @throws ValidatorException */ - private function validate(array $columnAry, $propertyValue) + private static function validate(array $columnAry, $propertyValue) { // 验证信息 $column = $columnAry['column']; @@ -380,7 +380,7 @@ private function validate(array $columnAry, $propertyValue) * @return mixed * @throws \InvalidArgumentException */ - private function getEntityProValue($entity, string $proName) + private static function getEntityProValue($entity, string $proName) { $proName = explode('_', $proName); $proName = array_map(function ($word) { From 10962cd385aa82119a0f0bae7e234e2c91645c68 Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Tue, 10 Apr 2018 15:20:23 +0800 Subject: [PATCH 17/27] revert getContextConnKey method name to getContextCntKey --- src/Db.php | 2 +- src/Event/Listeners/ResourceReleaseBeforeListener.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Db.php b/src/Db.php index 7f373b0..97791bd 100644 --- a/src/Db.php +++ b/src/Db.php @@ -200,7 +200,7 @@ private static function getConnection(string $instance, string $node, $ts = 'que private static function getTransactionConnection(string $instance) { $contextTsKey = DbHelper::getContextTransactionsKey(); - $contextCntKey = PoolHelper::getContextConnKey(); + $contextCntKey = PoolHelper::getContextCntKey(); $instanceKey = DbHelper::getTsInstanceKey($instance); /* @var \SplStack $tsStack */ $tsStack = RequestContext::getContextDataByChildKey($contextTsKey, $instanceKey, new \SplStack()); diff --git a/src/Event/Listeners/ResourceReleaseBeforeListener.php b/src/Event/Listeners/ResourceReleaseBeforeListener.php index 4dca4a0..7b23a85 100644 --- a/src/Event/Listeners/ResourceReleaseBeforeListener.php +++ b/src/Event/Listeners/ResourceReleaseBeforeListener.php @@ -25,7 +25,7 @@ class ResourceReleaseBeforeListener implements EventHandlerInterface public function handle(EventInterface $event) { $contextTsKey = DbHelper::getContextTransactionsKey(); - $contextCntKey = PoolHelper::getContextConnKey(); + $contextCntKey = PoolHelper::getContextCntKey(); $transactions = RequestContext::getContextDataByKey($contextTsKey, []); $connections = RequestContext::getContextDataByKey($contextCntKey, []); From 5d433eaa6fabee830c10c7fa64dc8313f728af56 Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Tue, 10 Apr 2018 17:06:52 +0800 Subject: [PATCH 18/27] Add decorators mechanism for Db result, and add exist() method to Model --- src/Db.php | 9 ++-- src/DbCoResult.php | 4 +- src/DbDataResult.php | 5 ++- src/DbResult.php | 19 ++++++++ src/Executor.php | 20 +++++++++ src/Model.php | 11 +++++ src/QueryBuilder.php | 44 ++++++++++++++++++- test/Cases/Mysql/ActiveRecordTest.php | 9 ++++ ...ueryBuildTest.php => QueryBuilderTest.php} | 3 +- 9 files changed, 115 insertions(+), 9 deletions(-) rename test/Cases/Mysql/{QueryBuildTest.php => QueryBuilderTest.php} (99%) diff --git a/src/Db.php b/src/Db.php index 97791bd..50bb331 100644 --- a/src/Db.php +++ b/src/Db.php @@ -42,13 +42,13 @@ class Db * Query by sql * * @param string $sql - * @param array $params + * @param array $params * @param string $instance * @param string $className - * - * @return ResultInterface + * @param array $resultDecorators + * @return \Swoft\Core\ResultInterface */ - public static function query(string $sql, array $params = [], string $instance = Pool::INSTANCE, string $className = ''): ResultInterface + public static function query(string $sql, array $params = [], string $instance = Pool::INSTANCE, string $className = '', array $resultDecorators = []): ResultInterface { $type = self::getOperation($sql); $instance = explode('.', $instance); @@ -78,6 +78,7 @@ public static function query(string $sql, array $params = [], string $instance = $dbResult = self::getResult($result, $connection, $profileKey); $dbResult->setType($type); $dbResult->setClassName($className); + $dbResult->setDecorators($resultDecorators); return $dbResult; } diff --git a/src/DbCoResult.php b/src/DbCoResult.php index a2d5d9e..58ae871 100644 --- a/src/DbCoResult.php +++ b/src/DbCoResult.php @@ -12,7 +12,6 @@ class DbCoResult extends DbResult /** * @param array ...$params - * * @return mixed */ public function getResult(...$params) @@ -21,6 +20,9 @@ public function getResult(...$params) $result = $this->getResultByClassName(); $this->release(); + foreach ($this->decorators ?? [] as $decorator) { + $result = value($decorator($result)); + } return $result; } } \ No newline at end of file diff --git a/src/DbDataResult.php b/src/DbDataResult.php index 0333247..514f456 100644 --- a/src/DbDataResult.php +++ b/src/DbDataResult.php @@ -9,14 +9,15 @@ class DbDataResult extends DbResult { /** * @param array ...$params - * * @return mixed */ public function getResult(...$params) { $result = $this->getResultByClassName(); $this->release(); - + foreach ($this->decorators ?? [] as $decorator) { + $result = value($decorator($result)); + } return $result; } } \ No newline at end of file diff --git a/src/DbResult.php b/src/DbResult.php index 9aba53a..b29920a 100644 --- a/src/DbResult.php +++ b/src/DbResult.php @@ -22,20 +22,39 @@ abstract class DbResult extends AbstractResult */ protected $className = ''; + /** + * @var array + */ + protected $decorators = []; + /** * @param int $type + * @return $this */ public function setType(int $type) { $this->type = $type; + return $this; } /** * @param string $className + * @return $this */ public function setClassName(string $className) { $this->className = $className; + return $this; + } + + /** + * @param array $decorators + * @return $this + */ + public function setDecorators(array $decorators) + { + $this->decorators = $decorators; + return $this; } /** diff --git a/src/Executor.php b/src/Executor.php index 0b844c4..9f252ef 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -184,6 +184,26 @@ public static function find($entity): ResultInterface return $query->get(); } + /** + * @param $className + * @param $id + * @return \Swoft\Core\ResultInterface + */ + public static function exist($className, $id): ResultInterface + { + list($tableName, , $idColumn) = self::getTable($className); + $instance = self::getInstance($className); + $query = Query::table($tableName) + ->where($idColumn, $id) + ->limit(1) + ->selectInstance($instance) + ->addDecorator(function ($result) { + return (bool)$result; + }); + + return $query->get([$idColumn]); + } + /** * @param string $className * @param mixed $id diff --git a/src/Model.php b/src/Model.php index 17dbde5..35f5062 100644 --- a/src/Model.php +++ b/src/Model.php @@ -145,6 +145,17 @@ public function find(): ResultInterface return Executor::find($this); } + /** + * Determine if Entity exist ? + * + * @param mixed $id + * @return ResultInterface + */ + public static function exist($id): ResultInterface + { + return Executor::exist(static::class, $id); + } + /** * @param array $condition * @param array $orderBy diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index d03b6b3..cce9200 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -259,6 +259,11 @@ class QueryBuilder implements QueryBuilderInterface */ protected $aggregate = []; + /** + * @var array + */ + protected $decorators = []; + /** * @var string */ @@ -896,6 +901,43 @@ public function setParameters(array $parameters) return $this; } + /** + * @param \Closure $closure + * @return $this + */ + public function addDecorator(\Closure $closure) + { + $this->decorators[] = $closure; + return $this; + } + + /** + * @return $this + */ + public function clearDecorators() + { + $this->decorators = []; + return $this; + } + + /** + * @param array $decorators + * @return $this + */ + public function setDecorators(array $decorators) + { + $this->decorators = $decorators; + return $this; + } + + /** + * @return array + */ + public function getDecorators(): array + { + return $this->decorators; + } + /** * 括号条件组拼 * @@ -1114,7 +1156,7 @@ public function execute() $sql = $statement->getStatement(); $instanceName = $this->getInstanceName(); - return Db::query($sql, $this->parameters, $instanceName, $this->className); + return Db::query($sql, $this->parameters, $instanceName, $this->className, $this->getDecorators()); } /** diff --git a/test/Cases/Mysql/ActiveRecordTest.php b/test/Cases/Mysql/ActiveRecordTest.php index b57183d..70c97d1 100644 --- a/test/Cases/Mysql/ActiveRecordTest.php +++ b/test/Cases/Mysql/ActiveRecordTest.php @@ -372,4 +372,13 @@ public function testFindAll(array $ids) $result = User::findAll(['name' => 'name', 'id' => $ids], ['id' => 'desc'], 2, 0)->getResult(); $this->assertCount(2,$result); } + + public function testExist() + { + $user = new User(); + $id = $user->fill(['name' => 'existTest'])->save()->getResult(); + $this->assertTrue(User::exist($id)->getResult()); + $this->assertFalse(User::exist('NotExistId')->getResult()); + } + } \ No newline at end of file diff --git a/test/Cases/Mysql/QueryBuildTest.php b/test/Cases/Mysql/QueryBuilderTest.php similarity index 99% rename from test/Cases/Mysql/QueryBuildTest.php rename to test/Cases/Mysql/QueryBuilderTest.php index 47ad6d6..4defb59 100644 --- a/test/Cases/Mysql/QueryBuildTest.php +++ b/test/Cases/Mysql/QueryBuilderTest.php @@ -10,7 +10,7 @@ /** * QueryTest */ -class QueryBuildTest extends AbstractMysqlCase +class QueryBuilderTest extends AbstractMysqlCase { /** * @dataProvider mysqlProvider @@ -345,4 +345,5 @@ public function testCondtion5AndByF3ByCo(array $ids) $this->testCondtion5AndByF3($ids); }); } + } \ No newline at end of file From 93d26c4f1c4e9dcac2fd9737f85a694878916c8a Mon Sep 17 00:00:00 2001 From: lilin <794774870@qq.com> Date: Tue, 10 Apr 2018 19:01:19 +0800 Subject: [PATCH 19/27] add options --- src/DbResult.php | 4 ++ src/Driver/Mysql/MysqlConnection.php | 3 +- src/Executor.php | 86 ++++++++++++++++++++------- src/Model.php | 24 ++++---- test/Cases/Mysql/ActiveRecordTest.php | 57 ++++++++++++++++-- 5 files changed, 135 insertions(+), 39 deletions(-) diff --git a/src/DbResult.php b/src/DbResult.php index b29920a..bae4cd6 100644 --- a/src/DbResult.php +++ b/src/DbResult.php @@ -89,6 +89,10 @@ protected function getResultByClassName() */ private function getResultByType() { + if($this->connection === null){ + return $this->result; + } + /* @var AbstractDbConnection $connection */ $connection = $this->connection; diff --git a/src/Driver/Mysql/MysqlConnection.php b/src/Driver/Mysql/MysqlConnection.php index 93d9bb9..563cf06 100644 --- a/src/Driver/Mysql/MysqlConnection.php +++ b/src/Driver/Mysql/MysqlConnection.php @@ -3,10 +3,9 @@ namespace Swoft\Db\Driver\Mysql; use Swoft\App; -use Swoft\Db\Bean\Annotation\Connection; use Swoft\Db\AbstractDbConnection; +use Swoft\Db\Bean\Annotation\Connection; use Swoft\Db\Exception\MysqlException; -use Swoft\Log\Log; use Swoole\Coroutine\Mysql; /** diff --git a/src/Executor.php b/src/Executor.php index 9f252ef..9bba62c 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -207,43 +207,50 @@ public static function exist($className, $id): ResultInterface /** * @param string $className * @param mixed $id + * @param array $options * * @return ResultInterface */ - public static function findById($className, $id): ResultInterface + public static function findById($className, $id, array $options): ResultInterface { list($tableName, , $columnId) = self::getTable($className); $instance = self::getInstance($className); - $query = Query::table($tableName)->className($className)->where($columnId, $id)->limit(1)->selectInstance($instance); + $query = Query::table($tableName)->className($className)->where($columnId, $id)->selectInstance($instance); - return $query->get(); + $options['limit'] = 1; + $query = self::addOptions($query, $options); + $fields = self::getFieldsFromOptions($options); + + return $query->get($fields); } /** * @param string $className * @param array $ids + * @param array $options * * @return ResultInterface */ - public static function findByIds($className, array $ids): ResultInterface + public static function findByIds($className, array $ids, array $options): ResultInterface { list($tableName, , $columnId) = self::getTable($className); $instance = self::getInstance($className); $query = Query::table($tableName)->className($className)->whereIn($columnId, $ids)->selectInstance($instance); - - return $query->get(); + $query = self::addOptions($query, $options); + $fields = self::getFieldsFromOptions($options); + return $query->get($fields); } /** * @param string $className * @param array $condition - * @param array $orderBy + * @param array $options * * @return \Swoft\Core\ResultInterface */ - public static function findOne(string $className, array $condition = [], array $orderBy = []) + public static function findOne(string $className, array $condition = [], array $options = []) { $instance = self::getInstance($className); $query = Query::table($className)->className($className)->selectInstance($instance); @@ -252,23 +259,20 @@ public static function findOne(string $className, array $condition = [], array $ $query = $query->condition($condition); } - foreach ($orderBy as $column => $order) { - $query = $query->orderBy($column, $order); - } - - return $query->limit(1)->get(); + $options['limit'] = 1; + $query = self::addOptions($query, $options); + $fields = self::getFieldsFromOptions($options); + return $query->get($fields); } /** * @param string $className * @param array $condition - * @param array $orderBy - * @param int $limit - * @param int $offset + * @param array $options * * @return ResultInterface */ - public static function findAll(string $className, array $condition = [], array $orderBy = [], int $limit = 20, int $offset = 0) + public static function findAll(string $className, array $condition = [], array $options = []) { $instance = self::getInstance($className); $query = Query::table($className)->className($className)->selectInstance($instance); @@ -277,11 +281,10 @@ public static function findAll(string $className, array $condition = [], array $ $query = $query->condition($condition); } - foreach ($orderBy as $column => $order) { - $query = $query->orderBy($column, $order); - } + $query = self::addOptions($query, $options); + $fields = self::getFieldsFromOptions($options); - return $query->limit($limit, $offset)->get(); + return $query->get($fields); } /** @@ -469,4 +472,45 @@ private static function getInstance(string $className): string return $collector[$className]['instance']; } + + /** + * @param array $options + * + * @return array + */ + private static function getFieldsFromOptions(array $options):array + { + return $options['fields']?? ['*']; + } + + /** + * @param QueryBuilder $query + * @param array $options + * @return QueryBuilder + */ + private static function addOptions(QueryBuilder $query, array $options) + { + if (isset($options['orderby'])) { + $option = $options['orderby']; + foreach ($option as $column => $order) { + $query = $query->orderBy($column, $order); + } + } + + $limit = null; + $offset = 0; + if (isset($options['limit'])) { + $limit = $options['limit']; + } + + if (isset($options['offset'])) { + $offset = $options['offset']; + } + + if ($limit !== null) { + $query = $query->limit($limit, $offset); + } + + return $query; + } } diff --git a/src/Model.php b/src/Model.php index 35f5062..86ad354 100644 --- a/src/Model.php +++ b/src/Model.php @@ -158,50 +158,50 @@ public static function exist($id): ResultInterface /** * @param array $condition - * @param array $orderBy + * @param array $options * * @return ResultInterface */ - public static function findOne(array $condition, array $orderBy = []): ResultInterface + public static function findOne(array $condition, array $options = []): ResultInterface { - return Executor::findOne(static::class, $condition, $orderBy); + return Executor::findOne(static::class, $condition, $options); } /** * @param array $condition - * @param array $orderBy - * @param int $limit - * @param int $offset + * @param array $options * * @return ResultInterface */ - public static function findAll(array $condition = [], array $orderBy = [], int $limit = 20, int $offset = 0): ResultInterface + public static function findAll(array $condition = [], array $options = []): ResultInterface { - return Executor::findAll(static::class, $condition, $orderBy, $limit, $offset); + return Executor::findAll(static::class, $condition, $options); } /** * Find by id * * @param mixed $id + * @param array $options * * @return ResultInterface */ - public static function findById($id): ResultInterface + public static function findById($id, array $options = []): ResultInterface { - return Executor::findById(static::class, $id); + return Executor::findById(static::class, $id, $options); } /** * Find by ids * * @param array $ids + * @param array $options * * @return ResultInterface */ - public static function findByIds(array $ids): ResultInterface + public static function findByIds(array $ids, array $options = []): ResultInterface { - return Executor::findByIds(static::class, $ids); + return Executor::findByIds(static::class, $ids, $options); } /** diff --git a/test/Cases/Mysql/ActiveRecordTest.php b/test/Cases/Mysql/ActiveRecordTest.php index 70c97d1..dd69f32 100644 --- a/test/Cases/Mysql/ActiveRecordTest.php +++ b/test/Cases/Mysql/ActiveRecordTest.php @@ -2,10 +2,9 @@ namespace Swoft\Db\Test\Cases\Mysql; -use Swoft\Db\Query; use Swoft\Db\QueryBuilder; -use Swoft\Db\Test\Testing\Entity\User; use Swoft\Db\Test\Cases\AbstractMysqlCase; +use Swoft\Db\Test\Testing\Entity\User; /** * MysqlTest @@ -150,6 +149,19 @@ public function testUpdate(int $id) /* @var User $newUser */ $newUser = User::findById($id)->getResult(); $this->assertEquals($newName, $newUser->getName()); + + $userObj=User::findById($id)->getResult(); + $userObj->setName("update"); + + $result= $userObj->update()->getResult(); + + $userObj=User::findById($id)->getResult(); + $userObj->setName("update"); + + $result2= $userObj->update()->getResult(); + + $this->assertEquals(1, $result); + $this->assertEquals(0, $result2); } /** @@ -174,8 +186,12 @@ public function testFindById(int $id) { $user = User::findById($id)->getResult(); $userEmpty = User::findById(99999999999)->getResult(); + $user2 = User::findById($id, ['fields' => ['id']])->getResult(); $this->assertEquals($id, $user['id']); $this->assertEquals($userEmpty, null); + + $this->assertEquals($id, $user2['id']); + $this->assertEquals(null, $user2['name']); } /** @@ -225,13 +241,25 @@ public function testFindByIds(array $ids) { $users = User::findByIds($ids)->getResult(); $userEmpty = User::findByIds([999999999999])->getResult(); + $users2 = User::findByIds($ids, ['fields' => ['id'], 'orderby' => ['id' => 'asc'], 'limit' => 2])->getResult(); + sort($ids); $resultIds = []; foreach ($users as $user) { $resultIds[] = $user['id']; } - $this->assertEquals(sort($resultIds), sort($ids)); + sort($resultIds); + $this->assertEquals($resultIds, $ids); $this->assertEquals($userEmpty, []); + + $queryIds = []; + foreach ($users2 as $user){ + $queryIds[] = $user['id']; + $this->assertEquals(null, $user['name']); + } + + + $this->assertEquals($ids, $queryIds); } /** @@ -359,7 +387,10 @@ public function testUpdateAll(array $ids) public function testFindOne(int $id) { $user = User::findOne(['id' => $id, 'name' => 'name'], ['id'=> 'desc', 'age' => 'desc'])->getResult(); + $user2 = User::findOne(['id' => $id], ['fields' => ['id', 'name']])->getResult(); $this->assertEquals($id, $user['id']); + $this->assertEquals($id, $user2['id']); + $this->assertEquals(null, $user2['desc']); } /** @@ -369,8 +400,26 @@ public function testFindOne(int $id) */ public function testFindAll(array $ids) { - $result = User::findAll(['name' => 'name', 'id' => $ids], ['id' => 'desc'], 2, 0)->getResult(); + $options = [ + 'orderby' => [ + 'id' => 'desc', + ], + 'limit' => 2, + 'offset' => 0, + 'fields' => ['id', 'name'], + ]; + $result = User::findAll(['name' => 'name'], $options)->getResult(); $this->assertCount(2,$result); + + $ids = []; + /* @var User $user */ + foreach ($result as $key => $user){ + $ids[$key] = $user->getId(); + $this->assertEquals($user->getName(), 'name'); + $this->assertEquals($user->getDesc(), null); + } + + $this->assertTrue($ids[0] > $ids[1]); } public function testExist() From 5c926246bc76d4581cdbf8fa4ec795499be93cb3 Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Tue, 10 Apr 2018 19:18:38 +0800 Subject: [PATCH 20/27] Rename method name addOptions to applyOptions --- src/Executor.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Executor.php b/src/Executor.php index 9bba62c..8f41080 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -219,7 +219,7 @@ public static function findById($className, $id, array $options): ResultInterfac $query = Query::table($tableName)->className($className)->where($columnId, $id)->selectInstance($instance); $options['limit'] = 1; - $query = self::addOptions($query, $options); + $query = self::applyOptions($query, $options); $fields = self::getFieldsFromOptions($options); return $query->get($fields); @@ -238,7 +238,7 @@ public static function findByIds($className, array $ids, array $options): Result $instance = self::getInstance($className); $query = Query::table($tableName)->className($className)->whereIn($columnId, $ids)->selectInstance($instance); - $query = self::addOptions($query, $options); + $query = self::applyOptions($query, $options); $fields = self::getFieldsFromOptions($options); return $query->get($fields); } @@ -260,7 +260,7 @@ public static function findOne(string $className, array $condition = [], array $ } $options['limit'] = 1; - $query = self::addOptions($query, $options); + $query = self::applyOptions($query, $options); $fields = self::getFieldsFromOptions($options); return $query->get($fields); } @@ -281,7 +281,7 @@ public static function findAll(string $className, array $condition = [], array $ $query = $query->condition($condition); } - $query = self::addOptions($query, $options); + $query = self::applyOptions($query, $options); $fields = self::getFieldsFromOptions($options); return $query->get($fields); @@ -488,7 +488,7 @@ private static function getFieldsFromOptions(array $options):array * @param array $options * @return QueryBuilder */ - private static function addOptions(QueryBuilder $query, array $options) + private static function applyOptions(QueryBuilder $query, array $options) { if (isset($options['orderby'])) { $option = $options['orderby']; From 31104d03dbd88915ad92953123a6b384fb1b048b Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Tue, 10 Apr 2018 19:19:40 +0800 Subject: [PATCH 21/27] simplify code --- src/Executor.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Executor.php b/src/Executor.php index 8f41080..d62dc4d 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -497,15 +497,8 @@ private static function applyOptions(QueryBuilder $query, array $options) } } - $limit = null; - $offset = 0; - if (isset($options['limit'])) { - $limit = $options['limit']; - } - - if (isset($options['offset'])) { - $offset = $options['offset']; - } + $limit = $options['limit'] ?? null; + $offset = $options['offset'] ?? 0; if ($limit !== null) { $query = $query->limit($limit, $offset); From 44a5d57c05e0e95a8d90274627ec45b47807e916 Mon Sep 17 00:00:00 2001 From: lilin <794774870@qq.com> Date: Tue, 10 Apr 2018 19:20:20 +0800 Subject: [PATCH 22/27] add count --- src/Executor.php | 39 +++++++++++++++++++-------- src/Model.php | 12 +++++++++ test/Cases/Mysql/ActiveRecordTest.php | 11 ++++++++ 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/Executor.php b/src/Executor.php index 9bba62c..3dff61c 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -185,25 +185,42 @@ public static function find($entity): ResultInterface } /** - * @param $className - * @param $id - * @return \Swoft\Core\ResultInterface + * @param string $className + * @param mixed $id + * + * @return ResultInterface */ - public static function exist($className, $id): ResultInterface + public static function exist(string $className, $id): ResultInterface { list($tableName, , $idColumn) = self::getTable($className); $instance = self::getInstance($className); - $query = Query::table($tableName) - ->where($idColumn, $id) - ->limit(1) - ->selectInstance($instance) - ->addDecorator(function ($result) { - return (bool)$result; - }); + $query = Query::table($tableName)->where($idColumn, $id)->limit(1)->selectInstance($instance)->addDecorator(function ($result) { + return (bool)$result; + }); return $query->get([$idColumn]); } + /** + * @param string $className + * @param string $column + * @param array $condition + * + * @return ResultInterface + */ + public static function count(string $className, string $column, array $condition): ResultInterface + { + $instance = self::getInstance($className); + $query = Query::table($className)->selectInstance($instance)->condition($condition)->addDecorator(function ($result){ + if(isset($result['count'])){ + return $result['count']; + } + return 0; + }); + + return $query->count($column); + } + /** * @param string $className * @param mixed $id diff --git a/src/Model.php b/src/Model.php index 86ad354..4eb1d4a 100644 --- a/src/Model.php +++ b/src/Model.php @@ -149,6 +149,7 @@ public function find(): ResultInterface * Determine if Entity exist ? * * @param mixed $id + * * @return ResultInterface */ public static function exist($id): ResultInterface @@ -156,6 +157,17 @@ public static function exist($id): ResultInterface return Executor::exist(static::class, $id); } + /** + * @param string $column + * @param array $condition + * + * @return ResultInterface + */ + public static function count(string $column = '*', array $condition = []): ResultInterface + { + return Executor::count(static::class, $column, $condition); + } + /** * @param array $condition * @param array $options diff --git a/test/Cases/Mysql/ActiveRecordTest.php b/test/Cases/Mysql/ActiveRecordTest.php index dd69f32..bb558ab 100644 --- a/test/Cases/Mysql/ActiveRecordTest.php +++ b/test/Cases/Mysql/ActiveRecordTest.php @@ -430,4 +430,15 @@ public function testExist() $this->assertFalse(User::exist('NotExistId')->getResult()); } + /** + * @dataProvider mysqlProviders + * + * @param array $ids + */ + public function testCount(array $ids) + { + $count = User::count('id', ['id' => $ids])->getResult(); + $this->assertEquals(2, $count); + } + } \ No newline at end of file From 5f8c0209a6a9e4e2e05a711b5db64b663c43002b Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Tue, 10 Apr 2018 19:30:30 +0800 Subject: [PATCH 23/27] add .php_cs and format code, and rename test namespace --- .php_cs | 38 +++++++++++++ composer.json | 14 +++-- src/AbstractDbConnection.php | 11 +++- src/Bean/Annotation/Column.php | 9 ++- src/Bean/Annotation/Connection.php | 11 +++- src/Bean/Annotation/Entity.php | 9 ++- src/Bean/Annotation/Id.php | 9 ++- src/Bean/Annotation/Required.php | 9 ++- src/Bean/Annotation/Statement.php | 11 +++- src/Bean/Annotation/Table.php | 9 ++- src/Bean/Collector/ConnectionCollector.php | 14 +++-- src/Bean/Collector/EntityCollector.php | 12 +++- src/Bean/Collector/StatementCollector.php | 11 +++- src/Bean/Parser/ColumnParser.php | 9 ++- src/Bean/Parser/ConnectionParser.php | 14 +++-- src/Bean/Parser/EntityParser.php | 9 ++- src/Bean/Parser/IdParser.php | 10 +++- src/Bean/Parser/RequiredParser.php | 9 ++- src/Bean/Parser/StatementParser.php | 12 +++- src/Bean/Parser/TableParser.php | 10 +++- src/Bean/Wrapper/ConnectionWrapper.php | 12 +++- src/Bean/Wrapper/EntityWrapper.php | 9 ++- src/Bean/Wrapper/StatementWrapper.php | 11 +++- src/Command/EntityCommand.php | 10 +++- src/Db.php | 11 +++- src/DbCoResult.php | 12 +++- src/DbConnectionInterface.php | 10 +++- src/DbDataResult.php | 11 +++- src/DbResult.php | 16 ++++-- src/Driver/Driver.php | 13 ++++- src/Driver/DriverType.php | 11 +++- src/Driver/Mysql/MysqlConnection.php | 14 ++++- src/Driver/Mysql/MysqlStatement.php | 11 +++- src/Driver/Mysql/SyncMysqlConnection.php | 13 ++++- src/Entity/AbstractGenerator.php | 9 ++- src/Entity/Generator.php | 9 ++- src/Entity/GeneratorInterface.php | 9 ++- src/Entity/Mysql/Schema.php | 9 ++- src/Entity/Schema.php | 12 +++- src/Entity/SetGetGenerator.php | 9 ++- src/EntityManager.php | 10 +++- src/EntityManagerInterface.php | 10 +++- .../ResourceReleaseBeforeListener.php | 11 +++- src/Exception/DbException.php | 9 ++- src/Exception/MysqlException.php | 12 +++- src/Executor.php | 9 ++- src/Helper/DbHelper.php | 13 +++-- src/Helper/EntityHelper.php | 11 +++- src/Helper/Functions.php | 12 +++- src/Model.php | 11 +++- src/Pool.php | 12 +++- src/Pool/Config/DbPoolConfig.php | 13 ++++- src/Pool/Config/DbPoolProperties.php | 11 +++- src/Pool/Config/DbSlavePoolConfig.php | 10 +++- src/Pool/DbPool.php | 9 ++- src/Pool/DbSlavePool.php | 9 ++- src/Query.php | 12 +++- src/QueryBuilder.php | 42 +++++++------- src/QueryBuilderInterface.php | 9 ++- src/Statement.php | 9 ++- src/StatementInterface.php | 11 +++- src/Types.php | 9 ++- src/Validator/BooleanValidator.php | 9 ++- src/Validator/DatetimeValidator.php | 9 ++- src/Validator/EnumValidator.php | 9 ++- src/Validator/FloatValidator.php | 9 ++- src/Validator/IntegerValidator.php | 9 ++- src/Validator/NumberValidator.php | 9 ++- src/Validator/StringValidator.php | 9 ++- src/Validator/ValidatorInterface.php | 9 ++- test/Cases/AbstractMysqlCase.php | 15 +++-- test/Cases/AbstractTestCase.php | 16 ++++-- test/Cases/EntityTest.php | 15 +++-- test/Cases/Mysql/ActiveRecordTest.php | 39 +++++++------ test/Cases/Mysql/AggregateTest.php | 27 +++++---- test/Cases/Mysql/QueryBuilderTest.php | 29 ++++++---- test/Cases/Mysql/RelationTest.php | 22 +++++--- test/Cases/Mysql/SqlTest.php | 21 ++++--- test/Cases/Mysql/TrasactionTest.php | 21 ++++--- test/Cases/PoolTest.php | 21 ++++--- test/Testing/Entity/Count.php | 13 ++++- test/Testing/Entity/OtherUser.php | 13 ++++- test/Testing/Entity/User.php | 13 ++++- test/Testing/Pool/DbEnvPoolConfig.php | 11 +++- test/Testing/Pool/DbPptPoolConfig.php | 13 +++-- test/Testing/Pool/DbSlaveEnvPoolConfig.php | 11 +++- test/Testing/Pool/DbSlavePptConfig.php | 11 +++- test/Testing/Pool/OtherDbConfig.php | 13 ++++- test/Testing/Pool/OtherDbPool.php | 13 ++++- test/Testing/Pool/OtherDbSlaveConfig.php | 14 ++++- test/Testing/Pool/OtherDbSlavePool.php | 13 ++++- test/bootstrap.php | 12 +++- test/config/beans/base.php | 9 ++- test/config/beans/log.php | 36 +++++++----- test/config/define.php | 9 ++- test/config/properties/app.php | 18 ++++-- test/config/properties/db.php | 56 +++++++++++-------- test/config/server.php | 8 +++ 98 files changed, 1001 insertions(+), 308 deletions(-) create mode 100644 .php_cs diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..41e1b73 --- /dev/null +++ b/.php_cs @@ -0,0 +1,38 @@ +setRiskyAllowed(true) + ->setRules([ + '@PSR2' => true, + 'header_comment' => [ + 'commentType' => 'PHPDoc', + 'header' => $header, + 'separate' => 'none' + ], + 'array_syntax' => [ + 'syntax' => 'short' + ], + 'single_quote' => true, + 'class_attributes_separation' => true, + 'no_unused_imports' => true, + 'standardize_not_equals' => true, + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->exclude('public') + ->exclude('resources') + ->exclude('config') + ->exclude('runtime') + ->exclude('vendor') + ->in(__DIR__) + ) + ->setUsingCache(false); diff --git a/composer.json b/composer.json index 61a19e0..4f86e10 100644 --- a/composer.json +++ b/composer.json @@ -25,9 +25,14 @@ "src/Helper/Functions.php" ] }, + "require-dev": { + "eaglewu/swoole-ide-helper": "dev-master", + "phpunit/phpunit": "^5.7", + "friendsofphp/php-cs-fixer": "^2.10" + }, "autoload-dev": { "psr-4": { - "Swoft\\Db\\Test\\": "test" + "SwoftTest\\Db\\": "test" } }, "repositories": [ @@ -36,11 +41,8 @@ "url": "https://packagist.phpcomposer.com" } ], - "require-dev": { - "eaglewu/swoole-ide-helper": "dev-master", - "phpunit/phpunit": "^5.7" - }, "scripts": { - "test": "./vendor/bin/phpunit -c phpunit.xml" + "test": "./vendor/bin/phpunit -c phpunit.xml", + "cs-fix": "./vendor/bin/php-cs-fixer fix $1" } } diff --git a/src/AbstractDbConnection.php b/src/AbstractDbConnection.php index e44b980..ac1fffe 100644 --- a/src/AbstractDbConnection.php +++ b/src/AbstractDbConnection.php @@ -1,5 +1,12 @@ currentDb) && $this->currentDb != $this->originDb){ + if (!empty($this->currentDb) && $this->currentDb != $this->originDb) { $this->selectDb($this->originDb); } parent::release($release); diff --git a/src/Bean/Annotation/Column.php b/src/Bean/Annotation/Column.php index ec0928f..404926a 100644 --- a/src/Bean/Annotation/Column.php +++ b/src/Bean/Annotation/Column.php @@ -1,5 +1,12 @@ type; } -} \ No newline at end of file +} diff --git a/src/Bean/Annotation/Entity.php b/src/Bean/Annotation/Entity.php index 3ae4ab6..a94ef7d 100644 --- a/src/Bean/Annotation/Entity.php +++ b/src/Bean/Annotation/Entity.php @@ -1,5 +1,12 @@ driver; } -} \ No newline at end of file +} diff --git a/src/Bean/Annotation/Table.php b/src/Bean/Annotation/Table.php index 5ecbc52..74e2e78 100644 --- a/src/Bean/Annotation/Table.php +++ b/src/Bean/Annotation/Table.php @@ -1,5 +1,12 @@ getType(); @@ -41,5 +48,4 @@ public static function getCollector() { return self::$connects; } - -} \ No newline at end of file +} diff --git a/src/Bean/Collector/EntityCollector.php b/src/Bean/Collector/EntityCollector.php index 6af64b8..99a12a8 100644 --- a/src/Bean/Collector/EntityCollector.php +++ b/src/Bean/Collector/EntityCollector.php @@ -1,5 +1,12 @@ connection === null){ + if ($this->connection === null) { return $this->result; } @@ -97,7 +104,8 @@ private function getResultByType() $connection = $this->connection; if ($this->type == Db::RETURN_INSERTID) { - return $this->connection->getInsertId();; + return $this->connection->getInsertId(); + ; } if ($this->type == Db::RETURN_ROWS) { @@ -113,4 +121,4 @@ private function getResultByType() return $result; } -} \ No newline at end of file +} diff --git a/src/Driver/Driver.php b/src/Driver/Driver.php index 26bd8c1..fa7ff34 100644 --- a/src/Driver/Driver.php +++ b/src/Driver/Driver.php @@ -1,5 +1,12 @@ &$value){ + foreach ($params as $key => &$value) { $value = "'{$value}'"; - if(is_int($key)){ + if (is_int($key)) { $key = sprintf('?%d', $key); } $newParams[$key] = $value; @@ -237,6 +244,7 @@ private function formatSqlByParams(array $params = null) } $this->sql = strtr($this->sql, $newParams); } + /** * 格式化?标记 */ diff --git a/src/Driver/Mysql/MysqlStatement.php b/src/Driver/Mysql/MysqlStatement.php index 4efaa08..f2e928e 100644 --- a/src/Driver/Mysql/MysqlStatement.php +++ b/src/Driver/Mysql/MysqlStatement.php @@ -1,5 +1,12 @@ connection = new \PDO($dsn, $user, $passwd, $pdoOptions); - $this->connection->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION); + $this->connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $this->originDb = $dbName; } @@ -62,7 +69,7 @@ public function createConnection() */ public function prepare(string $sql) { - $this->sql = $sql . " Params:"; + $this->sql = $sql . ' Params:'; $this->stmt = $this->connection->prepare($sql); } diff --git a/src/Entity/AbstractGenerator.php b/src/Entity/AbstractGenerator.php index f8f278a..d285d4d 100644 --- a/src/Entity/AbstractGenerator.php +++ b/src/Entity/AbstractGenerator.php @@ -1,5 +1,12 @@ isEmpty()){ + if ($stack->isEmpty()) { return ''; } return $stack->pop(); } -} \ No newline at end of file +} diff --git a/src/Model.php b/src/Model.php index 86ad354..6cf7c02 100644 --- a/src/Model.php +++ b/src/Model.php @@ -1,5 +1,12 @@ driver; } -} \ No newline at end of file +} diff --git a/src/Pool/Config/DbSlavePoolConfig.php b/src/Pool/Config/DbSlavePoolConfig.php index e6dbb19..513e8a6 100644 --- a/src/Pool/Config/DbSlavePoolConfig.php +++ b/src/Pool/Config/DbSlavePoolConfig.php @@ -1,5 +1,12 @@ criteria($this->where, $column, array($min, $max), self::BETWEEN, $connector); + $this->criteria($this->where, $column, [$min, $max], self::BETWEEN, $connector); return $this; } @@ -640,7 +646,7 @@ public function whereBetween(string $column, $min, $max, string $connector = sel */ public function whereNotBetween(string $column, $min, $max, string $connector = self::LOGICAL_AND): QueryBuilder { - $this->criteria($this->where, $column, array($min, $max), self::NOT_BETWEEN, $connector); + $this->criteria($this->where, $column, [$min, $max], self::NOT_BETWEEN, $connector); return $this; } @@ -738,7 +744,7 @@ public function havingNotIn(string $column, array $values, string $connector = s */ public function havingBetween(string $column, $min, $max, string $connector = self::LOGICAL_AND): QueryBuilder { - $this->criteria($this->having, $column, array($min, $max), self::BETWEEN, $connector); + $this->criteria($this->having, $column, [$min, $max], self::BETWEEN, $connector); return $this; } @@ -755,7 +761,7 @@ public function havingBetween(string $column, $min, $max, string $connector = se */ public function havingNotBetween(string $column, $min, $max, string $connector = self::LOGICAL_AND): QueryBuilder { - $this->criteria($this->having, $column, array($min, $max), self::NOT_BETWEEN, $connector); + $this->criteria($this->having, $column, [$min, $max], self::NOT_BETWEEN, $connector); return $this; } @@ -792,10 +798,10 @@ public function closeHaving(): QueryBuilder */ public function groupBy(string $column, string $order = null): QueryBuilder { - $this->groupBy[] = array( + $this->groupBy[] = [ 'column' => $column, 'order' => $order, - ); + ]; return $this; } @@ -810,10 +816,10 @@ public function groupBy(string $column, string $order = null): QueryBuilder */ public function orderBy(string $column, string $order = self::ORDER_BY_ASC): QueryBuilder { - $this->orderBy[] = array( + $this->orderBy[] = [ 'column' => $column, 'order' => $order, - ); + ]; return $this; } @@ -949,10 +955,10 @@ public function getDecorators(): array */ private function bracketCriteria(array &$criteria, string $bracket = self::BRACKET_OPEN, string $connector = self::LOGICAL_AND): QueryBuilder { - $criteria[] = array( + $criteria[] = [ 'bracket' => $bracket, 'connector' => $connector, - ); + ]; return $this; } @@ -972,15 +978,15 @@ private function join(string $table, $criteria = null, string $type = self::INNE // 是否存在判断... if (\is_string($criteria)) { - $criteria = array($criteria); + $criteria = [$criteria]; } - $this->join[] = array( + $this->join[] = [ 'table' => $table, 'criteria' => $criteria, 'type' => $type, 'alias' => $alias, - ); + ]; return $this; } @@ -1003,12 +1009,12 @@ private function criteria( string $operator = self::OPERATOR_EQ, string $connector = self::LOGICAL_AND ): QueryBuilder { - $criteria[] = array( + $criteria[] = [ 'column' => $column, 'value' => $value, 'operator' => $operator, 'connector' => $connector, - ); + ]; return $this; } @@ -1167,7 +1173,6 @@ private function getInstanceName() return sprintf('%s.%s.%s', $this->instance, $this->node, $this->db); } - /** * 实体类名获取表名 * @@ -1206,7 +1211,6 @@ private function getTableName(): string return $table; } - /** * @return string */ diff --git a/src/QueryBuilderInterface.php b/src/QueryBuilderInterface.php index d8fb351..0ecf213 100644 --- a/src/QueryBuilderInterface.php +++ b/src/QueryBuilderInterface.php @@ -1,5 +1,12 @@ assertEquals('this my desc9', $resultUser2['desc']); $this->assertEquals(99, $resultUser2['age']); } -} \ No newline at end of file +} diff --git a/test/Cases/Mysql/ActiveRecordTest.php b/test/Cases/Mysql/ActiveRecordTest.php index dd69f32..373c3ec 100644 --- a/test/Cases/Mysql/ActiveRecordTest.php +++ b/test/Cases/Mysql/ActiveRecordTest.php @@ -1,10 +1,17 @@ testBatchInsert(); }); } @@ -151,12 +157,12 @@ public function testUpdate(int $id) $this->assertEquals($newName, $newUser->getName()); $userObj=User::findById($id)->getResult(); - $userObj->setName("update"); + $userObj->setName('update'); $result= $userObj->update()->getResult(); $userObj=User::findById($id)->getResult(); - $userObj->setName("update"); + $userObj->setName('update'); $result2= $userObj->update()->getResult(); @@ -176,7 +182,6 @@ public function testUpdateByCo(int $id) }); } - /** * @dataProvider mysqlProvider * @@ -253,7 +258,7 @@ public function testFindByIds(array $ids) $this->assertEquals($userEmpty, []); $queryIds = []; - foreach ($users2 as $user){ + foreach ($users2 as $user) { $queryIds[] = $user['id']; $this->assertEquals(null, $user['name']); } @@ -349,7 +354,7 @@ public function testDeleteOne() public function testDeleteAll(array $ids) { $result = User::deleteAll(['name' => 'name', 'id' => $ids])->getResult(); - $this->assertEquals(2,$result); + $this->assertEquals(2, $result); } /** @@ -374,11 +379,10 @@ public function testUpdateAll(array $ids) { $result = User::updateAll(['name' => 'testUpdateAll'], ['id' => $ids])->getResult(); $count = User::findAll(['name' => 'testUpdateAll', 'id' => $ids])->getResult(); - $this->assertEquals(2,$result); - $this->assertCount(2,$count); + $this->assertEquals(2, $result); + $this->assertCount(2, $count); } - /** * @dataProvider mysqlProvider * @@ -409,11 +413,11 @@ public function testFindAll(array $ids) 'fields' => ['id', 'name'], ]; $result = User::findAll(['name' => 'name'], $options)->getResult(); - $this->assertCount(2,$result); + $this->assertCount(2, $result); $ids = []; /* @var User $user */ - foreach ($result as $key => $user){ + foreach ($result as $key => $user) { $ids[$key] = $user->getId(); $this->assertEquals($user->getName(), 'name'); $this->assertEquals($user->getDesc(), null); @@ -429,5 +433,4 @@ public function testExist() $this->assertTrue(User::exist($id)->getResult()); $this->assertFalse(User::exist('NotExistId')->getResult()); } - -} \ No newline at end of file +} diff --git a/test/Cases/Mysql/AggregateTest.php b/test/Cases/Mysql/AggregateTest.php index 70ef3e2..1eca4ea 100644 --- a/test/Cases/Mysql/AggregateTest.php +++ b/test/Cases/Mysql/AggregateTest.php @@ -1,10 +1,17 @@ testCount($ids); }); } @@ -54,7 +61,7 @@ public function testSum(array $ids) */ public function testSumByCo(array $ids) { - go(function () use ($ids){ + go(function () use ($ids) { $this->testSum($ids); }); } @@ -78,7 +85,7 @@ public function testMax(array $ids) */ public function testMaxByCo(array $ids) { - go(function () use ($ids){ + go(function () use ($ids) { $this->testMax($ids); }); } @@ -102,7 +109,7 @@ public function testMin(array $ids) */ public function testMinByCo(array $ids) { - go(function () use ($ids){ + go(function () use ($ids) { $this->testMin($ids); }); } @@ -126,8 +133,8 @@ public function testAvg(array $ids) */ public function testAvgByCo(array $ids) { - go(function () use ($ids){ + go(function () use ($ids) { $this->testAvg($ids); }); } -} \ No newline at end of file +} diff --git a/test/Cases/Mysql/QueryBuilderTest.php b/test/Cases/Mysql/QueryBuilderTest.php index 4defb59..11e6624 100644 --- a/test/Cases/Mysql/QueryBuilderTest.php +++ b/test/Cases/Mysql/QueryBuilderTest.php @@ -1,11 +1,18 @@ assertCount(5, $user); } - public function testDbInsertByCo() { go(function () { @@ -260,7 +266,7 @@ public function testCondtion2AndByF3() public function testCondtion2AndByF3ByCo() { - go(function (){ + go(function () { $this->testCondtion2AndByF3(); }); } @@ -293,7 +299,7 @@ public function testCondtion3AndByF3(int $id) */ public function testCondtion3AndByF3ByCo(int $id) { - go(function ()use ($id){ + go(function () use ($id) { $this->testCondtion3AndByF3($id); }); } @@ -317,7 +323,7 @@ public function testCondtion4AndByF3(array $ids) */ public function testCondtion4AndByF3ByCo(array $ids) { - go(function ()use ($ids){ + go(function () use ($ids) { $this->testCondtion4AndByF3($ids); }); } @@ -341,9 +347,8 @@ public function testCondtion5AndByF3(array $ids) */ public function testCondtion5AndByF3ByCo(array $ids) { - go(function ()use ($ids){ + go(function () use ($ids) { $this->testCondtion5AndByF3($ids); }); } - -} \ No newline at end of file +} diff --git a/test/Cases/Mysql/RelationTest.php b/test/Cases/Mysql/RelationTest.php index 8f046d7..beeaf87 100644 --- a/test/Cases/Mysql/RelationTest.php +++ b/test/Cases/Mysql/RelationTest.php @@ -1,12 +1,19 @@ testJoin($uid); }); } - -} \ No newline at end of file +} diff --git a/test/Cases/Mysql/SqlTest.php b/test/Cases/Mysql/SqlTest.php index 419f93a..0929510 100644 --- a/test/Cases/Mysql/SqlTest.php +++ b/test/Cases/Mysql/SqlTest.php @@ -1,10 +1,17 @@ getResult(); $user = User::findById($result)->getResult(); @@ -77,7 +84,7 @@ public function testSelect2($id) */ public function testSelect2ByCo($id) { - go(function ()use ($id){ + go(function () use ($id) { $this->testSelect2($id); }); } @@ -135,4 +142,4 @@ public function testUpdateByCo($id) $this->testUpdate($id); }); } -} \ No newline at end of file +} diff --git a/test/Cases/Mysql/TrasactionTest.php b/test/Cases/Mysql/TrasactionTest.php index ca82f8c..7e9a49a 100644 --- a/test/Cases/Mysql/TrasactionTest.php +++ b/test/Cases/Mysql/TrasactionTest.php @@ -1,10 +1,17 @@ testCommit(); }); } @@ -73,8 +80,8 @@ public function testRollback() public function testRollbackByCo() { - go(function (){ + go(function () { $this->testRollback(); }); } -} \ No newline at end of file +} diff --git a/test/Cases/PoolTest.php b/test/Cases/PoolTest.php index bbe84ce..0001810 100644 --- a/test/Cases/PoolTest.php +++ b/test/Cases/PoolTest.php @@ -1,12 +1,19 @@ assertEquals($pConfig->isUseProvider(), false); $this->assertEquals($pConfig->getMaxWait(), 10); } -} \ No newline at end of file +} diff --git a/test/Testing/Entity/Count.php b/test/Testing/Entity/Count.php index 9b3de2e..ac2f912 100644 --- a/test/Testing/Entity/Count.php +++ b/test/Testing/Entity/Count.php @@ -1,6 +1,13 @@ follows = $follows; } -} \ No newline at end of file +} diff --git a/test/Testing/Entity/OtherUser.php b/test/Testing/Entity/OtherUser.php index 03aa2f7..35c5cbf 100644 --- a/test/Testing/Entity/OtherUser.php +++ b/test/Testing/Entity/OtherUser.php @@ -1,6 +1,13 @@ maxIdel; } - - } diff --git a/test/Testing/Pool/DbSlaveEnvPoolConfig.php b/test/Testing/Pool/DbSlaveEnvPoolConfig.php index 4f3034b..4b439b4 100644 --- a/test/Testing/Pool/DbSlaveEnvPoolConfig.php +++ b/test/Testing/Pool/DbSlaveEnvPoolConfig.php @@ -1,6 +1,13 @@ init(); -\Swoft\App::$isInTest = true; \ No newline at end of file +\Swoft\App::$isInTest = true; diff --git a/test/config/beans/base.php b/test/config/beans/base.php index 02a0e87..0cfb5ab 100644 --- a/test/config/beans/base.php +++ b/test/config/beans/base.php @@ -1,5 +1,12 @@ [ 'class' => \Swoft\Event\EventManager::class, diff --git a/test/config/beans/log.php b/test/config/beans/log.php index 5a2e121..14e02d8 100644 --- a/test/config/beans/log.php +++ b/test/config/beans/log.php @@ -1,31 +1,39 @@ [ - "class" => \Swoft\Log\FileHandler::class, - "logFile" => "@runtime/logs/notice.log", + 'noticeHandler' => [ + 'class' => \Swoft\Log\FileHandler::class, + 'logFile' => '@runtime/logs/notice.log', 'formatter' => '${lineFormatter}', - "levels" => [ + 'levels' => [ \Swoft\Log\Logger::NOTICE, \Swoft\Log\Logger::INFO, \Swoft\Log\Logger::DEBUG, \Swoft\Log\Logger::TRACE, ] ], - "applicationHandler" => [ - "class" => \Swoft\Log\FileHandler::class, - "logFile" => "@runtime/logs/error.log", + 'applicationHandler' => [ + 'class' => \Swoft\Log\FileHandler::class, + 'logFile' => '@runtime/logs/error.log', 'formatter' => '${lineFormatter}', - "levels" => [ + 'levels' => [ \Swoft\Log\Logger::ERROR, \Swoft\Log\Logger::WARNING ] ], - "logger" => [ - "class" => \Swoft\Log\Logger::class, - "name" => APP_NAME, - "flushInterval" => 100, - "flushRequest" => true, - "handlers" => [ + 'logger' => [ + 'class' => \Swoft\Log\Logger::class, + 'name' => APP_NAME, + 'flushInterval' => 100, + 'flushRequest' => true, + 'handlers' => [ '${noticeHandler}', '${applicationHandler}' ] diff --git a/test/config/define.php b/test/config/define.php index e18d417..410c414 100644 --- a/test/config/define.php +++ b/test/config/define.php @@ -1,5 +1,12 @@ '1.0', + 'version' => '1.0', 'autoInitBean' => true, - 'beanScan' => [ - 'Swoft\\Db\\Test\\Testing' => BASE_PATH."/Testing", - 'Swoft\\Db' => BASE_PATH."/../src", + 'beanScan' => [ + 'SwoftTest\\Db\\Testing' => BASE_PATH . '/Testing', + 'Swoft\\Db' => BASE_PATH . '/../src', ], 'I18n' => [ 'sourceLanguage' => '@root/resources/messages/', @@ -16,5 +24,5 @@ 'timeout' => 3000 ] ], - 'db' => require dirname(__FILE__) . DS . "db.php", + 'db' => require dirname(__FILE__) . DS . 'db.php', ]; diff --git a/test/config/properties/db.php b/test/config/properties/db.php index 1f6cef8..d203508 100644 --- a/test/config/properties/db.php +++ b/test/config/properties/db.php @@ -1,58 +1,66 @@ [ 'name' => 'master1', - "uri" => [ + 'uri' => [ '127.0.0.1:3301', '127.0.0.1:3301', ], - "maxIdel" => 1, - "maxActive" => 1, - "maxWait" => 1, - "timeout" => 1, - "balancer" => 'random1', - "useProvider" => true, + 'maxIdel' => 1, + 'maxActive' => 1, + 'maxWait' => 1, + 'timeout' => 1, + 'balancer' => 'random1', + 'useProvider' => true, 'provider' => 'consul1', ], 'slave' => [ 'name' => 'slave1', - "uri" => [ + 'uri' => [ '127.0.0.1:3301', '127.0.0.1:3301', ], - "maxIdel" => 1, - "maxActive" => 1, - "maxWait" => 1, - "timeout" => 1, - "balancer" => 'random1', - "useProvider" => true, + 'maxIdel' => 1, + 'maxActive' => 1, + 'maxWait' => 1, + 'timeout' => 1, + 'balancer' => 'random1', + 'useProvider' => true, 'provider' => 'consul1', ], 'other' => [ 'master' => [ 'name' => 'master2', - "uri" => [ + 'uri' => [ '127.0.0.1:3301', '127.0.0.1:3301', ], - "maxIdel" => 1, - "maxActive" => 1, - "maxWait" => 1, - "timeout" => 1, + 'maxIdel' => 1, + 'maxActive' => 1, + 'maxWait' => 1, + 'timeout' => 1, ], 'slave' => [ 'name' => 'slave3', - "uri" => [ + 'uri' => [ '127.0.0.1:3301', '127.0.0.1:3301', ], - "maxIdel" => 1, - "maxActive" => 1, - "maxWait" => 1, - "timeout" => 1, + 'maxIdel' => 1, + 'maxActive' => 1, + 'maxWait' => 1, + 'timeout' => 1, ], ], ]; diff --git a/test/config/server.php b/test/config/server.php index b83d552..26030c8 100644 --- a/test/config/server.php +++ b/test/config/server.php @@ -1,4 +1,12 @@ [ 'pfile' => env('PFILE', '/tmp/swoft.pid'), From 5b1b96c67c5c1aaebc1c6991609cd29909c6af9c Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Tue, 10 Apr 2018 19:32:12 +0800 Subject: [PATCH 24/27] format --- src/Executor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Executor.php b/src/Executor.php index 39c216b..29e87fc 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -218,8 +218,8 @@ public static function exist(string $className, $id): ResultInterface public static function count(string $className, string $column, array $condition): ResultInterface { $instance = self::getInstance($className); - $query = Query::table($className)->selectInstance($instance)->condition($condition)->addDecorator(function ($result){ - if(isset($result['count'])){ + $query = Query::table($className)->selectInstance($instance)->condition($condition)->addDecorator(function ($result) { + if (isset($result['count'])) { return $result['count']; } return 0; From 1fb99eb18c52ec15baa4aa97e2e93aafbd30bb04 Mon Sep 17 00:00:00 2001 From: huangzhhui Date: Tue, 10 Apr 2018 20:16:23 +0800 Subject: [PATCH 25/27] Update README.md --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5bc62de..8defd45 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,15 @@ Swoft Database Component # Install -composer require +Install by [Composer](https://getcomposer.org) +`composer require swoft/db` + +# Require +- Swoole 2.1.2, enable coroutine, enable mysqld +- PDO Mysql + # Document +[Official document](https://doc.swoft.org) # LICENSE -Swoft Database Component is open-sourced software licensed under the [Apache license](LICENSE). +Swoft Database Component is open-sourced software licensed under the [Apache license](LICENSE). \ No newline at end of file From 687ba5b66a74f83d6a3fb7e57773ad2eeac91941 Mon Sep 17 00:00:00 2001 From: Inhere Date: Tue, 10 Apr 2018 20:29:59 +0800 Subject: [PATCH 26/27] Update README.md --- README.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8defd45..1f90a9b 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,24 @@ # Swoft Database + Swoft Database Component -# Install +## Install + Install by [Composer](https://getcomposer.org) -`composer require swoft/db` -# Require +```bash +composer require swoft/db +``` + +## Require + - Swoole 2.1.2, enable coroutine, enable mysqld - PDO Mysql -# Document +## Document + [Official document](https://doc.swoft.org) -# LICENSE -Swoft Database Component is open-sourced software licensed under the [Apache license](LICENSE). \ No newline at end of file +## LICENSE + +Swoft Database Component is open-sourced software licensed under the [Apache license](LICENSE). From 93cd418ebb451fc466fa1e64c85056b10bf9ad0c Mon Sep 17 00:00:00 2001 From: inhere Date: Tue, 10 Apr 2018 21:32:33 +0800 Subject: [PATCH 27/27] run code inspect check --- src/AbstractDbConnection.php | 20 ++++--- src/Bean/Collector/EntityCollector.php | 6 +-- src/Command/EntityCommand.php | 2 +- src/Db.php | 9 ++-- src/DbConnectionInterface.php | 6 +-- src/DbResult.php | 11 ++-- src/Driver/Mysql/MysqlConnection.php | 10 ++-- src/Driver/Mysql/SyncMysqlConnection.php | 12 ++--- src/Entity/Generator.php | 22 ++++---- src/Entity/SetGetGenerator.php | 2 +- .../ResourceReleaseBeforeListener.php | 2 +- src/Executor.php | 30 +++++------ src/Helper/DbHelper.php | 6 +-- src/Helper/EntityHelper.php | 2 +- src/Model.php | 11 ++-- src/Query.php | 2 +- src/QueryBuilder.php | 53 +++++++++---------- src/Statement.php | 8 ++- src/Validator/StringValidator.php | 2 +- 19 files changed, 110 insertions(+), 106 deletions(-) diff --git a/src/AbstractDbConnection.php b/src/AbstractDbConnection.php index ac1fffe..06bb856 100644 --- a/src/AbstractDbConnection.php +++ b/src/AbstractDbConnection.php @@ -42,9 +42,10 @@ public function getDriver(): string */ public function release($release = false) { - if (!empty($this->currentDb) && $this->currentDb != $this->originDb) { + if (!empty($this->currentDb) && $this->currentDb !== $this->originDb) { $this->selectDb($this->originDb); } + parent::release($release); } @@ -58,22 +59,26 @@ public function release($release = false) */ protected function parseUri(string $uri): array { - $parseAry = parse_url($uri); - if (!isset($parseAry['host']) || !isset($parseAry['port']) || !isset($parseAry['path']) || !isset($parseAry['query'])) { + $parseAry = \parse_url($uri); + + if (!isset($parseAry['host'], $parseAry['port'], $parseAry['path'], $parseAry['query'])) { throw new MysqlException('Uri format error uri=' . $uri); } - $parseAry['database'] = str_replace('/', '', $parseAry['path']); + + $parseAry['database'] = \str_replace('/', '', $parseAry['path']); $query = $parseAry['query']; - parse_str($query, $options); - if (!isset($options['user']) || !isset($options['password'])) { + \parse_str($query, $options); + + if (!isset($options['user'], $options['password'])) { throw new MysqlException('Lack of username and password,uri=' . $uri); } + if (!isset($options['charset'])) { $options['charset'] = ''; } - $configs = array_merge($parseAry, $options); + $configs = \array_merge($parseAry, $options); unset($configs['path'], $configs['query']); return $configs; @@ -85,6 +90,7 @@ protected function parseUri(string $uri): array protected function pushSqlToStack(string $sql) { $contextSqlKey = DbHelper::getContextSqlKey(); + /* @var \SplStack $stack */ $stack = RequestContext::getContextDataByKey($contextSqlKey, new \SplStack()); $stack->push($sql); diff --git a/src/Bean/Collector/EntityCollector.php b/src/Bean/Collector/EntityCollector.php index 99a12a8..fb6fcdc 100644 --- a/src/Bean/Collector/EntityCollector.php +++ b/src/Bean/Collector/EntityCollector.php @@ -85,12 +85,12 @@ private static function collectId(string $className, string $propertyName) } /** - * @param Entity $objectAnnotationstring + * @param Entity $objectAnnotation * @param string $className */ - private static function collectEntity(Entity $objectAnnotationstring, string $className) + private static function collectEntity(Entity $objectAnnotation, string $className) { - $instance = $objectAnnotationstring->getInstance(); + $instance = $objectAnnotation->getInstance(); self::$entities[$className]['instance'] = $instance; } diff --git a/src/Command/EntityCommand.php b/src/Command/EntityCommand.php index f052d5f..f5b0acc 100644 --- a/src/Command/EntityCommand.php +++ b/src/Command/EntityCommand.php @@ -104,7 +104,7 @@ private function initDatabase(): bool private function parseDatabaseCommand(string &$database) { if (input()->hasSOpt('d') || input()->hasLOpt('database')) { - $database = input()->hasSOpt('d') ? input()->getShortOpt('d') : input()->getLongOpt('database'); + $database = (string)\input()->getSameOpt(['d','database']); } } diff --git a/src/Db.php b/src/Db.php index 27de316..dac78f0 100644 --- a/src/Db.php +++ b/src/Db.php @@ -53,7 +53,8 @@ class Db * @param string $instance * @param string $className * @param array $resultDecorators - * @return \Swoft\Core\ResultInterface + * @return \Swoft\Core\ResultInterface|DbResult + * @throws DbException */ public static function query(string $sql, array $params = [], string $instance = Pool::INSTANCE, string $className = '', array $resultDecorators = []): ResultInterface { @@ -113,7 +114,7 @@ public static function rollback(string $instance = Pool::INSTANCE) /* @var AbstractDbConnection $connection */ $connection = self::getTransactionConnection($instance); if ($connection === null) { - throw new DbException('No transaction needs to be rollbacked'); + throw new DbException('No transaction needs to be rolled back'); } $connection->rollback(); @@ -150,7 +151,7 @@ private static function getInstanceAndNodeByType(string $instance, string $node, return [$instance, $node]; } - if ($type === Db::RETURN_ROWS || $type == Db::RETURN_INSERTID) { + if ($type === self::RETURN_ROWS || $type === self::RETURN_INSERTID) { return [$instance, Pool::MASTER]; } @@ -277,7 +278,7 @@ private static function getResult($result, ConnectionInterface $connection = nul * @throws DbException * @return array */ - private static function transferParams($params) + private static function transferParams($params): array { $newParams = []; foreach ($params as $key => $value) { diff --git a/src/DbConnectionInterface.php b/src/DbConnectionInterface.php index 7a1bacd..636d3ae 100644 --- a/src/DbConnectionInterface.php +++ b/src/DbConnectionInterface.php @@ -39,7 +39,7 @@ public function getInsertId(); /** * @return int */ - public function getAffectedRows(); + public function getAffectedRows(): int; /** * @return mixed @@ -64,7 +64,7 @@ public function commit(); public function selectDb(string $db); /** - * Destory + * Destroy */ - public function destory(); + public function destroy(); } diff --git a/src/DbResult.php b/src/DbResult.php index 9305373..1041b02 100644 --- a/src/DbResult.php +++ b/src/DbResult.php @@ -38,7 +38,7 @@ abstract class DbResult extends AbstractResult * @param int $type * @return $this */ - public function setType(int $type) + public function setType(int $type): self { $this->type = $type; return $this; @@ -48,7 +48,7 @@ public function setType(int $type) * @param string $className * @return $this */ - public function setClassName(string $className) + public function setClassName(string $className): self { $this->className = $className; return $this; @@ -58,7 +58,7 @@ public function setClassName(string $className) * @param array $decorators * @return $this */ - public function setDecorators(array $decorators) + public function setDecorators(array $decorators): self { $this->decorators = $decorators; return $this; @@ -72,11 +72,11 @@ protected function getResultByClassName() $className = $this->className; $result = $this->getResultByType(); - if (isset($result[0]) && !empty($className)) { + if (!empty($className) && isset($result[0])) { return EntityHelper::listToEntity($result, $className); } - if (is_array($result) && !empty($result) && !empty($className)) { + if (\is_array($result) && !empty($result) && !empty($className)) { return EntityHelper::arrayToEntity($result, $className); } @@ -105,7 +105,6 @@ private function getResultByType() if ($this->type == Db::RETURN_INSERTID) { return $this->connection->getInsertId(); - ; } if ($this->type == Db::RETURN_ROWS) { diff --git a/src/Driver/Mysql/MysqlConnection.php b/src/Driver/Mysql/MysqlConnection.php index b5c572d..1723fee 100644 --- a/src/Driver/Mysql/MysqlConnection.php +++ b/src/Driver/Mysql/MysqlConnection.php @@ -25,7 +25,7 @@ class MysqlConnection extends AbstractDbConnection /** * @var Mysql */ - private $connection = null; + private $connection; /** * @var string @@ -211,9 +211,9 @@ public function getSql(): string } /** - * Destory sql + * Destroy sql */ - public function destory() + public function destroy() { $this->sql = ''; } @@ -230,9 +230,9 @@ private function formatSqlByParams(array $params = null) } $newParams = []; - foreach ($params as $key => &$value) { + foreach ($params as $key => $value) { $value = "'{$value}'"; - if (is_int($key)) { + if (\is_int($key)) { $key = sprintf('?%d', $key); } $newParams[$key] = $value; diff --git a/src/Driver/Mysql/SyncMysqlConnection.php b/src/Driver/Mysql/SyncMysqlConnection.php index 27b5867..03e8585 100644 --- a/src/Driver/Mysql/SyncMysqlConnection.php +++ b/src/Driver/Mysql/SyncMysqlConnection.php @@ -34,7 +34,7 @@ class SyncMysqlConnection extends AbstractDbConnection /** * @var string */ - private $sql; + private $sql = ''; /** * Create connection @@ -102,8 +102,8 @@ private function bindParams(array $params = null) } foreach ($params as $key => $value) { - if (is_int($key)) { - $key = $key + 1; + if (\is_int($key)) { + ++$key; } $this->stmt->bindValue($key, $value); } @@ -191,9 +191,9 @@ public function commit() } /** - * Destory sql + * Destroy sql */ - public function destory() + public function destroy() { $this->sql = ''; $this->stmt = null; @@ -202,7 +202,7 @@ public function destory() /** * @return string */ - public function getSql() + public function getSql(): string { return $this->sql; } diff --git a/src/Entity/Generator.php b/src/Entity/Generator.php index 1f5a0b6..af47203 100644 --- a/src/Entity/Generator.php +++ b/src/Entity/Generator.php @@ -211,11 +211,13 @@ public function __get($name) $method = 'get' . ucfirst($name); if (method_exists($this, $method)) { return $this->$method(); - } elseif (method_exists($this, 'set' . ucfirst($name))) { - throw new \RunTimeException('the property only access write' . get_class($this) . '::' . $name); - } else { - throw new \RunTimeException('unknow the property' . get_class($this) . '::' . $name); } + + if (method_exists($this, 'set' . ucfirst($name))) { + throw new \RunTimeException('the property only access write' . \get_class($this) . '::' . $name); + } + + throw new \RunTimeException('unknown the property' . \get_class($this) . '::' . $name); } /** @@ -233,12 +235,14 @@ public function __set($name, $value): self { // TODO add pair method __isset() $method = 'set' . ucfirst($name); - if (method_exists($this, $method)) { + if (\method_exists($this, $method)) { return $this->$method($value); - } elseif (method_exists($this, 'get' . ucfirst($name))) { - throw new \RunTimeException('the property only access read' . get_class($this) . '::' . $name); - } else { - throw new \RunTimeException('unknow the property' . get_class($this) . '::' . $name); } + + if (\method_exists($this, 'get' . ucfirst($name))) { + throw new \RunTimeException('the property only access read' . \get_class($this) . '::' . $name); + } + + throw new \RunTimeException('unknown the property' . \get_class($this) . '::' . $name); } } diff --git a/src/Entity/SetGetGenerator.php b/src/Entity/SetGetGenerator.php index 21e73d7..cec8c6b 100644 --- a/src/Entity/SetGetGenerator.php +++ b/src/Entity/SetGetGenerator.php @@ -43,7 +43,7 @@ class SetGetGenerator private $propertyStubFile = 'Property.stub'; /** - * @var string $setterStub SettrStub + * @var string $setterStub SetterStub */ private $setterStubFile = 'Setter.stub'; diff --git a/src/Event/Listeners/ResourceReleaseBeforeListener.php b/src/Event/Listeners/ResourceReleaseBeforeListener.php index 5d8deaa..2a68293 100644 --- a/src/Event/Listeners/ResourceReleaseBeforeListener.php +++ b/src/Event/Listeners/ResourceReleaseBeforeListener.php @@ -53,7 +53,7 @@ public function handle(EventInterface $event) if ($connection instanceof AbstractDbConnection) { $connection->rollback(); - Log::error(sprintf('%s transaction is not committed or rollbacked', get_class($connection))); + Log::error(sprintf('%s transaction is not committed or rollbacked', \get_class($connection))); } } } diff --git a/src/Executor.php b/src/Executor.php index 29e87fc..a59e548 100644 --- a/src/Executor.php +++ b/src/Executor.php @@ -28,7 +28,7 @@ class Executor */ public static function save($entity): ResultInterface { - $className = get_class($entity); + $className = \get_class($entity); list($table, , , $fields) = self::getFields($entity, 1); $instance = self::getInstance($className); @@ -57,7 +57,7 @@ public static function batchInsert(string $className, array $rows): ResultInterf */ public static function delete($entity): ResultInterface { - $className = get_class($entity); + $className = \get_class($entity); list($table, , , $fields) = self::getFields($entity, 3); $instance = self::getInstance($className); @@ -132,7 +132,7 @@ public static function deleteAll(string $className, array $condition) */ public static function update($entity): ResultInterface { - $className = get_class($entity); + $className = \get_class($entity); list($table, $idColumn, $idValue, $fields) = self::getFields($entity, 2); if (empty($fields)) { @@ -179,7 +179,7 @@ public static function updateAll(string $className, array $attributes, array $co */ public static function find($entity): ResultInterface { - $className = get_class($entity); + $className = \get_class($entity); list($tableName, , , $fields) = self::getFields($entity, 3); $instance = self::getInstance($className); @@ -429,18 +429,18 @@ private static function validate(array $columnAry, $propertyValue) */ private static function getEntityProValue($entity, string $proName) { - $proName = explode('_', $proName); - $proName = array_map(function ($word) { - return ucfirst($word); - }, $proName); - $proName = implode('', $proName); + $tmpNodes = \explode('_', $proName); + $tmpNodes = \array_map(function ($word) { + return \ucfirst($word); + }, $tmpNodes); + $proName = \implode('', $tmpNodes); $getterMethod = 'get' . $proName; - if (!method_exists($entity, $getterMethod)) { - throw new \InvalidArgumentException('实体对象属性getter方法不存在,properName=' . $proName); + + if (!\method_exists($entity, $getterMethod)) { + throw new \InvalidArgumentException('Entity object property getter method does not exist, properName=' . $proName); } - $proValue = $entity->$getterMethod(); - return $proValue; + return $entity->$getterMethod(); } /** @@ -453,14 +453,14 @@ private static function getClassMetaData($entity): array { // 不是对象 if (!\is_object($entity) && !class_exists($entity)) { - throw new \InvalidArgumentException('实体不是对象'); + throw new \InvalidArgumentException('Entity is not an object'); } // 对象实例不是实体 $entities = EntityCollector::getCollector(); $className = \is_string($entity) ? $entity : \get_class($entity); if (!isset($entities[$className]['table']['name'])) { - throw new \InvalidArgumentException('对象不是实体对象,className=' . $className); + throw new \InvalidArgumentException('Object is not an entity object, className=' . $className); } return self::getTable($className); diff --git a/src/Helper/DbHelper.php b/src/Helper/DbHelper.php index 24cdd75..4388fcc 100644 --- a/src/Helper/DbHelper.php +++ b/src/Helper/DbHelper.php @@ -55,7 +55,7 @@ public static function getPool(string $group, string $node): PoolInterface public static function getStatementClassNameByInstance(string $instance): string { - $pool = DbHelper::getPool($instance, Pool::MASTER); + $pool = self::getPool($instance, Pool::MASTER); /* @var \Swoft\Db\Pool\Config\DbPoolProperties $poolConfig */ $poolConfig = $pool->getPoolConfig(); $driver = $poolConfig->getDriver(); @@ -87,7 +87,7 @@ public static function getTsInstanceKey(string $instance): string public static function getDriverByInstance(string $instance): string { - $pool = DbHelper::getPool($instance, Pool::MASTER); + $pool = self::getPool($instance, Pool::MASTER); /* @var DbPoolProperties $poolConfig */ $poolConfig = $pool->getPoolConfig(); @@ -103,7 +103,7 @@ public static function getDriverByInstance(string $instance): string private static function getPoolName(string $group, string $node): string { $groupNode = explode(self::GROUP_NODE_DELIMITER, $group); - if (count($groupNode) == 2) { + if (\count($groupNode) == 2) { return $group; } diff --git a/src/Helper/EntityHelper.php b/src/Helper/EntityHelper.php index b427e18..cded85d 100644 --- a/src/Helper/EntityHelper.php +++ b/src/Helper/EntityHelper.php @@ -111,7 +111,7 @@ public static function transferParameter($key, $value, $type): array // 参数值类型转换 if ($type !== null) { - $value = EntityHelper::trasferTypes($type, $value); + $value = self::trasferTypes($type, $value); } return [$key, $value]; diff --git a/src/Model.php b/src/Model.php index 9e4270f..71fa379 100644 --- a/src/Model.php +++ b/src/Model.php @@ -14,7 +14,7 @@ use Swoft\Db\Bean\Collector\EntityCollector; /** - * Activerecord + * ActiveRecord */ class Model implements \ArrayAccess, \Iterator, Arrayable { @@ -257,7 +257,7 @@ public function setAttrs(array $attrs) * * @return \Swoft\Db\Model */ - public function fill(array $attributes) + public function fill(array $attributes): self { foreach ($attributes as $name => $value) { $methodName = sprintf('set%s', ucfirst($name)); @@ -288,7 +288,7 @@ public function toArray(): array $data = []; foreach ($columns as $propertyName => $column) { $methodName = sprintf('get%s', ucfirst($propertyName)); - if (!method_exists($this, $methodName) || !isset($column['column'])) { + if (!isset($column['column']) || !\method_exists($this, $methodName)) { continue; } @@ -330,9 +330,8 @@ public function offsetExists($offset) public function offsetGet($offset) { $data = $this->toArray(); - $value = $data[$offset]??null; - return $value; + return $data[$offset]??null; } /** @@ -391,7 +390,7 @@ public function key() * @return boolean The return value will be casted to boolean and then evaluated. * Returns true on success or false on failure. */ - public function valid() + public function valid(): bool { return ($this->current() !== false); } diff --git a/src/Query.php b/src/Query.php index 1dee5c2..a4db400 100644 --- a/src/Query.php +++ b/src/Query.php @@ -20,7 +20,7 @@ class Query * * @return QueryBuilder */ - public static function table(string $tableName, string $alias = null) + public static function table(string $tableName, string $alias = null): QueryBuilder { $query = new QueryBuilder(); $query = $query->table($tableName, $alias); diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 7e69ee6..d283c57 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -279,7 +279,7 @@ class QueryBuilder implements QueryBuilderInterface * @param array $values * * @return ResultInterface - * @throws DbException + * @throws MysqlException */ public function insert(array $values): ResultInterface { @@ -294,7 +294,7 @@ public function insert(array $values): ResultInterface * @param array $rows * * @return ResultInterface - * @throws DbException + * @throws MysqlException */ public function batchInsert(array $rows): ResultInterface { @@ -314,7 +314,7 @@ public function batchInsert(array $rows): ResultInterface * @param array $values * * @return ResultInterface - * @throws DbException + * @throws MysqlException */ public function update(array $values): ResultInterface { @@ -359,8 +359,9 @@ public function get(array $columns = ['*']): ResultInterface * @param string $alias * * @return QueryBuilder + * @throws DbException */ - public function table(string $table, string $alias = null) + public function table(string $table, string $alias = null): self { $this->table['table'] = $this->getTableNameByClassName($table); $this->table['alias'] = $alias; @@ -467,7 +468,7 @@ public function where(string $column, $value, $operator = self::OPERATOR_EQ, $co * * @return \Swoft\Db\QueryBuilder */ - public function condition(array $condition) + public function condition(array $condition): self { foreach ($condition as $key => $value) { if (\is_int($key)) { @@ -487,7 +488,7 @@ public function condition(array $condition) public function operatorCondition(array $condition) { foreach ($condition as $column => $value) { - if (is_array($value)) { + if (\is_array($value)) { $this->whereIn($column, $value); continue; } @@ -880,25 +881,23 @@ public function setParameter($key, $value, $type = null): QueryBuilder * @throws \Swoft\Db\Exception\DbException * @return $this */ - public function setParameters(array $parameters) + public function setParameters(array $parameters): self { // 循环设置每个参数 foreach ($parameters as $index => $parameter) { - $key = null; - $type = null; - $value = null; + $key = $type = $value = null; if (\count($parameter) >= 3) { list($key, $value, $type) = $parameter; } elseif (\count($parameter) == 2) { list($key, $value) = $parameter; - } elseif (!is_array($parameter)) { + } elseif (!\is_array($parameter)) { $key = $index; $value = $parameter; } if ($key === null || $value === null) { - App::warning('sql参数设置格式错误,parameters=' . json_encode($parameters)); + App::warning('Sql parameter formatting error, parameters=' . \json_encode($parameters)); continue; } $this->setParameter($key, $value, $type); @@ -911,7 +910,7 @@ public function setParameters(array $parameters) * @param \Closure $closure * @return $this */ - public function addDecorator(\Closure $closure) + public function addDecorator(\Closure $closure): self { $this->decorators[] = $closure; return $this; @@ -920,7 +919,7 @@ public function addDecorator(\Closure $closure) /** * @return $this */ - public function clearDecorators() + public function clearDecorators(): self { $this->decorators = []; return $this; @@ -930,7 +929,7 @@ public function clearDecorators() * @param array $decorators * @return $this */ - public function setDecorators(array $decorators) + public function setDecorators(array $decorators): self { $this->decorators = $decorators; return $this; @@ -1024,7 +1023,7 @@ private function criteria( * * @return QueryBuilder */ - public function selectDb(string $db) + public function selectDb(string $db): self { $this->db = $db; @@ -1036,7 +1035,7 @@ public function selectDb(string $db) * * @return QueryBuilder */ - public function selectNode(string $node = Pool::MASTER) + public function selectNode(string $node = Pool::MASTER): self { $this->node = $node; @@ -1048,7 +1047,7 @@ public function selectNode(string $node = Pool::MASTER) * * @return QueryBuilder */ - public function className(string $className) + public function className(string $className): self { $this->className = $className; @@ -1060,7 +1059,7 @@ public function className(string $className) * * @return QueryBuilder */ - public function selectInstance(string $instance) + public function selectInstance(string $instance): self { $this->instance = $instance; @@ -1072,7 +1071,7 @@ public function selectInstance(string $instance) * * @return QueryBuilder */ - public function force(bool $master = true) + public function force(bool $master = true): self { if ($master) { $this->node = Pool::MASTER; @@ -1168,7 +1167,7 @@ public function execute() /** * @return string */ - private function getInstanceName() + private function getInstanceName(): string { return sprintf('%s.%s.%s', $this->instance, $this->node, $this->db); } @@ -1190,11 +1189,10 @@ private function getTableNameByClassName($tableName): string $entities = EntityCollector::getCollector(); if (!isset($entities[$tableName]['table']['name'])) { - throw new DbException('类不是实体,className=' . $tableName); + throw new DbException('Class is not an entity,className=' . $tableName); } - $name = $entities[$tableName]['table']['name']; - return $name; + return $entities[$tableName]['table']['name']; } /** @@ -1204,11 +1202,10 @@ private function getTableNameByClassName($tableName): string private function getTableName(): string { if (empty($this->table)) { - throw new MysqlException('Table name must be setted!'); + throw new MysqlException('Table name must be setting!'); } - $table = $this->table['table']; - return $table; + return $this->table['table']; } /** @@ -1258,7 +1255,7 @@ public function getSet(): array public function getFrom(): array { if (empty($this->table)) { - throw new MysqlException('Table name must be setted!'); + throw new MysqlException('Table name must be set!'); } return $this->table; diff --git a/src/Statement.php b/src/Statement.php index 6056350..b1eedd9 100644 --- a/src/Statement.php +++ b/src/Statement.php @@ -346,7 +346,7 @@ protected function getJoinCriteria(int $joinIndex, string $table, string $statem foreach ($criteria as $x => $criterion) { // 多个条件连接使用and逻辑符号 if ($x !== 0) { - $statement .= ' ' . self::LOGICAL_AND . ' '; + $statement .= ' ' . QueryBuilder::LOGICAL_AND . ' '; } // 条件里面不包含'='符号,默认关联上一个join表 @@ -801,9 +801,8 @@ protected function isUpdate(): bool protected function getFrom(): string { $from = $this->builder->getFrom(); - $table = $from['table']??''; - return $table; + return $from['table'] ?? ''; } /** @@ -814,9 +813,8 @@ protected function getFrom(): string protected function getFromAlias(): string { $from = $this->builder->getFrom(); - $alias = $from['alias']??''; - return $alias; + return $from['alias']??''; } /** diff --git a/src/Validator/StringValidator.php b/src/Validator/StringValidator.php index 14df9d0..8aab575 100644 --- a/src/Validator/StringValidator.php +++ b/src/Validator/StringValidator.php @@ -18,7 +18,7 @@ class StringValidator implements ValidatorInterface { /** - * @param string $column Colunm name + * @param string $column Column name * @param mixed $value Column value * @param array ...$params Other parameters * @throws ValidatorException When validation failures, will throw an Exception