1、更换编辑器
2、内核升级
This commit is contained in:
@@ -27,13 +27,15 @@ use think\exception\PDOException;
|
||||
use think\Loader;
|
||||
use think\Model;
|
||||
use think\model\Relation;
|
||||
use think\model\relation\BelongsTo;
|
||||
use think\model\relation\HasOne;
|
||||
use think\Paginator;
|
||||
|
||||
class Query
|
||||
{
|
||||
// 数据库Connection对象实例
|
||||
protected $connection;
|
||||
// 数据库驱动类型
|
||||
// 数据库Builder对象实例
|
||||
protected $builder;
|
||||
// 当前模型类名称
|
||||
protected $model;
|
||||
@@ -51,6 +53,8 @@ class Query
|
||||
protected $bind = [];
|
||||
// 数据表信息
|
||||
protected static $info = [];
|
||||
// 回调事件
|
||||
private static $event = [];
|
||||
|
||||
/**
|
||||
* 架构函数
|
||||
@@ -61,9 +65,10 @@ class Query
|
||||
public function __construct(Connection $connection = null, $model = '')
|
||||
{
|
||||
$this->connection = $connection ?: Db::connect([], true);
|
||||
$this->builder = $this->connection->getConfig('builder') ?: $this->connection->getConfig('type');
|
||||
$this->prefix = $this->connection->getConfig('prefix');
|
||||
$this->model = $model;
|
||||
// 设置当前连接的Builder对象
|
||||
$this->setBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,9 +116,42 @@ class Query
|
||||
public function connect($config)
|
||||
{
|
||||
$this->connection = Db::connect($config);
|
||||
$this->setBuilder();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前的数据库Builder对象
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function setBuilder()
|
||||
{
|
||||
$builder = $this->connection->getConfig('builder') ?: $this->connection->getConfig('type');
|
||||
$class = false !== strpos($builder, '\\') ? $builder : '\\think\\db\\builder\\' . ucfirst($builder);
|
||||
$this->builder = new $class($this->connection, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的模型对象名
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getModel()
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的builder实例对象
|
||||
* @access public
|
||||
* @return Builder
|
||||
*/
|
||||
public function getBuilder()
|
||||
{
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定默认的数据表名(不含前缀)
|
||||
* @access public
|
||||
@@ -350,24 +388,6 @@ class Query
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的builder实例对象
|
||||
* @access protected
|
||||
* @return Builder
|
||||
*/
|
||||
protected function builder()
|
||||
{
|
||||
static $builder = [];
|
||||
$driver = $this->builder;
|
||||
if (!isset($builder[$driver])) {
|
||||
$class = false !== strpos($driver, '\\') ? $driver : '\\think\\db\\builder\\' . ucfirst($driver);
|
||||
$builder[$driver] = new $class($this->connection);
|
||||
}
|
||||
// 设置当前查询对象
|
||||
$builder[$driver]->setQuery($this);
|
||||
return $builder[$driver];
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到某个字段的值
|
||||
* @access public
|
||||
@@ -457,6 +477,9 @@ class Query
|
||||
$key1 = array_shift($fields);
|
||||
$key2 = $fields ? array_shift($fields) : '';
|
||||
$key = $key ?: $key1;
|
||||
if (strpos($key, '.')) {
|
||||
list($alias, $key) = explode('.', $key);
|
||||
}
|
||||
foreach ($resultSet as $val) {
|
||||
if ($count > 2) {
|
||||
$result[$val[$key]] = $val;
|
||||
@@ -704,6 +727,9 @@ class Query
|
||||
}
|
||||
}
|
||||
if (isset($alias)) {
|
||||
if (isset($this->options['alias'][$table])) {
|
||||
$table = $table . '@think' . uniqid();
|
||||
}
|
||||
$table = [$table => $alias];
|
||||
$this->alias($table);
|
||||
}
|
||||
@@ -976,6 +1002,20 @@ class Query
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 去除某个查询参数
|
||||
* @access public
|
||||
* @param string $option 参数名
|
||||
* @return $this
|
||||
*/
|
||||
public function removeOption($option)
|
||||
{
|
||||
if (isset($this->options[$option])) {
|
||||
unset($this->options[$option]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定查询数量
|
||||
* @access public
|
||||
@@ -1071,7 +1111,6 @@ class Query
|
||||
if (is_string($table)) {
|
||||
if (strpos($table, ')')) {
|
||||
// 子查询
|
||||
$table = $table;
|
||||
} elseif (strpos($table, ',')) {
|
||||
$tables = explode(',', $table);
|
||||
$table = [];
|
||||
@@ -1086,7 +1125,8 @@ class Query
|
||||
}
|
||||
} elseif (strpos($table, ' ')) {
|
||||
list($table, $alias) = explode(' ', $table);
|
||||
$table = [$table => $alias];
|
||||
|
||||
$table = [$table => $alias];
|
||||
$this->alias($table);
|
||||
}
|
||||
} else {
|
||||
@@ -1292,18 +1332,6 @@ class Query
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定数据集返回对象
|
||||
* @access public
|
||||
* @param string $class 指定返回的数据集对象类名
|
||||
* @return $this
|
||||
*/
|
||||
public function fetchClass($class)
|
||||
{
|
||||
$this->options['fetch_class'] = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置从主服务器读取数据
|
||||
* @access public
|
||||
@@ -1435,6 +1463,11 @@ class Query
|
||||
$tableName = $this->parseSqlTable($tableName);
|
||||
}
|
||||
|
||||
// 修正子查询作为表名的问题
|
||||
if (strpos($tableName, ')')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
list($guid) = explode(' ', $tableName);
|
||||
$db = $this->getConfig('database');
|
||||
if (!isset(self::$info[$db . '.' . $guid])) {
|
||||
@@ -1601,13 +1634,14 @@ class Query
|
||||
$with = explode(',', $with);
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
$first = true;
|
||||
$currentModel = $this->model;
|
||||
|
||||
/** @var Model $class */
|
||||
$class = new $currentModel;
|
||||
foreach ($with as $key => $relation) {
|
||||
$closure = false;
|
||||
$subRelation = '';
|
||||
$closure = false;
|
||||
if ($relation instanceof \Closure) {
|
||||
// 支持闭包查询过滤关联条件
|
||||
$closure = $relation;
|
||||
@@ -1620,48 +1654,9 @@ class Query
|
||||
|
||||
/** @var Relation $model */
|
||||
$model = $class->$relation();
|
||||
$info = $model->getRelationInfo();
|
||||
if (in_array($info['type'], [Relation::HAS_ONE, Relation::BELONGS_TO])) {
|
||||
if (0 == $i) {
|
||||
$name = Loader::parseName(basename(str_replace('\\', '/', $currentModel)));
|
||||
$table = $this->getTable();
|
||||
$alias = isset($info['alias'][$name]) ? $info['alias'][$name] : $name;
|
||||
$this->table([$table => $alias]);
|
||||
if (isset($this->options['field'])) {
|
||||
$field = $this->options['field'];
|
||||
unset($this->options['field']);
|
||||
} else {
|
||||
$field = true;
|
||||
}
|
||||
$this->field($field, false, $table, $alias);
|
||||
}
|
||||
// 预载入封装
|
||||
$joinTable = $model->getTable();
|
||||
$joinName = Loader::parseName(basename(str_replace('\\', '/', $info['model'])));
|
||||
$joinAlias = isset($info['alias'][$joinName]) ? $info['alias'][$joinName] : $relation;
|
||||
$this->via($joinAlias);
|
||||
|
||||
if (Relation::HAS_ONE == $info['type']) {
|
||||
$this->join($joinTable . ' ' . $joinAlias, $alias . '.' . $info['localKey'] . '=' . $joinAlias . '.' . $info['foreignKey'], $info['joinType']);
|
||||
} else {
|
||||
$this->join($joinTable . ' ' . $joinAlias, $alias . '.' . $info['foreignKey'] . '=' . $joinAlias . '.' . $info['localKey'], $info['joinType']);
|
||||
}
|
||||
|
||||
if ($closure) {
|
||||
// 执行闭包查询
|
||||
call_user_func_array($closure, [ & $this]);
|
||||
//指定获取关联的字段
|
||||
//需要在 回调中 调方法 withField 方法,如
|
||||
// $query->where(['id'=>1])->withField('id,name');
|
||||
if (!empty($this->options['with_field'])) {
|
||||
$field = $this->options['with_field'];
|
||||
unset($this->options['with_field']);
|
||||
}
|
||||
} elseif (isset($info['option']['field'])) {
|
||||
$field = $info['option']['field'];
|
||||
}
|
||||
$this->field($field, false, $joinTable, $joinAlias, $relation . '__');
|
||||
$i++;
|
||||
if ($model instanceof HasOne || $model instanceof BelongsTo) {
|
||||
$model->eagerly($this, $relation, $subRelation, $closure, $first);
|
||||
$first = false;
|
||||
} elseif ($closure) {
|
||||
$with[$key] = $closure;
|
||||
}
|
||||
@@ -1771,7 +1766,7 @@ class Query
|
||||
// 分析查询表达式
|
||||
$options = $this->parseExpress();
|
||||
// 生成SQL语句
|
||||
$sql = $this->builder()->insert($data, $options, $replace);
|
||||
$sql = $this->builder->insert($data, $options, $replace);
|
||||
// 获取参数绑定
|
||||
$bind = $this->getBind();
|
||||
if ($options['fetch_sql']) {
|
||||
@@ -1781,6 +1776,9 @@ class Query
|
||||
|
||||
// 执行操作
|
||||
$result = $this->execute($sql, $bind);
|
||||
if ($result) {
|
||||
$this->trigger('after_insert', $options);
|
||||
}
|
||||
if ($getLastInsID) {
|
||||
$sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null);
|
||||
return $this->getLastInsID($sequence);
|
||||
@@ -1815,7 +1813,7 @@ class Query
|
||||
return false;
|
||||
}
|
||||
// 生成SQL语句
|
||||
$sql = $this->builder()->insertAll($dataSet, $options);
|
||||
$sql = $this->builder->insertAll($dataSet, $options);
|
||||
// 获取参数绑定
|
||||
$bind = $this->getBind();
|
||||
if ($options['fetch_sql']) {
|
||||
@@ -1841,7 +1839,7 @@ class Query
|
||||
$options = $this->parseExpress();
|
||||
// 生成SQL语句
|
||||
$table = $this->parseSqlTable($table);
|
||||
$sql = $this->builder()->selectInsert($fields, $table, $options);
|
||||
$sql = $this->builder->selectInsert($fields, $table, $options);
|
||||
// 获取参数绑定
|
||||
$bind = $this->getBind();
|
||||
if ($options['fetch_sql']) {
|
||||
@@ -1899,7 +1897,7 @@ class Query
|
||||
$key = 'think:' . $options['table'] . '|' . $options['where']['AND'][$pk];
|
||||
}
|
||||
// 生成UPDATE SQL语句
|
||||
$sql = $this->builder()->update($data, $options);
|
||||
$sql = $this->builder->update($data, $options);
|
||||
// 获取参数绑定
|
||||
$bind = $this->getBind();
|
||||
if ($options['fetch_sql']) {
|
||||
@@ -1912,7 +1910,11 @@ class Query
|
||||
Cache::rm($key);
|
||||
}
|
||||
// 执行操作
|
||||
return '' == $sql ? 0 : $this->execute($sql, $bind);
|
||||
$result = '' == $sql ? 0 : $this->execute($sql, $bind);
|
||||
if ($result) {
|
||||
$this->trigger('after_update', $options);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1954,19 +1956,22 @@ class Query
|
||||
}
|
||||
if (!$resultSet) {
|
||||
// 生成查询SQL
|
||||
$sql = $this->builder()->select($options);
|
||||
$sql = $this->builder->select($options);
|
||||
// 获取参数绑定
|
||||
$bind = $this->getBind();
|
||||
if ($options['fetch_sql']) {
|
||||
// 获取实际执行的SQL语句
|
||||
return $this->connection->getRealSql($sql, $bind);
|
||||
}
|
||||
// 执行查询操作
|
||||
$resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_class']);
|
||||
if ($resultSet = $this->trigger('before_select', $options)) {
|
||||
} else {
|
||||
// 执行查询操作
|
||||
$resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_class']);
|
||||
|
||||
if ($resultSet instanceof \PDOStatement) {
|
||||
// 返回PDOStatement对象
|
||||
return $resultSet;
|
||||
if ($resultSet instanceof \PDOStatement) {
|
||||
// 返回PDOStatement对象
|
||||
return $resultSet;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($cache)) {
|
||||
@@ -1979,12 +1984,11 @@ class Query
|
||||
}
|
||||
}
|
||||
|
||||
// 返回结果处理
|
||||
if (count($resultSet) > 0) {
|
||||
// 数据列表读取后的处理
|
||||
if (!empty($this->model)) {
|
||||
// 生成模型对象
|
||||
$model = $this->model;
|
||||
// 数据列表读取后的处理
|
||||
if (!empty($this->model)) {
|
||||
// 生成模型对象
|
||||
$model = $this->model;
|
||||
if (count($resultSet) > 0) {
|
||||
foreach ($resultSet as $key => $result) {
|
||||
/** @var Model $result */
|
||||
$result = new $model($result);
|
||||
@@ -1995,12 +1999,16 @@ class Query
|
||||
}
|
||||
$resultSet[$key] = $result;
|
||||
}
|
||||
if (!empty($options['with']) && $result instanceof Model) {
|
||||
if (!empty($options['with'])) {
|
||||
// 预载入
|
||||
$resultSet = $result->eagerlyResultSet($resultSet, $options['with'], is_object($resultSet) ? get_class($resultSet) : '');
|
||||
$result->eagerlyResultSet($resultSet, $options['with'], is_object($resultSet) ? get_class($resultSet) : '');
|
||||
}
|
||||
}
|
||||
} elseif (!empty($options['fail'])) {
|
||||
// 模型数据集转换
|
||||
$resultSet = (new $model)->toCollection($resultSet);
|
||||
}
|
||||
// 返回结果处理
|
||||
if (!empty($options['fail']) && count($resultSet) == 0) {
|
||||
$this->throwNotFound($options);
|
||||
}
|
||||
return $resultSet;
|
||||
@@ -2045,19 +2053,24 @@ class Query
|
||||
}
|
||||
if (!$result) {
|
||||
// 生成查询SQL
|
||||
$sql = $this->builder()->select($options);
|
||||
$sql = $this->builder->select($options);
|
||||
// 获取参数绑定
|
||||
$bind = $this->getBind();
|
||||
if ($options['fetch_sql']) {
|
||||
// 获取实际执行的SQL语句
|
||||
return $this->connection->getRealSql($sql, $bind);
|
||||
}
|
||||
// 执行查询
|
||||
$result = $this->query($sql, $bind, $options['master'], $options['fetch_class']);
|
||||
|
||||
if ($result instanceof \PDOStatement) {
|
||||
// 返回PDOStatement对象
|
||||
return $result;
|
||||
// 事件回调
|
||||
if ($result = $this->trigger('before_find', $options)) {
|
||||
} else {
|
||||
// 执行查询
|
||||
$result = $this->query($sql, $bind, $options['master'], $options['fetch_class']);
|
||||
|
||||
if ($result instanceof \PDOStatement) {
|
||||
// 返回PDOStatement对象
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($cache)) {
|
||||
@@ -2241,7 +2254,7 @@ class Query
|
||||
throw new Exception('delete without condition');
|
||||
}
|
||||
// 生成删除SQL语句
|
||||
$sql = $this->builder()->delete($options);
|
||||
$sql = $this->builder->delete($options);
|
||||
// 获取参数绑定
|
||||
$bind = $this->getBind();
|
||||
if ($options['fetch_sql']) {
|
||||
@@ -2255,7 +2268,11 @@ class Query
|
||||
Cache::rm($key);
|
||||
}
|
||||
// 执行操作
|
||||
return $this->execute($sql, $bind);
|
||||
$result = $this->execute($sql, $bind);
|
||||
if ($result) {
|
||||
$this->trigger('after_delete', $options);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2345,4 +2362,32 @@ class Query
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册回调方法
|
||||
* @access public
|
||||
* @param string $event 事件名
|
||||
* @param callable $callback 回调方法
|
||||
* @return void
|
||||
*/
|
||||
public static function event($event, $callback)
|
||||
{
|
||||
self::$event[$event] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发事件
|
||||
* @access protected
|
||||
* @param string $event 事件名
|
||||
* @param mixed $options 当前查询参数
|
||||
* @return bool
|
||||
*/
|
||||
protected function trigger($event, $options = [])
|
||||
{
|
||||
$result = false;
|
||||
if (isset(self::$event[$event])) {
|
||||
$callback = self::$event[$event];
|
||||
$result = call_user_func_array($callback, [$options, $this]);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user