内核更新
This commit is contained in:
@@ -12,9 +12,6 @@
|
||||
namespace think\db;
|
||||
|
||||
use PDO;
|
||||
use think\Db;
|
||||
use think\db\Connection;
|
||||
use think\db\Query;
|
||||
use think\Exception;
|
||||
|
||||
abstract class Builder
|
||||
@@ -118,6 +115,9 @@ abstract class Builder
|
||||
$this->query->bind($key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR);
|
||||
$result[$item] = ':' . $key;
|
||||
}
|
||||
} elseif (is_object($val) && method_exists($val, '__toString')) {
|
||||
// 对象数据写入
|
||||
$result[$item] = $val->__toString();
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
@@ -317,6 +317,11 @@ abstract class Builder
|
||||
}
|
||||
}
|
||||
$bindName = $bindName ?: 'where_' . str_replace('.', '_', $field);
|
||||
if (preg_match('/\W/', $bindName)) {
|
||||
// 处理带非单词字符的字段名
|
||||
$bindName = md5($bindName);
|
||||
}
|
||||
|
||||
$bindType = isset($binds[$field]) ? $binds[$field] : PDO::PARAM_STR;
|
||||
if (is_scalar($value) && array_key_exists($field, $binds) && !in_array($exp, ['EXP', 'NOT NULL', 'NULL', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) && strpos($exp, 'TIME') === false) {
|
||||
if (strpos($value, ':') !== 0 || !$this->query->isBind(substr($value, 1))) {
|
||||
@@ -702,8 +707,13 @@ abstract class Builder
|
||||
throw new Exception('fields not exists:[' . $key . ']');
|
||||
}
|
||||
unset($data[$key]);
|
||||
} elseif (is_null($val)) {
|
||||
$data[$key] = 'NULL';
|
||||
} elseif (is_scalar($val)) {
|
||||
$data[$key] = $this->parseValue($val, $key);
|
||||
} elseif (is_object($val) && method_exists($val, '__toString')) {
|
||||
// 对象数据写入
|
||||
$data[$key] = $val->__toString();
|
||||
} else {
|
||||
// 过滤掉非标量数据
|
||||
unset($data[$key]);
|
||||
|
||||
@@ -16,7 +16,6 @@ use PDOStatement;
|
||||
use think\Collection;
|
||||
use think\Db;
|
||||
use think\db\exception\BindParamException;
|
||||
use think\db\Query;
|
||||
use think\Debug;
|
||||
use think\Exception;
|
||||
use think\exception\PDOException;
|
||||
@@ -65,47 +64,49 @@ abstract class Connection
|
||||
// 数据库连接参数配置
|
||||
protected $config = [
|
||||
// 数据库类型
|
||||
'type' => '',
|
||||
'type' => '',
|
||||
// 服务器地址
|
||||
'hostname' => '',
|
||||
'hostname' => '',
|
||||
// 数据库名
|
||||
'database' => '',
|
||||
'database' => '',
|
||||
// 用户名
|
||||
'username' => '',
|
||||
'username' => '',
|
||||
// 密码
|
||||
'password' => '',
|
||||
'password' => '',
|
||||
// 端口
|
||||
'hostport' => '',
|
||||
'hostport' => '',
|
||||
// 连接dsn
|
||||
'dsn' => '',
|
||||
'dsn' => '',
|
||||
// 数据库连接参数
|
||||
'params' => [],
|
||||
'params' => [],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8',
|
||||
'charset' => 'utf8',
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
'prefix' => '',
|
||||
// 数据库调试模式
|
||||
'debug' => false,
|
||||
'debug' => false,
|
||||
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
||||
'deploy' => 0,
|
||||
'deploy' => 0,
|
||||
// 数据库读写是否分离 主从式有效
|
||||
'rw_separate' => false,
|
||||
'rw_separate' => false,
|
||||
// 读写分离后 主服务器数量
|
||||
'master_num' => 1,
|
||||
'master_num' => 1,
|
||||
// 指定从服务器序号
|
||||
'slave_no' => '',
|
||||
'slave_no' => '',
|
||||
// 是否严格检查字段是否存在
|
||||
'fields_strict' => true,
|
||||
'fields_strict' => true,
|
||||
// 数据集返回类型
|
||||
'resultset_type' => 'array',
|
||||
'resultset_type' => 'array',
|
||||
// 自动写入时间戳字段
|
||||
'auto_timestamp' => false,
|
||||
'auto_timestamp' => false,
|
||||
// 时间字段取出后的默认时间格式
|
||||
'datetime_format' => 'Y-m-d H:i:s',
|
||||
// 是否需要进行SQL性能分析
|
||||
'sql_explain' => false,
|
||||
'sql_explain' => false,
|
||||
// Builder类
|
||||
'builder' => '',
|
||||
'builder' => '',
|
||||
// Query类
|
||||
'query' => '\\think\\db\\Query',
|
||||
'query' => '\\think\\db\\Query',
|
||||
];
|
||||
|
||||
// PDO连接参数
|
||||
@@ -136,11 +137,11 @@ abstract class Connection
|
||||
* @param string $queryClass 查询对象类名
|
||||
* @return Query
|
||||
*/
|
||||
public function model($model, $queryClass = '')
|
||||
public function getQuery($model = 'db', $queryClass = '')
|
||||
{
|
||||
if (!isset($this->query[$model])) {
|
||||
$class = $queryClass ?: $this->config['query'];
|
||||
$this->query[$model] = new $class($this, $model);
|
||||
$this->query[$model] = new $class($this, 'db' == $model ? '' : $model);
|
||||
}
|
||||
return $this->query[$model];
|
||||
}
|
||||
@@ -154,11 +155,7 @@ abstract class Connection
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
if (!isset($this->query['database'])) {
|
||||
$class = $this->config['query'];
|
||||
$this->query['database'] = new $class($this);
|
||||
}
|
||||
return call_user_func_array([$this->query['database'], $method], $args);
|
||||
return call_user_func_array([$this->getQuery(), $method], $args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,8 +16,6 @@ use think\Cache;
|
||||
use think\Collection;
|
||||
use think\Config;
|
||||
use think\Db;
|
||||
use think\db\Builder;
|
||||
use think\db\Connection;
|
||||
use think\db\exception\BindParamException;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
@@ -27,8 +25,7 @@ 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\model\relation\OneToOne;
|
||||
use think\Paginator;
|
||||
|
||||
class Query
|
||||
@@ -1182,7 +1179,14 @@ class Query
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->options['order'] = $field;
|
||||
if (!isset($this->options['order'])) {
|
||||
$this->options['order'] = [];
|
||||
}
|
||||
if (is_array($field)) {
|
||||
$this->options['order'] = array_merge($this->options['order'], $field);
|
||||
} else {
|
||||
$this->options['order'][] = $field;
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
@@ -1552,7 +1556,7 @@ class Query
|
||||
*/
|
||||
protected function getFieldBindType($type)
|
||||
{
|
||||
if (preg_match('/(int|double|float|decimal|real|numeric|serial)/is', $type)) {
|
||||
if (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) {
|
||||
$bind = PDO::PARAM_INT;
|
||||
} elseif (preg_match('/bool/is', $type)) {
|
||||
$bind = PDO::PARAM_BOOL;
|
||||
@@ -1653,8 +1657,9 @@ class Query
|
||||
}
|
||||
|
||||
/** @var Relation $model */
|
||||
$model = $class->$relation();
|
||||
if ($model instanceof HasOne || $model instanceof BelongsTo) {
|
||||
$relation = Loader::parseName($relation, 1, false);
|
||||
$model = $class->$relation();
|
||||
if ($model instanceof OneToOne && 0 == $model->getEagerlyType()) {
|
||||
$model->eagerly($this, $relation, $subRelation, $closure, $first);
|
||||
$first = false;
|
||||
} elseif ($closure) {
|
||||
@@ -1666,6 +1671,36 @@ class Query
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联统计
|
||||
* @access public
|
||||
* @param string|array $relation 关联方法名
|
||||
* @param bool $subQuery 是否使用子查询
|
||||
* @return $this
|
||||
*/
|
||||
public function withCount($relation, $subQuery = true)
|
||||
{
|
||||
if (!$subQuery) {
|
||||
$this->options['with_count'] = $relation;
|
||||
} else {
|
||||
$relations = is_string($relation) ? explode(',', $relation) : $relation;
|
||||
if (!isset($this->options['field'])) {
|
||||
$this->field('*');
|
||||
}
|
||||
foreach ($relations as $key => $relation) {
|
||||
$closure = false;
|
||||
if ($relation instanceof \Closure) {
|
||||
$closure = $relation;
|
||||
$relation = $key;
|
||||
}
|
||||
$relation = Loader::parseName($relation, 1, false);
|
||||
$count = '(' . (new $this->model)->$relation()->getRelationCountQuery($closure) . ')';
|
||||
$this->field([$count => Loader::parseName($relation) . '_count']);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联预加载中 获取关联指定字段值
|
||||
* example:
|
||||
@@ -1997,6 +2032,10 @@ class Query
|
||||
if (!empty($options['relation'])) {
|
||||
$result->relationQuery($options['relation']);
|
||||
}
|
||||
// 关联统计
|
||||
if (!empty($options['with_count'])) {
|
||||
$result->relationCount($result, $options['with_count']);
|
||||
}
|
||||
$resultSet[$key] = $result;
|
||||
}
|
||||
if (!empty($options['with'])) {
|
||||
@@ -2095,10 +2134,14 @@ class Query
|
||||
if (!empty($options['relation'])) {
|
||||
$data->relationQuery($options['relation']);
|
||||
}
|
||||
// 预载入查询
|
||||
if (!empty($options['with'])) {
|
||||
// 预载入
|
||||
$data->eagerlyResult($data, $options['with'], is_object($result) ? get_class($result) : '');
|
||||
}
|
||||
// 关联统计
|
||||
if (!empty($options['with_count'])) {
|
||||
$data->relationCount($data, $options['with_count']);
|
||||
}
|
||||
}
|
||||
} elseif (!empty($options['fail'])) {
|
||||
$this->throwNotFound($options);
|
||||
|
||||
@@ -16,7 +16,7 @@ use think\exception\DbException;
|
||||
/**
|
||||
* PDO参数绑定异常
|
||||
*/
|
||||
class BindParamException extends DbException
|
||||
class BindParamException extends DbException
|
||||
{
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace think\db\exception;
|
||||
|
||||
use think\exception\DbException;
|
||||
|
||||
class DataNotFoundException extends DbException
|
||||
class DataNotFoundException extends DbException
|
||||
{
|
||||
protected $table;
|
||||
|
||||
@@ -23,10 +23,10 @@ class DataNotFoundException extends DbException
|
||||
* @param string $table
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct($message, $table = '', Array $config = [])
|
||||
public function __construct($message, $table = '', array $config = [])
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->table = $table;
|
||||
$this->message = $message;
|
||||
$this->table = $table;
|
||||
|
||||
$this->setData('Database Config', $config);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace think\db\exception;
|
||||
|
||||
use think\exception\DbException;
|
||||
|
||||
class ModelNotFoundException extends DbException
|
||||
class ModelNotFoundException extends DbException
|
||||
{
|
||||
protected $model;
|
||||
|
||||
@@ -22,10 +22,10 @@ class ModelNotFoundException extends DbException
|
||||
* @param string $message
|
||||
* @param string $model
|
||||
*/
|
||||
public function __construct($message, $model = '', Array $config = [])
|
||||
public function __construct($message, $model = '', array $config = [])
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->model = $model;
|
||||
$this->message = $message;
|
||||
$this->model = $model;
|
||||
|
||||
$this->setData('Database Config', $config);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user