2022-03-15 18:05:33 +08:00
|
|
|
|
<?php
|
2021-03-18 14:56:35 +08:00
|
|
|
|
|
|
|
|
|
|
/** @noinspection PhpComposerExtensionStubsInspection */
|
2020-03-02 16:14:20 +08:00
|
|
|
|
|
2022-03-15 18:05:33 +08:00
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
|
|
/** @noinspection PhpUnused */
|
2020-03-02 16:14:20 +08:00
|
|
|
|
|
|
|
|
|
|
namespace ZM\DB;
|
|
|
|
|
|
|
2020-05-31 14:22:39 +08:00
|
|
|
|
use PDOException;
|
2020-03-02 16:14:20 +08:00
|
|
|
|
use ZM\Exception\DbException;
|
2022-03-15 18:05:33 +08:00
|
|
|
|
use ZM\MySQL\MySQLManager;
|
|
|
|
|
|
use ZM\Store\MySQL\SqlPoolStorage;
|
2020-03-02 16:14:20 +08:00
|
|
|
|
|
2021-07-09 01:38:30 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* Class DB
|
|
|
|
|
|
* @deprecated This will delete in 2.6 or future version, use \ZM\MySQL\MySQLManager::getConnection() instead
|
|
|
|
|
|
*/
|
2020-03-02 16:14:20 +08:00
|
|
|
|
class DB
|
|
|
|
|
|
{
|
|
|
|
|
|
private static $table_list = [];
|
|
|
|
|
|
|
2020-04-29 15:29:56 +08:00
|
|
|
|
/**
|
2022-04-02 23:37:22 +08:00
|
|
|
|
* @param string $db_name 数据库名称
|
2020-04-29 15:29:56 +08:00
|
|
|
|
* @throws DbException
|
|
|
|
|
|
*/
|
2022-04-02 23:37:22 +08:00
|
|
|
|
public static function initTableList(string $db_name)
|
2022-03-15 18:05:33 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (!extension_loaded('mysqlnd')) {
|
|
|
|
|
|
throw new DbException('Can not find mysqlnd PHP extension.');
|
|
|
|
|
|
}
|
|
|
|
|
|
$result = MySQLManager::getWrapper()->fetchAllAssociative('select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA=?;', [$db_name]);
|
2020-03-02 16:14:20 +08:00
|
|
|
|
foreach ($result as $v) {
|
|
|
|
|
|
self::$table_list[] = $v['TABLE_NAME'];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2022-04-02 23:37:22 +08:00
|
|
|
|
* @param string $table_name 表名
|
2020-03-02 16:14:20 +08:00
|
|
|
|
* @throws DbException
|
2022-04-02 23:37:22 +08:00
|
|
|
|
* @return Table 返回表对象
|
2020-03-02 16:14:20 +08:00
|
|
|
|
*/
|
2022-04-02 23:37:22 +08:00
|
|
|
|
public static function table(string $table_name): Table
|
2022-03-15 18:05:33 +08:00
|
|
|
|
{
|
2020-03-02 16:14:20 +08:00
|
|
|
|
if (Table::getTableInstance($table_name) === null) {
|
2022-03-15 18:05:33 +08:00
|
|
|
|
if (in_array($table_name, self::$table_list)) {
|
2020-11-03 21:02:24 +08:00
|
|
|
|
return new Table($table_name);
|
2020-03-02 16:14:20 +08:00
|
|
|
|
}
|
2022-03-15 18:05:33 +08:00
|
|
|
|
if (SqlPoolStorage::$sql_pool !== null) {
|
|
|
|
|
|
throw new DbException('Table ' . $table_name . ' not exist in database.');
|
|
|
|
|
|
}
|
|
|
|
|
|
throw new DbException('Database connection not exist or connect failed. Please check sql configuration');
|
2020-03-02 16:14:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
return Table::getTableInstance($table_name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-29 15:29:56 +08:00
|
|
|
|
/**
|
2022-04-02 23:37:22 +08:00
|
|
|
|
* @param string $line SQL语句
|
2020-04-29 15:29:56 +08:00
|
|
|
|
* @throws DbException
|
|
|
|
|
|
*/
|
2022-04-02 23:37:22 +08:00
|
|
|
|
public static function statement(string $line)
|
2022-03-15 18:05:33 +08:00
|
|
|
|
{
|
2020-03-02 16:14:20 +08:00
|
|
|
|
self::rawQuery($line, []);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-29 15:29:56 +08:00
|
|
|
|
/**
|
2022-04-02 23:37:22 +08:00
|
|
|
|
* @param string $line SQL语句
|
|
|
|
|
|
* @return bool 返回查询是否成功的结果
|
2020-04-29 15:29:56 +08:00
|
|
|
|
*/
|
2022-04-02 23:37:22 +08:00
|
|
|
|
public static function unprepared(string $line): bool
|
2022-03-15 18:05:33 +08:00
|
|
|
|
{
|
2022-04-02 23:37:22 +08:00
|
|
|
|
$conn = SqlPoolStorage::$sql_pool->getConnection();
|
|
|
|
|
|
$result = !($conn->query($line) === false);
|
|
|
|
|
|
SqlPoolStorage::$sql_pool->putConnection($conn);
|
|
|
|
|
|
return $result;
|
2020-03-02 16:14:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-04-02 23:37:22 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @param string $line SQL语句
|
|
|
|
|
|
* @param array $params 查询参数
|
|
|
|
|
|
* @param int $fetch_mode fetch规则
|
|
|
|
|
|
* @throws DbException
|
|
|
|
|
|
* @return array|false 返回结果集或false
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function rawQuery(string $line, array $params = [], int $fetch_mode = ZM_DEFAULT_FETCH_MODE)
|
2022-03-15 18:05:33 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (!is_array($params)) {
|
|
|
|
|
|
$params = [$params];
|
|
|
|
|
|
}
|
2022-06-08 23:11:17 +08:00
|
|
|
|
logger()->debug('MySQL: ' . $line . ' | ' . implode(', ', $params));
|
2020-03-02 16:14:20 +08:00
|
|
|
|
try {
|
2022-03-15 18:05:33 +08:00
|
|
|
|
if (SqlPoolStorage::$sql_pool === null) {
|
|
|
|
|
|
throw new DbException('未连接到任何数据库!');
|
|
|
|
|
|
}
|
2021-07-09 01:38:30 +08:00
|
|
|
|
$conn = SqlPoolStorage::$sql_pool->getConnection();
|
2020-03-02 16:14:20 +08:00
|
|
|
|
$ps = $conn->prepare($line);
|
|
|
|
|
|
if ($ps === false) {
|
2021-07-09 01:38:30 +08:00
|
|
|
|
SqlPoolStorage::$sql_pool->putConnection(null);
|
2022-04-02 23:37:22 +08:00
|
|
|
|
throw new DbException('SQL语句查询错误,' . $line . ',错误信息:' . $conn->errorInfo()[2]);
|
2020-03-02 16:14:20 +08:00
|
|
|
|
}
|
2022-03-15 18:05:33 +08:00
|
|
|
|
if ($params == []) {
|
|
|
|
|
|
$result = $ps->execute();
|
|
|
|
|
|
} elseif (!is_array($params)) {
|
|
|
|
|
|
$result = $ps->execute([$params]);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$result = $ps->execute($params);
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($result !== true) {
|
|
|
|
|
|
SqlPoolStorage::$sql_pool->putConnection(null);
|
|
|
|
|
|
throw new DBException("语句[{$line}]错误!" . $ps->errorInfo()[2]);
|
2022-03-20 16:23:07 +08:00
|
|
|
|
// echo json_encode(debug_backtrace(), 128 | 256);
|
2022-03-15 18:05:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
SqlPoolStorage::$sql_pool->putConnection($conn);
|
|
|
|
|
|
return $ps->fetchAll($fetch_mode);
|
2020-05-31 14:22:39 +08:00
|
|
|
|
} catch (DbException $e) {
|
2022-03-15 18:05:33 +08:00
|
|
|
|
if (mb_strpos($e->getMessage(), 'has gone away') !== false) {
|
2022-04-02 23:37:22 +08:00
|
|
|
|
zm_sleep();
|
2022-06-08 23:11:17 +08:00
|
|
|
|
logger()->warning('Gone away of MySQL! retrying!');
|
2020-05-23 17:23:29 +08:00
|
|
|
|
return self::rawQuery($line, $params);
|
|
|
|
|
|
}
|
2022-06-08 23:11:17 +08:00
|
|
|
|
logger()->warning($e->getMessage());
|
2020-04-29 15:29:56 +08:00
|
|
|
|
throw $e;
|
2020-05-31 14:22:39 +08:00
|
|
|
|
} catch (PDOException $e) {
|
2022-03-15 18:05:33 +08:00
|
|
|
|
if (mb_strpos($e->getMessage(), 'has gone away') !== false) {
|
2022-04-02 23:37:22 +08:00
|
|
|
|
zm_sleep();
|
2022-06-08 23:11:17 +08:00
|
|
|
|
logger()->warning('Gone away of MySQL! retrying!');
|
2020-05-31 14:22:39 +08:00
|
|
|
|
return self::rawQuery($line, $params);
|
|
|
|
|
|
}
|
2022-06-08 23:11:17 +08:00
|
|
|
|
logger()->warning($e->getMessage());
|
2020-05-31 14:22:39 +08:00
|
|
|
|
throw new DbException($e->getMessage(), $e->getCode(), $e);
|
2020-03-02 16:14:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-04-26 15:01:18 +08:00
|
|
|
|
|
2022-03-15 18:05:33 +08:00
|
|
|
|
public static function isTableExists($table): bool
|
|
|
|
|
|
{
|
2020-04-26 15:01:18 +08:00
|
|
|
|
return in_array($table, self::$table_list);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|