<?php

// php + mysql fuction class
error_reporting(E_ALL & ~ E_NOTICE);

/**
 * CDB工具类[APHP三大操作单元之一]
 * @author jgao
 */
class CDbUtil {

    var $conn = 0;

    function dbconn($dbhost, $dbport, $dbuser, $dbpw, $dbname) {
        $this->conn = mysqli_connect($dbhost . ":" . $dbport, $dbuser, $dbpw);
        !$this->conn && $this->halt("Connect to MySQL failed");
        $serverinfo = mysqli_get_server_info($this->conn);
        if ($serverinfo > '4.1' && $GLOBALS['charset']) {
            mysqli_query($this->conn, "SET character_set_connection=" . $GLOBALS['charset'] . ",character_set_results=" . $GLOBALS['charset'] . ",character_set_client=binary");
        }
        if ($serverinfo > '5.0') {
            mysqli_query($this->conn, "SET sql_mode=''");
        }
        if ($dbname && !@mysqli_select_db($this->conn, $dbname)) {
            $this->halt('Cannot use database');
        }
        $this->conn->set_charset('UTF-8');                                      # 设置字符集
    }

    function select_db($dbname) {
        if (!@mysqli_select_db($this->conn, $dbname)) {
            $this->halt('Cannot use database');
        }
    }

    function server_info() {
        return mysqli_get_server_info($this->conn);
    }

    function insert_id() {
        $arr = $this->fetch_array('SELECT LAST_INSERT_ID() as id');
        return $arr["id"];
    }

    function get_value($SQL, $offset = 0, $field = 0) {
        $rt = $this->fetch_result($SQL);
        if (isset($rt[$offset][$field])) {
            return $rt[$offset][$field];
        }
        return false;
    }

    /**
     * 执行查询
     * @param type $SQL
     * @param type $method
     * @param type $error
     * @return mixed
     */
    function query($SQL, $method = null, $error = true) {
        $query = mysqli_query($this->conn, $SQL);
        !$query && $error && $this->halt('Query Error: ' . $SQL);
        return $query;
    }

    /**
     * 执行数据库中的玩家存在查询 因为合区涉及数据库的查找是否存在玩家 不能抛出错误 故另写次函数 仅自己和userProc使用  zyt
     * @param type $SQL
     * @param type $method
     * @param type $error
     * @return mixed
     */
    function userQuery($SQL, $method = null, $error = true) {
        $query = mysqli_query($this->conn, $SQL);
//        !$query && $error && $this->halt('Query Error: ' . $SQL);
        if (!$query && $error && mysqli_error($this->conn) == "No database selected") {
            return null;
        }
        return $query;
    }

    /**
     * 执行更新的时候加上事物逻辑
     * @param type $SQL
     * @return int errno
     */
    function safeQuery($SQL) {
        mysqli_query($this->conn, 'start transaction');
        mysqli_query($this->conn, 'SET autocommit=0');
//        CLogUtil::err($SQL);
//        CLogUtil::err(debug_backtrace());
        $query = mysqli_query($this->conn, $SQL);
        $err = mysqli_errno($this->conn);
        if ($err && !$query) {
            mysqli_query($this->conn, 'rollback');
        } else {
            mysqli_query($this->conn, 'commit');
        }
        mysqli_query($this->conn, 'SET autocommit=1');
        return $err;
    }

    /**
     * 将查询结果作为索引数组返回
     * @param string $SQL
     * @return array
     */
    function fetch_row($SQL) {
        return $this->fetch_result($SQL, MYSQLI_NUM);
    }

    /**
     * 将查询结果作为关联数组返回
     * @param string $SQL
     * @return array
     */
    function fetch_array($SQL) {
        return $this->fetch_result($SQL, MYSQLI_ASSOC);
    }

    /**
     * 从结果中取一行作为结果返回
     * @param string $SQL
     * @param int $result_type 1. 关联数组, 2. 索引数组, 3 both
     * @return type
     */
    function fetch_result($SQL, $result_type = MYSQLI_BOTH) {
        $arr = array();
        $query = $this->query($SQL);
        while ($data = mysqli_fetch_array($query, $result_type)) {
            $arr[] = $data;
        }
        $this->free_result();
        return $arr;
    }

    function affected_rows() {
        return mysqli_affected_rows($this->conn);
    }

    /**
     * 调取结果集中行的数目
     * @param type $SQL
     * @return int
     */
    function num_rows($SQL) {
        $query = $this->query($SQL);
        if (!is_bool($query)) {
            return mysqli_num_rows($query);
        }
        return 0;
    }

    function num_fields($SQL) {
        $query = $this->query($SQL);
        return mysqli_num_fields($query);
    }

    function escape_string($str) {
        return mysqli_escape_string($this->conn, $str);
    }

    function free_result() {
        $void = func_get_args();
        foreach ($void as $query) {
            if (is_resource($query) && get_resource_type($query) === 'mysql result') {
                mysqli_free_result($query);
            }
        }
        unset($void);
    }

    function close() {
        $this->free_result();
        return @mysqli_close($this->conn);
    }

    function halt($msg = null) {
        exit($msg . '<br /><br />' . mysqli_error());
    }

}
