2020-11-03 21:02:24 +08:00

140 lines
4.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php /** @noinspection PhpComposerExtensionStubsInspection */
namespace ZM\DB;
use Exception;
use ZM\Config\ZMConfig;
use ZM\Console\Console;
use ZM\Store\MySQL\SqlPoolStorage;
use PDOException;
use PDOStatement;
use Swoole\Database\PDOStatementProxy;
use ZM\Exception\DbException;
class DB
{
private static $table_list = [];
/**
* @throws DbException
* @throws Exception
*/
public static function initTableList() {
if (!extension_loaded("mysqlnd")) throw new Exception("Can not find mysqlnd PHP extension.");
$result = self::rawQuery("select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='" . ZMConfig::get("global", "sql_config")["sql_database"] . "';", []);
foreach ($result as $v) {
self::$table_list[] = $v['TABLE_NAME'];
}
}
/**
* @param $table_name
* @param bool $enable_cache
* @return Table
* @throws DbException
*/
public static function table($table_name) {
if (Table::getTableInstance($table_name) === null) {
if (in_array($table_name, self::$table_list))
return new Table($table_name);
elseif(SqlPoolStorage::$sql_pool !== null){
throw new DbException("Table " . $table_name . " not exist in database.");
} else {
throw new DbException("Database connection not exist or connect failed. Please check sql configuration");
}
}
return Table::getTableInstance($table_name);
}
/**
* @param $line
* @throws DbException
*/
public static function statement($line) {
self::rawQuery($line, []);
}
/**
* @param $line
* @return bool
* @throws DbException
*/
public static function unprepared($line) {
try {
$conn = SqlPoolStorage::$sql_pool->get();
if ($conn === false) {
SqlPoolStorage::$sql_pool->put(null);
throw new DbException("无法连接SQL" . $line);
}
$result = $conn->query($line) === false ? false : true;
SqlPoolStorage::$sql_pool->put($conn);
return $result;
} catch (DBException $e) {
Console::warning($e->getMessage());
throw $e;
}
}
/**
* @param string $line
* @param array $params
* @param int $fetch_mode
* @return mixed
* @throws DbException
*/
public static function rawQuery(string $line, $params = [], $fetch_mode = ZM_DEFAULT_FETCH_MODE) {
Console::debug("MySQL: ".$line." | ". implode(", ", $params));
try {
$conn = SqlPoolStorage::$sql_pool->get();
if ($conn === false) {
SqlPoolStorage::$sql_pool->put(null);
throw new DbException("无法连接SQL" . $line);
}
$ps = $conn->prepare($line);
if ($ps === false) {
SqlPoolStorage::$sql_pool->put(null);
throw new DbException("SQL语句查询错误" . $line . ",错误信息:" . $conn->error);
} else {
if (!($ps instanceof PDOStatement) && !($ps instanceof PDOStatementProxy)) {
var_dump($ps);
SqlPoolStorage::$sql_pool->put(null);
throw new DbException("语句查询错误!返回的不是 PDOStatement" . $line);
}
if ($params == []) $result = $ps->execute();
elseif (!is_array($params)) {
$result = $ps->execute([$params]);
} else $result = $ps->execute($params);
if ($result !== true) {
SqlPoolStorage::$sql_pool->put(null);
throw new DBException("语句[$line]错误!" . $ps->errorInfo()[2]);
//echo json_encode(debug_backtrace(), 128 | 256);
}
SqlPoolStorage::$sql_pool->put($conn);
return $ps->fetchAll($fetch_mode);
}
} catch (DbException $e) {
if(mb_strpos($e->getMessage(), "has gone away") !== false) {
zm_sleep(0.2);
Console::warning("Gone away of MySQL! retrying!");
return self::rawQuery($line, $params);
}
Console::warning($e->getMessage());
throw $e;
} catch (PDOException $e) {
if(mb_strpos($e->getMessage(), "has gone away") !== false) {
zm_sleep(0.2);
Console::warning("Gone away of MySQL! retrying!");
return self::rawQuery($line, $params);
}
Console::warning($e->getMessage());
throw new DbException($e->getMessage(), $e->getCode(), $e);
}
}
public static function isTableExists($table) {
return in_array($table, self::$table_list);
}
}