更新tp5内核

This commit is contained in:
2018-01-02 23:03:31 +08:00
parent 590696a06b
commit 3818619504
99 changed files with 3362 additions and 2006 deletions
+144 -95
View File
@@ -2,7 +2,7 @@
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
@@ -12,6 +12,7 @@
namespace think\db;
use PDO;
use think\App;
use think\Cache;
use think\Collection;
use think\Config;
@@ -114,6 +115,7 @@ class Query
{
$this->connection = Db::connect($config);
$this->setBuilder();
$this->prefix = $this->connection->getConfig('prefix');
return $this;
}
@@ -310,9 +312,9 @@ class Query
* @param array $sql SQL批处理指令
* @return boolean
*/
public function batchQuery($sql = [])
public function batchQuery($sql = [], $bind = [])
{
return $this->connection->batchQuery($sql);
return $this->connection->batchQuery($sql, $bind);
}
/**
@@ -415,8 +417,9 @@ class Query
}
$result = $pdo->fetchColumn();
if ($force) {
$result = is_numeric($result) ? $result + 0 : $result;
$result += 0;
}
if (isset($cache)) {
// 缓存数据
$this->cacheData($key, $result, $cache);
@@ -531,22 +534,24 @@ class Query
* MIN查询
* @access public
* @param string $field 字段名
* @param bool $force 强制转为数字类型
* @return mixed
*/
public function min($field)
public function min($field, $force = true)
{
return $this->value('MIN(' . $field . ') AS tp_min', 0, true);
return $this->value('MIN(' . $field . ') AS tp_min', 0, $force);
}
/**
* MAX查询
* @access public
* @param string $field 字段名
* @param bool $force 强制转为数字类型
* @return mixed
*/
public function max($field)
public function max($field, $force = true)
{
return $this->value('MAX(' . $field . ') AS tp_max', 0, true);
return $this->value('MAX(' . $field . ') AS tp_max', 0, $force);
}
/**
@@ -604,7 +609,7 @@ class Query
return true;
}
}
return $this->setField($field, ['exp', $field . '+' . $step]);
return $this->setField($field, ['inc', $field, $step]);
}
/**
@@ -632,8 +637,9 @@ class Query
$this->options = [];
return true;
}
return $this->setField($field, ['inc', $field, $step]);
}
return $this->setField($field, ['exp', $field . '-' . $step]);
return $this->setField($field, ['dec', $field, $step]);
}
/**
@@ -701,7 +707,8 @@ class Query
{
// 传入的表名为数组
if (is_array($join)) {
list($table, $alias) = each($join);
$table = key($join);
$alias = current($join);
} else {
$join = trim($join);
if (false !== strpos($join, '(')) {
@@ -723,10 +730,13 @@ class Query
}
}
}
if (isset($alias)) {
if (isset($alias) && $table != $alias) {
if (isset($this->options['alias'][$table])) {
$table = $table . '@think' . uniqid();
} elseif ($this->gettable() == $table) {
$table = $table . '@think' . uniqid();
}
$table = [$table => $alias];
$this->alias($table);
}
@@ -825,7 +835,7 @@ class Query
{
$fields = is_string($field) ? explode(',', $field) : $field;
foreach ($fields as $field) {
$this->data($field, ['exp', $field . '+' . $step]);
$this->data($field, ['inc', $field, $step]);
}
return $this;
}
@@ -841,7 +851,7 @@ class Query
{
$fields = is_string($field) ? explode(',', $field) : $field;
foreach ($fields as $field) {
$this->data($field, ['exp', $field . '-' . $step]);
$this->data($field, ['dec', $field, $step]);
}
return $this;
}
@@ -1184,10 +1194,8 @@ class Query
$this->options['multi'][$logic][$field][] = $where[$field];
} elseif (is_null($condition)) {
// 字段相等查询
$where[$field] = ['eq', $op];
if ('AND' != $logic) {
$this->options['multi'][$logic][$field][] = $where[$field];
}
$where[$field] = ['eq', $op];
$this->options['multi'][$logic][$field][] = $where[$field];
} else {
$where[$field] = [$op, $condition, isset($param[2]) ? $param[2] : null];
if ('exp' == strtolower($op) && isset($param[2]) && is_array($param[2])) {
@@ -1238,6 +1246,7 @@ 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;
}
@@ -1444,18 +1453,19 @@ class Query
/**
* 查询缓存
* @access public
* @param mixed $key 缓存key
* @param integer $expire 缓存有效期
* @param string $tag 缓存标签
* @param mixed $key 缓存key
* @param integer|\DateTime $expire 缓存有效期
* @param string $tag 缓存标签
* @return $this
*/
public function cache($key = true, $expire = null, $tag = null)
{
// 增加快捷调用方式 cache(10) 等同于 cache(true, 10)
if (is_numeric($key) && is_null($expire)) {
if ($key instanceof \DateTime || (is_numeric($key) && is_null($expire))) {
$expire = $key;
$key = true;
}
if (false !== $key) {
$this->options['cache'] = ['key' => $key, 'expire' => $expire, 'tag' => $tag];
}
@@ -1489,7 +1499,7 @@ class Query
/**
* 指定查询lock
* @access public
* @param boolean $lock 是否lock
* @param bool|string $lock 是否lock
* @return $this
*/
public function lock($lock = false)
@@ -1521,7 +1531,12 @@ class Query
{
if (is_array($alias)) {
foreach ($alias as $key => $val) {
$this->options['alias'][$key] = $val;
if (false !== strpos($key, '__')) {
$table = $this->parseSqlTable($key);
} else {
$table = $key;
}
$this->options['alias'][$table] = $val;
}
} else {
if (isset($this->options['table'])) {
@@ -1649,46 +1664,49 @@ class Query
* 查询日期或者时间
* @access public
* @param string $field 日期字段名
* @param string $op 比较运算符或者表达式
* @param string|array $op 比较运算符或者表达式
* @param string|array $range 比较范围
* @return $this
*/
public function whereTime($field, $op, $range = null)
{
if (is_null($range)) {
// 使用日期表达式
$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;
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;
}
}
$op = is_array($range) ? 'between' : '>';
}
@@ -1733,7 +1751,7 @@ class Query
$schema = $guid;
}
// 读取缓存
if (is_file(RUNTIME_PATH . 'schema/' . $schema . '.php')) {
if (!App::$debug && is_file(RUNTIME_PATH . 'schema/' . $schema . '.php')) {
$info = include RUNTIME_PATH . 'schema/' . $schema . '.php';
} else {
$info = $this->connection->getFields($guid);
@@ -1808,7 +1826,9 @@ class Query
*/
protected function getFieldBindType($type)
{
if (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $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)) {
$bind = PDO::PARAM_INT;
} elseif (preg_match('/bool/is', $type)) {
$bind = PDO::PARAM_BOOL;
@@ -2080,7 +2100,7 @@ class Query
}
// 执行操作
$result = $this->execute($sql, $bind);
$result = 0 === $sql ? 0 : $this->execute($sql, $bind);
if ($result) {
$sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null);
$lastInsId = $this->getLastInsID($sequence);
@@ -2116,24 +2136,37 @@ class Query
/**
* 批量插入记录
* @access public
* @param mixed $dataSet 数据集
* @param boolean $replace 是否replace
* @param mixed $dataSet 数据集
* @param boolean $replace 是否replace
* @param integer $limit 每次写入数据限制
* @return integer|string
*/
public function insertAll(array $dataSet, $replace = false)
public function insertAll(array $dataSet, $replace = false, $limit = null)
{
// 分析查询表达式
$options = $this->parseExpress();
if (!is_array(reset($dataSet))) {
return false;
}
// 生成SQL语句
$sql = $this->builder->insertAll($dataSet, $options, $replace);
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);
}
}
// 获取参数绑定
$bind = $this->getBind();
if ($options['fetch_sql']) {
// 获取实际执行的SQL语句
return $this->connection->getRealSql($sql, $bind);
} elseif (is_array($sql)) {
// 执行操作
return $this->batchQuery($sql, $bind);
} else {
// 执行操作
return $this->execute($sql, $bind);
@@ -2335,7 +2368,7 @@ class Query
$modelName = $this->model;
if (count($resultSet) > 0) {
foreach ($resultSet as $key => $result) {
/** @var Model $result */
/** @var Model $model */
$model = new $modelName($result);
$model->isUpdate(true);
@@ -2391,12 +2424,13 @@ class Query
* @param mixed $value 缓存数据
* @param array $options 缓存参数
* @param array $bind 绑定参数
* @return string
*/
protected function getCacheKey($value, $options, $bind = [])
{
if (is_scalar($value)) {
$data = $value;
} elseif (is_array($value) && 'eq' == strtolower($value[0])) {
} elseif (is_array($value) && is_string($value[0]) && 'eq' == strtolower($value[0])) {
$data = $value[1];
}
if (isset($data)) {
@@ -2564,44 +2598,59 @@ class Query
* @param integer $count 每次处理的数据数量
* @param callable $callback 处理回调方法
* @param string $column 分批处理的字段名
* @param string $order 排序规则
* @return boolean
* @throws \LogicException
*/
public function chunk($count, $callback, $column = null)
public function chunk($count, $callback, $column = null, $order = 'asc')
{
$options = $this->getOptions();
if (isset($options['table'])) {
$table = is_array($options['table']) ? key($options['table']) : $options['table'];
} else {
$table = '';
}
$column = $column ?: $this->getPk($table);
$bind = $this->bind;
$resultSet = $this->limit($count)->order($column, 'asc')->select();
if (strpos($column, '.')) {
list($alias, $key) = explode('.', $column);
} else {
$key = $column;
}
if ($resultSet instanceof Collection) {
$resultSet = $resultSet->all();
}
while (!empty($resultSet)) {
if (false === call_user_func($callback, $resultSet)) {
return false;
$column = $column ?: $this->getPk($options);
if (isset($options['order'])) {
if (App::$debug) {
throw new \LogicException('chunk not support call order');
}
$end = end($resultSet);
$lastId = is_array($end) ? $end[$key] : $end->$key;
$resultSet = $this->options($options)
->limit($count)
->bind($bind)
->where($column, '>', $lastId)
->order($column, 'asc')
->select();
unset($options['order']);
}
$bind = $this->bind;
if (is_array($column)) {
$times = 1;
$query = $this->options($options)->page($times, $count);
} else {
if (strpos($column, '.')) {
list($alias, $key) = explode('.', $column);
} else {
$key = $column;
}
$query = $this->options($options)->limit($count);
}
$resultSet = $query->order($column, $order)->select();
while (count($resultSet) > 0) {
if ($resultSet instanceof Collection) {
$resultSet = $resultSet->all();
}
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);
}
$resultSet = $query->bind($bind)->order($column, $order)->select();
}
return true;
}