mirror of
https://gitee.com/zoujingli/ThinkAdmin.git
synced 2025-04-05 19:41:44 +08:00
ComposerUpdate
This commit is contained in:
parent
21a79bb794
commit
0efb9180c1
21
composer.lock
generated
21
composer.lock
generated
@ -721,16 +721,16 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-orm",
|
||||
"version": "v2.0.31",
|
||||
"version": "v2.0.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-orm.git",
|
||||
"reference": "d6965dfae21f150e29cc899ab6f9b1bd2c0f2ee4"
|
||||
"reference": "03aaaa4d8c4475115b3acaa5aa2498bf5792e017"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/d6965dfae21f150e29cc899ab6f9b1bd2c0f2ee4",
|
||||
"reference": "d6965dfae21f150e29cc899ab6f9b1bd2c0f2ee4",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/03aaaa4d8c4475115b3acaa5aa2498bf5792e017",
|
||||
"reference": "03aaaa4d8c4475115b3acaa5aa2498bf5792e017",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -768,7 +768,7 @@
|
||||
"database",
|
||||
"orm"
|
||||
],
|
||||
"time": "2020-01-07T10:05:10+00:00"
|
||||
"time": "2020-04-26T13:54:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-template",
|
||||
@ -909,12 +909,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zoujingli/ThinkLibrary.git",
|
||||
"reference": "373e7587a6ade11254892b63e431cb57498f8fa3"
|
||||
"reference": "646ddaf7017822aabbc9aa7c3e8e4e0aa095c515"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/373e7587a6ade11254892b63e431cb57498f8fa3",
|
||||
"reference": "373e7587a6ade11254892b63e431cb57498f8fa3",
|
||||
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/646ddaf7017822aabbc9aa7c3e8e4e0aa095c515",
|
||||
"reference": "646ddaf7017822aabbc9aa7c3e8e4e0aa095c515",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -958,7 +958,7 @@
|
||||
],
|
||||
"description": "ThinkPHP v6.0 Development Library",
|
||||
"homepage": "http://framework.thinkadmin.top",
|
||||
"time": "2020-04-26T09:48:50+00:00"
|
||||
"time": "2020-05-01T12:57:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "zoujingli/wechat-developer",
|
||||
@ -1047,5 +1047,6 @@
|
||||
"ext-mbstring": "*",
|
||||
"ext-simplexml": "*"
|
||||
},
|
||||
"platform-dev": []
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "1.1.0"
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ return [
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
// 数据库调试模式
|
||||
'debug' => true,
|
||||
'debug' => app()->isDebug(),
|
||||
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
||||
'deploy' => 0,
|
||||
// 数据库读写是否分离 主从式有效
|
||||
|
3
vendor/composer/autoload_real.php
vendored
3
vendor/composer/autoload_real.php
vendored
@ -13,6 +13,9 @@ class ComposerAutoloaderInitf41e9df38a61a147f539b835fbd021f0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
|
20
vendor/composer/installed.json
vendored
20
vendor/composer/installed.json
vendored
@ -738,17 +738,17 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-orm",
|
||||
"version": "v2.0.31",
|
||||
"version_normalized": "2.0.31.0",
|
||||
"version": "v2.0.32",
|
||||
"version_normalized": "2.0.32.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-orm.git",
|
||||
"reference": "d6965dfae21f150e29cc899ab6f9b1bd2c0f2ee4"
|
||||
"reference": "03aaaa4d8c4475115b3acaa5aa2498bf5792e017"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/d6965dfae21f150e29cc899ab6f9b1bd2c0f2ee4",
|
||||
"reference": "d6965dfae21f150e29cc899ab6f9b1bd2c0f2ee4",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/03aaaa4d8c4475115b3acaa5aa2498bf5792e017",
|
||||
"reference": "03aaaa4d8c4475115b3acaa5aa2498bf5792e017",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -764,7 +764,7 @@
|
||||
"psr/simple-cache": "^1.0",
|
||||
"topthink/think-helper": "^3.1"
|
||||
},
|
||||
"time": "2020-01-07T10:05:10+00:00",
|
||||
"time": "2020-04-26T13:54:48+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -935,12 +935,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zoujingli/ThinkLibrary.git",
|
||||
"reference": "373e7587a6ade11254892b63e431cb57498f8fa3"
|
||||
"reference": "646ddaf7017822aabbc9aa7c3e8e4e0aa095c515"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/373e7587a6ade11254892b63e431cb57498f8fa3",
|
||||
"reference": "373e7587a6ade11254892b63e431cb57498f8fa3",
|
||||
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/646ddaf7017822aabbc9aa7c3e8e4e0aa095c515",
|
||||
"reference": "646ddaf7017822aabbc9aa7c3e8e4e0aa095c515",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -956,7 +956,7 @@
|
||||
"ext-json": "*",
|
||||
"topthink/framework": "^6.0"
|
||||
},
|
||||
"time": "2020-04-26T09:48:50+00:00",
|
||||
"time": "2020-05-01T12:57:12+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"think": {
|
||||
|
2
vendor/services.php
vendored
2
vendor/services.php
vendored
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// This file is automatically generated at:2020-04-30 14:37:31
|
||||
// This file is automatically generated at:2020-05-01 21:06:44
|
||||
declare (strict_types = 1);
|
||||
return array (
|
||||
0 => 'think\\app\\Service',
|
||||
|
2121
vendor/topthink/think-orm/src/Model.php
vendored
2121
vendor/topthink/think-orm/src/Model.php
vendored
File diff suppressed because it is too large
Load Diff
2564
vendor/topthink/think-orm/src/db/BaseQuery.php
vendored
2564
vendor/topthink/think-orm/src/db/BaseQuery.php
vendored
File diff suppressed because it is too large
Load Diff
5
vendor/topthink/think-orm/src/db/Builder.php
vendored
5
vendor/topthink/think-orm/src/db/Builder.php
vendored
@ -368,7 +368,10 @@ abstract class Builder
|
||||
|
||||
if ($value instanceof Closure) {
|
||||
// 使用闭包查询
|
||||
$where[] = $this->parseClosureWhere($query, $value, $logic);
|
||||
$whereClosureStr = $this->parseClosureWhere($query, $value, $logic);
|
||||
if ($whereClosureStr) {
|
||||
$where[] = $whereClosureStr;
|
||||
}
|
||||
} elseif (is_array($field)) {
|
||||
$where[] = $this->parseMultiWhereField($query, $value, $field, $logic, $binds);
|
||||
} elseif ($field instanceof Raw) {
|
||||
|
12
vendor/topthink/think-orm/src/db/Connection.php
vendored
12
vendor/topthink/think-orm/src/db/Connection.php
vendored
@ -214,11 +214,12 @@ abstract class Connection
|
||||
* 分析缓存Key
|
||||
* @access protected
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param string $method查询方法
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheKey(BaseQuery $query): string
|
||||
protected function getCacheKey(BaseQuery $query, string $method = ''): string
|
||||
{
|
||||
if (!empty($query->getOptions('key'))) {
|
||||
if (!empty($query->getOptions('key')) && empty($method)) {
|
||||
$key = 'think:' . $this->getConfig('database') . '.' . $query->getTable() . '|' . $query->getOptions('key');
|
||||
} else {
|
||||
$key = $query->getQueryGuid();
|
||||
@ -231,10 +232,11 @@ abstract class Connection
|
||||
* 分析缓存
|
||||
* @access protected
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param array $cache 缓存信息
|
||||
* @param array $cache 缓存信息
|
||||
* @param string $method查询方法
|
||||
* @return CacheItem
|
||||
*/
|
||||
protected function parseCache(BaseQuery $query, array $cache): CacheItem
|
||||
protected function parseCache(BaseQuery $query, array $cache, string $method = ''): CacheItem
|
||||
{
|
||||
[$key, $expire, $tag] = $cache;
|
||||
|
||||
@ -242,7 +244,7 @@ abstract class Connection
|
||||
$cacheItem = $key;
|
||||
} else {
|
||||
if (true === $key) {
|
||||
$key = $this->getCacheKey($query);
|
||||
$key = $this->getCacheKey($query, $method);
|
||||
}
|
||||
|
||||
$cacheItem = new CacheItem($key);
|
||||
|
@ -1033,7 +1033,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
$query->setOption('field', (array) $field);
|
||||
|
||||
if (!empty($options['cache'])) {
|
||||
$cacheItem = $this->parseCache($query, $options['cache']);
|
||||
$cacheItem = $this->parseCache($query, $options['cache'], 'value');
|
||||
$key = $cacheItem->getKey();
|
||||
|
||||
if ($this->cache->has($key)) {
|
||||
@ -1118,7 +1118,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
|
||||
if (!empty($options['cache'])) {
|
||||
// 判断查询缓存
|
||||
$cacheItem = $this->parseCache($query, $options['cache']);
|
||||
$cacheItem = $this->parseCache($query, $options['cache'], 'column');
|
||||
$name = $cacheItem->getKey();
|
||||
|
||||
if ($this->cache->has($name)) {
|
||||
@ -1151,6 +1151,8 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
|
||||
if (strpos($column, ',')) {
|
||||
$column = null;
|
||||
} elseif (strpos($column, ' ')) {
|
||||
$column = substr(strrchr(trim($column), ' '), 1);
|
||||
} elseif (strpos($column, '.')) {
|
||||
[$alias, $column] = explode('.', $column);
|
||||
}
|
||||
|
966
vendor/topthink/think-orm/src/db/Query.php
vendored
966
vendor/topthink/think-orm/src/db/Query.php
vendored
@ -1,483 +1,483 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace think\db;
|
||||
|
||||
use PDOStatement;
|
||||
use think\helper\Str;
|
||||
|
||||
/**
|
||||
* PDO数据查询类
|
||||
*/
|
||||
class Query extends BaseQuery
|
||||
{
|
||||
use concern\JoinAndViewQuery;
|
||||
use concern\ParamsBind;
|
||||
use concern\TableFieldInfo;
|
||||
|
||||
/**
|
||||
* 表达式方式指定Field排序
|
||||
* @access public
|
||||
* @param string $field 排序字段
|
||||
* @param array $bind 参数绑定
|
||||
* @return $this
|
||||
*/
|
||||
public function orderRaw(string $field, array $bind = [])
|
||||
{
|
||||
if (!empty($bind)) {
|
||||
$this->bindParams($field, $bind);
|
||||
}
|
||||
|
||||
$this->options['order'][] = new Raw($field);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 表达式方式指定查询字段
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @return $this
|
||||
*/
|
||||
public function fieldRaw(string $field)
|
||||
{
|
||||
$this->options['field'][] = new Raw($field);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定Field排序 orderField('id',[1,2,3],'desc')
|
||||
* @access public
|
||||
* @param string $field 排序字段
|
||||
* @param array $values 排序值
|
||||
* @param string $order 排序 desc/asc
|
||||
* @return $this
|
||||
*/
|
||||
public function orderField(string $field, array $values, string $order = '')
|
||||
{
|
||||
if (!empty($values)) {
|
||||
$values['sort'] = $order;
|
||||
|
||||
$this->options['order'][$field] = $values;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机排序
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function orderRand()
|
||||
{
|
||||
$this->options['order'][] = '[rand]';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用表达式设置数据
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @param string $value 字段值
|
||||
* @return $this
|
||||
*/
|
||||
public function exp(string $field, string $value)
|
||||
{
|
||||
$this->options['data'][$field] = new Raw($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 表达式方式指定当前操作的数据表
|
||||
* @access public
|
||||
* @param mixed $table 表名
|
||||
* @return $this
|
||||
*/
|
||||
public function tableRaw(string $table)
|
||||
{
|
||||
$this->options['table'] = new Raw($table);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询 返回数据集
|
||||
* @access public
|
||||
* @param string $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
* @return array
|
||||
* @throws BindParamException
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function query(string $sql, array $bind = []): array
|
||||
{
|
||||
return $this->connection->query($this, $sql, $bind);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行语句
|
||||
* @access public
|
||||
* @param string $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
* @return int
|
||||
* @throws BindParamException
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function execute(string $sql, array $bind = []): int
|
||||
{
|
||||
return $this->connection->execute($this, $sql, $bind, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取执行的SQL语句而不进行实际的查询
|
||||
* @access public
|
||||
* @param bool $fetch 是否返回sql
|
||||
* @return $this|Fetch
|
||||
*/
|
||||
public function fetchSql(bool $fetch = true)
|
||||
{
|
||||
$this->options['fetch_sql'] = $fetch;
|
||||
|
||||
if ($fetch) {
|
||||
return new Fetch($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批处理执行SQL语句
|
||||
* 批处理的指令都认为是execute操作
|
||||
* @access public
|
||||
* @param array $sql SQL批处理指令
|
||||
* @return bool
|
||||
*/
|
||||
public function batchQuery(array $sql = []): bool
|
||||
{
|
||||
return $this->connection->batchQuery($this, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* USING支持 用于多表删除
|
||||
* @access public
|
||||
* @param mixed $using USING
|
||||
* @return $this
|
||||
*/
|
||||
public function using($using)
|
||||
{
|
||||
$this->options['using'] = $using;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 存储过程调用
|
||||
* @access public
|
||||
* @param bool $procedure 是否为存储过程查询
|
||||
* @return $this
|
||||
*/
|
||||
public function procedure(bool $procedure = true)
|
||||
{
|
||||
$this->options['procedure'] = $procedure;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定group查询
|
||||
* @access public
|
||||
* @param string|array $group GROUP
|
||||
* @return $this
|
||||
*/
|
||||
public function group($group)
|
||||
{
|
||||
$this->options['group'] = $group;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定having查询
|
||||
* @access public
|
||||
* @param string $having having
|
||||
* @return $this
|
||||
*/
|
||||
public function having(string $having)
|
||||
{
|
||||
$this->options['having'] = $having;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定distinct查询
|
||||
* @access public
|
||||
* @param bool $distinct 是否唯一
|
||||
* @return $this
|
||||
*/
|
||||
public function distinct(bool $distinct = true)
|
||||
{
|
||||
$this->options['distinct'] = $distinct;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定强制索引
|
||||
* @access public
|
||||
* @param string $force 索引名称
|
||||
* @return $this
|
||||
*/
|
||||
public function force(string $force)
|
||||
{
|
||||
$this->options['force'] = $force;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询注释
|
||||
* @access public
|
||||
* @param string $comment 注释
|
||||
* @return $this
|
||||
*/
|
||||
public function comment(string $comment)
|
||||
{
|
||||
$this->options['comment'] = $comment;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否REPLACE
|
||||
* @access public
|
||||
* @param bool $replace 是否使用REPLACE写入数据
|
||||
* @return $this
|
||||
*/
|
||||
public function replace(bool $replace = true)
|
||||
{
|
||||
$this->options['replace'] = $replace;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前查询所在的分区
|
||||
* @access public
|
||||
* @param string|array $partition 分区名称
|
||||
* @return $this
|
||||
*/
|
||||
public function partition($partition)
|
||||
{
|
||||
$this->options['partition'] = $partition;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置DUPLICATE
|
||||
* @access public
|
||||
* @param array|string|Raw $duplicate DUPLICATE信息
|
||||
* @return $this
|
||||
*/
|
||||
public function duplicate($duplicate)
|
||||
{
|
||||
$this->options['duplicate'] = $duplicate;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置查询的额外参数
|
||||
* @access public
|
||||
* @param string $extra 额外信息
|
||||
* @return $this
|
||||
*/
|
||||
public function extra(string $extra)
|
||||
{
|
||||
$this->options['extra'] = $extra;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建子查询SQL
|
||||
* @access public
|
||||
* @param bool $sub 是否添加括号
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function buildSql(bool $sub = true): string
|
||||
{
|
||||
return $sub ? '( ' . $this->fetchSql()->select() . ' )' : $this->fetchSql()->select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前数据表的主键
|
||||
* @access public
|
||||
* @return string|array
|
||||
*/
|
||||
public function getPk()
|
||||
{
|
||||
if (empty($this->pk)) {
|
||||
$this->pk = $this->connection->getPk($this->getTable());
|
||||
}
|
||||
|
||||
return $this->pk;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定数据表自增主键
|
||||
* @access public
|
||||
* @param string $autoinc 自增键
|
||||
* @return $this
|
||||
*/
|
||||
public function autoinc(string $autoinc)
|
||||
{
|
||||
$this->autoinc = $autoinc;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前数据表的自增主键
|
||||
* @access public
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAutoInc()
|
||||
{
|
||||
$tableName = $this->getTable();
|
||||
|
||||
if (empty($this->autoinc) && $tableName) {
|
||||
$this->autoinc = $this->connection->getAutoInc($tableName);
|
||||
}
|
||||
|
||||
return $this->autoinc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段值增长
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @param float $step 增长值
|
||||
* @return $this
|
||||
*/
|
||||
public function inc(string $field, float $step = 1)
|
||||
{
|
||||
$this->options['data'][$field] = ['INC', $step];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段值减少
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @param float $step 增长值
|
||||
* @return $this
|
||||
*/
|
||||
public function dec(string $field, float $step = 1)
|
||||
{
|
||||
$this->options['data'][$field] = ['DEC', $step];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的查询标识
|
||||
* @access public
|
||||
* @param mixed $data 要序列化的数据
|
||||
* @return string
|
||||
*/
|
||||
public function getQueryGuid($data = null): string
|
||||
{
|
||||
return md5($this->getConfig('database') . serialize(var_export($data ?: $this->options, true)) . serialize($this->getBind(false)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询但只返回PDOStatement对象
|
||||
* @access public
|
||||
* @return PDOStatement
|
||||
*/
|
||||
public function getPdo(): PDOStatement
|
||||
{
|
||||
return $this->connection->pdo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用游标查找记录
|
||||
* @access public
|
||||
* @param mixed $data 数据
|
||||
* @return \Generator
|
||||
*/
|
||||
public function cursor($data = null)
|
||||
{
|
||||
if (!is_null($data)) {
|
||||
// 主键条件分析
|
||||
$this->parsePkWhere($data);
|
||||
}
|
||||
|
||||
$this->options['data'] = $data;
|
||||
|
||||
$connection = clone $this->connection;
|
||||
|
||||
return $connection->cursor($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分批数据返回处理
|
||||
* @access public
|
||||
* @param integer $count 每次处理的数据数量
|
||||
* @param callable $callback 处理回调方法
|
||||
* @param string|array $column 分批处理的字段名
|
||||
* @param string $order 字段排序
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function chunk(int $count, callable $callback, $column = null, string $order = 'asc'): bool
|
||||
{
|
||||
$options = $this->getOptions();
|
||||
$column = $column ?: $this->getPk();
|
||||
|
||||
if (isset($options['order'])) {
|
||||
unset($options['order']);
|
||||
}
|
||||
|
||||
$bind = $this->bind;
|
||||
|
||||
if (is_array($column)) {
|
||||
$times = 1;
|
||||
$query = $this->options($options)->page($times, $count);
|
||||
} else {
|
||||
$query = $this->options($options)->limit($count);
|
||||
|
||||
if (strpos($column, '.')) {
|
||||
[$alias, $key] = explode('.', $column);
|
||||
} else {
|
||||
$key = $column;
|
||||
}
|
||||
}
|
||||
|
||||
$resultSet = $query->order($column, $order)->select();
|
||||
|
||||
while (count($resultSet) > 0) {
|
||||
if (false === call_user_func($callback, $resultSet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($times)) {
|
||||
$times++;
|
||||
$query = $this->options($options)->page($times, $count);
|
||||
} else {
|
||||
$end = $resultSet->pop();
|
||||
$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;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace think\db;
|
||||
|
||||
use PDOStatement;
|
||||
use think\helper\Str;
|
||||
|
||||
/**
|
||||
* PDO数据查询类
|
||||
*/
|
||||
class Query extends BaseQuery
|
||||
{
|
||||
use concern\JoinAndViewQuery;
|
||||
use concern\ParamsBind;
|
||||
use concern\TableFieldInfo;
|
||||
|
||||
/**
|
||||
* 表达式方式指定Field排序
|
||||
* @access public
|
||||
* @param string $field 排序字段
|
||||
* @param array $bind 参数绑定
|
||||
* @return $this
|
||||
*/
|
||||
public function orderRaw(string $field, array $bind = [])
|
||||
{
|
||||
if (!empty($bind)) {
|
||||
$this->bindParams($field, $bind);
|
||||
}
|
||||
|
||||
$this->options['order'][] = new Raw($field);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 表达式方式指定查询字段
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @return $this
|
||||
*/
|
||||
public function fieldRaw(string $field)
|
||||
{
|
||||
$this->options['field'][] = new Raw($field);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定Field排序 orderField('id',[1,2,3],'desc')
|
||||
* @access public
|
||||
* @param string $field 排序字段
|
||||
* @param array $values 排序值
|
||||
* @param string $order 排序 desc/asc
|
||||
* @return $this
|
||||
*/
|
||||
public function orderField(string $field, array $values, string $order = '')
|
||||
{
|
||||
if (!empty($values)) {
|
||||
$values['sort'] = $order;
|
||||
|
||||
$this->options['order'][$field] = $values;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机排序
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function orderRand()
|
||||
{
|
||||
$this->options['order'][] = '[rand]';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用表达式设置数据
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @param string $value 字段值
|
||||
* @return $this
|
||||
*/
|
||||
public function exp(string $field, string $value)
|
||||
{
|
||||
$this->options['data'][$field] = new Raw($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 表达式方式指定当前操作的数据表
|
||||
* @access public
|
||||
* @param mixed $table 表名
|
||||
* @return $this
|
||||
*/
|
||||
public function tableRaw(string $table)
|
||||
{
|
||||
$this->options['table'] = new Raw($table);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询 返回数据集
|
||||
* @access public
|
||||
* @param string $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
* @return array
|
||||
* @throws BindParamException
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function query(string $sql, array $bind = []): array
|
||||
{
|
||||
return $this->connection->query($this, $sql, $bind);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行语句
|
||||
* @access public
|
||||
* @param string $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
* @return int
|
||||
* @throws BindParamException
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function execute(string $sql, array $bind = []): int
|
||||
{
|
||||
return $this->connection->execute($this, $sql, $bind, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取执行的SQL语句而不进行实际的查询
|
||||
* @access public
|
||||
* @param bool $fetch 是否返回sql
|
||||
* @return $this|Fetch
|
||||
*/
|
||||
public function fetchSql(bool $fetch = true)
|
||||
{
|
||||
$this->options['fetch_sql'] = $fetch;
|
||||
|
||||
if ($fetch) {
|
||||
return new Fetch($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批处理执行SQL语句
|
||||
* 批处理的指令都认为是execute操作
|
||||
* @access public
|
||||
* @param array $sql SQL批处理指令
|
||||
* @return bool
|
||||
*/
|
||||
public function batchQuery(array $sql = []): bool
|
||||
{
|
||||
return $this->connection->batchQuery($this, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* USING支持 用于多表删除
|
||||
* @access public
|
||||
* @param mixed $using USING
|
||||
* @return $this
|
||||
*/
|
||||
public function using($using)
|
||||
{
|
||||
$this->options['using'] = $using;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 存储过程调用
|
||||
* @access public
|
||||
* @param bool $procedure 是否为存储过程查询
|
||||
* @return $this
|
||||
*/
|
||||
public function procedure(bool $procedure = true)
|
||||
{
|
||||
$this->options['procedure'] = $procedure;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定group查询
|
||||
* @access public
|
||||
* @param string|array $group GROUP
|
||||
* @return $this
|
||||
*/
|
||||
public function group($group)
|
||||
{
|
||||
$this->options['group'] = $group;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定having查询
|
||||
* @access public
|
||||
* @param string $having having
|
||||
* @return $this
|
||||
*/
|
||||
public function having(string $having)
|
||||
{
|
||||
$this->options['having'] = $having;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定distinct查询
|
||||
* @access public
|
||||
* @param bool $distinct 是否唯一
|
||||
* @return $this
|
||||
*/
|
||||
public function distinct(bool $distinct = true)
|
||||
{
|
||||
$this->options['distinct'] = $distinct;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定强制索引
|
||||
* @access public
|
||||
* @param string $force 索引名称
|
||||
* @return $this
|
||||
*/
|
||||
public function force(string $force)
|
||||
{
|
||||
$this->options['force'] = $force;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询注释
|
||||
* @access public
|
||||
* @param string $comment 注释
|
||||
* @return $this
|
||||
*/
|
||||
public function comment(string $comment)
|
||||
{
|
||||
$this->options['comment'] = $comment;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否REPLACE
|
||||
* @access public
|
||||
* @param bool $replace 是否使用REPLACE写入数据
|
||||
* @return $this
|
||||
*/
|
||||
public function replace(bool $replace = true)
|
||||
{
|
||||
$this->options['replace'] = $replace;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前查询所在的分区
|
||||
* @access public
|
||||
* @param string|array $partition 分区名称
|
||||
* @return $this
|
||||
*/
|
||||
public function partition($partition)
|
||||
{
|
||||
$this->options['partition'] = $partition;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置DUPLICATE
|
||||
* @access public
|
||||
* @param array|string|Raw $duplicate DUPLICATE信息
|
||||
* @return $this
|
||||
*/
|
||||
public function duplicate($duplicate)
|
||||
{
|
||||
$this->options['duplicate'] = $duplicate;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置查询的额外参数
|
||||
* @access public
|
||||
* @param string $extra 额外信息
|
||||
* @return $this
|
||||
*/
|
||||
public function extra(string $extra)
|
||||
{
|
||||
$this->options['extra'] = $extra;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建子查询SQL
|
||||
* @access public
|
||||
* @param bool $sub 是否添加括号
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function buildSql(bool $sub = true): string
|
||||
{
|
||||
return $sub ? '( ' . $this->fetchSql()->select() . ' )' : $this->fetchSql()->select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前数据表的主键
|
||||
* @access public
|
||||
* @return string|array
|
||||
*/
|
||||
public function getPk()
|
||||
{
|
||||
if (empty($this->pk)) {
|
||||
$this->pk = $this->connection->getPk($this->getTable());
|
||||
}
|
||||
|
||||
return $this->pk;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定数据表自增主键
|
||||
* @access public
|
||||
* @param string $autoinc 自增键
|
||||
* @return $this
|
||||
*/
|
||||
public function autoinc(string $autoinc)
|
||||
{
|
||||
$this->autoinc = $autoinc;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前数据表的自增主键
|
||||
* @access public
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAutoInc()
|
||||
{
|
||||
$tableName = $this->getTable();
|
||||
|
||||
if (empty($this->autoinc) && $tableName) {
|
||||
$this->autoinc = $this->connection->getAutoInc($tableName);
|
||||
}
|
||||
|
||||
return $this->autoinc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段值增长
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @param float $step 增长值
|
||||
* @return $this
|
||||
*/
|
||||
public function inc(string $field, float $step = 1)
|
||||
{
|
||||
$this->options['data'][$field] = ['INC', $step];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段值减少
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @param float $step 增长值
|
||||
* @return $this
|
||||
*/
|
||||
public function dec(string $field, float $step = 1)
|
||||
{
|
||||
$this->options['data'][$field] = ['DEC', $step];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的查询标识
|
||||
* @access public
|
||||
* @param mixed $data 要序列化的数据
|
||||
* @return string
|
||||
*/
|
||||
public function getQueryGuid($data = null): string
|
||||
{
|
||||
return md5($this->getConfig('database') . serialize(var_export($data ?: $this->options, true)) . serialize($this->getBind(false)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询但只返回PDOStatement对象
|
||||
* @access public
|
||||
* @return PDOStatement
|
||||
*/
|
||||
public function getPdo(): PDOStatement
|
||||
{
|
||||
return $this->connection->pdo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用游标查找记录
|
||||
* @access public
|
||||
* @param mixed $data 数据
|
||||
* @return \Generator
|
||||
*/
|
||||
public function cursor($data = null)
|
||||
{
|
||||
if (!is_null($data)) {
|
||||
// 主键条件分析
|
||||
$this->parsePkWhere($data);
|
||||
}
|
||||
|
||||
$this->options['data'] = $data;
|
||||
|
||||
$connection = clone $this->connection;
|
||||
|
||||
return $connection->cursor($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分批数据返回处理
|
||||
* @access public
|
||||
* @param integer $count 每次处理的数据数量
|
||||
* @param callable $callback 处理回调方法
|
||||
* @param string|array $column 分批处理的字段名
|
||||
* @param string $order 字段排序
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function chunk(int $count, callable $callback, $column = null, string $order = 'asc'): bool
|
||||
{
|
||||
$options = $this->getOptions();
|
||||
$column = $column ?: $this->getPk();
|
||||
|
||||
if (isset($options['order'])) {
|
||||
unset($options['order']);
|
||||
}
|
||||
|
||||
$bind = $this->bind;
|
||||
|
||||
if (is_array($column)) {
|
||||
$times = 1;
|
||||
$query = $this->options($options)->page($times, $count);
|
||||
} else {
|
||||
$query = $this->options($options)->limit($count);
|
||||
|
||||
if (strpos($column, '.')) {
|
||||
[$alias, $key] = explode('.', $column);
|
||||
} else {
|
||||
$key = $column;
|
||||
}
|
||||
}
|
||||
|
||||
$resultSet = $query->order($column, $order)->select();
|
||||
|
||||
while (count($resultSet) > 0) {
|
||||
if (false === call_user_func($callback, $resultSet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($times)) {
|
||||
$times++;
|
||||
$query = $this->options($options)->page($times, $count);
|
||||
} else {
|
||||
$end = $resultSet->pop();
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
@ -140,13 +140,19 @@ trait ModelRelationQuery
|
||||
/**
|
||||
* 使用搜索器条件搜索字段
|
||||
* @access public
|
||||
* @param array $fields 搜索字段
|
||||
* @param array $data 搜索数据
|
||||
* @param string $prefix 字段前缀标识
|
||||
* @param string|array $fields 搜索字段
|
||||
* @param mixed $data 搜索数据
|
||||
* @param string $prefix 字段前缀标识
|
||||
* @return $this
|
||||
*/
|
||||
public function withSearch(array $fields, array $data = [], string $prefix = '')
|
||||
public function withSearch($fields, $data = [], string $prefix = '')
|
||||
{
|
||||
if (is_string($fields)) {
|
||||
$fields = explode(',', $fields);
|
||||
}
|
||||
|
||||
$likeFields = $this->getConfig('match_like_fields') ?: [];
|
||||
|
||||
foreach ($fields as $key => $field) {
|
||||
if ($field instanceof Closure) {
|
||||
$field($this, $data[$key] ?? null, $data, $prefix);
|
||||
@ -157,6 +163,8 @@ trait ModelRelationQuery
|
||||
|
||||
if (method_exists($this->model, $method)) {
|
||||
$this->model->$method($this, $data[$field] ?? null, $data, $prefix);
|
||||
} elseif (isset($data[$field])) {
|
||||
$this->where($fieldName, in_array($fieldName, $likeFields) ? 'like' : '=', in_array($fieldName, $likeFields) ? '%' . $data[$field] . '%' : $data[$field]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,10 +12,14 @@ declare (strict_types = 1);
|
||||
|
||||
namespace think\db\concern;
|
||||
|
||||
use Closure;
|
||||
use think\Collection;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\db\Query;
|
||||
use think\helper\Str;
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 查询数据处理
|
||||
@ -103,6 +107,7 @@ trait ResultOperation
|
||||
*/
|
||||
protected function filterResult(&$result): void
|
||||
{
|
||||
$array = [];
|
||||
if (!empty($this->options['visible'])) {
|
||||
foreach ($this->options['visible'] as $key) {
|
||||
$array[] = $key;
|
||||
@ -222,9 +227,6 @@ trait ResultOperation
|
||||
* @access public
|
||||
* @param array|string|Query|Closure $data 数据
|
||||
* @return array|Model
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
* @throws DataNotFoundException
|
||||
*/
|
||||
public function selectOrFail($data = null)
|
||||
{
|
||||
@ -236,9 +238,6 @@ trait ResultOperation
|
||||
* @access public
|
||||
* @param array|string|Query|Closure $data 数据
|
||||
* @return array|Model
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
* @throws DataNotFoundException
|
||||
*/
|
||||
public function findOrFail($data = null)
|
||||
{
|
||||
|
@ -228,7 +228,7 @@ abstract class Relation
|
||||
|
||||
if (!empty($params)) {
|
||||
$type = $params[0]->getType();
|
||||
return Relation::class == $type || is_null($type) ? $this : $this->query;
|
||||
return is_null($type) || Relation::class == $type->getName() ? $this : $this->query;
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@ -720,7 +720,7 @@ trait RelationShip
|
||||
{
|
||||
$relation = Str::camel($attr);
|
||||
|
||||
if (method_exists($this, $relation) && !method_exists('think\Model', $relation)) {
|
||||
if ((method_exists($this, $relation) && !method_exists('think\Model', $relation)) || isset(static::$macro[static::class][$relation])) {
|
||||
return $relation;
|
||||
}
|
||||
|
||||
|
@ -13,9 +13,11 @@ declare (strict_types = 1);
|
||||
namespace think\model\concern;
|
||||
|
||||
use think\db\BaseQuery as Query;
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 数据软删除
|
||||
* @mixin Model
|
||||
*/
|
||||
trait SoftDelete
|
||||
{
|
||||
@ -149,7 +151,7 @@ trait SoftDelete
|
||||
public static function destroy($data, bool $force = false): bool
|
||||
{
|
||||
// 包含软删除数据
|
||||
$query = (new static())->db(false);
|
||||
$query = (new static())->withTrashedData(true)->db(false);
|
||||
|
||||
if (is_array($data) && key($data) !== 0) {
|
||||
$query->where($data);
|
||||
|
@ -222,7 +222,7 @@ class BelongsToMany extends Relation
|
||||
*/
|
||||
public function find($data = null)
|
||||
{
|
||||
$result = $this->buildQuery()->find($data);
|
||||
$result = $this->buildQuery()->findOrEmpty($data);
|
||||
|
||||
if (!$result->isEmpty()) {
|
||||
$this->hydratePivot([$result]);
|
||||
|
@ -340,7 +340,7 @@ class HasMany extends Relation
|
||||
|
||||
return $query->group($model . '.' . $this->localKey)
|
||||
->field($fields)
|
||||
->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey)
|
||||
->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $joinType)
|
||||
->when($softDelete, function ($query) use ($softDelete, $relation) {
|
||||
$query->where($relation . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
|
||||
})
|
||||
|
@ -154,7 +154,7 @@ class HasManyThrough extends Relation
|
||||
$query = $query ?: $this->parent->db()->alias($model);
|
||||
|
||||
return $query->join($throughTable, $throughTable . '.' . $this->foreignKey . '=' . $model . '.' . $this->localKey)
|
||||
->join($modelTable, $modelTable . '.' . $throughKey . '=' . $throughTable . '.' . $this->throughPk)
|
||||
->join($modelTable, $modelTable . '.' . $throughKey . '=' . $throughTable . '.' . $this->throughPk, $joinType)
|
||||
->when($softDelete, function ($query) use ($softDelete, $modelTable) {
|
||||
$query->where($modelTable . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
|
||||
})
|
||||
|
@ -1,333 +1,332 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\model\relation;
|
||||
|
||||
use Closure;
|
||||
use think\db\exception\DbException as Exception;
|
||||
use think\helper\Str;
|
||||
use think\Model;
|
||||
use think\model\Relation;
|
||||
|
||||
/**
|
||||
* 多态关联类
|
||||
*/
|
||||
class MorphTo extends Relation
|
||||
{
|
||||
/**
|
||||
* 多态关联外键
|
||||
* @var string
|
||||
*/
|
||||
protected $morphKey;
|
||||
|
||||
/**
|
||||
* 多态字段
|
||||
* @var string
|
||||
*/
|
||||
protected $morphType;
|
||||
|
||||
/**
|
||||
* 多态别名
|
||||
* @var array
|
||||
*/
|
||||
protected $alias = [];
|
||||
|
||||
/**
|
||||
* 关联名
|
||||
* @var string
|
||||
*/
|
||||
protected $relation;
|
||||
|
||||
/**
|
||||
* 架构函数
|
||||
* @access public
|
||||
* @param Model $parent 上级模型对象
|
||||
* @param string $morphType 多态字段名
|
||||
* @param string $morphKey 外键名
|
||||
* @param array $alias 多态别名定义
|
||||
* @param string $relation 关联名
|
||||
*/
|
||||
public function __construct(Model $parent, string $morphType, string $morphKey, array $alias = [], string $relation = null)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->morphType = $morphType;
|
||||
$this->morphKey = $morphKey;
|
||||
$this->alias = $alias;
|
||||
$this->relation = $relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的关联模型类的实例
|
||||
* @access public
|
||||
* @return Model
|
||||
*/
|
||||
public function getModel(): Model
|
||||
{
|
||||
$morphType = $this->morphType;
|
||||
$model = $this->parseModel($this->parent->$morphType);
|
||||
|
||||
return (new $model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 延迟获取关联数据
|
||||
* @access public
|
||||
* @param array $subRelation 子关联名
|
||||
* @param Closure $closure 闭包查询条件
|
||||
* @return Model
|
||||
*/
|
||||
public function getRelation(array $subRelation = [], Closure $closure = null)
|
||||
{
|
||||
$morphKey = $this->morphKey;
|
||||
$morphType = $this->morphType;
|
||||
|
||||
// 多态模型
|
||||
$model = $this->parseModel($this->parent->$morphType);
|
||||
|
||||
// 主键数据
|
||||
$pk = $this->parent->$morphKey;
|
||||
|
||||
$relationModel = (new $model)->relation($subRelation)->find($pk);
|
||||
|
||||
if ($relationModel) {
|
||||
$relationModel->setParent(clone $this->parent);
|
||||
}
|
||||
|
||||
return $relationModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据关联条件查询当前模型
|
||||
* @access public
|
||||
* @param string $operator 比较操作符
|
||||
* @param integer $count 个数
|
||||
* @param string $id 关联表的统计字段
|
||||
* @param string $joinType JOIN类型
|
||||
* @param Query $query Query对象
|
||||
* @return Query
|
||||
*/
|
||||
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', Query $query = null)
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据关联条件查询当前模型
|
||||
* @access public
|
||||
* @param mixed $where 查询条件(数组或者闭包)
|
||||
* @param mixed $fields 字段
|
||||
* @param string $joinType JOIN类型
|
||||
* @param Query $query Query对象
|
||||
* @return Query
|
||||
*/
|
||||
public function hasWhere($where = [], $fields = null, string $joinType = '', Query $query = null)
|
||||
{
|
||||
throw new Exception('relation not support: hasWhere');
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析模型的完整命名空间
|
||||
* @access protected
|
||||
* @param string $model 模型名(或者完整类名)
|
||||
* @return string
|
||||
*/
|
||||
protected function parseModel(string $model): string
|
||||
{
|
||||
if (isset($this->alias[$model])) {
|
||||
$model = $this->alias[$model];
|
||||
}
|
||||
|
||||
if (false === strpos($model, '\\')) {
|
||||
$path = explode('\\', get_class($this->parent));
|
||||
array_pop($path);
|
||||
array_push($path, Str::studly($model));
|
||||
$model = implode('\\', $path);
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置多态别名
|
||||
* @access public
|
||||
* @param array $alias 别名定义
|
||||
* @return $this
|
||||
*/
|
||||
public function setAlias(array $alias)
|
||||
{
|
||||
$this->alias = $alias;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除关联查询参数
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function removeOption()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预载入关联查询
|
||||
* @access public
|
||||
* @param array $resultSet 数据集
|
||||
* @param string $relation 当前关联名
|
||||
* @param array $subRelation 子关联名
|
||||
* @param Closure $closure 闭包
|
||||
* @param array $cache 关联缓存
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, Closure $closure = null, array $cache = []): void
|
||||
{
|
||||
$morphKey = $this->morphKey;
|
||||
$morphType = $this->morphType;
|
||||
$range = [];
|
||||
|
||||
foreach ($resultSet as $result) {
|
||||
// 获取关联外键列表
|
||||
if (!empty($result->$morphKey)) {
|
||||
$range[$result->$morphType][] = $result->$morphKey;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($range)) {
|
||||
|
||||
foreach ($range as $key => $val) {
|
||||
// 多态类型映射
|
||||
$model = $this->parseModel($key);
|
||||
$obj = new $model;
|
||||
$pk = $obj->getPk();
|
||||
$list = $obj->with($subRelation)
|
||||
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
|
||||
->select($val);
|
||||
$data = [];
|
||||
|
||||
foreach ($list as $k => $vo) {
|
||||
$data[$vo->$pk] = $vo;
|
||||
}
|
||||
|
||||
foreach ($resultSet as $result) {
|
||||
if ($key == $result->$morphType) {
|
||||
// 关联模型
|
||||
if (!isset($data[$result->$morphKey])) {
|
||||
$relationModel = null;
|
||||
throw new Exception('relation data not exists :' . $this->model);
|
||||
} else {
|
||||
$relationModel = $data[$result->$morphKey];
|
||||
$relationModel->setParent(clone $result);
|
||||
$relationModel->exists(true);
|
||||
}
|
||||
|
||||
$result->setRelation($relation, $relationModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 预载入关联查询
|
||||
* @access public
|
||||
* @param Model $result 数据对象
|
||||
* @param string $relation 当前关联名
|
||||
* @param array $subRelation 子关联名
|
||||
* @param Closure $closure 闭包
|
||||
* @param array $cache 关联缓存
|
||||
* @return void
|
||||
*/
|
||||
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
|
||||
{
|
||||
// 多态类型映射
|
||||
$model = $this->parseModel($result->{$this->morphType});
|
||||
|
||||
$this->eagerlyMorphToOne($model, $relation, $result, $subRelation, $cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联统计
|
||||
* @access public
|
||||
* @param Model $result 数据对象
|
||||
* @param Closure $closure 闭包
|
||||
* @param string $aggregate 聚合查询方法
|
||||
* @param string $field 字段
|
||||
* @return integer
|
||||
*/
|
||||
public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*')
|
||||
{}
|
||||
|
||||
/**
|
||||
* 多态MorphTo 关联模型预查询
|
||||
* @access protected
|
||||
* @param string $model 关联模型对象
|
||||
* @param string $relation 关联名
|
||||
* @param Model $result
|
||||
* @param array $subRelation 子关联
|
||||
* @param array $cache 关联缓存
|
||||
* @return void
|
||||
*/
|
||||
protected function eagerlyMorphToOne(string $model, string $relation, Model $result, array $subRelation = [], array $cache = []): void
|
||||
{
|
||||
// 预载入关联查询 支持嵌套预载入
|
||||
$pk = $this->parent->{$this->morphKey};
|
||||
$data = (new $model)->with($subRelation)
|
||||
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
|
||||
->find($pk);
|
||||
|
||||
if ($data) {
|
||||
$data->setParent(clone $result);
|
||||
$data->exists(true);
|
||||
}
|
||||
|
||||
$result->setRelation($relation, $data ?: null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加关联数据
|
||||
* @access public
|
||||
* @param Model $model 关联模型对象
|
||||
* @param string $type 多态类型
|
||||
* @return Model
|
||||
*/
|
||||
public function associate(Model $model, string $type = ''): Model
|
||||
{
|
||||
$morphKey = $this->morphKey;
|
||||
$morphType = $this->morphType;
|
||||
$pk = $model->getPk();
|
||||
|
||||
$this->parent->setAttr($morphKey, $model->$pk);
|
||||
$this->parent->setAttr($morphType, $type ?: get_class($model));
|
||||
$this->parent->save();
|
||||
|
||||
return $this->parent->setRelation($this->relation, $model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销关联数据
|
||||
* @access public
|
||||
* @return Model
|
||||
*/
|
||||
public function dissociate(): Model
|
||||
{
|
||||
$morphKey = $this->morphKey;
|
||||
$morphType = $this->morphType;
|
||||
|
||||
$this->parent->setAttr($morphKey, null);
|
||||
$this->parent->setAttr($morphType, null);
|
||||
$this->parent->save();
|
||||
|
||||
return $this->parent->setRelation($this->relation, null);
|
||||
}
|
||||
|
||||
}
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\model\relation;
|
||||
|
||||
use Closure;
|
||||
use think\db\exception\DbException as Exception;
|
||||
use think\helper\Str;
|
||||
use think\Model;
|
||||
use think\model\Relation;
|
||||
|
||||
/**
|
||||
* 多态关联类
|
||||
*/
|
||||
class MorphTo extends Relation
|
||||
{
|
||||
/**
|
||||
* 多态关联外键
|
||||
* @var string
|
||||
*/
|
||||
protected $morphKey;
|
||||
|
||||
/**
|
||||
* 多态字段
|
||||
* @var string
|
||||
*/
|
||||
protected $morphType;
|
||||
|
||||
/**
|
||||
* 多态别名
|
||||
* @var array
|
||||
*/
|
||||
protected $alias = [];
|
||||
|
||||
/**
|
||||
* 关联名
|
||||
* @var string
|
||||
*/
|
||||
protected $relation;
|
||||
|
||||
/**
|
||||
* 架构函数
|
||||
* @access public
|
||||
* @param Model $parent 上级模型对象
|
||||
* @param string $morphType 多态字段名
|
||||
* @param string $morphKey 外键名
|
||||
* @param array $alias 多态别名定义
|
||||
* @param string $relation 关联名
|
||||
*/
|
||||
public function __construct(Model $parent, string $morphType, string $morphKey, array $alias = [], string $relation = null)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->morphType = $morphType;
|
||||
$this->morphKey = $morphKey;
|
||||
$this->alias = $alias;
|
||||
$this->relation = $relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的关联模型类的实例
|
||||
* @access public
|
||||
* @return Model
|
||||
*/
|
||||
public function getModel(): Model
|
||||
{
|
||||
$morphType = $this->morphType;
|
||||
$model = $this->parseModel($this->parent->$morphType);
|
||||
|
||||
return (new $model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 延迟获取关联数据
|
||||
* @access public
|
||||
* @param array $subRelation 子关联名
|
||||
* @param Closure $closure 闭包查询条件
|
||||
* @return Model
|
||||
*/
|
||||
public function getRelation(array $subRelation = [], Closure $closure = null)
|
||||
{
|
||||
$morphKey = $this->morphKey;
|
||||
$morphType = $this->morphType;
|
||||
|
||||
// 多态模型
|
||||
$model = $this->parseModel($this->parent->$morphType);
|
||||
|
||||
// 主键数据
|
||||
$pk = $this->parent->$morphKey;
|
||||
|
||||
$relationModel = (new $model)->relation($subRelation)->find($pk);
|
||||
|
||||
if ($relationModel) {
|
||||
$relationModel->setParent(clone $this->parent);
|
||||
}
|
||||
|
||||
return $relationModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据关联条件查询当前模型
|
||||
* @access public
|
||||
* @param string $operator 比较操作符
|
||||
* @param integer $count 个数
|
||||
* @param string $id 关联表的统计字段
|
||||
* @param string $joinType JOIN类型
|
||||
* @param Query $query Query对象
|
||||
* @return Query
|
||||
*/
|
||||
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', Query $query = null)
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据关联条件查询当前模型
|
||||
* @access public
|
||||
* @param mixed $where 查询条件(数组或者闭包)
|
||||
* @param mixed $fields 字段
|
||||
* @param string $joinType JOIN类型
|
||||
* @param Query $query Query对象
|
||||
* @return Query
|
||||
*/
|
||||
public function hasWhere($where = [], $fields = null, string $joinType = '', Query $query = null)
|
||||
{
|
||||
throw new Exception('relation not support: hasWhere');
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析模型的完整命名空间
|
||||
* @access protected
|
||||
* @param string $model 模型名(或者完整类名)
|
||||
* @return string
|
||||
*/
|
||||
protected function parseModel(string $model): string
|
||||
{
|
||||
if (isset($this->alias[$model])) {
|
||||
$model = $this->alias[$model];
|
||||
}
|
||||
|
||||
if (false === strpos($model, '\\')) {
|
||||
$path = explode('\\', get_class($this->parent));
|
||||
array_pop($path);
|
||||
array_push($path, Str::studly($model));
|
||||
$model = implode('\\', $path);
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置多态别名
|
||||
* @access public
|
||||
* @param array $alias 别名定义
|
||||
* @return $this
|
||||
*/
|
||||
public function setAlias(array $alias)
|
||||
{
|
||||
$this->alias = $alias;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除关联查询参数
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function removeOption()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预载入关联查询
|
||||
* @access public
|
||||
* @param array $resultSet 数据集
|
||||
* @param string $relation 当前关联名
|
||||
* @param array $subRelation 子关联名
|
||||
* @param Closure $closure 闭包
|
||||
* @param array $cache 关联缓存
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, Closure $closure = null, array $cache = []): void
|
||||
{
|
||||
$morphKey = $this->morphKey;
|
||||
$morphType = $this->morphType;
|
||||
$range = [];
|
||||
|
||||
foreach ($resultSet as $result) {
|
||||
// 获取关联外键列表
|
||||
if (!empty($result->$morphKey)) {
|
||||
$range[$result->$morphType][] = $result->$morphKey;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($range)) {
|
||||
|
||||
foreach ($range as $key => $val) {
|
||||
// 多态类型映射
|
||||
$model = $this->parseModel($key);
|
||||
$obj = new $model;
|
||||
$pk = $obj->getPk();
|
||||
$list = $obj->with($subRelation)
|
||||
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
|
||||
->select($val);
|
||||
$data = [];
|
||||
|
||||
foreach ($list as $k => $vo) {
|
||||
$data[$vo->$pk] = $vo;
|
||||
}
|
||||
|
||||
foreach ($resultSet as $result) {
|
||||
if ($key == $result->$morphType) {
|
||||
// 关联模型
|
||||
if (!isset($data[$result->$morphKey])) {
|
||||
$relationModel = null;
|
||||
} else {
|
||||
$relationModel = $data[$result->$morphKey];
|
||||
$relationModel->setParent(clone $result);
|
||||
$relationModel->exists(true);
|
||||
}
|
||||
|
||||
$result->setRelation($relation, $relationModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 预载入关联查询
|
||||
* @access public
|
||||
* @param Model $result 数据对象
|
||||
* @param string $relation 当前关联名
|
||||
* @param array $subRelation 子关联名
|
||||
* @param Closure $closure 闭包
|
||||
* @param array $cache 关联缓存
|
||||
* @return void
|
||||
*/
|
||||
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
|
||||
{
|
||||
// 多态类型映射
|
||||
$model = $this->parseModel($result->{$this->morphType});
|
||||
|
||||
$this->eagerlyMorphToOne($model, $relation, $result, $subRelation, $cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联统计
|
||||
* @access public
|
||||
* @param Model $result 数据对象
|
||||
* @param Closure $closure 闭包
|
||||
* @param string $aggregate 聚合查询方法
|
||||
* @param string $field 字段
|
||||
* @return integer
|
||||
*/
|
||||
public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*')
|
||||
{}
|
||||
|
||||
/**
|
||||
* 多态MorphTo 关联模型预查询
|
||||
* @access protected
|
||||
* @param string $model 关联模型对象
|
||||
* @param string $relation 关联名
|
||||
* @param Model $result
|
||||
* @param array $subRelation 子关联
|
||||
* @param array $cache 关联缓存
|
||||
* @return void
|
||||
*/
|
||||
protected function eagerlyMorphToOne(string $model, string $relation, Model $result, array $subRelation = [], array $cache = []): void
|
||||
{
|
||||
// 预载入关联查询 支持嵌套预载入
|
||||
$pk = $this->parent->{$this->morphKey};
|
||||
$data = (new $model)->with($subRelation)
|
||||
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
|
||||
->find($pk);
|
||||
|
||||
if ($data) {
|
||||
$data->setParent(clone $result);
|
||||
$data->exists(true);
|
||||
}
|
||||
|
||||
$result->setRelation($relation, $data ?: null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加关联数据
|
||||
* @access public
|
||||
* @param Model $model 关联模型对象
|
||||
* @param string $type 多态类型
|
||||
* @return Model
|
||||
*/
|
||||
public function associate(Model $model, string $type = ''): Model
|
||||
{
|
||||
$morphKey = $this->morphKey;
|
||||
$morphType = $this->morphType;
|
||||
$pk = $model->getPk();
|
||||
|
||||
$this->parent->setAttr($morphKey, $model->$pk);
|
||||
$this->parent->setAttr($morphType, $type ?: get_class($model));
|
||||
$this->parent->save();
|
||||
|
||||
return $this->parent->setRelation($this->relation, $model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销关联数据
|
||||
* @access public
|
||||
* @return Model
|
||||
*/
|
||||
public function dissociate(): Model
|
||||
{
|
||||
$morphKey = $this->morphKey;
|
||||
$morphType = $this->morphType;
|
||||
|
||||
$this->parent->setAttr($morphKey, null);
|
||||
$this->parent->setAttr($morphType, null);
|
||||
$this->parent->save();
|
||||
|
||||
return $this->parent->setRelation($this->relation, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
namespace think\admin\command;
|
||||
|
||||
use Psr\Log\NullLogger;
|
||||
use think\admin\Command;
|
||||
use think\admin\service\ProcessService;
|
||||
use think\console\Input;
|
||||
@ -44,8 +45,9 @@ abstract class Queue extends Command
|
||||
* @param Input $input
|
||||
* @param Output $output
|
||||
*/
|
||||
public function initialize(Input $input, Output $output)
|
||||
protected function initialize(Input $input, Output $output)
|
||||
{
|
||||
$this->app->db->setLog(new NullLogger());
|
||||
$this->process = ProcessService::instance();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user