Server : nginx/1.20.1 System : Linux iZ2ze9ojcl78uluczwag69Z 4.18.0-240.22.1.el8_3.x86_64 #1 SMP Thu Apr 8 19:01:30 UTC 2021 x86_64 User : www ( 1000) PHP Version : 7.3.28 Disable Function : passthru,exec,system,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv Directory : /www/wwwroot/0531yanglao.com/vendor/topthink/think-orm/src/db/ |
<?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 think\db\exception\DbException as Exception; use think\helper\Str; /** * SQL获取类 */ class Fetch { /** * 查询对象 * @var Query */ protected $query; /** * Connection对象 * @var Connection */ protected $connection; /** * Builder对象 * @var Builder */ protected $builder; /** * 创建一个查询SQL获取对象 * * @param Query $query 查询对象 */ public function __construct(Query $query) { $this->query = $query; $this->connection = $query->getConnection(); $this->builder = $this->connection->getBuilder(); } /** * 聚合查询 * @access protected * @param string $aggregate 聚合方法 * @param string $field 字段名 * @return string */ protected function aggregate(string $aggregate, string $field): string { $this->query->parseOptions(); $field = $aggregate . '(' . $this->builder->parseKey($this->query, $field) . ') AS think_' . strtolower($aggregate); return $this->value($field, 0, false); } /** * 得到某个字段的值 * @access public * @param string $field 字段名 * @param mixed $default 默认值 * @param bool $one * @return string */ public function value(string $field, $default = null, bool $one = true): string { $options = $this->query->parseOptions(); if (isset($options['field'])) { $this->query->removeOption('field'); } $this->query->setOption('field', (array) $field); // 生成查询SQL $sql = $this->builder->select($this->query, $one); if (isset($options['field'])) { $this->query->setOption('field', $options['field']); } else { $this->query->removeOption('field'); } return $this->fetch($sql); } /** * 得到某个列的数组 * @access public * @param string $field 字段名 多个字段用逗号分隔 * @param string $key 索引 * @return string */ public function column(string $field, string $key = ''): string { $options = $this->query->parseOptions(); if (isset($options['field'])) { $this->query->removeOption('field'); } if ($key && '*' != $field) { $field = $key . ',' . $field; } $field = array_map('trim', explode(',', $field)); $this->query->setOption('field', $field); // 生成查询SQL $sql = $this->builder->select($this->query); if (isset($options['field'])) { $this->query->setOption('field', $options['field']); } else { $this->query->removeOption('field'); } return $this->fetch($sql); } /** * 插入记录 * @access public * @param array $data 数据 * @return string */ public function insert(array $data = []): string { $options = $this->query->parseOptions(); if (!empty($data)) { $this->query->setOption('data', $data); } $sql = $this->builder->insert($this->query); return $this->fetch($sql); } /** * 插入记录并获取自增ID * @access public * @param array $data 数据 * @return string */ public function insertGetId(array $data = []): string { return $this->insert($data); } /** * 保存数据 自动判断insert或者update * @access public * @param array $data 数据 * @param bool $forceInsert 是否强制insert * @return string */ public function save(array $data = [], bool $forceInsert = false): string { if ($forceInsert) { return $this->insert($data); } $data = array_merge($this->query->getOptions('data') ?: [], $data); $this->query->setOption('data', $data); if ($this->query->getOptions('where')) { $isUpdate = true; } else { $isUpdate = $this->query->parseUpdateData($data); } return $isUpdate ? $this->update() : $this->insert(); } /** * 批量插入记录 * @access public * @param array $dataSet 数据集 * @param integer $limit 每次写入数据限制 * @return string */ public function insertAll(array $dataSet = [], int $limit = null): string { $options = $this->query->parseOptions(); if (empty($dataSet)) { $dataSet = $options['data']; } if (empty($limit) && !empty($options['limit'])) { $limit = $options['limit']; } if ($limit) { $array = array_chunk($dataSet, $limit, true); $fetchSql = []; foreach ($array as $item) { $sql = $this->builder->insertAll($this->query, $item); $bind = $this->query->getBind(); $fetchSql[] = $this->connection->getRealSql($sql, $bind); } return implode(';', $fetchSql); } $sql = $this->builder->insertAll($this->query, $dataSet); return $this->fetch($sql); } /** * 通过Select方式插入记录 * @access public * @param array $fields 要插入的数据表字段名 * @param string $table 要插入的数据表名 * @return string */ public function selectInsert(array $fields, string $table): string { $this->query->parseOptions(); $sql = $this->builder->selectInsert($this->query, $fields, $table); return $this->fetch($sql); } /** * 更新记录 * @access public * @param mixed $data 数据 * @return string */ public function update(array $data = []): string { $options = $this->query->parseOptions(); $data = !empty($data) ? $data : $options['data']; $pk = $this->query->getPk(); if (empty($options['where'])) { // 如果存在主键数据 则自动作为更新条件 if (is_string($pk) && isset($data[$pk])) { $this->query->where($pk, '=', $data[$pk]); unset($data[$pk]); } elseif (is_array($pk)) { // 增加复合主键支持 foreach ($pk as $field) { if (isset($data[$field])) { $this->query->where($field, '=', $data[$field]); } else { // 如果缺少复合主键数据则不执行 throw new Exception('miss complex primary data'); } unset($data[$field]); } } if (empty($this->query->getOptions('where'))) { // 如果没有任何更新条件则不执行 throw new Exception('miss update condition'); } } // 更新数据 $this->query->setOption('data', $data); // 生成UPDATE SQL语句 $sql = $this->builder->update($this->query); return $this->fetch($sql); } /** * 删除记录 * @access public * @param mixed $data 表达式 true 表示强制删除 * @return string */ public function delete($data = null): string { $options = $this->query->parseOptions(); if (!is_null($data) && true !== $data) { // AR模式分析主键条件 $this->query->parsePkWhere($data); } if (!empty($options['soft_delete'])) { // 软删除 [$field, $condition] = $options['soft_delete']; if ($condition) { $this->query->setOption('soft_delete', null); $this->query->setOption('data', [$field => $condition]); // 生成删除SQL语句 $sql = $this->builder->delete($this->query); return $this->fetch($sql); } } // 生成删除SQL语句 $sql = $this->builder->delete($this->query); return $this->fetch($sql); } /** * 查找记录 返回SQL * @access public * @param mixed $data * @return string */ public function select($data = null): string { $this->query->parseOptions(); if (!is_null($data)) { // 主键条件分析 $this->query->parsePkWhere($data); } // 生成查询SQL $sql = $this->builder->select($this->query); return $this->fetch($sql); } /** * 查找单条记录 返回SQL语句 * @access public * @param mixed $data * @return string */ public function find($data = null): string { $this->query->parseOptions(); if (!is_null($data)) { // AR模式分析主键条件 $this->query->parsePkWhere($data); } // 生成查询SQL $sql = $this->builder->select($this->query, true); // 获取实际执行的SQL语句 return $this->fetch($sql); } /** * 查找多条记录 如果不存在则抛出异常 * @access public * @param mixed $data * @return string */ public function selectOrFail($data = null): string { return $this->select($data); } /** * 查找单条记录 如果不存在则抛出异常 * @access public * @param mixed $data * @return string */ public function findOrFail($data = null): string { return $this->find($data); } /** * 查找单条记录 不存在返回空数据(或者空模型) * @access public * @param mixed $data 数据 * @return string */ public function findOrEmpty($data = null) { return $this->find($data); } /** * 获取实际的SQL语句 * @access public * @param string $sql * @return string */ public function fetch(string $sql): string { $bind = $this->query->getBind(); return $this->connection->getRealSql($sql, $bind); } /** * COUNT查询 * @access public * @param string $field 字段名 * @return string */ public function count(string $field = '*'): string { $options = $this->query->parseOptions(); if (!empty($options['group'])) { // 支持GROUP $subSql = $this->query->field('count(' . $field . ') AS think_count')->buildSql(); $query = $this->query->newQuery()->table([$subSql => '_group_count_']); return $query->fetchsql()->aggregate('COUNT', '*'); } else { return $this->aggregate('COUNT', $field); } } /** * SUM查询 * @access public * @param string $field 字段名 * @return string */ public function sum(string $field): string { return $this->aggregate('SUM', $field); } /** * MIN查询 * @access public * @param string $field 字段名 * @return string */ public function min(string $field): string { return $this->aggregate('MIN', $field); } /** * MAX查询 * @access public * @param string $field 字段名 * @return string */ public function max(string $field): string { return $this->aggregate('MAX', $field); } /** * AVG查询 * @access public * @param string $field 字段名 * @return string */ public function avg(string $field): string { return $this->aggregate('AVG', $field); } public function __call($method, $args) { if (strtolower(substr($method, 0, 5)) == 'getby') { // 根据某个字段获取记录 $field = Str::snake(substr($method, 5)); return $this->where($field, '=', $args[0])->find(); } elseif (strtolower(substr($method, 0, 10)) == 'getfieldby') { // 根据某个字段获取记录的某个值 $name = Str::snake(substr($method, 10)); return $this->where($name, '=', $args[0])->value($args[1]); } $result = call_user_func_array([$this->query, $method], $args); return $result === $this->query ? $this : $result; } }