387 lines
8.5 KiB
PHP
387 lines
8.5 KiB
PHP
<?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;
|
|
|
|
use InvalidArgumentException;
|
|
use Psr\Log\LoggerInterface;
|
|
use Psr\SimpleCache\CacheInterface;
|
|
use think\db\BaseQuery;
|
|
use think\db\ConnectionInterface;
|
|
use think\db\Query;
|
|
use think\db\Raw;
|
|
|
|
/**
|
|
* Class DbManager
|
|
* @package think
|
|
* @mixin BaseQuery
|
|
* @mixin Query
|
|
*/
|
|
class DbManager
|
|
{
|
|
/**
|
|
* 数据库连接实例
|
|
* @var array
|
|
*/
|
|
protected $instance = [];
|
|
|
|
/**
|
|
* 数据库配置
|
|
* @var array
|
|
*/
|
|
protected $config = [];
|
|
|
|
/**
|
|
* Event对象或者数组
|
|
* @var array|object
|
|
*/
|
|
protected $event;
|
|
|
|
/**
|
|
* SQL监听
|
|
* @var array
|
|
*/
|
|
protected $listen = [];
|
|
|
|
/**
|
|
* SQL日志
|
|
* @var array
|
|
*/
|
|
protected $dbLog = [];
|
|
|
|
/**
|
|
* 查询次数
|
|
* @var int
|
|
*/
|
|
protected $queryTimes = 0;
|
|
|
|
/**
|
|
* 查询缓存对象
|
|
* @var CacheInterface
|
|
*/
|
|
protected $cache;
|
|
|
|
/**
|
|
* 查询日志对象
|
|
* @var LoggerInterface
|
|
*/
|
|
protected $log;
|
|
|
|
/**
|
|
* 架构函数
|
|
* @access public
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->modelMaker();
|
|
}
|
|
|
|
/**
|
|
* 注入模型对象
|
|
* @access public
|
|
* @return void
|
|
*/
|
|
protected function modelMaker()
|
|
{
|
|
Model::setDb($this);
|
|
|
|
if (is_object($this->event)) {
|
|
Model::setEvent($this->event);
|
|
}
|
|
|
|
Model::maker(function (Model $model) {
|
|
$isAutoWriteTimestamp = $model->getAutoWriteTimestamp();
|
|
|
|
if (is_null($isAutoWriteTimestamp)) {
|
|
// 自动写入时间戳
|
|
$model->isAutoWriteTimestamp($this->getConfig('auto_timestamp', true));
|
|
}
|
|
|
|
$dateFormat = $model->getDateFormat();
|
|
|
|
if (is_null($dateFormat)) {
|
|
// 设置时间戳格式
|
|
$model->setDateFormat($this->getConfig('datetime_format', 'Y-m-d H:i:s'));
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 监听SQL
|
|
* @access protected
|
|
* @return void
|
|
*/
|
|
public function triggerSql(): void
|
|
{}
|
|
|
|
/**
|
|
* 初始化配置参数
|
|
* @access public
|
|
* @param array $config 连接配置
|
|
* @return void
|
|
*/
|
|
public function setConfig($config): void
|
|
{
|
|
$this->config = $config;
|
|
}
|
|
|
|
/**
|
|
* 设置缓存对象
|
|
* @access public
|
|
* @param CacheInterface $cache 缓存对象
|
|
* @return void
|
|
*/
|
|
public function setCache(CacheInterface $cache): void
|
|
{
|
|
$this->cache = $cache;
|
|
}
|
|
|
|
/**
|
|
* 设置日志对象
|
|
* @access public
|
|
* @param LoggerInterface $log 日志对象
|
|
* @return void
|
|
*/
|
|
public function setLog(LoggerInterface $log): void
|
|
{
|
|
$this->log = $log;
|
|
}
|
|
|
|
/**
|
|
* 记录SQL日志
|
|
* @access protected
|
|
* @param string $log SQL日志信息
|
|
* @param string $type 日志类型
|
|
* @return void
|
|
*/
|
|
public function log(string $log, string $type = 'sql')
|
|
{
|
|
if ($this->log) {
|
|
$this->log->log($type, $log);
|
|
} else {
|
|
$this->dbLog[$type][] = $log;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获得查询日志(没有设置日志对象使用)
|
|
* @access public
|
|
* @param bool $clear 是否清空
|
|
* @return array
|
|
*/
|
|
public function getDbLog(bool $clear = false): array
|
|
{
|
|
$logs = $this->dbLog;
|
|
if ($clear) {
|
|
$this->dbLog = [];
|
|
}
|
|
|
|
return $logs;
|
|
}
|
|
|
|
/**
|
|
* 获取配置参数
|
|
* @access public
|
|
* @param string $name 配置参数
|
|
* @param mixed $default 默认值
|
|
* @return mixed
|
|
*/
|
|
public function getConfig(string $name = '', $default = null)
|
|
{
|
|
if ('' === $name) {
|
|
return $this->config;
|
|
}
|
|
|
|
return $this->config[$name] ?? $default;
|
|
}
|
|
|
|
/**
|
|
* 创建/切换数据库连接查询
|
|
* @access public
|
|
* @param string|null $name 连接配置标识
|
|
* @param bool $force 强制重新连接
|
|
* @return ConnectionInterface
|
|
*/
|
|
public function connect(string $name = null, bool $force = false)
|
|
{
|
|
return $this->instance($name, $force);
|
|
}
|
|
|
|
/**
|
|
* 创建数据库连接实例
|
|
* @access protected
|
|
* @param string|null $name 连接标识
|
|
* @param bool $force 强制重新连接
|
|
* @return ConnectionInterface
|
|
*/
|
|
protected function instance(string $name = null, bool $force = false): ConnectionInterface
|
|
{
|
|
if (empty($name)) {
|
|
$name = $this->getConfig('default', 'mysql');
|
|
}
|
|
|
|
if ($force || !isset($this->instance[$name])) {
|
|
$this->instance[$name] = $this->createConnection($name);
|
|
}
|
|
|
|
return $this->instance[$name];
|
|
}
|
|
|
|
/**
|
|
* 获取连接配置
|
|
* @param string $name
|
|
* @return array
|
|
*/
|
|
protected function getConnectionConfig(string $name): array
|
|
{
|
|
$connections = $this->getConfig('connections');
|
|
if (!isset($connections[$name])) {
|
|
throw new InvalidArgumentException('Undefined db config:' . $name);
|
|
}
|
|
|
|
return $connections[$name];
|
|
}
|
|
|
|
/**
|
|
* 创建连接
|
|
* @param $name
|
|
* @return ConnectionInterface
|
|
*/
|
|
protected function createConnection(string $name): ConnectionInterface
|
|
{
|
|
$config = $this->getConnectionConfig($name);
|
|
|
|
$type = !empty($config['type']) ? $config['type'] : 'mysql';
|
|
|
|
if (false !== strpos($type, '\\')) {
|
|
$class = $type;
|
|
} else {
|
|
$class = '\\think\\db\\connector\\' . ucfirst($type);
|
|
}
|
|
|
|
/** @var ConnectionInterface $connection */
|
|
$connection = new $class($config);
|
|
$connection->setDb($this);
|
|
|
|
if ($this->cache) {
|
|
$connection->setCache($this->cache);
|
|
}
|
|
|
|
return $connection;
|
|
}
|
|
|
|
/**
|
|
* 使用表达式设置数据
|
|
* @access public
|
|
* @param string $value 表达式
|
|
* @return Raw
|
|
*/
|
|
public function raw(string $value): Raw
|
|
{
|
|
return new Raw($value);
|
|
}
|
|
|
|
/**
|
|
* 更新查询次数
|
|
* @access public
|
|
* @return void
|
|
*/
|
|
public function updateQueryTimes(): void
|
|
{
|
|
$this->queryTimes++;
|
|
}
|
|
|
|
/**
|
|
* 重置查询次数
|
|
* @access public
|
|
* @return void
|
|
*/
|
|
public function clearQueryTimes(): void
|
|
{
|
|
$this->queryTimes = 0;
|
|
}
|
|
|
|
/**
|
|
* 获得查询次数
|
|
* @access public
|
|
* @return integer
|
|
*/
|
|
public function getQueryTimes(): int
|
|
{
|
|
return $this->queryTimes;
|
|
}
|
|
|
|
/**
|
|
* 监听SQL执行
|
|
* @access public
|
|
* @param callable $callback 回调方法
|
|
* @return void
|
|
*/
|
|
public function listen(callable $callback): void
|
|
{
|
|
$this->listen[] = $callback;
|
|
}
|
|
|
|
/**
|
|
* 获取监听SQL执行
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function getListen(): array
|
|
{
|
|
return $this->listen;
|
|
}
|
|
|
|
/**
|
|
* 获取所有连接实列
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function getInstance(): array
|
|
{
|
|
return $this->instance;
|
|
}
|
|
|
|
/**
|
|
* 注册回调方法
|
|
* @access public
|
|
* @param string $event 事件名
|
|
* @param callable $callback 回调方法
|
|
* @return void
|
|
*/
|
|
public function event(string $event, callable $callback): void
|
|
{
|
|
$this->event[$event][] = $callback;
|
|
}
|
|
|
|
/**
|
|
* 触发事件
|
|
* @access public
|
|
* @param string $event 事件名
|
|
* @param mixed $params 传入参数
|
|
* @return mixed
|
|
*/
|
|
public function trigger(string $event, $params = null)
|
|
{
|
|
if (isset($this->event[$event])) {
|
|
foreach ($this->event[$event] as $callback) {
|
|
call_user_func_array($callback, [$params]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function __call($method, $args)
|
|
{
|
|
return call_user_func_array([$this->connect(), $method], $args);
|
|
}
|
|
}
|