377 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
			
		
		
	
	
			377 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
| <?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
 | |
|      * @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);
 | |
|     }
 | |
| }
 |