| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493 |
- <?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 $sequence 自增序列名
- * @return $this
- */
- public function sequence(string $sequence = null)
- {
- $this->options['sequence'] = $sequence;
- 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
- */
- public function getAutoInc()
- {
- if (empty($this->autoinc)) {
- $this->autoinc = $this->connection->getAutoInc($this->getTable());
- }
- 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, '.')) {
- list($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;
- }
- }
|