|
@@ -13,49 +13,34 @@ require_once(BASE_CORE_PATH . '/framework/function/statistic_tm.php');
|
|
|
|
|
|
class Db
|
|
|
{
|
|
|
+ const ErrUnConnect = 2006;
|
|
|
+
|
|
|
private static $link = array();
|
|
|
private static $iftransacte = true;
|
|
|
- const reconnect_time = 3600;
|
|
|
|
|
|
private function __construct()
|
|
|
{
|
|
|
if (!extension_loaded('mysqli')) {
|
|
|
throw_exception("Db Error: mysqli is not install");
|
|
|
}
|
|
|
+ else {
|
|
|
+ self::init_link();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- private static function connect($host = 'slave')
|
|
|
- {
|
|
|
- static $connect_time = 0;
|
|
|
- if((time() - $connect_time > self::reconnect_time) && $connect_time > 0)
|
|
|
- {
|
|
|
- if(is_object(self::$link[$host]) && self::$link[$host]->ping()) {
|
|
|
- return;
|
|
|
- } else {
|
|
|
- self::closeLink('master');
|
|
|
- self::closeLink('slave');
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (C('db.master') == C('db.slave'))
|
|
|
- {
|
|
|
- if (is_object(self::$link['slave'])){
|
|
|
- self::$link['master'] = &self::$link['slave'];
|
|
|
- return ;
|
|
|
- }
|
|
|
- elseif(is_object(self::$link['master'])){
|
|
|
- self::$link['slave'] = &self::$link['master'];
|
|
|
- return ;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!in_array($host,array('master','slave'))) {
|
|
|
- $host = 'slave';
|
|
|
+ private static function init_link()
|
|
|
+ {
|
|
|
+ if(!isset(self::$link['master']) || is_object(self::$link['master']) == false) {
|
|
|
+ self::connect('master');
|
|
|
}
|
|
|
+ if(!isset(self::$link['slave']) || is_object(self::$link['slave']) == false) {
|
|
|
+ self::connect('slave');
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if (is_object(self::$link[$host])) {
|
|
|
- return;
|
|
|
- }
|
|
|
+ private static function connect($host = 'slave')
|
|
|
+ {
|
|
|
+ self::closeLink($host);
|
|
|
|
|
|
$conf = C('db.'.$host);
|
|
|
self::$link[$host] = @new mysqli($conf['dbhost'], $conf['dbuser'], $conf['dbpwd'], $conf['dbname'], $conf['dbport']);
|
|
@@ -65,7 +50,6 @@ class Db
|
|
|
throw_exception("Db Error: database connect failed errno={$err_no} err={$error}");
|
|
|
}
|
|
|
|
|
|
- $connect_time = time();
|
|
|
switch (strtoupper($conf['dbcharset']))
|
|
|
{
|
|
|
case 'UTF-8':
|
|
@@ -105,16 +89,16 @@ class Db
|
|
|
|
|
|
private static function closeLink($host)
|
|
|
{
|
|
|
- if(is_object(self::$link[$host])){
|
|
|
+ if(isset(self::$link[$host]) && is_object(self::$link[$host])) {
|
|
|
self::$link[$host]->close();
|
|
|
}
|
|
|
self::$link[$host] = null;
|
|
|
}
|
|
|
|
|
|
- public static function ping($host = 'master') {
|
|
|
+ public static function ping($host = 'master')
|
|
|
+ {
|
|
|
if (is_object(self::$link[$host])) {
|
|
|
- self::$link[$host]->close();
|
|
|
- self::$link[$host] = null;
|
|
|
+ return self::$link[$host]->ping();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -126,26 +110,45 @@ class Db
|
|
|
*/
|
|
|
public static function query($sql, $host = 'master')
|
|
|
{
|
|
|
- self::connect($host);
|
|
|
- $staer = new statistic_tm();
|
|
|
- $query = self::$link[$host]->query($sql);
|
|
|
- $staer->end();
|
|
|
-
|
|
|
- if ($query === false)
|
|
|
- {
|
|
|
- $error = 'Db Error: no=' . mysqli_errno(self::$link[$host]) . ' error=' .mysqli_error(self::$link[$host]);
|
|
|
- if (C('debug')) {
|
|
|
- throw_exception($error.'<br/>'.$sql);
|
|
|
- } else {
|
|
|
- Log::record($error."\r\n".$sql,Log::ERR);
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Log::record($sql . " [ RunTime:" . $staer->elapsed(6) . "s ]", Log::SQL);
|
|
|
- return $query;
|
|
|
- }
|
|
|
+ self::init_link();
|
|
|
+
|
|
|
+ $count = 0;
|
|
|
+ do
|
|
|
+ {
|
|
|
+ $staer = new statistic_tm();
|
|
|
+ $query = self::$link[$host]->query($sql);
|
|
|
+ $staer->end();
|
|
|
+
|
|
|
+ if ($query === false)
|
|
|
+ {
|
|
|
+ $errno = mysqli_errno(self::$link[$host]);
|
|
|
+ $error = "Db Error: no= error={$errno}" . mysqli_error(self::$link[$host]);
|
|
|
+ Log::record($error."\r\n".$sql,Log::ERR);
|
|
|
+
|
|
|
+ if($errno == self::ErrUnConnect)
|
|
|
+ {
|
|
|
+ if($count > 0) return false;
|
|
|
+ self::closeLink($host);
|
|
|
+ self::connect($host);
|
|
|
+ $count++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (C('debug')) {
|
|
|
+ throw_exception($error.'<br/>'.$sql);
|
|
|
+ return false;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Log::record($sql . " [ RunTime:" . $staer->elapsed(6) . "s ]", Log::SQL);
|
|
|
+ return $query;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ while(true);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -156,7 +159,6 @@ class Db
|
|
|
*/
|
|
|
public static function getAll($sql, $host = 'slave')
|
|
|
{
|
|
|
- self::connect($host);
|
|
|
$result = self::query($sql, $host);
|
|
|
if ($result === false) return array();
|
|
|
$array = array();
|
|
@@ -173,35 +175,37 @@ class Db
|
|
|
* @param object $obj_page 分类对象
|
|
|
* @return array
|
|
|
*/
|
|
|
- public static function select($param, $obj_page='', $host = 'slave'){
|
|
|
- self::connect($host);
|
|
|
+ public static function select($param, $obj_page='', $host = 'slave')
|
|
|
+ {
|
|
|
static $_cache = array();
|
|
|
-
|
|
|
if (empty($param)) throw_exception('Db Error: select param is empty!');
|
|
|
|
|
|
- if (empty($param['field'])){
|
|
|
+ if (empty($param['field'])) {
|
|
|
$param['field'] = '*';
|
|
|
}
|
|
|
- if (empty($param['count'])){
|
|
|
+ if (empty($param['count'])) {
|
|
|
$param['count'] = 'count(*)';
|
|
|
}
|
|
|
|
|
|
- if (isset($param['index'])){
|
|
|
+ if (isset($param['index'])) {
|
|
|
$param['index'] = 'USE INDEX ('.$param['index'].')';
|
|
|
}
|
|
|
|
|
|
- if (trim($param['where']) != ''){
|
|
|
- if (strtoupper(substr(trim($param['where']),0,5)) != 'WHERE'){
|
|
|
+ if (trim($param['where']) != '')
|
|
|
+ {
|
|
|
+ if (strtoupper(substr(trim($param['where']),0,5)) != 'WHERE')
|
|
|
+ {
|
|
|
if (strtoupper(substr(trim($param['where']),0,3)) == 'AND'){
|
|
|
$param['where'] = substr(trim($param['where']),3);
|
|
|
}
|
|
|
$param['where'] = 'WHERE '.$param['where'];
|
|
|
}
|
|
|
- }else {
|
|
|
+ } else {
|
|
|
$param['where'] = '';
|
|
|
}
|
|
|
+
|
|
|
$param['where_group'] = '';
|
|
|
- if (!empty($param['group'])){
|
|
|
+ if (!empty($param['group'])) {
|
|
|
$param['where_group'] .= ' group by '.$param['group'];
|
|
|
}
|
|
|
$param['where_order'] = '';
|
|
@@ -211,7 +215,8 @@ class Db
|
|
|
|
|
|
//判断是否是联表
|
|
|
$tmp_table = explode(',',$param['table']);
|
|
|
- if (!empty($tmp_table) && count($tmp_table) > 1){
|
|
|
+ if (!empty($tmp_table) && count($tmp_table) > 1)
|
|
|
+ {
|
|
|
//判断join表数量和join条件是否一致
|
|
|
if ((count($tmp_table)-1) != count($param['join_on'])){
|
|
|
throw_exception('Db Error: join number is wrong!');
|
|
@@ -231,30 +236,36 @@ class Db
|
|
|
|
|
|
//如果有分页,那么计算信息总数
|
|
|
$count_sql = 'SELECT '.$param['count'].' as count FROM `'.DBPRE.$tmp_table[0].'` as `'.$tmp_table[0].'` '.$tmp_sql.' '.$param['where'].$param['where_group'];
|
|
|
- }else {
|
|
|
+ }
|
|
|
+ else {
|
|
|
$sql = 'SELECT '.$param['field'].' FROM `'.DBPRE.$param['table'].'` as `'.$param['table'].'` '.$param['index'].' '.$param['where'].$param['where_group'].$param['where_order'];
|
|
|
$count_sql = 'SELECT '.$param['count'].' as count FROM `'.DBPRE.$param['table'].'` as `'.$param['table'].'` '.$param['index'].' '.$param['where'];
|
|
|
}
|
|
|
+
|
|
|
//limit ,如果有分页对象的话,那么优先分页对象
|
|
|
- if ($obj_page instanceof Page ){
|
|
|
+ if ($obj_page instanceof Page )
|
|
|
+ {
|
|
|
$count_query = self::query($count_sql,$host);
|
|
|
$count_fetch = mysqli_fetch_array($count_query,MYSQLI_ASSOC);
|
|
|
$obj_page->setTotalNum($count_fetch['count']);
|
|
|
$param['limit'] = $obj_page->getLimitStart().",".$obj_page->getEachNum();
|
|
|
}
|
|
|
- if ($param['limit'] != ''){
|
|
|
+
|
|
|
+ if ($param['limit'] != '') {
|
|
|
$sql .= ' limit '.$param['limit'];
|
|
|
}
|
|
|
- if ($param['cache'] !== false){
|
|
|
+ if ($param['cache'] !== false)
|
|
|
+ {
|
|
|
$key = is_string($param['cache_key'])?$param['cache_key']:md5($sql);
|
|
|
if (isset($_cache[$key])) return $_cache[$key];
|
|
|
}
|
|
|
+
|
|
|
$result = self::query($sql,$host);
|
|
|
if ($result === false) $result = array();
|
|
|
- while ($tmp=mysqli_fetch_array($result,MYSQLI_ASSOC)){
|
|
|
+ while ($tmp=mysqli_fetch_array($result,MYSQLI_ASSOC)) {
|
|
|
$array[] = $tmp;
|
|
|
}
|
|
|
- if ($param['cache'] !== false && !isset($_cache[$key])){
|
|
|
+ if ($param['cache'] !== false && !isset($_cache[$key])) {
|
|
|
$_cache[$key] = $array;
|
|
|
}
|
|
|
return $array;
|
|
@@ -267,12 +278,12 @@ class Db
|
|
|
* @param array $insert_array 待插入数据
|
|
|
* @return mixed
|
|
|
*/
|
|
|
- public static function insert($table_name, $insert_array=array(), $host = 'master'){
|
|
|
- self::connect($host);
|
|
|
+ public static function insert($table_name, $insert_array=array(), $host = 'master')
|
|
|
+ {
|
|
|
if (!is_array($insert_array)) return false;
|
|
|
$fields = array();
|
|
|
$value = array();
|
|
|
- foreach ($insert_array as $key => $val){
|
|
|
+ foreach ($insert_array as $key => $val) {
|
|
|
$fields[] = self::parseKey($key);
|
|
|
$value[] = self::parseValue($val);
|
|
|
}
|
|
@@ -293,12 +304,12 @@ class Db
|
|
|
*/
|
|
|
public static function insertAll($table_name, $insert_array=array(), $host = 'master')
|
|
|
{
|
|
|
- self::connect($host);
|
|
|
if (!is_array($insert_array[0])) return false;
|
|
|
$fields = array_keys($insert_array[0]);
|
|
|
array_walk($fields,array(self,'parseKey'));
|
|
|
$values = array();
|
|
|
- foreach ($insert_array as $data) {
|
|
|
+ foreach ($insert_array as $data)
|
|
|
+ {
|
|
|
$value = array();
|
|
|
foreach ($data as $key=>$val) {
|
|
|
$val = self::parseValue($val);
|
|
@@ -308,6 +319,7 @@ class Db
|
|
|
}
|
|
|
$values[] = '('.implode(',',$value).')';
|
|
|
}
|
|
|
+
|
|
|
$sql = 'INSERT INTO `'.DBPRE.$table_name.'` ('.implode(',',$fields).') VALUES '.implode(',',$values);
|
|
|
$result = self::query($sql,$host);
|
|
|
$insert_id = self::getLastId($host);
|
|
@@ -324,10 +336,10 @@ class Db
|
|
|
*/
|
|
|
public static function update($table_name, $update_array = array(), $where = '', $host = 'master')
|
|
|
{
|
|
|
- self::connect($host);
|
|
|
if (!is_array($update_array)) return false;
|
|
|
$string_value = '';
|
|
|
- foreach ($update_array as $k => $v){
|
|
|
+ foreach ($update_array as $k => $v)
|
|
|
+ {
|
|
|
if (is_array($v)){
|
|
|
switch ($v['sign']){
|
|
|
case 'increase': $string_value .= " $k = $k + ". $v['value'] .","; break;
|
|
@@ -335,14 +347,16 @@ class Db
|
|
|
case 'calc': $string_value .= " $k = ". $v['value'] .","; break;
|
|
|
default: $string_value .= " $k = ". self::parseValue($v['value']) .",";
|
|
|
}
|
|
|
- }else {
|
|
|
+ } else {
|
|
|
$string_value .= " $k = ". self::parseValue($v) .",";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$string_value = trim(trim($string_value),',');
|
|
|
- if (trim($where) != ''){
|
|
|
- if (strtoupper(substr(trim($where),0,5)) != 'WHERE'){
|
|
|
+ if (trim($where) != '')
|
|
|
+ {
|
|
|
+ if (strtoupper(substr(trim($where),0,5)) != 'WHERE')
|
|
|
+ {
|
|
|
if (strtoupper(substr(trim($where),0,3)) == 'AND'){
|
|
|
$where = substr(trim($where),3);
|
|
|
}
|
|
@@ -363,9 +377,10 @@ class Db
|
|
|
*/
|
|
|
public static function delete($table_name, $where = '', $host = 'master')
|
|
|
{
|
|
|
- self::connect($host);
|
|
|
- if (trim($where) != ''){
|
|
|
- if (strtoupper(substr(trim($where),0,5)) != 'WHERE'){
|
|
|
+ if (trim($where) != '')
|
|
|
+ {
|
|
|
+ if (strtoupper(substr(trim($where),0,5)) != 'WHERE')
|
|
|
+ {
|
|
|
if (strtoupper(substr(trim($where),0,3)) == 'AND'){
|
|
|
$where = substr(trim($where),3);
|
|
|
}
|
|
@@ -373,7 +388,7 @@ class Db
|
|
|
}
|
|
|
$sql = 'DELETE FROM `'.DBPRE.$table_name.'` '.$where;
|
|
|
return self::query($sql, $host);
|
|
|
- }else {
|
|
|
+ } else {
|
|
|
throw_exception('Db Error: the condition of delete is empty!');
|
|
|
}
|
|
|
}
|
|
@@ -383,8 +398,8 @@ class Db
|
|
|
*
|
|
|
* @return int
|
|
|
*/
|
|
|
- public static function getLastId($host = 'master'){
|
|
|
- self::connect($host);
|
|
|
+ public static function getLastId($host = 'master')
|
|
|
+ {
|
|
|
$id = mysqli_insert_id(self::$link[$host]);
|
|
|
if (!$id){
|
|
|
$result = self::query('SELECT last_insert_id() as id',$host);
|
|
@@ -404,18 +419,19 @@ class Db
|
|
|
*/
|
|
|
public static function getRow($param, $fields = '*', $host = 'slave')
|
|
|
{
|
|
|
- self::connect($host);
|
|
|
$table = $param['table'];
|
|
|
$wfield = $param['field'];
|
|
|
$value = $param['value'];
|
|
|
|
|
|
- if (is_array($wfield)){
|
|
|
+ if (is_array($wfield))
|
|
|
+ {
|
|
|
$where = array();
|
|
|
foreach ($wfield as $k => $v){
|
|
|
$where[] = $v."='".$value[$k]."'";
|
|
|
}
|
|
|
$where = implode(' and ',$where);
|
|
|
- }else {
|
|
|
+ }
|
|
|
+ else {
|
|
|
$where = $wfield."='".$value."'";
|
|
|
}
|
|
|
|
|
@@ -434,7 +450,6 @@ class Db
|
|
|
*/
|
|
|
public static function replace($table_name, $replace_array = array(), $host = 'master')
|
|
|
{
|
|
|
- self::connect($host);
|
|
|
if (!empty($replace_array))
|
|
|
{
|
|
|
$string_field = '';
|
|
@@ -459,9 +474,8 @@ class Db
|
|
|
*/
|
|
|
public static function getCount($table, $condition = null, $host = 'slave')
|
|
|
{
|
|
|
- self::connect($host);
|
|
|
-
|
|
|
- if (!empty($condition) && is_array($condition)){
|
|
|
+ if (!empty($condition) && is_array($condition))
|
|
|
+ {
|
|
|
$where = '';
|
|
|
foreach ($condition as $key=>$val) {
|
|
|
self::parseKey($key);
|
|
@@ -469,13 +483,16 @@ class Db
|
|
|
$where .= ' AND '.$key.'='.$val;
|
|
|
}
|
|
|
$where = ' WHERE '.substr($where,4);
|
|
|
- }elseif(is_string($condition)){
|
|
|
+ }
|
|
|
+ elseif(is_string($condition))
|
|
|
+ {
|
|
|
if (strtoupper(substr(trim($condition),0,3)) == 'AND'){
|
|
|
$where = ' WHERE '.substr(trim($condition),4);
|
|
|
}else{
|
|
|
$where = ' WHERE '.$condition;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
$sql = 'SELECT COUNT(*) as `count` FROM `'.DBPRE.$table.'` as `'.$table.'` '.(isset($where) ? $where : '');
|
|
|
$result = self::query($sql,$host);
|
|
|
if ($result === false) return 0;
|
|
@@ -490,7 +507,6 @@ class Db
|
|
|
* @return
|
|
|
*/
|
|
|
public static function execute($sql, $host = 'master'){
|
|
|
- self::connect($host);
|
|
|
$result = self::query($sql,$host);
|
|
|
return $result;
|
|
|
}
|
|
@@ -500,8 +516,8 @@ class Db
|
|
|
*
|
|
|
* @return array
|
|
|
*/
|
|
|
- public static function showTables($host = 'slave'){
|
|
|
- self::connect($host);
|
|
|
+ public static function showTables($host = 'slave')
|
|
|
+ {
|
|
|
$sql = 'SHOW TABLES';
|
|
|
$result = self::query($sql,$host);
|
|
|
if ($result === false) return array();
|
|
@@ -518,8 +534,8 @@ class Db
|
|
|
* @param string $table
|
|
|
* @return string
|
|
|
*/
|
|
|
- public static function showCreateTable($table, $host = 'slave'){
|
|
|
- self::connect($host);
|
|
|
+ public static function showCreateTable($table, $host = 'slave')
|
|
|
+ {
|
|
|
$sql = 'SHOW CREATE TABLE `'.DBPRE.$table.'`';
|
|
|
$result = self::query($sql,$host);
|
|
|
if ($result === false) return '';
|
|
@@ -533,13 +549,15 @@ class Db
|
|
|
* @param string $table
|
|
|
* @return array
|
|
|
*/
|
|
|
- public static function showColumns($table, $host = 'slave'){
|
|
|
- self::connect($host);
|
|
|
+ public static function showColumns($table, $host = 'slave')
|
|
|
+ {
|
|
|
$sql = 'SHOW COLUMNS FROM `'.DBPRE.$table.'`';
|
|
|
$result = self::query($sql,$host);
|
|
|
if ($result === false) return array();
|
|
|
$array = array();
|
|
|
- while ($tmp=mysqli_fetch_array($result,MYSQLI_ASSOC)){
|
|
|
+
|
|
|
+ while ($tmp=mysqli_fetch_array($result,MYSQLI_ASSOC))
|
|
|
+ {
|
|
|
$array[$tmp['Field']] = array(
|
|
|
'name' => $tmp['Field'],
|
|
|
'type' => $tmp['Type'],
|
|
@@ -558,7 +576,7 @@ class Db
|
|
|
* @return string
|
|
|
*/
|
|
|
public static function getServerInfo($host = 'slave'){
|
|
|
- self::connect($host);
|
|
|
+ self::init_link();
|
|
|
$result = mysqli_get_server_info(self::$link[$host]);
|
|
|
return $result;
|
|
|
}
|
|
@@ -590,26 +608,29 @@ class Db
|
|
|
|
|
|
public static function beginTransaction($host = 'master')
|
|
|
{
|
|
|
- self::connect($host);
|
|
|
- if (self::$iftransacte){
|
|
|
- self::$link[$host]->autocommit(false);//关闭自动提交
|
|
|
+ self::init_link();
|
|
|
+ if (self::$iftransacte)
|
|
|
+ {
|
|
|
+ $result = self::$link[$host]->autocommit(false);
|
|
|
+ if($result == false)
|
|
|
+ {
|
|
|
+ $errno = mysqli_errno(self::$link[$host]);
|
|
|
+ $error = "Db Error autocommit no= error={$errno}" . mysqli_error(self::$link[$host]);
|
|
|
+ Log::record($error."\r\n",Log::ERR);
|
|
|
+
|
|
|
+ if($errno == self::ErrUnConnect) {
|
|
|
+ self::closeLink($host);
|
|
|
+ self::connect($host);
|
|
|
+ }
|
|
|
+ self::$link[$host]->autocommit(false);
|
|
|
+ }
|
|
|
}
|
|
|
self::$iftransacte = false;
|
|
|
}
|
|
|
|
|
|
- public static function start_transaction($falg,$host = 'master')
|
|
|
- {
|
|
|
- self::connect($host);
|
|
|
- if (self::$iftransacte){
|
|
|
- self::$link[$host]->autocommit(false);//关闭自动提交
|
|
|
- self::$iftransacte = false;
|
|
|
- }
|
|
|
- self::$link[$host]->begin_transaction($falg);
|
|
|
- }
|
|
|
-
|
|
|
public static function commit($host = 'master')
|
|
|
{
|
|
|
- if (!self::$iftransacte){
|
|
|
+ if (!self::$iftransacte) {
|
|
|
$result = self::$link[$host]->commit();
|
|
|
self::$link[$host]->autocommit(true);//开启自动提交
|
|
|
self::$iftransacte = true;
|