140 lines
4.8 KiB
PHP
Raw Normal View History

2020-10-03 23:00:18 +08:00
<?php /** @noinspection PhpComposerExtensionStubsInspection */
2020-03-02 16:14:20 +08:00
namespace ZM\DB;
use Exception;
2020-08-31 10:11:06 +08:00
use ZM\Config\ZMConfig;
use ZM\Console\Console;
2020-11-03 21:02:24 +08:00
use ZM\Store\MySQL\SqlPoolStorage;
use PDOException;
use PDOStatement;
2020-05-23 17:23:29 +08:00
use Swoole\Database\PDOStatementProxy;
2020-03-02 16:14:20 +08:00
use ZM\Exception\DbException;
class DB
{
private static $table_list = [];
/**
* @throws DbException
* @throws Exception
*/
2020-03-02 16:14:20 +08:00
public static function initTableList() {
if (!extension_loaded("mysqlnd")) throw new Exception("Can not find mysqlnd PHP extension.");
2020-08-31 10:11:06 +08:00
$result = self::rawQuery("select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='" . ZMConfig::get("global", "sql_config")["sql_database"] . "';", []);
2020-03-02 16:14:20 +08:00
foreach ($result as $v) {
self::$table_list[] = $v['TABLE_NAME'];
}
}
/**
* @param $table_name
* @param bool $enable_cache
* @return Table
* @throws DbException
*/
2020-11-03 21:02:24 +08:00
public static function table($table_name) {
2020-03-02 16:14:20 +08:00
if (Table::getTableInstance($table_name) === null) {
if (in_array($table_name, self::$table_list))
2020-11-03 21:02:24 +08:00
return new Table($table_name);
elseif(SqlPoolStorage::$sql_pool !== null){
2020-03-02 16:14:20 +08:00
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
*/
2020-03-02 16:14:20 +08:00
public static function statement($line) {
self::rawQuery($line, []);
}
/**
* @param $line
* @return bool
* @throws DbException
*/
2020-03-02 16:14:20 +08:00
public static function unprepared($line) {
try {
2020-11-03 21:02:24 +08:00
$conn = SqlPoolStorage::$sql_pool->get();
2020-03-02 16:14:20 +08:00
if ($conn === false) {
2020-11-03 21:02:24 +08:00
SqlPoolStorage::$sql_pool->put(null);
2020-03-02 16:14:20 +08:00
throw new DbException("无法连接SQL" . $line);
}
2020-05-23 17:23:29 +08:00
$result = $conn->query($line) === false ? false : true;
2020-11-03 21:02:24 +08:00
SqlPoolStorage::$sql_pool->put($conn);
2020-03-02 16:14:20 +08:00
return $result;
} catch (DBException $e) {
Console::warning($e->getMessage());
throw $e;
2020-03-02 16:14:20 +08:00
}
}
/**
* @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) {
2020-08-31 10:11:06 +08:00
Console::debug("MySQL: ".$line." | ". implode(", ", $params));
2020-03-02 16:14:20 +08:00
try {
2020-11-03 21:02:24 +08:00
$conn = SqlPoolStorage::$sql_pool->get();
2020-03-02 16:14:20 +08:00
if ($conn === false) {
2020-11-03 21:02:24 +08:00
SqlPoolStorage::$sql_pool->put(null);
2020-03-02 16:14:20 +08:00
throw new DbException("无法连接SQL" . $line);
}
$ps = $conn->prepare($line);
if ($ps === false) {
2020-11-03 21:02:24 +08:00
SqlPoolStorage::$sql_pool->put(null);
2020-03-02 16:14:20 +08:00
throw new DbException("SQL语句查询错误" . $line . ",错误信息:" . $conn->error);
} else {
2020-05-23 17:23:29 +08:00
if (!($ps instanceof PDOStatement) && !($ps instanceof PDOStatementProxy)) {
var_dump($ps);
2020-11-03 21:02:24 +08:00
SqlPoolStorage::$sql_pool->put(null);
2020-05-23 17:23:29 +08:00
throw new DbException("语句查询错误!返回的不是 PDOStatement" . $line);
2020-03-02 16:14:20 +08:00
}
if ($params == []) $result = $ps->execute();
elseif (!is_array($params)) {
$result = $ps->execute([$params]);
} else $result = $ps->execute($params);
if ($result !== true) {
2020-11-03 21:02:24 +08:00
SqlPoolStorage::$sql_pool->put(null);
throw new DBException("语句[$line]错误!" . $ps->errorInfo()[2]);
2020-03-02 16:14:20 +08:00
//echo json_encode(debug_backtrace(), 128 | 256);
}
2020-11-03 21:02:24 +08:00
SqlPoolStorage::$sql_pool->put($conn);
return $ps->fetchAll($fetch_mode);
2020-03-02 16:14:20 +08:00
}
} catch (DbException $e) {
2020-05-23 17:23:29 +08:00
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);
2020-03-02 16:14:20 +08:00
}
}
2020-04-26 15:01:18 +08:00
public static function isTableExists($table) {
return in_array($table, self::$table_list);
}
}