2020-10-03 23:00:18 +08:00
< ? php /** @noinspection PhpComposerExtensionStubsInspection */
2020-03-02 16:14:20 +08:00
namespace ZM\DB ;
2020-05-10 14:11:32 +08:00
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 ;
2020-05-31 14:22:39 +08:00
use PDOException ;
2020-05-10 14:11:32 +08:00
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 = [];
2020-04-29 15:29:56 +08:00
/**
* @ throws DbException
2020-05-10 14:11:32 +08:00
* @ throws Exception
2020-04-29 15:29:56 +08:00
*/
2020-03-02 16:14:20 +08:00
public static function initTableList () {
2020-05-10 14:11:32 +08:00
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 );
}
2020-04-29 15:29:56 +08:00
/**
* @ param $line
* @ throws DbException
*/
2020-03-02 16:14:20 +08:00
public static function statement ( $line ) {
self :: rawQuery ( $line , []);
}
2020-04-29 15:29:56 +08:00
/**
* @ 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 ) {
2020-04-29 15:29:56 +08:00
Console :: warning ( $e -> getMessage ());
throw $e ;
2020-03-02 16:14:20 +08:00
}
}
2020-04-29 15:29:56 +08:00
/**
* @ param string $line
* @ param array $params
2020-06-15 19:50:07 +08:00
* @ param int $fetch_mode
2020-04-29 15:29:56 +08:00
* @ return mixed
* @ throws DbException
*/
2020-06-15 19:50:07 +08:00
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 );
2020-05-10 14:11:32 +08:00
if ( $result !== true ) {
2020-11-03 21:02:24 +08:00
SqlPoolStorage :: $sql_pool -> put ( null );
2020-05-10 14:11:32 +08:00
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 );
2020-06-15 19:50:07 +08:00
return $ps -> fetchAll ( $fetch_mode );
2020-03-02 16:14:20 +08:00
}
2020-05-31 14:22:39 +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 );
}
2020-04-29 15:29:56 +08:00
Console :: warning ( $e -> getMessage ());
throw $e ;
2020-05-31 14:22:39 +08:00
} 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 );
}
}