内核更新

This commit is contained in:
2016-12-28 10:41:09 +08:00
parent c89254e12a
commit ffab826db0
65 changed files with 1194 additions and 610 deletions

View File

@@ -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]);

View File

@@ -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);
}
/**

View File

@@ -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);

View File

@@ -16,7 +16,7 @@ use think\exception\DbException;
/**
* PDO参数绑定异常
*/
class BindParamException extends DbException
class BindParamException extends DbException
{
/**

View File

@@ -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);
}

View File

@@ -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);
}