<?php<liu21st@gmail.com>declare (strict_types = 1);
namespace think\db;
use PDOStatement;
use think\helper\Str;
class Query extends BaseQuery
{
use concern\JoinAndViewQuery;
use concern\ParamsBind;
use concern\TableFieldInfo;
public function orderRaw(string $field, array $bind = [])
{
$this->options['order'][] = new Raw($field, $bind);
return $this;
}
public function fieldRaw(string $field)
{
$this->options['field'][] = new Raw($field);
return $this;
}
public function orderField(string $field, array $values, string $order = '')
{
if (!empty($values)) {
$values['sort'] = $order;
$this->options['order'][$field] = $values;
}
return $this;
}
public function orderRand()
{
$this->options['order'][] = '[rand]';
return $this;
}
public function exp(string $field, string $value)
{
$this->options['data'][$field] = new Raw($value);
return $this;
}
public function tableRaw(string $table)
{
$this->options['table'] = new Raw($table);
return $this;
}
public function fetchSql(bool $fetch = true)
{
$this->options['fetch_sql'] = $fetch;
if ($fetch) {
return new Fetch($this);
}
return $this;
}
public function batchQuery(array $sql = []): bool
{
return $this->connection->batchQuery($this, $sql);
}
public function using($using)
{
$this->options['using'] = $using;
return $this;
}
public function procedure(bool $procedure = true)
{
$this->options['procedure'] = $procedure;
return $this;
}
public function group($group)
{
$this->options['group'] = $group;
return $this;
}
public function having(string $having)
{
$this->options['having'] = $having;
return $this;
}
public function distinct(bool $distinct = true)
{
$this->options['distinct'] = $distinct;
return $this;
}
public function force(string $force)
{
$this->options['force'] = $force;
return $this;
}
public function comment(string $comment)
{
$this->options['comment'] = $comment;
return $this;
}
public function replace(bool $replace = true)
{
$this->options['replace'] = $replace;
return $this;
}
public function partition($partition)
{
$this->options['partition'] = $partition;
return $this;
}
public function duplicate($duplicate)
{
$this->options['duplicate'] = $duplicate;
return $this;
}
public function extra(string $extra)
{
$this->options['extra'] = $extra;
return $this;
}
public function buildSql(bool $sub = true): string
{
return $sub ? '( ' . $this->fetchSql()->select() . ' )' : $this->fetchSql()->select();
}
public function getPk()
{
if (empty($this->pk)) {
$this->pk = $this->connection->getPk($this->getTable());
}
return $this->pk;
}
public function autoinc(string $autoinc)
{
$this->autoinc = $autoinc;
return $this;
}
public function getAutoInc()
{
$tableName = $this->getTable();
if (empty($this->autoinc) && $tableName) {
$this->autoinc = $this->connection->getAutoInc($tableName);
}
return $this->autoinc;
}
public function inc(string $field, float $step = 1)
{
$this->options['data'][$field] = ['INC', $step];
return $this;
}
public function dec(string $field, float $step = 1)
{
$this->options['data'][$field] = ['DEC', $step];
return $this;
}
public function getQueryGuid($data = null): string
{
return md5($this->getConfig('database') . serialize(var_export($data ?: $this->options, true)) . serialize($this->getBind(false)));
}
public function getPdo(): PDOStatement
{
return $this->connection->pdo($this);
}
public function cursor($data = null)
{
if (!is_null($data)) {
$this->parsePkWhere($data);
}
$this->options['data'] = $data;
$connection = clone $this->connection;
return $connection->cursor($this);
}
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;
}
}