DbManager.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. declare(strict_types=1);
  12. namespace think;
  13. use InvalidArgumentException;
  14. use Psr\Log\LoggerInterface;
  15. use Psr\SimpleCache\CacheInterface;
  16. use think\db\BaseQuery;
  17. use think\db\ConnectionInterface;
  18. use think\db\Query;
  19. use think\db\Raw;
  20. /**
  21. * Class DbManager.
  22. *
  23. * @mixin BaseQuery
  24. * @mixin Query
  25. */
  26. class DbManager
  27. {
  28. /**
  29. * 数据库连接实例.
  30. *
  31. * @var array
  32. */
  33. protected $instance = [];
  34. /**
  35. * 数据库配置.
  36. *
  37. * @var array
  38. */
  39. protected $config = [];
  40. /**
  41. * Event对象或者数组.
  42. *
  43. * @var array|object
  44. */
  45. protected $event;
  46. /**
  47. * SQL监听.
  48. *
  49. * @var array
  50. */
  51. protected $listen = [];
  52. /**
  53. * SQL日志.
  54. *
  55. * @var array
  56. */
  57. protected $dbLog = [];
  58. /**
  59. * 查询次数.
  60. *
  61. * @var int
  62. */
  63. protected $queryTimes = 0;
  64. /**
  65. * 查询缓存对象
  66. *
  67. * @var CacheInterface
  68. */
  69. protected $cache;
  70. /**
  71. * 查询日志对象
  72. *
  73. * @var LoggerInterface
  74. */
  75. protected $log;
  76. /**
  77. * 架构函数.
  78. */
  79. public function __construct()
  80. {
  81. $this->modelMaker();
  82. }
  83. /**
  84. * 注入模型对象
  85. *
  86. * @return void
  87. */
  88. protected function modelMaker()
  89. {
  90. Model::setDb($this);
  91. if (is_object($this->event)) {
  92. Model::setEvent($this->event);
  93. }
  94. Model::maker(function (Model $model) {
  95. $isAutoWriteTimestamp = $model->getAutoWriteTimestamp();
  96. if (is_null($isAutoWriteTimestamp)) {
  97. // 自动写入时间戳
  98. $model->isAutoWriteTimestamp($this->getConfig('auto_timestamp', true));
  99. }
  100. $dateFormat = $model->getDateFormat();
  101. if (is_null($dateFormat)) {
  102. // 设置时间戳格式
  103. $model->setDateFormat($this->getConfig('datetime_format', 'Y-m-d H:i:s'));
  104. }
  105. });
  106. }
  107. /**
  108. * 监听SQL.
  109. *
  110. * @return void
  111. */
  112. public function triggerSql(): void
  113. {
  114. }
  115. /**
  116. * 初始化配置参数.
  117. *
  118. * @param array $config 连接配置
  119. *
  120. * @return void
  121. */
  122. public function setConfig($config): void
  123. {
  124. $this->config = $config;
  125. }
  126. /**
  127. * 设置缓存对象
  128. *
  129. * @param CacheInterface $cache 缓存对象
  130. *
  131. * @return void
  132. */
  133. public function setCache(CacheInterface $cache): void
  134. {
  135. $this->cache = $cache;
  136. }
  137. /**
  138. * 设置日志对象
  139. *
  140. * @param LoggerInterface $log 日志对象
  141. *
  142. * @return void
  143. */
  144. public function setLog(LoggerInterface $log): void
  145. {
  146. $this->log = $log;
  147. }
  148. /**
  149. * 记录SQL日志.
  150. *
  151. * @param string $log SQL日志信息
  152. * @param string $type 日志类型
  153. *
  154. * @return void
  155. */
  156. public function log(string $log, string $type = 'sql')
  157. {
  158. if ($this->log) {
  159. $this->log->log($type, $log);
  160. } else {
  161. $this->dbLog[$type][] = $log;
  162. }
  163. }
  164. /**
  165. * 获得查询日志(没有设置日志对象使用).
  166. *
  167. * @param bool $clear 是否清空
  168. *
  169. * @return array
  170. */
  171. public function getDbLog(bool $clear = false): array
  172. {
  173. $logs = $this->dbLog;
  174. if ($clear) {
  175. $this->dbLog = [];
  176. }
  177. return $logs;
  178. }
  179. /**
  180. * 获取配置参数.
  181. *
  182. * @param string $name 配置参数
  183. * @param mixed $default 默认值
  184. *
  185. * @return mixed
  186. */
  187. public function getConfig(string $name = '', $default = null)
  188. {
  189. if ('' === $name) {
  190. return $this->config;
  191. }
  192. return $this->config[$name] ?? $default;
  193. }
  194. /**
  195. * 创建/切换数据库连接查询.
  196. *
  197. * @param string|null $name 连接配置标识
  198. * @param bool $force 强制重新连接
  199. *
  200. * @return ConnectionInterface
  201. */
  202. public function connect(string $name = null, bool $force = false)
  203. {
  204. return $this->instance($name, $force);
  205. }
  206. /**
  207. * 创建数据库连接实例.
  208. *
  209. * @param string|null $name 连接标识
  210. * @param bool $force 强制重新连接
  211. *
  212. * @return ConnectionInterface
  213. */
  214. protected function instance(string $name = null, bool $force = false): ConnectionInterface
  215. {
  216. if (empty($name)) {
  217. $name = $this->getConfig('default', 'mysql');
  218. }
  219. if ($force || !isset($this->instance[$name])) {
  220. $this->instance[$name] = $this->createConnection($name);
  221. }
  222. return $this->instance[$name];
  223. }
  224. /**
  225. * 获取连接配置.
  226. *
  227. * @param string $name
  228. *
  229. * @return array
  230. */
  231. protected function getConnectionConfig(string $name): array
  232. {
  233. $connections = $this->getConfig('connections');
  234. if (!isset($connections[$name])) {
  235. throw new InvalidArgumentException('Undefined db config:' . $name);
  236. }
  237. return $connections[$name];
  238. }
  239. /**
  240. * 创建连接.
  241. *
  242. * @param $name
  243. *
  244. * @return ConnectionInterface
  245. */
  246. protected function createConnection(string $name): ConnectionInterface
  247. {
  248. $config = $this->getConnectionConfig($name);
  249. $type = !empty($config['type']) ? $config['type'] : 'mysql';
  250. if (str_contains($type, '\\')) {
  251. $class = $type;
  252. } else {
  253. $class = '\\think\\db\\connector\\' . ucfirst($type);
  254. }
  255. /** @var ConnectionInterface $connection */
  256. $connection = new $class($config);
  257. $connection->setDb($this);
  258. if ($this->cache) {
  259. $connection->setCache($this->cache);
  260. }
  261. return $connection;
  262. }
  263. /**
  264. * 使用表达式设置数据.
  265. *
  266. * @param string $value 表达式
  267. *
  268. * @return Raw
  269. */
  270. public function raw(string $value): Raw
  271. {
  272. return new Raw($value);
  273. }
  274. /**
  275. * 更新查询次数.
  276. *
  277. * @return void
  278. */
  279. public function updateQueryTimes(): void
  280. {
  281. $this->queryTimes++;
  282. }
  283. /**
  284. * 重置查询次数.
  285. *
  286. * @return void
  287. */
  288. public function clearQueryTimes(): void
  289. {
  290. $this->queryTimes = 0;
  291. }
  292. /**
  293. * 获得查询次数.
  294. *
  295. * @return int
  296. */
  297. public function getQueryTimes(): int
  298. {
  299. return $this->queryTimes;
  300. }
  301. /**
  302. * 监听SQL执行.
  303. *
  304. * @param callable $callback 回调方法
  305. *
  306. * @return void
  307. */
  308. public function listen(callable $callback): void
  309. {
  310. $this->listen[] = $callback;
  311. }
  312. /**
  313. * 获取监听SQL执行.
  314. *
  315. * @return array
  316. */
  317. public function getListen(): array
  318. {
  319. return $this->listen;
  320. }
  321. /**
  322. * 获取所有连接实列.
  323. *
  324. * @return array
  325. */
  326. public function getInstance(): array
  327. {
  328. return $this->instance;
  329. }
  330. /**
  331. * 注册回调方法.
  332. *
  333. * @param string $event 事件名
  334. * @param callable $callback 回调方法
  335. *
  336. * @return void
  337. */
  338. public function event(string $event, callable $callback): void
  339. {
  340. $this->event[$event][] = $callback;
  341. }
  342. /**
  343. * 触发事件.
  344. *
  345. * @param string $event 事件名
  346. * @param mixed $params 传入参数
  347. *
  348. * @return mixed
  349. */
  350. public function trigger(string $event, $params = null)
  351. {
  352. if (isset($this->event[$event])) {
  353. foreach ($this->event[$event] as $callback) {
  354. call_user_func_array($callback, [$params]);
  355. }
  356. }
  357. }
  358. public function __call($method, $args)
  359. {
  360. return call_user_func_array([$this->connect(), $method], $args);
  361. }
  362. }