mirror of
https://github.com/crmeb/CRMEB.git
synced 2025-12-16 14:22:48 +00:00
tp db更新
This commit is contained in:
parent
2b351f8b15
commit
f37507e33b
@ -115,16 +115,18 @@ abstract class Builder
|
|||||||
} elseif (is_array($val) && !empty($val)) {
|
} elseif (is_array($val) && !empty($val)) {
|
||||||
switch (strtolower($val[0])) {
|
switch (strtolower($val[0])) {
|
||||||
case 'inc':
|
case 'inc':
|
||||||
//$result[$item] = $item . '+' . floatval($val[1]);
|
// $result[$item] = $item . '+' . floatval($val[1]);
|
||||||
if ($key == $val[1]) {
|
if ($key == $val[1]) {
|
||||||
$result[$item] = $this->parseKey($val[1]) . '+' . floatval($val[2]);
|
$result[$item] = $this->parseKey($val[1]) . '+' . floatval($val[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'dec':
|
case 'dec':
|
||||||
//$result[$item] = $item . '-' . floatval($val[1]);
|
// $result[$item] = $item . '-' . floatval($val[1]);
|
||||||
if ($key == $val[1]) {
|
if ($key == $val[1]) {
|
||||||
$result[$item] = $this->parseKey($val[1]) . '-' . floatval($val[2]);
|
$result[$item] = $this->parseKey($val[1]) . '-' . floatval($val[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'exp':
|
case 'exp':
|
||||||
throw new Exception('not support data:[' . $val[0] . ']');
|
throw new Exception('not support data:[' . $val[0] . ']');
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | 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 )
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
@ -90,6 +90,8 @@ abstract class Connection
|
|||||||
'master_num' => 1,
|
'master_num' => 1,
|
||||||
// 指定从服务器序号
|
// 指定从服务器序号
|
||||||
'slave_no' => '',
|
'slave_no' => '',
|
||||||
|
// 模型写入后自动读取主服务器
|
||||||
|
'read_master' => false,
|
||||||
// 是否严格检查字段是否存在
|
// 是否严格检查字段是否存在
|
||||||
'fields_strict' => true,
|
'fields_strict' => true,
|
||||||
// 数据返回类型
|
// 数据返回类型
|
||||||
@ -354,15 +356,15 @@ abstract class Connection
|
|||||||
$this->bind = $bind;
|
$this->bind = $bind;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 释放前次的查询结果
|
|
||||||
if (!empty($this->PDOStatement)) {
|
|
||||||
$this->free();
|
|
||||||
}
|
|
||||||
|
|
||||||
Db::$queryTimes++;
|
Db::$queryTimes++;
|
||||||
try {
|
try {
|
||||||
// 调试开始
|
// 调试开始
|
||||||
$this->debug(true);
|
$this->debug(true);
|
||||||
|
|
||||||
|
// 释放前次的查询结果
|
||||||
|
if (!empty($this->PDOStatement)) {
|
||||||
|
$this->free();
|
||||||
|
}
|
||||||
// 预处理
|
// 预处理
|
||||||
if (empty($this->PDOStatement)) {
|
if (empty($this->PDOStatement)) {
|
||||||
$this->PDOStatement = $this->linkID->prepare($sql);
|
$this->PDOStatement = $this->linkID->prepare($sql);
|
||||||
@ -378,7 +380,7 @@ abstract class Connection
|
|||||||
// 执行查询
|
// 执行查询
|
||||||
$this->PDOStatement->execute();
|
$this->PDOStatement->execute();
|
||||||
// 调试结束
|
// 调试结束
|
||||||
$this->debug(false);
|
$this->debug(false, '', $master);
|
||||||
// 返回结果集
|
// 返回结果集
|
||||||
return $this->getResult($pdo, $procedure);
|
return $this->getResult($pdo, $procedure);
|
||||||
} catch (\PDOException $e) {
|
} catch (\PDOException $e) {
|
||||||
@ -386,6 +388,11 @@ abstract class Connection
|
|||||||
return $this->close()->query($sql, $bind, $master, $pdo);
|
return $this->close()->query($sql, $bind, $master, $pdo);
|
||||||
}
|
}
|
||||||
throw new PDOException($e, $this->config, $this->getLastsql());
|
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) {
|
} catch (\Exception $e) {
|
||||||
if ($this->isBreak($e)) {
|
if ($this->isBreak($e)) {
|
||||||
return $this->close()->query($sql, $bind, $master, $pdo);
|
return $this->close()->query($sql, $bind, $master, $pdo);
|
||||||
@ -399,11 +406,12 @@ abstract class Connection
|
|||||||
* @access public
|
* @access public
|
||||||
* @param string $sql sql指令
|
* @param string $sql sql指令
|
||||||
* @param array $bind 参数绑定
|
* @param array $bind 参数绑定
|
||||||
|
* @param Query $query 查询对象
|
||||||
* @return int
|
* @return int
|
||||||
* @throws PDOException
|
* @throws PDOException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function execute($sql, $bind = [])
|
public function execute($sql, $bind = [], Query $query = null)
|
||||||
{
|
{
|
||||||
$this->initConnect(true);
|
$this->initConnect(true);
|
||||||
if (!$this->linkID) {
|
if (!$this->linkID) {
|
||||||
@ -416,15 +424,15 @@ abstract class Connection
|
|||||||
$this->bind = $bind;
|
$this->bind = $bind;
|
||||||
}
|
}
|
||||||
|
|
||||||
//释放前次的查询结果
|
|
||||||
if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) {
|
|
||||||
$this->free();
|
|
||||||
}
|
|
||||||
|
|
||||||
Db::$executeTimes++;
|
Db::$executeTimes++;
|
||||||
try {
|
try {
|
||||||
// 调试开始
|
// 调试开始
|
||||||
$this->debug(true);
|
$this->debug(true);
|
||||||
|
|
||||||
|
//释放前次的查询结果
|
||||||
|
if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) {
|
||||||
|
$this->free();
|
||||||
|
}
|
||||||
// 预处理
|
// 预处理
|
||||||
if (empty($this->PDOStatement)) {
|
if (empty($this->PDOStatement)) {
|
||||||
$this->PDOStatement = $this->linkID->prepare($sql);
|
$this->PDOStatement = $this->linkID->prepare($sql);
|
||||||
@ -440,18 +448,27 @@ abstract class Connection
|
|||||||
// 执行语句
|
// 执行语句
|
||||||
$this->PDOStatement->execute();
|
$this->PDOStatement->execute();
|
||||||
// 调试结束
|
// 调试结束
|
||||||
$this->debug(false);
|
$this->debug(false, '', true);
|
||||||
|
|
||||||
|
if ($query && !empty($this->config['deploy']) && !empty($this->config['read_master'])) {
|
||||||
|
$query->readMaster();
|
||||||
|
}
|
||||||
|
|
||||||
$this->numRows = $this->PDOStatement->rowCount();
|
$this->numRows = $this->PDOStatement->rowCount();
|
||||||
return $this->numRows;
|
return $this->numRows;
|
||||||
} catch (\PDOException $e) {
|
} catch (\PDOException $e) {
|
||||||
if ($this->isBreak($e)) {
|
if ($this->isBreak($e)) {
|
||||||
return $this->close()->execute($sql, $bind);
|
return $this->close()->execute($sql, $bind, $query);
|
||||||
}
|
}
|
||||||
throw new PDOException($e, $this->config, $this->getLastsql());
|
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) {
|
} catch (\Exception $e) {
|
||||||
if ($this->isBreak($e)) {
|
if ($this->isBreak($e)) {
|
||||||
return $this->close()->execute($sql, $bind);
|
return $this->close()->execute($sql, $bind, $query);
|
||||||
}
|
}
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
@ -466,6 +483,10 @@ abstract class Connection
|
|||||||
*/
|
*/
|
||||||
public function getRealSql($sql, array $bind = [])
|
public function getRealSql($sql, array $bind = [])
|
||||||
{
|
{
|
||||||
|
if (is_array($sql)) {
|
||||||
|
$sql = implode(';', $sql);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($bind as $key => $val) {
|
foreach ($bind as $key => $val) {
|
||||||
$value = is_array($val) ? $val[0] : $val;
|
$value = is_array($val) ? $val[0] : $val;
|
||||||
$type = is_array($val) ? $val[1] : PDO::PARAM_STR;
|
$type = is_array($val) ? $val[1] : PDO::PARAM_STR;
|
||||||
@ -478,8 +499,8 @@ abstract class Connection
|
|||||||
$sql = is_numeric($key) ?
|
$sql = is_numeric($key) ?
|
||||||
substr_replace($sql, $value, strpos($sql, '?'), 1) :
|
substr_replace($sql, $value, strpos($sql, '?'), 1) :
|
||||||
str_replace(
|
str_replace(
|
||||||
[':' . $key . ')', ':' . $key . ',', ':' . $key . ' '],
|
[':' . $key . ')', ':' . $key . ',', ':' . $key . ' ', ':' . $key . PHP_EOL],
|
||||||
[$value . ')', $value . ',', $value . ' '],
|
[$value . ')', $value . ',', $value . ' ', $value . PHP_EOL],
|
||||||
$sql . ' ');
|
$sql . ' ');
|
||||||
}
|
}
|
||||||
return rtrim($sql);
|
return rtrim($sql);
|
||||||
@ -648,6 +669,11 @@ abstract class Connection
|
|||||||
return $this->close()->startTrans();
|
return $this->close()->startTrans();
|
||||||
}
|
}
|
||||||
throw $e;
|
throw $e;
|
||||||
|
} catch (\Error $e) {
|
||||||
|
if ($this->isBreak($e)) {
|
||||||
|
return $this->close()->startTrans();
|
||||||
|
}
|
||||||
|
throw $e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,7 +751,7 @@ abstract class Connection
|
|||||||
* @param array $sqlArray SQL批处理指令
|
* @param array $sqlArray SQL批处理指令
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function batchQuery($sqlArray = [])
|
public function batchQuery($sqlArray = [], $bind = [], Query $query = null)
|
||||||
{
|
{
|
||||||
if (!is_array($sqlArray)) {
|
if (!is_array($sqlArray)) {
|
||||||
return false;
|
return false;
|
||||||
@ -734,7 +760,7 @@ abstract class Connection
|
|||||||
$this->startTrans();
|
$this->startTrans();
|
||||||
try {
|
try {
|
||||||
foreach ($sqlArray as $sql) {
|
foreach ($sqlArray as $sql) {
|
||||||
$this->execute($sql);
|
$this->execute($sql, $bind, $query);
|
||||||
}
|
}
|
||||||
// 提交事务
|
// 提交事务
|
||||||
$this->commit();
|
$this->commit();
|
||||||
@ -742,6 +768,7 @@ abstract class Connection
|
|||||||
$this->rollback();
|
$this->rollback();
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,6 +830,7 @@ abstract class Connection
|
|||||||
'SSL connection has been closed unexpectedly',
|
'SSL connection has been closed unexpectedly',
|
||||||
'Error writing data to the connection',
|
'Error writing data to the connection',
|
||||||
'Resource deadlock avoided',
|
'Resource deadlock avoided',
|
||||||
|
'failed with errno',
|
||||||
];
|
];
|
||||||
|
|
||||||
$error = $e->getMessage();
|
$error = $e->getMessage();
|
||||||
@ -883,9 +911,10 @@ abstract class Connection
|
|||||||
* @access protected
|
* @access protected
|
||||||
* @param boolean $start 调试开始标记 true 开始 false 结束
|
* @param boolean $start 调试开始标记 true 开始 false 结束
|
||||||
* @param string $sql 执行的SQL语句 留空自动获取
|
* @param string $sql 执行的SQL语句 留空自动获取
|
||||||
|
* @param boolean $master 主从标记
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function debug($start, $sql = '')
|
protected function debug($start, $sql = '', $master = false)
|
||||||
{
|
{
|
||||||
if (!empty($this->config['debug'])) {
|
if (!empty($this->config['debug'])) {
|
||||||
// 开启数据库调试模式
|
// 开启数据库调试模式
|
||||||
@ -902,7 +931,7 @@ abstract class Connection
|
|||||||
$result = $this->getExplain($sql);
|
$result = $this->getExplain($sql);
|
||||||
}
|
}
|
||||||
// SQL监听
|
// SQL监听
|
||||||
$this->trigger($sql, $runtime, $result);
|
$this->trigger($sql, $runtime, $result, $master);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -924,19 +953,27 @@ abstract class Connection
|
|||||||
* @param string $sql SQL语句
|
* @param string $sql SQL语句
|
||||||
* @param float $runtime SQL运行时间
|
* @param float $runtime SQL运行时间
|
||||||
* @param mixed $explain SQL分析
|
* @param mixed $explain SQL分析
|
||||||
* @return bool
|
* @param bool $master 主从标记
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function trigger($sql, $runtime, $explain = [])
|
protected function trigger($sql, $runtime, $explain = [], $master = false)
|
||||||
{
|
{
|
||||||
if (!empty(self::$event)) {
|
if (!empty(self::$event)) {
|
||||||
foreach (self::$event as $callback) {
|
foreach (self::$event as $callback) {
|
||||||
if (is_callable($callback)) {
|
if (is_callable($callback)) {
|
||||||
call_user_func_array($callback, [$sql, $runtime, $explain]);
|
call_user_func_array($callback, [$sql, $runtime, $explain, $master]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 未注册监听则记录到日志中
|
// 未注册监听则记录到日志中
|
||||||
Log::record('[ SQL ] ' . $sql . ' [ RunTime:' . $runtime . 's ]', 'sql');
|
if ($this->config['deploy']) {
|
||||||
|
// 分布式记录当前操作的主从
|
||||||
|
$master = $master ? 'master|' : 'slave|';
|
||||||
|
} else {
|
||||||
|
$master = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::record('[ SQL ] ' . $sql . ' [ ' . $master . 'RunTime:' . $runtime . 's ]', 'sql');
|
||||||
if (!empty($explain)) {
|
if (!empty($explain)) {
|
||||||
Log::record('[ EXPLAIN : ' . var_export($explain, true) . ' ]', 'sql');
|
Log::record('[ EXPLAIN : ' . var_export($explain, true) . ' ]', 'sql');
|
||||||
}
|
}
|
||||||
|
|||||||
48
thinkphp/library/think/db/Expression.php
Normal file
48
thinkphp/library/think/db/Expression.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: liu21st <liu21st@gmail.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace think\db;
|
||||||
|
|
||||||
|
class Expression
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 查询表达式
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一个查询表达式
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct($value)
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取表达式
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getValue()
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return (string) $this->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | 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 )
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
@ -53,14 +53,16 @@ class Query
|
|||||||
protected static $info = [];
|
protected static $info = [];
|
||||||
// 回调事件
|
// 回调事件
|
||||||
private static $event = [];
|
private static $event = [];
|
||||||
|
// 读取主库
|
||||||
|
private static $readMaster = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造函数
|
* 构造函数
|
||||||
* @access public
|
* @access public
|
||||||
* @param Connection $connection 数据库对象实例
|
* @param Connection $connection 数据库对象实例
|
||||||
* @param string $model 模型名
|
* @param Model $model 模型对象
|
||||||
*/
|
*/
|
||||||
public function __construct(Connection $connection = null, $model = '')
|
public function __construct(Connection $connection = null, $model = null)
|
||||||
{
|
{
|
||||||
$this->connection = $connection ?: Db::connect([], true);
|
$this->connection = $connection ?: Db::connect([], true);
|
||||||
$this->prefix = $this->connection->getConfig('prefix');
|
$this->prefix = $this->connection->getConfig('prefix');
|
||||||
@ -131,15 +133,34 @@ class Query
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前的模型对象名
|
* 获取当前的模型对象实例
|
||||||
* @access public
|
* @access public
|
||||||
* @return string
|
* @return Model|null
|
||||||
*/
|
*/
|
||||||
public function getModel()
|
public function getModel()
|
||||||
{
|
{
|
||||||
return $this->model;
|
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实例对象
|
* 获取当前的builder实例对象
|
||||||
* @access public
|
* @access public
|
||||||
@ -238,7 +259,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function execute($sql, $bind = [])
|
public function execute($sql, $bind = [])
|
||||||
{
|
{
|
||||||
return $this->connection->execute($sql, $bind);
|
return $this->connection->execute($sql, $bind, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -312,9 +333,9 @@ class Query
|
|||||||
* @param array $sql SQL批处理指令
|
* @param array $sql SQL批处理指令
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function batchQuery($sql = [])
|
public function batchQuery($sql = [], $bind = [])
|
||||||
{
|
{
|
||||||
return $this->connection->batchQuery($sql);
|
return $this->connection->batchQuery($sql, $bind);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -403,7 +424,7 @@ class Query
|
|||||||
if (empty($this->options['table'])) {
|
if (empty($this->options['table'])) {
|
||||||
$this->options['table'] = $this->getTable();
|
$this->options['table'] = $this->getTable();
|
||||||
}
|
}
|
||||||
$key = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options) . serialize($this->bind));
|
$key = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . $field . serialize($this->options) . serialize($this->bind));
|
||||||
$result = Cache::get($key);
|
$result = Cache::get($key);
|
||||||
}
|
}
|
||||||
if (false === $result) {
|
if (false === $result) {
|
||||||
@ -420,7 +441,7 @@ class Query
|
|||||||
$result += 0;
|
$result += 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($cache)) {
|
if (isset($cache) && false !== $result) {
|
||||||
// 缓存数据
|
// 缓存数据
|
||||||
$this->cacheData($key, $result, $cache);
|
$this->cacheData($key, $result, $cache);
|
||||||
}
|
}
|
||||||
@ -447,7 +468,7 @@ class Query
|
|||||||
if (empty($this->options['table'])) {
|
if (empty($this->options['table'])) {
|
||||||
$this->options['table'] = $this->getTable();
|
$this->options['table'] = $this->getTable();
|
||||||
}
|
}
|
||||||
$guid = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options) . serialize($this->bind));
|
$guid = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . $field . serialize($this->options) . serialize($this->bind));
|
||||||
$result = Cache::get($guid);
|
$result = Cache::get($guid);
|
||||||
}
|
}
|
||||||
if (false === $result) {
|
if (false === $result) {
|
||||||
@ -534,22 +555,24 @@ class Query
|
|||||||
* MIN查询
|
* MIN查询
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $field 字段名
|
* @param string $field 字段名
|
||||||
|
* @param bool $force 强制转为数字类型
|
||||||
* @return mixed
|
* @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查询
|
* MAX查询
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $field 字段名
|
* @param string $field 字段名
|
||||||
|
* @param bool $force 强制转为数字类型
|
||||||
* @return mixed
|
* @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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -607,7 +630,7 @@ class Query
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $this->setField($field, ['exp', $field . '+' . $step]);
|
return $this->setField($field, ['inc', $step]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -635,8 +658,9 @@ class Query
|
|||||||
$this->options = [];
|
$this->options = [];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return $this->setField($field, ['inc', $step]);
|
||||||
}
|
}
|
||||||
return $this->setField($field, ['exp', $field . '-' . $step]);
|
return $this->setField($field, ['dec', $step]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -704,7 +728,8 @@ class Query
|
|||||||
{
|
{
|
||||||
// 传入的表名为数组
|
// 传入的表名为数组
|
||||||
if (is_array($join)) {
|
if (is_array($join)) {
|
||||||
list($table, $alias) = each($join);
|
$table = $join;
|
||||||
|
$alias = array_shift($join);
|
||||||
} else {
|
} else {
|
||||||
$join = trim($join);
|
$join = trim($join);
|
||||||
if (false !== strpos($join, '(')) {
|
if (false !== strpos($join, '(')) {
|
||||||
@ -725,13 +750,9 @@ class Query
|
|||||||
$table = $this->getTable($table);
|
$table = $this->getTable($table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (isset($alias) && $table != $alias) {
|
||||||
if (isset($alias)) {
|
|
||||||
if (isset($this->options['alias'][$table])) {
|
|
||||||
$table = $table . '@think' . uniqid();
|
|
||||||
}
|
|
||||||
$table = [$table => $alias];
|
$table = [$table => $alias];
|
||||||
$this->alias($table);
|
}
|
||||||
}
|
}
|
||||||
return $table;
|
return $table;
|
||||||
}
|
}
|
||||||
@ -769,8 +790,15 @@ class Query
|
|||||||
{
|
{
|
||||||
if (empty($field)) {
|
if (empty($field)) {
|
||||||
return $this;
|
return $this;
|
||||||
|
} elseif ($field instanceof Expression) {
|
||||||
|
$this->options['field'][] = $field;
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_string($field)) {
|
if (is_string($field)) {
|
||||||
|
if (preg_match('/[\<\'\"\(]/', $field)) {
|
||||||
|
return $this->fieldRaw($field);
|
||||||
|
}
|
||||||
$field = array_map('trim', explode(',', $field));
|
$field = array_map('trim', explode(',', $field));
|
||||||
}
|
}
|
||||||
if (true === $field) {
|
if (true === $field) {
|
||||||
@ -794,12 +822,30 @@ class Query
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->options['field'])) {
|
if (isset($this->options['field'])) {
|
||||||
$field = array_merge($this->options['field'], $field);
|
$field = array_merge((array) $this->options['field'], $field);
|
||||||
}
|
}
|
||||||
$this->options['field'] = array_unique($field);
|
$this->options['field'] = array_unique($field);
|
||||||
return $this;
|
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
|
* @access public
|
||||||
@ -828,7 +874,7 @@ class Query
|
|||||||
{
|
{
|
||||||
$fields = is_string($field) ? explode(',', $field) : $field;
|
$fields = is_string($field) ? explode(',', $field) : $field;
|
||||||
foreach ($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
$this->data($field, ['exp', $field . '+' . $step]);
|
$this->data($field, ['inc', $step]);
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -844,7 +890,7 @@ class Query
|
|||||||
{
|
{
|
||||||
$fields = is_string($field) ? explode(',', $field) : $field;
|
$fields = is_string($field) ? explode(',', $field) : $field;
|
||||||
foreach ($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
$this->data($field, ['exp', $field . '-' . $step]);
|
$this->data($field, ['dec', $step]);
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -858,25 +904,36 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function exp($field, $value)
|
public function exp($field, $value)
|
||||||
{
|
{
|
||||||
$this->data($field, ['exp', $value]);
|
$this->data($field, $this->raw($value));
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用表达式设置数据
|
||||||
|
* @access public
|
||||||
|
* @param mixed $value 表达式
|
||||||
|
* @return Expression
|
||||||
|
*/
|
||||||
|
public function raw($value)
|
||||||
|
{
|
||||||
|
return new Expression($value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 指定JOIN查询字段
|
* 指定JOIN查询字段
|
||||||
* @access public
|
* @access public
|
||||||
* @param string|array $table 数据表
|
* @param string|array $table 数据表
|
||||||
* @param string|array $field 查询字段
|
* @param string|array $field 查询字段
|
||||||
* @param string|array $on JOIN条件
|
* @param mixed $on JOIN条件
|
||||||
* @param string $type JOIN类型
|
* @param string $type JOIN类型
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function view($join, $field = true, $on = null, $type = 'INNER')
|
public function view($join, $field = true, $on = null, $type = 'INNER')
|
||||||
{
|
{
|
||||||
$this->options['view'] = true;
|
$this->options['view'] = true;
|
||||||
if (is_array($join) && key($join) !== 0) {
|
if (is_array($join) && key($join) === 0) {
|
||||||
foreach ($join as $key => $val) {
|
foreach ($join as $key => $val) {
|
||||||
$this->view($key, $val[0], isset($val[1]) ? $val[1] : null, isset($val[2]) ? $val[2] : 'INNER');
|
$this->view($val[0], $val[1], isset($val[2]) ? $val[2] : null, isset($val[3]) ? $val[3] : 'INNER');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$fields = [];
|
$fields = [];
|
||||||
@ -975,6 +1032,37 @@ class Query
|
|||||||
return $this;
|
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查询条件
|
* 指定Null查询条件
|
||||||
* @access public
|
* @access public
|
||||||
@ -984,7 +1072,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function whereNull($field, $logic = 'AND')
|
public function whereNull($field, $logic = 'AND')
|
||||||
{
|
{
|
||||||
$this->parseWhereExp($logic, $field, 'null', null);
|
$this->parseWhereExp($logic, $field, 'null', null, [], true);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,7 +1085,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function whereNotNull($field, $logic = 'AND')
|
public function whereNotNull($field, $logic = 'AND')
|
||||||
{
|
{
|
||||||
$this->parseWhereExp($logic, $field, 'notnull', null);
|
$this->parseWhereExp($logic, $field, 'notnull', null, [], true);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1037,7 +1125,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function whereIn($field, $condition, $logic = 'AND')
|
public function whereIn($field, $condition, $logic = 'AND')
|
||||||
{
|
{
|
||||||
$this->parseWhereExp($logic, $field, 'in', $condition);
|
$this->parseWhereExp($logic, $field, 'in', $condition, [], true);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1051,7 +1139,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function whereNotIn($field, $condition, $logic = 'AND')
|
public function whereNotIn($field, $condition, $logic = 'AND')
|
||||||
{
|
{
|
||||||
$this->parseWhereExp($logic, $field, 'not in', $condition);
|
$this->parseWhereExp($logic, $field, 'not in', $condition, [], true);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1065,7 +1153,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function whereLike($field, $condition, $logic = 'AND')
|
public function whereLike($field, $condition, $logic = 'AND')
|
||||||
{
|
{
|
||||||
$this->parseWhereExp($logic, $field, 'like', $condition);
|
$this->parseWhereExp($logic, $field, 'like', $condition, [], true);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1079,7 +1167,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function whereNotLike($field, $condition, $logic = 'AND')
|
public function whereNotLike($field, $condition, $logic = 'AND')
|
||||||
{
|
{
|
||||||
$this->parseWhereExp($logic, $field, 'not like', $condition);
|
$this->parseWhereExp($logic, $field, 'not like', $condition, [], true);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1093,7 +1181,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function whereBetween($field, $condition, $logic = 'AND')
|
public function whereBetween($field, $condition, $logic = 'AND')
|
||||||
{
|
{
|
||||||
$this->parseWhereExp($logic, $field, 'between', $condition);
|
$this->parseWhereExp($logic, $field, 'between', $condition, [], true);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1107,7 +1195,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function whereNotBetween($field, $condition, $logic = 'AND')
|
public function whereNotBetween($field, $condition, $logic = 'AND')
|
||||||
{
|
{
|
||||||
$this->parseWhereExp($logic, $field, 'not between', $condition);
|
$this->parseWhereExp($logic, $field, 'not between', $condition, [], true);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1121,7 +1209,7 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function whereExp($field, $condition, $logic = 'AND')
|
public function whereExp($field, $condition, $logic = 'AND')
|
||||||
{
|
{
|
||||||
$this->parseWhereExp($logic, $field, 'exp', $condition);
|
$this->parseWhereExp($logic, $field, 'exp', $this->raw($condition), [], true);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1148,9 +1236,10 @@ class Query
|
|||||||
* @param mixed $op 查询表达式
|
* @param mixed $op 查询表达式
|
||||||
* @param mixed $condition 查询条件
|
* @param mixed $condition 查询条件
|
||||||
* @param array $param 查询参数
|
* @param array $param 查询参数
|
||||||
|
* @param bool $strict 严格模式
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function parseWhereExp($logic, $field, $op, $condition, $param = [])
|
protected function parseWhereExp($logic, $field, $op, $condition, $param = [], $strict = false)
|
||||||
{
|
{
|
||||||
$logic = strtoupper($logic);
|
$logic = strtoupper($logic);
|
||||||
if ($field instanceof \Closure) {
|
if ($field instanceof \Closure) {
|
||||||
@ -1161,8 +1250,17 @@ class Query
|
|||||||
if (is_string($field) && !empty($this->options['via']) && !strpos($field, '.')) {
|
if (is_string($field) && !empty($this->options['via']) && !strpos($field, '.')) {
|
||||||
$field = $this->options['via'] . '.' . $field;
|
$field = $this->options['via'] . '.' . $field;
|
||||||
}
|
}
|
||||||
if (is_string($field) && preg_match('/[,=\>\<\'\"\(\s]/', $field)) {
|
|
||||||
$where[] = ['exp', $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_array($op)) {
|
if (is_array($op)) {
|
||||||
// 参数绑定
|
// 参数绑定
|
||||||
$this->bind($op);
|
$this->bind($op);
|
||||||
@ -1184,20 +1282,27 @@ class Query
|
|||||||
} elseif (in_array(strtolower($op), ['null', 'notnull', 'not null'])) {
|
} elseif (in_array(strtolower($op), ['null', 'notnull', 'not null'])) {
|
||||||
// null查询
|
// null查询
|
||||||
$where[$field] = [$op, ''];
|
$where[$field] = [$op, ''];
|
||||||
|
|
||||||
$this->options['multi'][$logic][$field][] = $where[$field];
|
$this->options['multi'][$logic][$field][] = $where[$field];
|
||||||
} elseif (is_null($condition)) {
|
} elseif (is_null($condition)) {
|
||||||
// 字段相等查询
|
// 字段相等查询
|
||||||
$where[$field] = ['eq', $op];
|
$where[$field] = ['eq', $op];
|
||||||
|
|
||||||
$this->options['multi'][$logic][$field][] = $where[$field];
|
$this->options['multi'][$logic][$field][] = $where[$field];
|
||||||
} else {
|
} else {
|
||||||
$where[$field] = [$op, $condition, isset($param[2]) ? $param[2] : null];
|
if ('exp' == strtolower($op)) {
|
||||||
if ('exp' == strtolower($op) && isset($param[2]) && is_array($param[2])) {
|
$where[$field] = ['exp', $this->raw($condition)];
|
||||||
// 参数绑定
|
// 参数绑定
|
||||||
|
if (isset($param[2]) && is_array($param[2])) {
|
||||||
$this->bind($param[2]);
|
$this->bind($param[2]);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$where[$field] = [$op, $condition];
|
||||||
|
}
|
||||||
// 记录一个字段多次查询条件
|
// 记录一个字段多次查询条件
|
||||||
$this->options['multi'][$logic][$field][] = $where[$field];
|
$this->options['multi'][$logic][$field][] = $where[$field];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($where)) {
|
if (!empty($where)) {
|
||||||
if (!isset($this->options['where'][$logic])) {
|
if (!isset($this->options['where'][$logic])) {
|
||||||
$this->options['where'][$logic] = [];
|
$this->options['where'][$logic] = [];
|
||||||
@ -1239,6 +1344,7 @@ class Query
|
|||||||
$logic = strtoupper($logic);
|
$logic = strtoupper($logic);
|
||||||
if (isset($this->options['where'][$logic][$field])) {
|
if (isset($this->options['where'][$logic][$field])) {
|
||||||
unset($this->options['where'][$logic][$field]);
|
unset($this->options['where'][$logic][$field]);
|
||||||
|
unset($this->options['multi'][$logic][$field]);
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -1414,12 +1520,22 @@ class Query
|
|||||||
*/
|
*/
|
||||||
public function order($field, $order = null)
|
public function order($field, $order = null)
|
||||||
{
|
{
|
||||||
if (!empty($field)) {
|
if (empty($field)) {
|
||||||
|
return $this;
|
||||||
|
} elseif ($field instanceof Expression) {
|
||||||
|
$this->options['order'][] = $field;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_string($field)) {
|
if (is_string($field)) {
|
||||||
if (!empty($this->options['via'])) {
|
if (!empty($this->options['via'])) {
|
||||||
$field = $this->options['via'] . '.' . $field;
|
$field = $this->options['via'] . '.' . $field;
|
||||||
}
|
}
|
||||||
|
if (strpos($field, ',')) {
|
||||||
|
$field = array_map('trim', explode(',', $field));
|
||||||
|
} else {
|
||||||
$field = empty($order) ? $field : [$field => $order];
|
$field = empty($order) ? $field : [$field => $order];
|
||||||
|
}
|
||||||
} elseif (!empty($this->options['via'])) {
|
} elseif (!empty($this->options['via'])) {
|
||||||
foreach ($field as $key => $val) {
|
foreach ($field as $key => $val) {
|
||||||
if (is_numeric($key)) {
|
if (is_numeric($key)) {
|
||||||
@ -1438,7 +1554,25 @@ class Query
|
|||||||
} else {
|
} else {
|
||||||
$this->options['order'][] = $field;
|
$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;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1523,7 +1657,12 @@ class Query
|
|||||||
{
|
{
|
||||||
if (is_array($alias)) {
|
if (is_array($alias)) {
|
||||||
foreach ($alias as $key => $val) {
|
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 {
|
} else {
|
||||||
if (isset($this->options['table'])) {
|
if (isset($this->options['table'])) {
|
||||||
@ -1651,15 +1790,17 @@ class Query
|
|||||||
* 查询日期或者时间
|
* 查询日期或者时间
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $field 日期字段名
|
* @param string $field 日期字段名
|
||||||
* @param string $op 比较运算符或者表达式
|
* @param string|array $op 比较运算符或者表达式
|
||||||
* @param string|array $range 比较范围
|
* @param string|array $range 比较范围
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function whereTime($field, $op, $range = null)
|
public function whereTime($field, $op, $range = null)
|
||||||
{
|
{
|
||||||
if (is_null($range)) {
|
if (is_null($range)) {
|
||||||
|
if (is_array($op)) {
|
||||||
|
$range = $op;
|
||||||
|
} else {
|
||||||
// 使用日期表达式
|
// 使用日期表达式
|
||||||
$date = getdate();
|
|
||||||
switch (strtolower($op)) {
|
switch (strtolower($op)) {
|
||||||
case 'today':
|
case 'today':
|
||||||
case 'd':
|
case 'd':
|
||||||
@ -1667,15 +1808,15 @@ class Query
|
|||||||
break;
|
break;
|
||||||
case 'week':
|
case 'week':
|
||||||
case 'w':
|
case 'w':
|
||||||
$range = 'this week 00:00:00';
|
$range = ['this week 00:00:00', 'next week 00:00:00'];
|
||||||
break;
|
break;
|
||||||
case 'month':
|
case 'month':
|
||||||
case 'm':
|
case 'm':
|
||||||
$range = mktime(0, 0, 0, $date['mon'], 1, $date['year']);
|
$range = ['first Day of this month 00:00:00', 'first Day of next month 00:00:00'];
|
||||||
break;
|
break;
|
||||||
case 'year':
|
case 'year':
|
||||||
case 'y':
|
case 'y':
|
||||||
$range = mktime(0, 0, 0, 1, 1, $date['year']);
|
$range = ['this year 1/1', 'next year 1/1'];
|
||||||
break;
|
break;
|
||||||
case 'yesterday':
|
case 'yesterday':
|
||||||
$range = ['yesterday', 'today'];
|
$range = ['yesterday', 'today'];
|
||||||
@ -1684,14 +1825,15 @@ class Query
|
|||||||
$range = ['last week 00:00:00', 'this week 00:00:00'];
|
$range = ['last week 00:00:00', 'this week 00:00:00'];
|
||||||
break;
|
break;
|
||||||
case 'last month':
|
case 'last month':
|
||||||
$range = [date('y-m-01', strtotime('-1 month')), mktime(0, 0, 0, $date['mon'], 1, $date['year'])];
|
$range = ['first Day of last month 00:00:00', 'first Day of this month 00:00:00'];
|
||||||
break;
|
break;
|
||||||
case 'last year':
|
case 'last year':
|
||||||
$range = [mktime(0, 0, 0, 1, 1, $date['year'] - 1), mktime(0, 0, 0, 1, 1, $date['year'])];
|
$range = ['last year 1/1', 'this year 1/1'];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$range = $op;
|
$range = $op;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
$op = is_array($range) ? 'between' : '>';
|
$op = is_array($range) ? 'between' : '>';
|
||||||
}
|
}
|
||||||
$this->where($field, strtolower($op) . ' time', $range);
|
$this->where($field, strtolower($op) . ' time', $range);
|
||||||
@ -1735,7 +1877,7 @@ class Query
|
|||||||
$schema = $guid;
|
$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';
|
$info = include RUNTIME_PATH . 'schema/' . $schema . '.php';
|
||||||
} else {
|
} else {
|
||||||
$info = $this->connection->getFields($guid);
|
$info = $this->connection->getFields($guid);
|
||||||
@ -1810,7 +1952,9 @@ class Query
|
|||||||
*/
|
*/
|
||||||
protected function getFieldBindType($type)
|
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;
|
$bind = PDO::PARAM_INT;
|
||||||
} elseif (preg_match('/bool/is', $type)) {
|
} elseif (preg_match('/bool/is', $type)) {
|
||||||
$bind = PDO::PARAM_BOOL;
|
$bind = PDO::PARAM_BOOL;
|
||||||
@ -1893,10 +2037,9 @@ class Query
|
|||||||
}
|
}
|
||||||
|
|
||||||
$first = true;
|
$first = true;
|
||||||
$currentModel = $this->model;
|
|
||||||
|
|
||||||
/** @var Model $class */
|
/** @var Model $class */
|
||||||
$class = new $currentModel;
|
$class = $this->model;
|
||||||
foreach ($with as $key => $relation) {
|
foreach ($with as $key => $relation) {
|
||||||
$subRelation = '';
|
$subRelation = '';
|
||||||
$closure = false;
|
$closure = false;
|
||||||
@ -1955,7 +2098,7 @@ class Query
|
|||||||
$relation = $key;
|
$relation = $key;
|
||||||
}
|
}
|
||||||
$relation = Loader::parseName($relation, 1, false);
|
$relation = Loader::parseName($relation, 1, false);
|
||||||
$count = '(' . (new $this->model)->$relation()->getRelationCountQuery($closure) . ')';
|
$count = '(' . $this->model->$relation()->getRelationCountQuery($closure) . ')';
|
||||||
$this->field([$count => Loader::parseName($relation) . '_count']);
|
$this->field([$count => Loader::parseName($relation) . '_count']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2082,7 +2225,7 @@ class Query
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 执行操作
|
// 执行操作
|
||||||
$result = 0 === $sql ? 0 : $this->execute($sql, $bind);
|
$result = 0 === $sql ? 0 : $this->execute($sql, $bind, $this);
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null);
|
$sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null);
|
||||||
$lastInsId = $this->getLastInsID($sequence);
|
$lastInsId = $this->getLastInsID($sequence);
|
||||||
@ -2120,25 +2263,38 @@ class Query
|
|||||||
* @access public
|
* @access public
|
||||||
* @param mixed $dataSet 数据集
|
* @param mixed $dataSet 数据集
|
||||||
* @param boolean $replace 是否replace
|
* @param boolean $replace 是否replace
|
||||||
|
* @param integer $limit 每次写入数据限制
|
||||||
* @return integer|string
|
* @return integer|string
|
||||||
*/
|
*/
|
||||||
public function insertAll(array $dataSet, $replace = false)
|
public function insertAll(array $dataSet, $replace = false, $limit = null)
|
||||||
{
|
{
|
||||||
// 分析查询表达式
|
// 分析查询表达式
|
||||||
$options = $this->parseExpress();
|
$options = $this->parseExpress();
|
||||||
if (!is_array(reset($dataSet))) {
|
if (!is_array(reset($dataSet))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成SQL语句
|
// 生成SQL语句
|
||||||
|
if (is_null($limit)) {
|
||||||
$sql = $this->builder->insertAll($dataSet, $options, $replace);
|
$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();
|
$bind = $this->getBind();
|
||||||
if ($options['fetch_sql']) {
|
if ($options['fetch_sql']) {
|
||||||
// 获取实际执行的SQL语句
|
// 获取实际执行的SQL语句
|
||||||
return $this->connection->getRealSql($sql, $bind);
|
return $this->connection->getRealSql($sql, $bind);
|
||||||
|
} elseif (is_array($sql)) {
|
||||||
|
// 执行操作
|
||||||
|
return $this->batchQuery($sql, $bind, $this);
|
||||||
} else {
|
} else {
|
||||||
// 执行操作
|
// 执行操作
|
||||||
return $this->execute($sql, $bind);
|
return $this->execute($sql, $bind, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2164,7 +2320,7 @@ class Query
|
|||||||
return $this->connection->getRealSql($sql, $bind);
|
return $this->connection->getRealSql($sql, $bind);
|
||||||
} else {
|
} else {
|
||||||
// 执行操作
|
// 执行操作
|
||||||
return $this->execute($sql, $bind);
|
return $this->execute($sql, $bind, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2231,7 +2387,7 @@ class Query
|
|||||||
Cache::clear($options['cache']['tag']);
|
Cache::clear($options['cache']['tag']);
|
||||||
}
|
}
|
||||||
// 执行操作
|
// 执行操作
|
||||||
$result = '' == $sql ? 0 : $this->execute($sql, $bind);
|
$result = '' == $sql ? 0 : $this->execute($sql, $bind, $this);
|
||||||
if ($result) {
|
if ($result) {
|
||||||
if (is_string($pk) && isset($where[$pk])) {
|
if (is_string($pk) && isset($where[$pk])) {
|
||||||
$data[$pk] = $where[$pk];
|
$data[$pk] = $where[$pk];
|
||||||
@ -2300,7 +2456,7 @@ class Query
|
|||||||
// 判断查询缓存
|
// 判断查询缓存
|
||||||
$cache = $options['cache'];
|
$cache = $options['cache'];
|
||||||
unset($options['cache']);
|
unset($options['cache']);
|
||||||
$key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options) . serialize($this->bind));
|
$key = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . serialize($options) . serialize($this->bind));
|
||||||
$resultSet = Cache::get($key);
|
$resultSet = Cache::get($key);
|
||||||
}
|
}
|
||||||
if (false === $resultSet) {
|
if (false === $resultSet) {
|
||||||
@ -2334,11 +2490,10 @@ class Query
|
|||||||
// 数据列表读取后的处理
|
// 数据列表读取后的处理
|
||||||
if (!empty($this->model)) {
|
if (!empty($this->model)) {
|
||||||
// 生成模型对象
|
// 生成模型对象
|
||||||
$modelName = $this->model;
|
|
||||||
if (count($resultSet) > 0) {
|
if (count($resultSet) > 0) {
|
||||||
foreach ($resultSet as $key => $result) {
|
foreach ($resultSet as $key => $result) {
|
||||||
/** @var Model $model */
|
/** @var Model $model */
|
||||||
$model = new $modelName($result);
|
$model = $this->model->newInstance($result);
|
||||||
$model->isUpdate(true);
|
$model->isUpdate(true);
|
||||||
|
|
||||||
// 关联查询
|
// 关联查询
|
||||||
@ -2358,7 +2513,7 @@ class Query
|
|||||||
// 模型数据集转换
|
// 模型数据集转换
|
||||||
$resultSet = $model->toCollection($resultSet);
|
$resultSet = $model->toCollection($resultSet);
|
||||||
} else {
|
} else {
|
||||||
$resultSet = (new $modelName)->toCollection($resultSet);
|
$resultSet = $this->model->toCollection($resultSet);
|
||||||
}
|
}
|
||||||
} elseif ('collection' == $this->connection->getConfig('resultset_type')) {
|
} elseif ('collection' == $this->connection->getConfig('resultset_type')) {
|
||||||
// 返回Collection对象
|
// 返回Collection对象
|
||||||
@ -2402,10 +2557,16 @@ class Query
|
|||||||
} elseif (is_array($value) && is_string($value[0]) && 'eq' == strtolower($value[0])) {
|
} elseif (is_array($value) && is_string($value[0]) && 'eq' == strtolower($value[0])) {
|
||||||
$data = $value[1];
|
$data = $value[1];
|
||||||
}
|
}
|
||||||
|
$prefix = $this->connection->getConfig('database') . '.';
|
||||||
|
|
||||||
if (isset($data)) {
|
if (isset($data)) {
|
||||||
return 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data;
|
return 'think:' . $prefix . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data;
|
||||||
} else {
|
}
|
||||||
return md5(serialize($options) . serialize($bind));
|
|
||||||
|
try {
|
||||||
|
return md5($prefix . serialize($options) . serialize($bind));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new Exception('closure not support cache(true)');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2442,11 +2603,11 @@ class Query
|
|||||||
// 判断查询缓存
|
// 判断查询缓存
|
||||||
$cache = $options['cache'];
|
$cache = $options['cache'];
|
||||||
if (true === $cache['key'] && !is_null($data) && !is_array($data)) {
|
if (true === $cache['key'] && !is_null($data) && !is_array($data)) {
|
||||||
$key = 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data;
|
$key = 'think:' . $this->connection->getConfig('database') . '.' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data;
|
||||||
} elseif (is_string($cache['key'])) {
|
} elseif (is_string($cache['key'])) {
|
||||||
$key = $cache['key'];
|
$key = $cache['key'];
|
||||||
} elseif (!isset($key)) {
|
} elseif (!isset($key)) {
|
||||||
$key = md5(serialize($options) . serialize($this->bind));
|
$key = md5($this->connection->getConfig('database') . '.' . serialize($options) . serialize($this->bind));
|
||||||
}
|
}
|
||||||
$result = Cache::get($key);
|
$result = Cache::get($key);
|
||||||
}
|
}
|
||||||
@ -2484,7 +2645,7 @@ class Query
|
|||||||
$result = isset($resultSet[0]) ? $resultSet[0] : null;
|
$result = isset($resultSet[0]) ? $resultSet[0] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($cache) && false !== $result) {
|
if (isset($cache) && $result) {
|
||||||
// 缓存数据
|
// 缓存数据
|
||||||
$this->cacheData($key, $result, $cache);
|
$this->cacheData($key, $result, $cache);
|
||||||
}
|
}
|
||||||
@ -2494,8 +2655,7 @@ class Query
|
|||||||
if (!empty($result)) {
|
if (!empty($result)) {
|
||||||
if (!empty($this->model)) {
|
if (!empty($this->model)) {
|
||||||
// 返回模型对象
|
// 返回模型对象
|
||||||
$model = $this->model;
|
$result = $this->model->newInstance($result);
|
||||||
$result = new $model($result);
|
|
||||||
$result->isUpdate(true, isset($options['where']['AND']) ? $options['where']['AND'] : null);
|
$result->isUpdate(true, isset($options['where']['AND']) ? $options['where']['AND'] : null);
|
||||||
// 关联查询
|
// 关联查询
|
||||||
if (!empty($options['relation'])) {
|
if (!empty($options['relation'])) {
|
||||||
@ -2526,7 +2686,8 @@ class Query
|
|||||||
protected function throwNotFound($options = [])
|
protected function throwNotFound($options = [])
|
||||||
{
|
{
|
||||||
if (!empty($this->model)) {
|
if (!empty($this->model)) {
|
||||||
throw new ModelNotFoundException('model data Not Found:' . $this->model, $this->model, $options);
|
$class = get_class($this->model);
|
||||||
|
throw new ModelNotFoundException('model data Not Found:' . $class, $class, $options);
|
||||||
} else {
|
} else {
|
||||||
$table = is_array($options['table']) ? key($options['table']) : $options['table'];
|
$table = is_array($options['table']) ? key($options['table']) : $options['table'];
|
||||||
throw new DataNotFoundException('table data not Found:' . $table, $table, $options);
|
throw new DataNotFoundException('table data not Found:' . $table, $table, $options);
|
||||||
@ -2574,15 +2735,11 @@ class Query
|
|||||||
public function chunk($count, $callback, $column = null, $order = 'asc')
|
public function chunk($count, $callback, $column = null, $order = 'asc')
|
||||||
{
|
{
|
||||||
$options = $this->getOptions();
|
$options = $this->getOptions();
|
||||||
if (isset($options['table'])) {
|
if (empty($options['table'])) {
|
||||||
$table = is_array($options['table']) ? key($options['table']) : $options['table'];
|
$options['table'] = $this->getTable();
|
||||||
} else {
|
|
||||||
$table = '';
|
|
||||||
}
|
|
||||||
$column = $column ?: $this->getPk($table);
|
|
||||||
if (is_array($column)) {
|
|
||||||
$column = $column[0];
|
|
||||||
}
|
}
|
||||||
|
$column = $column ?: $this->getPk($options);
|
||||||
|
|
||||||
if (isset($options['order'])) {
|
if (isset($options['order'])) {
|
||||||
if (App::$debug) {
|
if (App::$debug) {
|
||||||
throw new \LogicException('chunk not support call order');
|
throw new \LogicException('chunk not support call order');
|
||||||
@ -2590,32 +2747,42 @@ class Query
|
|||||||
unset($options['order']);
|
unset($options['order']);
|
||||||
}
|
}
|
||||||
$bind = $this->bind;
|
$bind = $this->bind;
|
||||||
$resultSet = $this->options($options)->limit($count)->order($column, $order)->select();
|
if (is_array($column)) {
|
||||||
|
$times = 1;
|
||||||
|
$query = $this->options($options)->page($times, $count);
|
||||||
|
} else {
|
||||||
if (strpos($column, '.')) {
|
if (strpos($column, '.')) {
|
||||||
list($alias, $key) = explode('.', $column);
|
list($alias, $key) = explode('.', $column);
|
||||||
} else {
|
} else {
|
||||||
$key = $column;
|
$key = $column;
|
||||||
}
|
}
|
||||||
|
$query = $this->options($options)->limit($count);
|
||||||
|
}
|
||||||
|
$resultSet = $query->order($column, $order)->select();
|
||||||
|
|
||||||
|
while (count($resultSet) > 0) {
|
||||||
if ($resultSet instanceof Collection) {
|
if ($resultSet instanceof Collection) {
|
||||||
$resultSet = $resultSet->all();
|
$resultSet = $resultSet->all();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!empty($resultSet)) {
|
|
||||||
if (false === call_user_func($callback, $resultSet)) {
|
if (false === call_user_func($callback, $resultSet)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_array($column)) {
|
||||||
|
$times++;
|
||||||
|
$query = $this->options($options)->page($times, $count);
|
||||||
|
} else {
|
||||||
$end = end($resultSet);
|
$end = end($resultSet);
|
||||||
$lastId = is_array($end) ? $end[$key] : $end->$key;
|
$lastId = is_array($end) ? $end[$key] : $end->getData($key);
|
||||||
$resultSet = $this->options($options)
|
$query = $this->options($options)
|
||||||
->limit($count)
|
->limit($count)
|
||||||
->bind($bind)
|
->where($column, 'asc' == strtolower($order) ? '>' : '<', $lastId);
|
||||||
->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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2692,7 +2859,7 @@ class Query
|
|||||||
Cache::clear($options['cache']['tag']);
|
Cache::clear($options['cache']['tag']);
|
||||||
}
|
}
|
||||||
// 执行操作
|
// 执行操作
|
||||||
$result = $this->execute($sql, $bind);
|
$result = $this->execute($sql, $bind, $this);
|
||||||
if ($result) {
|
if ($result) {
|
||||||
if (!is_array($data) && is_string($pk) && isset($key) && strpos($key, '|')) {
|
if (!is_array($data) && is_string($pk) && isset($key) && strpos($key, '|')) {
|
||||||
list($a, $val) = explode('|', $key);
|
list($a, $val) = explode('|', $key);
|
||||||
@ -2777,6 +2944,10 @@ 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) {
|
foreach (['join', 'union', 'group', 'having', 'limit', 'order', 'force', 'comment'] as $name) {
|
||||||
if (!isset($options[$name])) {
|
if (!isset($options[$name])) {
|
||||||
$options[$name] = '';
|
$options[$name] = '';
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | 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 )
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
@ -12,28 +12,93 @@
|
|||||||
namespace think\db\builder;
|
namespace think\db\builder;
|
||||||
|
|
||||||
use think\db\Builder;
|
use think\db\Builder;
|
||||||
|
use think\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mysql数据库驱动
|
* mysql数据库驱动
|
||||||
*/
|
*/
|
||||||
class Mysql extends Builder
|
class Mysql extends Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
|
protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES %DATA% %COMMENT%';
|
||||||
protected $updateSql = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';
|
protected $updateSql = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成insertall SQL
|
||||||
|
* @access public
|
||||||
|
* @param array $dataSet 数据集
|
||||||
|
* @param array $options 表达式
|
||||||
|
* @param bool $replace 是否replace
|
||||||
|
* @return string
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function insertAll($dataSet, $options = [], $replace = false)
|
||||||
|
{
|
||||||
|
// 获取合法的字段
|
||||||
|
if ('*' == $options['field']) {
|
||||||
|
$fields = array_keys($this->query->getFieldsType($options['table']));
|
||||||
|
} else {
|
||||||
|
$fields = $options['field'];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($dataSet as $data) {
|
||||||
|
foreach ($data as $key => $val) {
|
||||||
|
if (!in_array($key, $fields, true)) {
|
||||||
|
if ($options['strict']) {
|
||||||
|
throw new Exception('fields not exists:[' . $key . ']');
|
||||||
|
}
|
||||||
|
unset($data[$key]);
|
||||||
|
} elseif (is_null($val)) {
|
||||||
|
$data[$key] = 'NULL';
|
||||||
|
} elseif (is_scalar($val)) {
|
||||||
|
$data[$key] = $this->parseValue($val, $key);
|
||||||
|
} elseif (is_object($val) && method_exists($val, '__toString')) {
|
||||||
|
// 对象数据写入
|
||||||
|
$data[$key] = $val->__toString();
|
||||||
|
} else {
|
||||||
|
// 过滤掉非标量数据
|
||||||
|
unset($data[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$value = array_values($data);
|
||||||
|
$values[] = '( ' . implode(',', $value) . ' )';
|
||||||
|
|
||||||
|
if (!isset($insertFields)) {
|
||||||
|
$insertFields = array_map([$this, 'parseKey'], array_keys($data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return str_replace(
|
||||||
|
['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'],
|
||||||
|
[
|
||||||
|
$replace ? 'REPLACE' : 'INSERT',
|
||||||
|
$this->parseTable($options['table'], $options),
|
||||||
|
implode(' , ', $insertFields),
|
||||||
|
implode(' , ', $values),
|
||||||
|
$this->parseComment($options['comment']),
|
||||||
|
], $this->insertAllSql);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字段和表名处理
|
* 字段和表名处理
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param string $key
|
* @param mixed $key
|
||||||
* @param array $options
|
* @param array $options
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function parseKey($key, $options = [])
|
protected function parseKey($key, $options = [], $strict = false)
|
||||||
{
|
{
|
||||||
|
if (is_numeric($key)) {
|
||||||
|
return $key;
|
||||||
|
} elseif ($key instanceof Expression) {
|
||||||
|
return $key->getValue();
|
||||||
|
}
|
||||||
|
|
||||||
$key = trim($key);
|
$key = trim($key);
|
||||||
if (strpos($key, '$.') && false === strpos($key, '(')) {
|
if (strpos($key, '$.') && false === strpos($key, '(')) {
|
||||||
// JSON字段支持
|
// JSON字段支持
|
||||||
list($field, $name) = explode('$.', $key);
|
list($field, $name) = explode('$.', $key);
|
||||||
$key = 'json_extract(' . $field . ', \'$.' . $name . '\')';
|
return 'json_extract(' . $field . ', \'$.' . $name . '\')';
|
||||||
} elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {
|
} elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {
|
||||||
list($table, $key) = explode('.', $key, 2);
|
list($table, $key) = explode('.', $key, 2);
|
||||||
if ('__TABLE__' == $table) {
|
if ('__TABLE__' == $table) {
|
||||||
@ -43,7 +108,8 @@ class Mysql extends Builder
|
|||||||
$table = $options['alias'][$table];
|
$table = $options['alias'][$table];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
|
|
||||||
|
if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)`.\s]/', $key))) {
|
||||||
$key = '`' . $key . '`';
|
$key = '`' . $key . '`';
|
||||||
}
|
}
|
||||||
if (isset($table)) {
|
if (isset($table)) {
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | 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 )
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
@ -44,12 +44,18 @@ class Pgsql extends Builder
|
|||||||
/**
|
/**
|
||||||
* 字段和表名处理
|
* 字段和表名处理
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param string $key
|
* @param mixed $key
|
||||||
* @param array $options
|
* @param array $options
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function parseKey($key, $options = [])
|
protected function parseKey($key, $options = [], $strict = false)
|
||||||
{
|
{
|
||||||
|
if (is_numeric($key)) {
|
||||||
|
return $key;
|
||||||
|
} elseif ($key instanceof Expression) {
|
||||||
|
return $key->getValue();
|
||||||
|
}
|
||||||
|
|
||||||
$key = trim($key);
|
$key = trim($key);
|
||||||
if (strpos($key, '$.') && false === strpos($key, '(')) {
|
if (strpos($key, '$.') && false === strpos($key, '(')) {
|
||||||
// JSON字段支持
|
// JSON字段支持
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | 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 )
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
@ -52,12 +52,18 @@ class Sqlite extends Builder
|
|||||||
/**
|
/**
|
||||||
* 字段和表名处理
|
* 字段和表名处理
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param string $key
|
* @param mixed $key
|
||||||
* @param array $options
|
* @param array $options
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function parseKey($key, $options = [])
|
protected function parseKey($key, $options = [], $strict = false)
|
||||||
{
|
{
|
||||||
|
if (is_numeric($key)) {
|
||||||
|
return $key;
|
||||||
|
} elseif ($key instanceof Expression) {
|
||||||
|
return $key->getValue();
|
||||||
|
}
|
||||||
|
|
||||||
$key = trim($key);
|
$key = trim($key);
|
||||||
if (strpos($key, '.')) {
|
if (strpos($key, '.')) {
|
||||||
list($table, $key) = explode('.', $key, 2);
|
list($table, $key) = explode('.', $key, 2);
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
namespace think\db\builder;
|
namespace think\db\builder;
|
||||||
|
|
||||||
use think\db\Builder;
|
use think\db\Builder;
|
||||||
|
use think\db\Expression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sqlsrv数据库驱动
|
* Sqlsrv数据库驱动
|
||||||
@ -34,10 +35,15 @@ class Sqlsrv extends Builder
|
|||||||
*/
|
*/
|
||||||
protected function parseOrder($order, $options = [])
|
protected function parseOrder($order, $options = [])
|
||||||
{
|
{
|
||||||
if (is_array($order)) {
|
if (empty($order)) {
|
||||||
|
return ' ORDER BY rand()';
|
||||||
|
}
|
||||||
|
|
||||||
$array = [];
|
$array = [];
|
||||||
foreach ($order as $key => $val) {
|
foreach ($order as $key => $val) {
|
||||||
if (is_numeric($key)) {
|
if ($val instanceof Expression) {
|
||||||
|
$array[] = $val->getValue();
|
||||||
|
} elseif (is_numeric($key)) {
|
||||||
if (false === strpos($val, '(')) {
|
if (false === strpos($val, '(')) {
|
||||||
$array[] = $this->parseKey($val, $options);
|
$array[] = $this->parseKey($val, $options);
|
||||||
} elseif ('[rand]' == $val) {
|
} elseif ('[rand]' == $val) {
|
||||||
@ -46,13 +52,12 @@ class Sqlsrv extends Builder
|
|||||||
$array[] = $val;
|
$array[] = $val;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$sort = in_array(strtolower(trim($val)), ['asc', 'desc']) ? ' ' . $val : '';
|
$sort = in_array(strtolower(trim($val)), ['asc', 'desc'], true) ? ' ' . $val : '';
|
||||||
$array[] = $this->parseKey($key, $options) . ' ' . $sort;
|
$array[] = $this->parseKey($key, $options, true) . ' ' . $sort;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$order = implode(',', $array);
|
|
||||||
}
|
return ' ORDER BY ' . implode(',', $array);
|
||||||
return !empty($order) ? ' ORDER BY ' . $order : ' ORDER BY rand()';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,12 +73,17 @@ class Sqlsrv extends Builder
|
|||||||
/**
|
/**
|
||||||
* 字段和表名处理
|
* 字段和表名处理
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param string $key
|
* @param mixed $key
|
||||||
* @param array $options
|
* @param array $options
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function parseKey($key, $options = [])
|
protected function parseKey($key, $options = [], $strict = false)
|
||||||
{
|
{
|
||||||
|
if (is_numeric($key)) {
|
||||||
|
return $key;
|
||||||
|
} elseif ($key instanceof Expression) {
|
||||||
|
return $key->getValue();
|
||||||
|
}
|
||||||
$key = trim($key);
|
$key = trim($key);
|
||||||
if (strpos($key, '.') && !preg_match('/[,\'\"\(\)\[\s]/', $key)) {
|
if (strpos($key, '.') && !preg_match('/[,\'\"\(\)\[\s]/', $key)) {
|
||||||
list($table, $key) = explode('.', $key, 2);
|
list($table, $key) = explode('.', $key, 2);
|
||||||
@ -84,7 +94,7 @@ class Sqlsrv extends Builder
|
|||||||
$table = $options['alias'][$table];
|
$table = $options['alias'][$table];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) {
|
if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)\[.\s]/', $key))) {
|
||||||
$key = '[' . $key . ']';
|
$key = '[' . $key . ']';
|
||||||
}
|
}
|
||||||
if (isset($table)) {
|
if (isset($table)) {
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | 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 )
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | 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 )
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | 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 )
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | 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 )
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | 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 )
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
// | 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 )
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user