...
|
...
|
@@ -2,6 +2,9 @@ |
|
|
|
|
|
namespace Lib;
|
|
|
|
|
|
use Swoole\Database\PDOConfig;
|
|
|
use Swoole\Database\PDOPool;
|
|
|
|
|
|
/**
|
|
|
* db 池
|
|
|
* @author:dc
|
...
|
...
|
@@ -11,384 +14,43 @@ namespace Lib; |
|
|
*/
|
|
|
class DbPool {
|
|
|
|
|
|
/**
|
|
|
* @var \Lib\DbPool[]
|
|
|
*/
|
|
|
static $instance = [];
|
|
|
|
|
|
|
|
|
/**
|
|
|
* @var \PDO
|
|
|
*/
|
|
|
private $client;
|
|
|
use DbQuery;
|
|
|
|
|
|
/**
|
|
|
* @var
|
|
|
* @var \Swoole\Database\PDOPool
|
|
|
*/
|
|
|
private $cid;
|
|
|
static $pool = null;
|
|
|
|
|
|
public $lastTimer;
|
|
|
|
|
|
/**
|
|
|
* @return mixed
|
|
|
* @author:dc
|
|
|
* @time 2023/2/13 9:12
|
|
|
* 实例
|
|
|
* DbPool constructor.
|
|
|
*/
|
|
|
public function getClient(){
|
|
|
if(!$this->client){
|
|
|
$this->connect();
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
// 判断是否链接中
|
|
|
if($this->client->getAttribute(\PDO::ATTR_CONNECTION_STATUS)===false){
|
|
|
$this->connect();
|
|
|
}
|
|
|
}catch (\Throwable $e){
|
|
|
$this->connect();
|
|
|
}
|
|
|
|
|
|
$this->lastTimer = time();
|
|
|
return $this->client;
|
|
|
}
|
|
|
|
|
|
|
|
|
public function __construct($cid)
|
|
|
public function __construct()
|
|
|
{
|
|
|
$this->cid = $cid;
|
|
|
|
|
|
$this->connect();
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 连接sql
|
|
|
* @author:dc
|
|
|
* @time 2023/3/23 9:14
|
|
|
*/
|
|
|
public function connect(){
|
|
|
$this->lastTimer = time();
|
|
|
$tryNum = 0;
|
|
|
|
|
|
DBPOOLCONNECTFOR:
|
|
|
try {
|
|
|
$this->client = new \PDO(
|
|
|
'mysql:charset=utf8mb4;dbname='.DB_DATABASE.';host='.DB_HOST.';port='.DB_PORT,
|
|
|
DB_USER,
|
|
|
DB_PASSWORD,
|
|
|
[
|
|
|
if(!static::$pool){
|
|
|
$pdoconfig = (new PDOConfig)
|
|
|
->withHost(DB_HOST)
|
|
|
->withPort(DB_PORT)
|
|
|
->withDbName(DB_DATABASE)
|
|
|
->withCharset('utf8mb4')
|
|
|
->withUsername(DB_USER)
|
|
|
->withPassword(DB_PASSWORD)
|
|
|
->withOptions([
|
|
|
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
|
|
|
\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8mb4'",
|
|
|
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
|
|
]
|
|
|
);
|
|
|
}catch (\Throwable $e){
|
|
|
// 重新链接3次
|
|
|
if($tryNum < 3){
|
|
|
$tryNum++;
|
|
|
goto DBPOOLCONNECTFOR;
|
|
|
}
|
|
|
|
|
|
logs($e->getMessage().$e->getTraceAsString());
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 查询
|
|
|
* @param string|array $sql
|
|
|
* @return false|\PDOStatement
|
|
|
* @author:dc
|
|
|
* @time 2023/2/17 10:01
|
|
|
*/
|
|
|
private function query(string|array $sql){
|
|
|
if(is_array($sql)){
|
|
|
list($sql,$params) = $sql;
|
|
|
}else{
|
|
|
$params = null;
|
|
|
}
|
|
|
|
|
|
if(APP_DEBUG) {
|
|
|
$timer = microtime(true);
|
|
|
}
|
|
|
|
|
|
|
|
|
try {
|
|
|
$query = $this->getClient()->prepare($sql);
|
|
|
$ret = $query->execute($params);
|
|
|
}catch (\Throwable $e){
|
|
|
logs([
|
|
|
$sql,$params,
|
|
|
$e->getMessage(),
|
|
|
$e->getTraceAsString()
|
|
|
],
|
|
|
LOG_PATH.'/'.date('Y-m-d').'-sql.error.log'
|
|
|
);
|
|
|
$ret = false;
|
|
|
}
|
|
|
|
|
|
|
|
|
if(APP_DEBUG){
|
|
|
$timer2 = microtime(true);
|
|
|
|
|
|
// todo:: 记录日志,生产请注释
|
|
|
$sql = '['.substr(($timer2-$timer)*1000,0,6).'ms] '.$sql;
|
|
|
logs(
|
|
|
$params ? [$sql,$params] : $sql,
|
|
|
LOG_PATH.'/'.date('Y-m-d').'.sql.log'
|
|
|
);
|
|
|
}
|
|
|
|
|
|
if($ret){
|
|
|
return $query;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 更新数据
|
|
|
* @param string $table
|
|
|
* @param array $data
|
|
|
* @param string $where
|
|
|
* @param bool $timeauto
|
|
|
* @return int
|
|
|
* @author:dc
|
|
|
* @time 2023/2/17 14:03
|
|
|
*/
|
|
|
public function update(string $table, array $data, string $where, $timeauto = true):int {
|
|
|
|
|
|
if($timeauto){
|
|
|
$data['updated_at'] = empty($data['updated_at']) ? date('Y-m-d H:i:s') : $data['updated_at'];
|
|
|
}
|
|
|
|
|
|
$sql = "update `{$table}` set ".dbUpdate($data). " where ".$where;
|
|
|
|
|
|
$data = $this->getData($data);
|
|
|
|
|
|
$query = $this->query([$sql,$data]);
|
|
|
if($query){
|
|
|
return $query->rowCount();
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 在更新/插入时处理数据
|
|
|
* @param $data
|
|
|
* @return mixed
|
|
|
* @author:dc
|
|
|
* @time 2023/2/18 14:50
|
|
|
*/
|
|
|
private function getData($data){
|
|
|
// 如果存储的值是数组,就json一次
|
|
|
foreach ($data as $k=>$datum){
|
|
|
if(is_array($datum)){
|
|
|
$data[$k] = json_encode($datum,JSON_UNESCAPED_UNICODE);
|
|
|
}elseif ($datum === null){
|
|
|
$data[$k] = '';
|
|
|
}
|
|
|
}
|
|
|
return $data;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 插入数据
|
|
|
* @param string $table
|
|
|
* @param array $data
|
|
|
* @param bool $timeauto
|
|
|
* @return int
|
|
|
* @author:dc
|
|
|
* @time 2023/2/17 14:04
|
|
|
*/
|
|
|
public function insert(string $table, array $data, $timeauto = true):int {
|
|
|
|
|
|
if($timeauto){
|
|
|
$data['created_at'] = empty($data['created_at']) ? date('Y-m-d H:i:s') : $data['created_at'];
|
|
|
}
|
|
|
|
|
|
$sql = "insert into `{$table}` set ".dbUpdate($data);
|
|
|
|
|
|
$data = $this->getData($data);
|
|
|
|
|
|
$query = $this->query([$sql,$data]);
|
|
|
|
|
|
if($query){
|
|
|
return $this->getClient()->lastInsertId();
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 删除语句 软删
|
|
|
* @param string $table
|
|
|
* @param array $where
|
|
|
* @param null $upFiled
|
|
|
* @return int
|
|
|
* @author:dc
|
|
|
* @time 2023/4/11 14:47
|
|
|
*/
|
|
|
public function delete(string $table, array $where,$upFiled=null){
|
|
|
|
|
|
if($upFiled){
|
|
|
return $this->update($table,[$upFiled === true ? 'deleted_at' : $upFiled =>time()],$where);
|
|
|
}
|
|
|
|
|
|
$sql = "delete from `{$table}` where ".dbUpdate($where);
|
|
|
|
|
|
$query = $this->query([$sql,$where]);
|
|
|
|
|
|
if($query){
|
|
|
return $query->rowCount();
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 统计数量
|
|
|
* @param string $sql
|
|
|
* @return int
|
|
|
* @author:dc
|
|
|
* @time 2023/2/14 16:19
|
|
|
*/
|
|
|
public function count(string|array $sql):int{
|
|
|
$query = $this->query($sql);
|
|
|
if($query){
|
|
|
return $query->fetch(\PDO::FETCH_COLUMN);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
]);
|
|
|
|
|
|
/**
|
|
|
* 某个值
|
|
|
* @param string|array $sql
|
|
|
* @return mixed|null
|
|
|
* @author:dc
|
|
|
* @time 2023/2/17 11:03
|
|
|
*/
|
|
|
public function value(string|array $sql){
|
|
|
$query = $this->query($sql);
|
|
|
if($query){
|
|
|
return $query->fetch(\PDO::FETCH_COLUMN);
|
|
|
static::$pool = new PDOPool($pdoconfig,1024);
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 查询一条数据
|
|
|
* @param string|array $sql
|
|
|
* @return mixed|null
|
|
|
* @author:dc
|
|
|
* @time 2023/2/13 14:54
|
|
|
*/
|
|
|
public function first(string|array $sql){
|
|
|
|
|
|
$query = $this->query($sql);
|
|
|
|
|
|
if($query){
|
|
|
return $query->fetch();
|
|
|
}
|
|
|
// 获取链接
|
|
|
$this->client = static::$pool->get();
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 查询列表
|
|
|
* @param string|array $sql
|
|
|
* @return mixed|null
|
|
|
* @author:dc
|
|
|
* @time 2023/2/13 14:54
|
|
|
*/
|
|
|
public function all(string|array $sql){
|
|
|
|
|
|
$query = $this->query($sql);
|
|
|
|
|
|
if($query){
|
|
|
return $query->fetchAll();
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 事务开启
|
|
|
* @author:dc
|
|
|
* @time 2023/2/17 11:35
|
|
|
*/
|
|
|
public function transaction(){
|
|
|
$this->getClient()->beginTransaction();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 事务回滚
|
|
|
* @author:dc
|
|
|
* @time 2023/2/17 11:35
|
|
|
*/
|
|
|
public function rollBack(){
|
|
|
$this->getClient()->rollBack();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 事务提交
|
|
|
* @author:dc
|
|
|
* @time 2023/2/17 11:35
|
|
|
*/
|
|
|
public function commit(){
|
|
|
$this->getClient()->commit();
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 验证是否正常连接
|
|
|
* @return bool
|
|
|
* @author:dc
|
|
|
* @time 2024/4/10 10:09
|
|
|
*/
|
|
|
public function ping(){
|
|
|
try {
|
|
|
$query = $this->getClient()->query("select 200;");
|
|
|
if($query->fetchColumn() == 200){
|
|
|
return true;
|
|
|
}
|
|
|
}catch (\Throwable $e){
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
* @param $cid
|
|
|
* @return DbPool
|
|
|
* @author:dc
|
|
|
* @time 2023/2/13 9:39
|
|
|
*/
|
|
|
public static function instance($cid=0){
|
|
|
if(empty(static::$instance[$cid])){
|
|
|
static::$instance[$cid] = new DbPool($cid);
|
|
|
}
|
|
|
|
|
|
if(!static::$instance[$cid]->ping()){
|
|
|
static::$instance[$cid]->close();
|
|
|
|
|
|
static::$instance[$cid] = new DbPool($cid);
|
|
|
}
|
|
|
|
|
|
return static::$instance[$cid];
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
...
|
...
|
@@ -398,10 +60,14 @@ class DbPool { |
|
|
$this->close();
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 关闭链接
|
|
|
* @author:dc
|
|
|
* @time 2024/5/30 10:30
|
|
|
*/
|
|
|
public function close(){
|
|
|
self::$pool->put($this->client);
|
|
|
$this->client = null;
|
|
|
unset(static::$instance[$this->cid]);
|
|
|
}
|
|
|
|
|
|
|
...
|
...
|
|