diff --git a/thinkphp/library/think/db/Connection.php b/thinkphp/library/think/db/Connection.php index 7720282d..24fe07f4 100644 --- a/thinkphp/library/think/db/Connection.php +++ b/thinkphp/library/think/db/Connection.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -90,8 +90,6 @@ abstract class Connection 'master_num' => 1, // 指定从服务器序号 'slave_no' => '', - // 模型写入后自动读取主服务器 - 'read_master' => false, // 是否严格检查字段是否存在 'fields_strict' => true, // 数据返回类型 @@ -356,15 +354,15 @@ abstract class Connection $this->bind = $bind; } + // 释放前次的查询结果 + if (!empty($this->PDOStatement)) { + $this->free(); + } + Db::$queryTimes++; try { // 调试开始 $this->debug(true); - - // 释放前次的查询结果 - if (!empty($this->PDOStatement)) { - $this->free(); - } // 预处理 if (empty($this->PDOStatement)) { $this->PDOStatement = $this->linkID->prepare($sql); @@ -380,7 +378,7 @@ abstract class Connection // 执行查询 $this->PDOStatement->execute(); // 调试结束 - $this->debug(false, '', $master); + $this->debug(false); // 返回结果集 return $this->getResult($pdo, $procedure); } catch (\PDOException $e) { @@ -388,11 +386,6 @@ abstract class Connection return $this->close()->query($sql, $bind, $master, $pdo); } throw new PDOException($e, $this->config, $this->getLastsql()); - } catch (\Throwable $e) { - if ($this->isBreak($e)) { - return $this->close()->query($sql, $bind, $master, $pdo); - } - throw $e; } catch (\Exception $e) { if ($this->isBreak($e)) { return $this->close()->query($sql, $bind, $master, $pdo); @@ -404,14 +397,13 @@ abstract class Connection /** * 执行语句 * @access public - * @param string $sql sql指令 - * @param array $bind 参数绑定 - * @param Query $query 查询对象 + * @param string $sql sql指令 + * @param array $bind 参数绑定 * @return int * @throws PDOException * @throws \Exception */ - public function execute($sql, $bind = [], Query $query = null) + public function execute($sql, $bind = []) { $this->initConnect(true); if (!$this->linkID) { @@ -424,15 +416,15 @@ abstract class Connection $this->bind = $bind; } + //释放前次的查询结果 + if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) { + $this->free(); + } + Db::$executeTimes++; try { // 调试开始 $this->debug(true); - - //释放前次的查询结果 - if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) { - $this->free(); - } // 预处理 if (empty($this->PDOStatement)) { $this->PDOStatement = $this->linkID->prepare($sql); @@ -448,27 +440,18 @@ abstract class Connection // 执行语句 $this->PDOStatement->execute(); // 调试结束 - $this->debug(false, '', true); - - if ($query && !empty($this->config['deploy']) && !empty($this->config['read_master'])) { - $query->readMaster(); - } + $this->debug(false); $this->numRows = $this->PDOStatement->rowCount(); return $this->numRows; } catch (\PDOException $e) { if ($this->isBreak($e)) { - return $this->close()->execute($sql, $bind, $query); + return $this->close()->execute($sql, $bind); } throw new PDOException($e, $this->config, $this->getLastsql()); - } catch (\Throwable $e) { - if ($this->isBreak($e)) { - return $this->close()->execute($sql, $bind, $query); - } - throw $e; } catch (\Exception $e) { if ($this->isBreak($e)) { - return $this->close()->execute($sql, $bind, $query); + return $this->close()->execute($sql, $bind); } throw $e; } @@ -483,10 +466,6 @@ abstract class Connection */ public function getRealSql($sql, array $bind = []) { - if (is_array($sql)) { - $sql = implode(';', $sql); - } - foreach ($bind as $key => $val) { $value = is_array($val) ? $val[0] : $val; $type = is_array($val) ? $val[1] : PDO::PARAM_STR; @@ -499,8 +478,8 @@ abstract class Connection $sql = is_numeric($key) ? substr_replace($sql, $value, strpos($sql, '?'), 1) : str_replace( - [':' . $key . ')', ':' . $key . ',', ':' . $key . ' ', ':' . $key . PHP_EOL], - [$value . ')', $value . ',', $value . ' ', $value . PHP_EOL], + [':' . $key . ')', ':' . $key . ',', ':' . $key . ' '], + [$value . ')', $value . ',', $value . ' '], $sql . ' '); } return rtrim($sql); @@ -669,11 +648,6 @@ abstract class Connection return $this->close()->startTrans(); } throw $e; - } catch (\Error $e) { - if ($this->isBreak($e)) { - return $this->close()->startTrans(); - } - throw $e; } } @@ -751,7 +725,7 @@ abstract class Connection * @param array $sqlArray SQL批处理指令 * @return boolean */ - public function batchQuery($sqlArray = [], $bind = [], Query $query = null) + public function batchQuery($sqlArray = []) { if (!is_array($sqlArray)) { return false; @@ -760,7 +734,7 @@ abstract class Connection $this->startTrans(); try { foreach ($sqlArray as $sql) { - $this->execute($sql, $bind, $query); + $this->execute($sql); } // 提交事务 $this->commit(); @@ -768,7 +742,6 @@ abstract class Connection $this->rollback(); throw $e; } - return true; } @@ -830,7 +803,6 @@ abstract class Connection 'SSL connection has been closed unexpectedly', 'Error writing data to the connection', 'Resource deadlock avoided', - 'failed with errno', ]; $error = $e->getMessage(); @@ -911,10 +883,9 @@ abstract class Connection * @access protected * @param boolean $start 调试开始标记 true 开始 false 结束 * @param string $sql 执行的SQL语句 留空自动获取 - * @param boolean $master 主从标记 * @return void */ - protected function debug($start, $sql = '', $master = false) + protected function debug($start, $sql = '') { if (!empty($this->config['debug'])) { // 开启数据库调试模式 @@ -931,7 +902,7 @@ abstract class Connection $result = $this->getExplain($sql); } // SQL监听 - $this->trigger($sql, $runtime, $result, $master); + $this->trigger($sql, $runtime, $result); } } } @@ -953,27 +924,19 @@ abstract class Connection * @param string $sql SQL语句 * @param float $runtime SQL运行时间 * @param mixed $explain SQL分析 - * @param bool $master 主从标记 - * @return void + * @return bool */ - protected function trigger($sql, $runtime, $explain = [], $master = false) + protected function trigger($sql, $runtime, $explain = []) { if (!empty(self::$event)) { foreach (self::$event as $callback) { if (is_callable($callback)) { - call_user_func_array($callback, [$sql, $runtime, $explain, $master]); + call_user_func_array($callback, [$sql, $runtime, $explain]); } } } else { // 未注册监听则记录到日志中 - if ($this->config['deploy']) { - // 分布式记录当前操作的主从 - $master = $master ? 'master|' : 'slave|'; - } else { - $master = ''; - } - - Log::record('[ SQL ] ' . $sql . ' [ ' . $master . 'RunTime:' . $runtime . 's ]', 'sql'); + Log::record('[ SQL ] ' . $sql . ' [ RunTime:' . $runtime . 's ]', 'sql'); if (!empty($explain)) { Log::record('[ EXPLAIN : ' . var_export($explain, true) . ' ]', 'sql'); } diff --git a/thinkphp/library/think/db/Query.php b/thinkphp/library/think/db/Query.php index b63c38e5..e03ad8a7 100644 --- a/thinkphp/library/think/db/Query.php +++ b/thinkphp/library/think/db/Query.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -53,16 +53,14 @@ class Query protected static $info = []; // 回调事件 private static $event = []; - // 读取主库 - private static $readMaster = []; /** * 构造函数 * @access public * @param Connection $connection 数据库对象实例 - * @param Model $model 模型对象 + * @param string $model 模型名 */ - public function __construct(Connection $connection = null, $model = null) + public function __construct(Connection $connection = null, $model = '') { $this->connection = $connection ?: Db::connect([], true); $this->prefix = $this->connection->getConfig('prefix'); @@ -133,34 +131,15 @@ class Query } /** - * 获取当前的模型对象实例 + * 获取当前的模型对象名 * @access public - * @return Model|null + * @return string */ public function getModel() { return $this->model; } - /** - * 设置后续从主库读取数据 - * @access public - * @param bool $allTable - * @return void - */ - public function readMaster($allTable = false) - { - if ($allTable) { - $table = '*'; - } else { - $table = isset($this->options['table']) ? $this->options['table'] : $this->getTable(); - } - - static::$readMaster[$table] = true; - - return $this; - } - /** * 获取当前的builder实例对象 * @access public @@ -259,7 +238,7 @@ class Query */ public function execute($sql, $bind = []) { - return $this->connection->execute($sql, $bind, $this); + return $this->connection->execute($sql, $bind); } /** @@ -333,9 +312,9 @@ class Query * @param array $sql SQL批处理指令 * @return boolean */ - public function batchQuery($sql = [], $bind = []) + public function batchQuery($sql = []) { - return $this->connection->batchQuery($sql, $bind); + return $this->connection->batchQuery($sql); } /** @@ -424,7 +403,7 @@ class Query if (empty($this->options['table'])) { $this->options['table'] = $this->getTable(); } - $key = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . $field . serialize($this->options) . serialize($this->bind)); + $key = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options) . serialize($this->bind)); $result = Cache::get($key); } if (false === $result) { @@ -441,7 +420,7 @@ class Query $result += 0; } - if (isset($cache) && false !== $result) { + if (isset($cache)) { // 缓存数据 $this->cacheData($key, $result, $cache); } @@ -468,7 +447,7 @@ class Query if (empty($this->options['table'])) { $this->options['table'] = $this->getTable(); } - $guid = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . $field . serialize($this->options) . serialize($this->bind)); + $guid = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options) . serialize($this->bind)); $result = Cache::get($guid); } if (false === $result) { @@ -555,24 +534,22 @@ class Query * MIN查询 * @access public * @param string $field 字段名 - * @param bool $force 强制转为数字类型 * @return mixed */ - public function min($field, $force = true) + public function min($field) { - return $this->value('MIN(' . $field . ') AS tp_min', 0, $force); + return $this->value('MIN(' . $field . ') AS tp_min', 0, true); } /** * MAX查询 * @access public * @param string $field 字段名 - * @param bool $force 强制转为数字类型 * @return mixed */ - public function max($field, $force = true) + public function max($field) { - return $this->value('MAX(' . $field . ') AS tp_max', 0, $force); + return $this->value('MAX(' . $field . ') AS tp_max', 0, true); } /** @@ -630,7 +607,7 @@ class Query return true; } } - return $this->setField($field, ['inc', $step]); + return $this->setField($field, ['exp', $field . '+' . $step]); } /** @@ -658,9 +635,8 @@ class Query $this->options = []; return true; } - return $this->setField($field, ['inc', $step]); } - return $this->setField($field, ['dec', $step]); + return $this->setField($field, ['exp', $field . '-' . $step]); } /** @@ -728,8 +704,7 @@ class Query { // 传入的表名为数组 if (is_array($join)) { - $table = $join; - $alias = array_shift($join); + list($table, $alias) = each($join); } else { $join = trim($join); if (false !== strpos($join, '(')) { @@ -750,9 +725,13 @@ class Query $table = $this->getTable($table); } } - if (isset($alias) && $table != $alias) { - $table = [$table => $alias]; + } + if (isset($alias)) { + if (isset($this->options['alias'][$table])) { + $table = $table . '@think' . uniqid(); } + $table = [$table => $alias]; + $this->alias($table); } return $table; } @@ -790,15 +769,8 @@ class Query { if (empty($field)) { return $this; - } elseif ($field instanceof Expression) { - $this->options['field'][] = $field; - return $this; } - if (is_string($field)) { - if (preg_match('/[\<\'\"\(]/', $field)) { - return $this->fieldRaw($field); - } $field = array_map('trim', explode(',', $field)); } if (true === $field) { @@ -822,30 +794,12 @@ class Query } if (isset($this->options['field'])) { - $field = array_merge((array) $this->options['field'], $field); + $field = array_merge($this->options['field'], $field); } $this->options['field'] = array_unique($field); return $this; } - /** - * 表达式方式指定查询字段 - * @access public - * @param string $field 字段名 - * @param array $bind 参数绑定 - * @return $this - */ - public function fieldRaw($field, array $bind = []) - { - $this->options['field'][] = $this->raw($field); - - if ($bind) { - $this->bind($bind); - } - - return $this; - } - /** * 设置数据 * @access public @@ -874,7 +828,7 @@ class Query { $fields = is_string($field) ? explode(',', $field) : $field; foreach ($fields as $field) { - $this->data($field, ['inc', $step]); + $this->data($field, ['exp', $field . '+' . $step]); } return $this; } @@ -890,7 +844,7 @@ class Query { $fields = is_string($field) ? explode(',', $field) : $field; foreach ($fields as $field) { - $this->data($field, ['dec', $step]); + $this->data($field, ['exp', $field . '-' . $step]); } return $this; } @@ -904,36 +858,25 @@ class Query */ public function exp($field, $value) { - $this->data($field, $this->raw($value)); + $this->data($field, ['exp', $value]); return $this; } - /** - * 使用表达式设置数据 - * @access public - * @param mixed $value 表达式 - * @return Expression - */ - public function raw($value) - { - return new Expression($value); - } - /** * 指定JOIN查询字段 * @access public * @param string|array $table 数据表 * @param string|array $field 查询字段 - * @param mixed $on JOIN条件 + * @param string|array $on JOIN条件 * @param string $type JOIN类型 * @return $this */ public function view($join, $field = true, $on = null, $type = 'INNER') { $this->options['view'] = true; - if (is_array($join) && key($join) === 0) { + if (is_array($join) && key($join) !== 0) { foreach ($join as $key => $val) { - $this->view($val[0], $val[1], isset($val[2]) ? $val[2] : null, isset($val[3]) ? $val[3] : 'INNER'); + $this->view($key, $val[0], isset($val[1]) ? $val[1] : null, isset($val[2]) ? $val[2] : 'INNER'); } } else { $fields = []; @@ -1032,37 +975,6 @@ class Query return $this; } - /** - * 指定表达式查询条件 - * @access public - * @param string $where 查询条件 - * @param array $bind 参数绑定 - * @param string $logic 查询逻辑 and or xor - * @return $this - */ - public function whereRaw($where, $bind = [], $logic = 'AND') - { - $this->options['where'][$logic][] = $this->raw($where); - - if ($bind) { - $this->bind($bind); - } - - return $this; - } - - /** - * 指定表达式查询条件 OR - * @access public - * @param string $where 查询条件 - * @param array $bind 参数绑定 - * @return $this - */ - public function whereOrRaw($where, $bind = []) - { - return $this->whereRaw($where, $bind, 'OR'); - } - /** * 指定Null查询条件 * @access public @@ -1072,7 +984,7 @@ class Query */ public function whereNull($field, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'null', null, [], true); + $this->parseWhereExp($logic, $field, 'null', null); return $this; } @@ -1085,7 +997,7 @@ class Query */ public function whereNotNull($field, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'notnull', null, [], true); + $this->parseWhereExp($logic, $field, 'notnull', null); return $this; } @@ -1125,7 +1037,7 @@ class Query */ public function whereIn($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'in', $condition, [], true); + $this->parseWhereExp($logic, $field, 'in', $condition); return $this; } @@ -1139,7 +1051,7 @@ class Query */ public function whereNotIn($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'not in', $condition, [], true); + $this->parseWhereExp($logic, $field, 'not in', $condition); return $this; } @@ -1153,7 +1065,7 @@ class Query */ public function whereLike($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'like', $condition, [], true); + $this->parseWhereExp($logic, $field, 'like', $condition); return $this; } @@ -1167,7 +1079,7 @@ class Query */ public function whereNotLike($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'not like', $condition, [], true); + $this->parseWhereExp($logic, $field, 'not like', $condition); return $this; } @@ -1181,7 +1093,7 @@ class Query */ public function whereBetween($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'between', $condition, [], true); + $this->parseWhereExp($logic, $field, 'between', $condition); return $this; } @@ -1195,7 +1107,7 @@ class Query */ public function whereNotBetween($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'not between', $condition, [], true); + $this->parseWhereExp($logic, $field, 'not between', $condition); return $this; } @@ -1209,7 +1121,7 @@ class Query */ public function whereExp($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'exp', $this->raw($condition), [], true); + $this->parseWhereExp($logic, $field, 'exp', $condition); return $this; } @@ -1236,10 +1148,9 @@ class Query * @param mixed $op 查询表达式 * @param mixed $condition 查询条件 * @param array $param 查询参数 - * @param bool $strict 严格模式 * @return void */ - protected function parseWhereExp($logic, $field, $op, $condition, $param = [], $strict = false) + protected function parseWhereExp($logic, $field, $op, $condition, $param = []) { $logic = strtoupper($logic); if ($field instanceof \Closure) { @@ -1250,17 +1161,8 @@ class Query if (is_string($field) && !empty($this->options['via']) && !strpos($field, '.')) { $field = $this->options['via'] . '.' . $field; } - - if ($field instanceof Expression) { - return $this->whereRaw($field, is_array($op) ? $op : []); - } elseif ($strict) { - // 使用严格模式查询 - $where[$field] = [$op, $condition]; - - // 记录一个字段多次查询条件 - $this->options['multi'][$logic][$field][] = $where[$field]; - } elseif (is_string($field) && preg_match('/[,=\>\<\'\"\(\s]/', $field)) { - $where[] = ['exp', $this->raw($field)]; + if (is_string($field) && preg_match('/[,=\>\<\'\"\(\s]/', $field)) { + $where[] = ['exp', $field]; if (is_array($op)) { // 参数绑定 $this->bind($op); @@ -1281,28 +1183,21 @@ class Query $where[$field] = $param; } elseif (in_array(strtolower($op), ['null', 'notnull', 'not null'])) { // null查询 - $where[$field] = [$op, '']; - + $where[$field] = [$op, '']; $this->options['multi'][$logic][$field][] = $where[$field]; } elseif (is_null($condition)) { // 字段相等查询 - $where[$field] = ['eq', $op]; - + $where[$field] = ['eq', $op]; $this->options['multi'][$logic][$field][] = $where[$field]; } else { - if ('exp' == strtolower($op)) { - $where[$field] = ['exp', $this->raw($condition)]; + $where[$field] = [$op, $condition, isset($param[2]) ? $param[2] : null]; + if ('exp' == strtolower($op) && isset($param[2]) && is_array($param[2])) { // 参数绑定 - if (isset($param[2]) && is_array($param[2])) { - $this->bind($param[2]); - } - } else { - $where[$field] = [$op, $condition]; + $this->bind($param[2]); } // 记录一个字段多次查询条件 $this->options['multi'][$logic][$field][] = $where[$field]; } - if (!empty($where)) { if (!isset($this->options['where'][$logic])) { $this->options['where'][$logic] = []; @@ -1344,7 +1239,6 @@ class Query $logic = strtoupper($logic); if (isset($this->options['where'][$logic][$field])) { unset($this->options['where'][$logic][$field]); - unset($this->options['multi'][$logic][$field]); } return $this; } @@ -1520,59 +1414,31 @@ class Query */ public function order($field, $order = null) { - if (empty($field)) { - return $this; - } elseif ($field instanceof Expression) { - $this->options['order'][] = $field; - return $this; - } - - if (is_string($field)) { - if (!empty($this->options['via'])) { - $field = $this->options['via'] . '.' . $field; - } - if (strpos($field, ',')) { - $field = array_map('trim', explode(',', $field)); - } else { + if (!empty($field)) { + if (is_string($field)) { + if (!empty($this->options['via'])) { + $field = $this->options['via'] . '.' . $field; + } $field = empty($order) ? $field : [$field => $order]; - } - } elseif (!empty($this->options['via'])) { - foreach ($field as $key => $val) { - if (is_numeric($key)) { - $field[$key] = $this->options['via'] . '.' . $val; - } else { - $field[$this->options['via'] . '.' . $key] = $val; - unset($field[$key]); + } elseif (!empty($this->options['via'])) { + foreach ($field as $key => $val) { + if (is_numeric($key)) { + $field[$key] = $this->options['via'] . '.' . $val; + } else { + $field[$this->options['via'] . '.' . $key] = $val; + unset($field[$key]); + } } } + if (!isset($this->options['order'])) { + $this->options['order'] = []; + } + if (is_array($field)) { + $this->options['order'] = array_merge($this->options['order'], $field); + } else { + $this->options['order'][] = $field; + } } - if (!isset($this->options['order'])) { - $this->options['order'] = []; - } - if (is_array($field)) { - $this->options['order'] = array_merge($this->options['order'], $field); - } else { - $this->options['order'][] = $field; - } - - return $this; - } - - /** - * 表达式方式指定Field排序 - * @access public - * @param string $field 排序字段 - * @param array $bind 参数绑定 - * @return $this - */ - public function orderRaw($field, array $bind = []) - { - $this->options['order'][] = $this->raw($field); - - if ($bind) { - $this->bind($bind); - } - return $this; } @@ -1657,12 +1523,7 @@ class Query { if (is_array($alias)) { foreach ($alias as $key => $val) { - if (false !== strpos($key, '__')) { - $table = $this->parseSqlTable($key); - } else { - $table = $key; - } - $this->options['alias'][$table] = $val; + $this->options['alias'][$key] = $val; } } else { if (isset($this->options['table'])) { @@ -1790,49 +1651,46 @@ class Query * 查询日期或者时间 * @access public * @param string $field 日期字段名 - * @param string|array $op 比较运算符或者表达式 + * @param string $op 比较运算符或者表达式 * @param string|array $range 比较范围 * @return $this */ public function whereTime($field, $op, $range = null) { if (is_null($range)) { - if (is_array($op)) { - $range = $op; - } else { - // 使用日期表达式 - switch (strtolower($op)) { - case 'today': - case 'd': - $range = ['today', 'tomorrow']; - break; - case 'week': - case 'w': - $range = ['this week 00:00:00', 'next week 00:00:00']; - break; - case 'month': - case 'm': - $range = ['first Day of this month 00:00:00', 'first Day of next month 00:00:00']; - break; - case 'year': - case 'y': - $range = ['this year 1/1', 'next year 1/1']; - break; - case 'yesterday': - $range = ['yesterday', 'today']; - break; - case 'last week': - $range = ['last week 00:00:00', 'this week 00:00:00']; - break; - case 'last month': - $range = ['first Day of last month 00:00:00', 'first Day of this month 00:00:00']; - break; - case 'last year': - $range = ['last year 1/1', 'this year 1/1']; - break; - default: - $range = $op; - } + // 使用日期表达式 + $date = getdate(); + switch (strtolower($op)) { + case 'today': + case 'd': + $range = ['today', 'tomorrow']; + break; + case 'week': + case 'w': + $range = 'this week 00:00:00'; + break; + case 'month': + case 'm': + $range = mktime(0, 0, 0, $date['mon'], 1, $date['year']); + break; + case 'year': + case 'y': + $range = mktime(0, 0, 0, 1, 1, $date['year']); + break; + case 'yesterday': + $range = ['yesterday', 'today']; + break; + case 'last week': + $range = ['last week 00:00:00', 'this week 00:00:00']; + break; + case 'last month': + $range = [date('y-m-01', strtotime('-1 month')), mktime(0, 0, 0, $date['mon'], 1, $date['year'])]; + break; + case 'last year': + $range = [mktime(0, 0, 0, 1, 1, $date['year'] - 1), mktime(0, 0, 0, 1, 1, $date['year'])]; + break; + default: + $range = $op; } $op = is_array($range) ? 'between' : '>'; } @@ -1877,7 +1735,7 @@ class Query $schema = $guid; } // 读取缓存 - if (!App::$debug && is_file(RUNTIME_PATH . 'schema/' . $schema . '.php')) { + if (is_file(RUNTIME_PATH . 'schema/' . $schema . '.php')) { $info = include RUNTIME_PATH . 'schema/' . $schema . '.php'; } else { $info = $this->connection->getFields($guid); @@ -1952,9 +1810,7 @@ class Query */ protected function getFieldBindType($type) { - if (0 === strpos($type, 'set') || 0 === strpos($type, 'enum')) { - $bind = PDO::PARAM_STR; - } elseif (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) { + if (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) { $bind = PDO::PARAM_INT; } elseif (preg_match('/bool/is', $type)) { $bind = PDO::PARAM_BOOL; @@ -2036,10 +1892,11 @@ class Query $with = explode(',', $with); } - $first = true; + $first = true; + $currentModel = $this->model; /** @var Model $class */ - $class = $this->model; + $class = new $currentModel; foreach ($with as $key => $relation) { $subRelation = ''; $closure = false; @@ -2098,7 +1955,7 @@ class Query $relation = $key; } $relation = Loader::parseName($relation, 1, false); - $count = '(' . $this->model->$relation()->getRelationCountQuery($closure) . ')'; + $count = '(' . (new $this->model)->$relation()->getRelationCountQuery($closure) . ')'; $this->field([$count => Loader::parseName($relation) . '_count']); } } @@ -2225,7 +2082,7 @@ class Query } // 执行操作 - $result = 0 === $sql ? 0 : $this->execute($sql, $bind, $this); + $result = 0 === $sql ? 0 : $this->execute($sql, $bind); if ($result) { $sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null); $lastInsId = $this->getLastInsID($sequence); @@ -2261,40 +2118,27 @@ class Query /** * 批量插入记录 * @access public - * @param mixed $dataSet 数据集 - * @param boolean $replace 是否replace - * @param integer $limit 每次写入数据限制 + * @param mixed $dataSet 数据集 + * @param boolean $replace 是否replace * @return integer|string */ - public function insertAll(array $dataSet, $replace = false, $limit = null) + public function insertAll(array $dataSet, $replace = false) { // 分析查询表达式 $options = $this->parseExpress(); if (!is_array(reset($dataSet))) { return false; } - // 生成SQL语句 - if (is_null($limit)) { - $sql = $this->builder->insertAll($dataSet, $options, $replace); - } else { - $array = array_chunk($dataSet, $limit, true); - foreach ($array as $item) { - $sql[] = $this->builder->insertAll($item, $options, $replace); - } - } - + $sql = $this->builder->insertAll($dataSet, $options, $replace); // 获取参数绑定 $bind = $this->getBind(); if ($options['fetch_sql']) { // 获取实际执行的SQL语句 return $this->connection->getRealSql($sql, $bind); - } elseif (is_array($sql)) { - // 执行操作 - return $this->batchQuery($sql, $bind, $this); } else { // 执行操作 - return $this->execute($sql, $bind, $this); + return $this->execute($sql, $bind); } } @@ -2320,7 +2164,7 @@ class Query return $this->connection->getRealSql($sql, $bind); } else { // 执行操作 - return $this->execute($sql, $bind, $this); + return $this->execute($sql, $bind); } } @@ -2387,7 +2231,7 @@ class Query Cache::clear($options['cache']['tag']); } // 执行操作 - $result = '' == $sql ? 0 : $this->execute($sql, $bind, $this); + $result = '' == $sql ? 0 : $this->execute($sql, $bind); if ($result) { if (is_string($pk) && isset($where[$pk])) { $data[$pk] = $where[$pk]; @@ -2456,7 +2300,7 @@ class Query // 判断查询缓存 $cache = $options['cache']; unset($options['cache']); - $key = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . serialize($options) . serialize($this->bind)); + $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options) . serialize($this->bind)); $resultSet = Cache::get($key); } if (false === $resultSet) { @@ -2490,10 +2334,11 @@ class Query // 数据列表读取后的处理 if (!empty($this->model)) { // 生成模型对象 + $modelName = $this->model; if (count($resultSet) > 0) { foreach ($resultSet as $key => $result) { /** @var Model $model */ - $model = $this->model->newInstance($result); + $model = new $modelName($result); $model->isUpdate(true); // 关联查询 @@ -2513,7 +2358,7 @@ class Query // 模型数据集转换 $resultSet = $model->toCollection($resultSet); } else { - $resultSet = $this->model->toCollection($resultSet); + $resultSet = (new $modelName)->toCollection($resultSet); } } elseif ('collection' == $this->connection->getConfig('resultset_type')) { // 返回Collection对象 @@ -2557,16 +2402,10 @@ class Query } elseif (is_array($value) && is_string($value[0]) && 'eq' == strtolower($value[0])) { $data = $value[1]; } - $prefix = $this->connection->getConfig('database') . '.'; - if (isset($data)) { - return 'think:' . $prefix . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; - } - - try { - return md5($prefix . serialize($options) . serialize($bind)); - } catch (\Exception $e) { - throw new Exception('closure not support cache(true)'); + return 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; + } else { + return md5(serialize($options) . serialize($bind)); } } @@ -2603,11 +2442,11 @@ class Query // 判断查询缓存 $cache = $options['cache']; if (true === $cache['key'] && !is_null($data) && !is_array($data)) { - $key = 'think:' . $this->connection->getConfig('database') . '.' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; + $key = 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; } elseif (is_string($cache['key'])) { $key = $cache['key']; } elseif (!isset($key)) { - $key = md5($this->connection->getConfig('database') . '.' . serialize($options) . serialize($this->bind)); + $key = md5(serialize($options) . serialize($this->bind)); } $result = Cache::get($key); } @@ -2645,7 +2484,7 @@ class Query $result = isset($resultSet[0]) ? $resultSet[0] : null; } - if (isset($cache) && $result) { + if (isset($cache) && false !== $result) { // 缓存数据 $this->cacheData($key, $result, $cache); } @@ -2655,7 +2494,8 @@ class Query if (!empty($result)) { if (!empty($this->model)) { // 返回模型对象 - $result = $this->model->newInstance($result); + $model = $this->model; + $result = new $model($result); $result->isUpdate(true, isset($options['where']['AND']) ? $options['where']['AND'] : null); // 关联查询 if (!empty($options['relation'])) { @@ -2686,8 +2526,7 @@ class Query protected function throwNotFound($options = []) { if (!empty($this->model)) { - $class = get_class($this->model); - throw new ModelNotFoundException('model data Not Found:' . $class, $class, $options); + throw new ModelNotFoundException('model data Not Found:' . $this->model, $this->model, $options); } else { $table = is_array($options['table']) ? key($options['table']) : $options['table']; throw new DataNotFoundException('table data not Found:' . $table, $table, $options); @@ -2735,54 +2574,48 @@ class Query public function chunk($count, $callback, $column = null, $order = 'asc') { $options = $this->getOptions(); - if (empty($options['table'])) { - $options['table'] = $this->getTable(); + if (isset($options['table'])) { + $table = is_array($options['table']) ? key($options['table']) : $options['table']; + } else { + $table = ''; + } + $column = $column ?: $this->getPk($table); + if (is_array($column)) { + $column = $column[0]; } - $column = $column ?: $this->getPk($options); - if (isset($options['order'])) { if (App::$debug) { throw new \LogicException('chunk not support call order'); } unset($options['order']); } - $bind = $this->bind; - if (is_array($column)) { - $times = 1; - $query = $this->options($options)->page($times, $count); + $bind = $this->bind; + $resultSet = $this->options($options)->limit($count)->order($column, $order)->select(); + if (strpos($column, '.')) { + list($alias, $key) = explode('.', $column); } else { - if (strpos($column, '.')) { - list($alias, $key) = explode('.', $column); - } else { - $key = $column; - } - $query = $this->options($options)->limit($count); + $key = $column; + } + if ($resultSet instanceof Collection) { + $resultSet = $resultSet->all(); } - $resultSet = $query->order($column, $order)->select(); - - while (count($resultSet) > 0) { - if ($resultSet instanceof Collection) { - $resultSet = $resultSet->all(); - } + while (!empty($resultSet)) { if (false === call_user_func($callback, $resultSet)) { return false; } - - if (is_array($column)) { - $times++; - $query = $this->options($options)->page($times, $count); - } else { - $end = end($resultSet); - $lastId = is_array($end) ? $end[$key] : $end->getData($key); - $query = $this->options($options) - ->limit($count) - ->where($column, 'asc' == strtolower($order) ? '>' : '<', $lastId); + $end = end($resultSet); + $lastId = is_array($end) ? $end[$key] : $end->$key; + $resultSet = $this->options($options) + ->limit($count) + ->bind($bind) + ->where($column, 'asc' == strtolower($order) ? '>' : '<', $lastId) + ->order($column, $order) + ->select(); + if ($resultSet instanceof Collection) { + $resultSet = $resultSet->all(); } - - $resultSet = $query->bind($bind)->order($column, $order)->select(); } - return true; } @@ -2859,7 +2692,7 @@ class Query Cache::clear($options['cache']['tag']); } // 执行操作 - $result = $this->execute($sql, $bind, $this); + $result = $this->execute($sql, $bind); if ($result) { if (!is_array($data) && is_string($pk) && isset($key) && strpos($key, '|')) { list($a, $val) = explode('|', $key); @@ -2944,10 +2777,6 @@ class Query } } - if (isset(static::$readMaster['*']) || (is_string($options['table']) && isset(static::$readMaster[$options['table']]))) { - $options['master'] = true; - } - foreach (['join', 'union', 'group', 'having', 'limit', 'order', 'force', 'comment'] as $name) { if (!isset($options[$name])) { $options[$name] = ''; diff --git a/thinkphp/library/think/db/builder/Pgsql.php b/thinkphp/library/think/db/builder/Pgsql.php index acc22896..b690401c 100644 --- a/thinkphp/library/think/db/builder/Pgsql.php +++ b/thinkphp/library/think/db/builder/Pgsql.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -44,18 +44,12 @@ class Pgsql extends Builder /** * 字段和表名处理 * @access protected - * @param mixed $key + * @param string $key * @param array $options * @return string */ - protected function parseKey($key, $options = [], $strict = false) + protected function parseKey($key, $options = []) { - if (is_numeric($key)) { - return $key; - } elseif ($key instanceof Expression) { - return $key->getValue(); - } - $key = trim($key); if (strpos($key, '$.') && false === strpos($key, '(')) { // JSON字段支持 diff --git a/thinkphp/library/think/db/builder/Sqlite.php b/thinkphp/library/think/db/builder/Sqlite.php index c727f04b..28a5d6f1 100644 --- a/thinkphp/library/think/db/builder/Sqlite.php +++ b/thinkphp/library/think/db/builder/Sqlite.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -52,18 +52,12 @@ class Sqlite extends Builder /** * 字段和表名处理 * @access protected - * @param mixed $key + * @param string $key * @param array $options * @return string */ - protected function parseKey($key, $options = [], $strict = false) + protected function parseKey($key, $options = []) { - if (is_numeric($key)) { - return $key; - } elseif ($key instanceof Expression) { - return $key->getValue(); - } - $key = trim($key); if (strpos($key, '.')) { list($table, $key) = explode('.', $key, 2); diff --git a/thinkphp/library/think/db/builder/Sqlsrv.php b/thinkphp/library/think/db/builder/Sqlsrv.php index f79ae030..59ea021f 100644 --- a/thinkphp/library/think/db/builder/Sqlsrv.php +++ b/thinkphp/library/think/db/builder/Sqlsrv.php @@ -12,7 +12,6 @@ namespace think\db\builder; use think\db\Builder; -use think\db\Expression; /** * Sqlsrv数据库驱动 @@ -35,29 +34,25 @@ class Sqlsrv extends Builder */ protected function parseOrder($order, $options = []) { - if (empty($order)) { - return ' ORDER BY rand()'; - } - - $array = []; - foreach ($order as $key => $val) { - if ($val instanceof Expression) { - $array[] = $val->getValue(); - } elseif (is_numeric($key)) { - if (false === strpos($val, '(')) { - $array[] = $this->parseKey($val, $options); - } elseif ('[rand]' == $val) { - $array[] = $this->parseRand(); + if (is_array($order)) { + $array = []; + foreach ($order as $key => $val) { + if (is_numeric($key)) { + if (false === strpos($val, '(')) { + $array[] = $this->parseKey($val, $options); + } elseif ('[rand]' == $val) { + $array[] = $this->parseRand(); + } else { + $array[] = $val; + } } else { - $array[] = $val; + $sort = in_array(strtolower(trim($val)), ['asc', 'desc']) ? ' ' . $val : ''; + $array[] = $this->parseKey($key, $options) . ' ' . $sort; } - } else { - $sort = in_array(strtolower(trim($val)), ['asc', 'desc'], true) ? ' ' . $val : ''; - $array[] = $this->parseKey($key, $options, true) . ' ' . $sort; } + $order = implode(',', $array); } - - return ' ORDER BY ' . implode(',', $array); + return !empty($order) ? ' ORDER BY ' . $order : ' ORDER BY rand()'; } /** @@ -73,17 +68,12 @@ class Sqlsrv extends Builder /** * 字段和表名处理 * @access protected - * @param mixed $key + * @param string $key * @param array $options * @return string */ - protected function parseKey($key, $options = [], $strict = false) + protected function parseKey($key, $options = []) { - if (is_numeric($key)) { - return $key; - } elseif ($key instanceof Expression) { - return $key->getValue(); - } $key = trim($key); if (strpos($key, '.') && !preg_match('/[,\'\"\(\)\[\s]/', $key)) { list($table, $key) = explode('.', $key, 2); @@ -94,7 +84,7 @@ class Sqlsrv extends Builder $table = $options['alias'][$table]; } } - if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)\[.\s]/', $key))) { + if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) { $key = '[' . $key . ']'; } if (isset($table)) { diff --git a/thinkphp/library/think/db/connector/Mysql.php b/thinkphp/library/think/db/connector/Mysql.php index be1a85ce..9d146c71 100644 --- a/thinkphp/library/think/db/connector/Mysql.php +++ b/thinkphp/library/think/db/connector/Mysql.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/db/connector/Pgsql.php b/thinkphp/library/think/db/connector/Pgsql.php index bbcf5768..761fbac4 100644 --- a/thinkphp/library/think/db/connector/Pgsql.php +++ b/thinkphp/library/think/db/connector/Pgsql.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/db/connector/Sqlite.php b/thinkphp/library/think/db/connector/Sqlite.php index c4e3a724..fd7f02b0 100644 --- a/thinkphp/library/think/db/connector/Sqlite.php +++ b/thinkphp/library/think/db/connector/Sqlite.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/db/exception/BindParamException.php b/thinkphp/library/think/db/exception/BindParamException.php index 4ed19546..d0e2387b 100644 --- a/thinkphp/library/think/db/exception/BindParamException.php +++ b/thinkphp/library/think/db/exception/BindParamException.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/db/exception/DataNotFoundException.php b/thinkphp/library/think/db/exception/DataNotFoundException.php index f2542ac6..e399b063 100644 --- a/thinkphp/library/think/db/exception/DataNotFoundException.php +++ b/thinkphp/library/think/db/exception/DataNotFoundException.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/db/exception/ModelNotFoundException.php b/thinkphp/library/think/db/exception/ModelNotFoundException.php index 6e5f930c..2180ab07 100644 --- a/thinkphp/library/think/db/exception/ModelNotFoundException.php +++ b/thinkphp/library/think/db/exception/ModelNotFoundException.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +----------------------------------------------------------------------