c语言mysql自动重连接_基于swoole的轻量级socket框架(含协程版数据库/缓存链接池)...

class MySQLPool {

const POOL_SIZE = 10;

protected $pool;

protected $logger;

static private $instances;

var $host = '';

var $username = '';

var $password = '';

var $dbname = '';

var $port = 3306;

var $pconnect = FALSE;

var $db_debug = FALSE;

var $char_set = 'utf8';

var $dbcollat = 'utf8_general_ci';

static public function instance($params) {

if (!isset(self::$instances[$params])) {

$params = empty($params) ? 'default' : $params;

global $util_db_config;

if (! isset($util_db_config[$params])) {

throw new RuntimeException("You have specified an invalid database connection group.");

}

$config = $util_db_config[$params];

$pool_size = isset($config['pool_size']) ? intval($config['pool_size']) : MySQLPool::POOL_SIZE;

$pool_size = $pool_size <= 0 ? MySQLPool::POOL_SIZE : $pool_size;

self::$instances[$params] = new MySQLPool($config, $pool_size);

}

return self::$instances[$params];

}

/**

* MySQLPool constructor.

* @param int $size 链接池的尺寸

*/

function __construct($params, $size) {

$this->logger = new Logger(array('file_name' => 'mysql_log'));

foreach ($params as $key => $val) {

$this->$key = $val;

}

$this->ycdb = new ycdb(["unix_socket" => ""]);

$this->pool = new Swoole\Coroutine\Channel($size);

for ($i = 0; $i < $size; $i++) {

$mysql = new Swoole\Coroutine\MySQL();

$ret = $this->connect($mysql);

if ($ret) {

$this->pool->push($mysql);

$this->query("SET NAMES '".$this->char_set."' COLLATE '".$this->dbcollat."'");

} else {

throw new RuntimeException("MySQL connect error host={$this->host}, port={$this->port}, user={$this->username}, database={$this->dbname}, errno=[" . $mysql->errno . "], error=[" . $mysql->error . "]");

}

}

}

function insert($table = '', $data = NULL) {

if (empty($table) || empty($data) || !is_array($data)) {

throw new RuntimeException("insert_table_or_data_must_be_set");

}

$ret = $this->ycdb->insert_sql($table, $data);

if (empty($ret) || $ret == -1) {

throw new RuntimeException("insert_sql error [$table][".json_encode($data)."]");

}

$sql = $ret['query'];

$map = $ret['map'];

$sql = str_replace(array_keys($map), "?", $sql);

$ret = $this->query($sql, array_values($map), $mysql);

if (!empty($ret)) {

return $mysql->insert_id;

} else {

return intval($ret);

}

}

function replace($table = '', $data = NULL) {

if (empty($table) || empty($data) || !is_array($data)) {

throw new RuntimeException("replace_table_or_data_must_be_set");

}

$ret = $this->ycdb->replace_sql($table, $data);

if (empty($ret) || $ret == -1) {

throw new RuntimeException("replace_sql error [$table][".json_encode($data)."]");

}

$sql = $ret['query'];

$map = $ret['map'];

$sql = str_replace(array_keys($map), "?", $sql);

$ret = $this->query($sql, array_values($map));

return $ret;

}

function update($table = '', $where = NULL, $data = NULL) {

if (empty($table) || empty($where) || empty($data) || !is_array($data)) {

throw new RuntimeException("update_table_or_data_must_be_set");

}

$ret = $this->ycdb->update_sql($table, $data, $where);

if (empty($ret) || $ret == -1) {

throw new RuntimeException("update_sql error [$table][".json_encode($data)."][".json_encode($where)."]");

}

$sql = $ret['query'];

$map = $ret['map'];

$sql = str_replace(array_keys($map), "?", $sql);

$ret = $this->query($sql, array_values($map));

return $ret;

}

function delete($table = '', $where = NULL) {

if (empty($table) || empty($where)) {

throw new RuntimeException("delete_table_or_where_must_be_set");

}

$ret = $this->ycdb->delete_sql($table, $where);

if (empty($ret) || $ret == -1) {

throw new RuntimeException("replace_sql error [$table][".json_encode($where)."]");

}

$sql = $ret['query'];

$map = $ret['map'];

$sql = str_replace(array_keys($map), "?", $sql);

$ret = $this->query($sql, array_values($map));

return $ret;

}

function get($table = '', $where = array(), $columns = "*") {

if (empty($table) || empty($columns)) {

throw new RuntimeException("select_table_or_columns_must_be_set");

}

$ret = $this->ycdb->select_sql($table, $columns, $where);

if (empty($ret) || $ret == -1) {

throw new RuntimeException("select_sql error [$table][".json_encode($where)."][".json_encode($columns)."]");

}

$sql = $ret['query'];

$map = $ret['map'];

$sql = str_replace(array_keys($map), "?", $sql);

$ret = $this->query($sql, array_values($map));

return $ret;

}

function get_one($table = '', $where = array(), $columns = "*") {

if (empty($table) || empty($columns)) {

throw new RuntimeException("select_table_or_columns_must_be_set");

}

$where['LIMIT'] = 1;

$ret = $this->get($table, $where, $columns);

if (empty($ret) || !is_array($ret)) {

return array();

}

return $ret[0];

}

private function connect(& $mysql, $reconn = false) {

if ($reconn) {

$mysql->close();

}

$options = array();

$options['host'] = $this->host;

$options['port'] = intval($this->port) == 0 ? 3306 : intval($this->port);

$options['user'] = $this->username;

$options['password'] = $this->password;

$options['database'] = $this->dbname;

$ret = $mysql->connect($options);

return $ret;

}

function real_query(& $mysql, & $sql, & $map) {

if (empty($map)) {

return $mysql->query($sql);

} else {

$stmt = $mysql->prepare($sql);

if ($stmt == false) {

return false;

} else {

return $stmt->execute($map);

}

}

}

function query($sql, $map = null, & $mysql = null) {

if (empty($sql)) {

throw new RuntimeException("input_empty_query_sql");

}

try {

$mysql = $this->pool->pop();

$ret = $this->real_query($mysql, $sql, $map);

if ($ret === false) {

$this->logger->LogError("MySQL QUERY FAIL [".$mysql->errno."][".$mysql->error."], sql=[{$sql}], map=[".json_encode($map)."]");

if ($mysql->errno == 2006 || $mysql->errno == 2013) {

//重连MySQL

$ret = $this->connect($mysql, true);

if ($ret) {

$ret = $this->real_query($mysql, $sql, $map);

} else {

throw new RuntimeException("reconnect fail: [" . $mysql->errno . "][" . $mysql->error . "], host={$this->host}, port={$this->port}, user={$this->username}, database={$this->dbname}");

}

}

}

if ($ret === false) {

throw new RuntimeException($mysql->errno . "|" . $mysql->error);

}

$this->pool->push($mysql);

return $ret;

} catch (Exception $e) {

$this->pool->push($mysql);

$this->logger->LogError("MySQL catch exception [".$e->getMessage()."], sql=[{$sql}], map=".json_encode($map));

throw new RuntimeException("MySQL catch exception [".$e->getMessage()."], sql=[{$sql}], map=".json_encode($map));

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值