<?php<liu21st@gmail.com>
define('CLIENT_MULTI_RESULTS', 131072);
class Db {
static private $_instance = null;
protected $autoFree = false;
public $debug = false;
protected $pconnect = false;
protected $queryStr = '';
protected $lastInsID = null;
protected $numRows = 0;
protected $numCols = 0;
protected $transTimes = 0;
protected $error = '';
protected $linkID = null;
protected $queryID = null;
protected $connected = false;
protected $config = '';
protected $comparison = array('eq'=>'=','neq'=>'!=','gt'=>'>','egt'=>'>=','lt'=>'<','elt'=>'<=','notlike'=>'NOT LIKE','like'=>'LIKE');
protected $selectSql = 'SELECT%DISTINCT% %FIELDS% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT%';
public function __construct($config=''){
if ( !extension_loaded('mysql') ) {
throw_exception(L('_NOT_SUPPERT_').':mysql');
}
$this->config = $this->parseConfig($config);
}
public function connect() {
if(!$this->connected) {
$config = $this->config;
$host = $config['hostname'].($config['hostport']?":{$config['hostport']}":'');
if($this->pconnect) {
$this->linkID = mysql_pconnect( $host, $config['username'], $config['password'],CLIENT_MULTI_RESULTS);
}else{
$this->linkID = mysql_connect( $host, $config['username'], $config['password'],true,CLIENT_MULTI_RESULTS);
}
if ( !$this->linkID || (!empty($config['database']) && !mysql_select_db($config['database'], $this->linkID)) ) {
throw_exception(mysql_error());
}
$dbVersion = mysql_get_server_info($this->linkID);
if ($dbVersion >= "4.1") {
mysql_query("SET NAMES '".C('DB_CHARSET')."'", $this->linkID);
}
if($dbVersion >'5.0.1'){
mysql_query("SET sql_mode=''",$this->linkID);
}
$this->connected = true;
unset($this->config);
}
}
public function free() {
mysql_free_result($this->queryID);
$this->queryID = 0;
}
public function query($str='') {
$this->connect();
if ( !$this->linkID ) return false;
if ( $str != '' ) $this->queryStr = $str;
if ( $this->queryID ) { $this->free(); }
N('db_query',1);
G('queryStartTime');
$this->queryID = mysql_query($this->queryStr, $this->linkID);
$this->debug();
if ( !$this->queryID ) {
if ( $this->debug )
throw_exception($this->error());
else
return false;
} else {
$this->numRows = mysql_num_rows($this->queryID);
return $this->getAll();
}
}
public function execute($str='') {
$this->connect();
if ( !$this->linkID ) return false;
if ( $str != '' ) $this->queryStr = $str;
if ( $this->queryID ) { $this->free(); }
N('db_write',1);
G('queryStartTime');
$result = mysql_query($this->queryStr, $this->linkID) ;
$this->debug();
if ( false === $result) {
if ( $this->debug )
throw_exception($this->error());
else
return false;
} else {
$this->numRows = mysql_affected_rows($this->linkID);
$this->lastInsID = mysql_insert_id($this->linkID);
return $this->numRows;
}
}
public function startTrans() {
$this->connect(true);
if ( !$this->linkID ) return false;
if ($this->transTimes == 0) {
mysql_query('START TRANSACTION', $this->linkID);
}
$this->transTimes++;
return ;
}
public function commit() {
if ($this->transTimes > 0) {
$result = mysql_query('COMMIT', $this->linkID);
$this->transTimes = 0;
if(!$result){
throw_exception($this->error());
return false;
}
}
return true;
}
public function rollback() {
if ($this->transTimes > 0) {
$result = mysql_query('ROLLBACK', $this->linkID);
$this->transTimes = 0;
if(!$result){
throw_exception($this->error());
return false;
}
}
return true;
}
public function getAll() {
if ( !$this->queryID ) {
throw_exception($this->error());
return false;
}
$result = array();
if($this->numRows >0) {
while($row = mysql_fetch_assoc($this->queryID)){
$result[] = $row;
}
mysql_data_seek($this->queryID,0);
}
return $result;
}
public function close() {
if (!empty($this->queryID))
mysql_free_result($this->queryID);
if ($this->linkID && !mysql_close($this->linkID)){
throw_exception($this->error());
}
$this->linkID = 0;
}
public function error() {
$this->error = mysql_error($this->linkID);
if($this->queryStr!=''){
$this->error .= "\n [ SQL语句 ] : ".$this->queryStr;
}
return $this->error;
}
public function escapeString($str) {
return mysql_escape_string($str);
}
public function __destruct() {
$this->close();
}
public static function getInstance($db_config='') {
if ( self::$_instance==null ){
self::$_instance = new Db($db_config);
}
return self::$_instance;
}
private function parseConfig($db_config='') {
if ( !empty($db_config) && is_string($db_config)) {
$db_config = $this->parseDSN($db_config);
}else if(empty($db_config)){
$db_config = array (
'dbms' => C('DB_TYPE'),
'username' => C('DB_USER'),
'password' => C('DB_PWD'),
'hostname' => C('DB_HOST'),
'hostport' => C('DB_PORT'),
'database' => C('DB_NAME'),
'dsn' => C('DB_DSN'),
'params' => C('DB_PARAMS'),
);
}
return $db_config;
}
public function parseDSN($dsnStr) {
if( empty($dsnStr) ){return false;}
$info = parse_url($dsnStr);
if($info['scheme']){
$dsn = array(
'dbms' => $info['scheme'],
'username' => isset($info['user']) ? $info['user'] : '',
'password' => isset($info['pass']) ? $info['pass'] : '',
'hostname' => isset($info['host']) ? $info['host'] : '',
'hostport' => isset($info['port']) ? $info['port'] : '',
'database' => isset($info['path']) ? substr($info['path'],1) : ''
);
}else {
preg_match('/^(.*?)\:\/\/(.*?)\:(.*?)\@(.*?)\:([0-9]{1, 6})\/(.*?)$/',trim($dsnStr),$matches);
$dsn = array (
'dbms' => $matches[1],
'username' => $matches[2],
'password' => $matches[3],
'hostname' => $matches[4],
'hostport' => $matches[5],
'database' => $matches[6]
);
}
return $dsn;
}
protected function debug() {
if ( $this->debug ) {
G('queryEndTime');
Log::record($this->queryStr." [ RunTime:".G('queryStartTime','queryEndTime',6)."s ]",Log::SQL);
}
}
public function getLastSql() {
return $this->queryStr;
}
public function getLastInsID(){
return $this->lastInsID;
}
}