<?php<liu21st@gmail.com>namespace Think\Db\Driver;
use Think\Db;
defined('THINK_PATH') or exit();
class Mysql extends Db{
public function __construct($config=''){
if ( !extension_loaded('mysql') ) {
E(L('_NOT_SUPPERT_').':mysql');
}
if(!empty($config)) {
$this->config = $config;
if(empty($this->config['params'])) {
$this->config['params'] = '';
}
}
}
public function connect($config='',$linkNum=0,$force=false) {
if ( !isset($this->linkID[$linkNum]) ) {
if(empty($config)) $config = $this->config;
$host = $config['hostname'].($config['hostport']?":{$config['hostport']}":'');
$pconnect = !empty($config['params']['persist'])? $config['params']['persist']:$this->pconnect;
if($pconnect) {
$this->linkID[$linkNum] = mysql_pconnect( $host, $config['username'], $config['password'],131072);
}else{
$this->linkID[$linkNum] = mysql_connect( $host, $config['username'], $config['password'],true,131072);
}
if ( !$this->linkID[$linkNum] || (!empty($config['database']) && !mysql_select_db($config['database'], $this->linkID[$linkNum])) ) {
E(mysql_error());
}
$dbVersion = mysql_get_server_info($this->linkID[$linkNum]);
mysql_query("SET NAMES '".$config['charset']."'", $this->linkID[$linkNum]);
if($dbVersion >'5.0.1'){
mysql_query("SET sql_mode=''",$this->linkID[$linkNum]);
}
$this->connected = true;
if(1 != C('DB_DEPLOY_TYPE')) unset($this->config);
}
return $this->linkID[$linkNum];
}
public function free() {
mysql_free_result($this->queryID);
$this->queryID = null;
}
public function query($str) {
if(0===stripos($str, 'call')){ $this->close();
$this->connected = false;
}
$this->initConnect(false);
if ( !$this->_linkID ) return false;
$this->queryStr = $str;
if ( $this->queryID ) { $this->free(); }
N('db_query',1);
G('queryStartTime');
$this->queryID = mysql_query($str, $this->_linkID);
$this->debug();
if ( false === $this->queryID ) {
$this->error();
return false;
} else {
$this->numRows = mysql_num_rows($this->queryID);
return $this->getAll();
}
}
public function execute($str) {
$this->initConnect(true);
if ( !$this->_linkID ) return false;
$this->queryStr = $str;
if ( $this->queryID ) { $this->free(); }
N('db_write',1);
G('queryStartTime');
$result = mysql_query($str, $this->_linkID) ;
$this->debug();
if ( false === $result) {
$this->error();
return false;
} else {
$this->numRows = mysql_affected_rows($this->_linkID);
$this->lastInsID = mysql_insert_id($this->_linkID);
return $this->numRows;
}
}
public function startTrans() {
$this->initConnect(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){
$this->error();
return false;
}
}
return true;
}
public function rollback() {
if ($this->transTimes > 0) {
$result = mysql_query('ROLLBACK', $this->_linkID);
$this->transTimes = 0;
if(!$result){
$this->error();
return false;
}
}
return true;
}
private function getAll() {
$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 getFields($tableName) {
$result = $this->query('SHOW COLUMNS FROM '.$this->parseKey($tableName));
$info = array();
if($result) {
foreach ($result as $key => $val) {
$info[$val['Field']] = array(
'name' => $val['Field'],
'type' => $val['Type'],
'notnull' => (bool) (strtoupper($val['Null']) === 'NO'), 'default' => $val['Default'],
'primary' => (strtolower($val['Key']) == 'pri'),
'autoinc' => (strtolower($val['Extra']) == 'auto_increment'),
);
}
}
return $info;
}
public function getTables($dbName='') {
if(!empty($dbName)) {
$sql = 'SHOW TABLES FROM '.$dbName;
}else{
$sql = 'SHOW TABLES ';
}
$result = $this->query($sql);
$info = array();
foreach ($result as $key => $val) {
$info[$key] = current($val);
}
return $info;
}
public function replace($data,$options=array()) {
foreach ($data as $key=>$val){
$value = $this->parseValue($val);
if(is_scalar($value)) { $values[] = $value;
$fields[] = $this->parseKey($key);
}
}
$sql = 'REPLACE INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')';
return $this->execute($sql);
}
public function insertAll($datas,$options=array(),$replace=false) {
if(!is_array($datas[0])) return false;
$fields = array_keys($datas[0]);
array_walk($fields, array($this, 'parseKey'));
$values = array();
foreach ($datas as $data){
$value = array();
foreach ($data as $key=>$val){
$val = $this->parseValue($val);
if(is_scalar($val)) { $value[] = $val;
}
}
$values[] = '('.implode(',', $value).')';
}
$sql = ($replace?'REPLACE':'INSERT').' INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES '.implode(',',$values);
return $this->execute($sql);
}
public function close() {
if ($this->_linkID){
mysql_close($this->_linkID);
}
$this->_linkID = null;
}
public function error() {
$this->error = mysql_errno().':'.mysql_error($this->_linkID);
if('' != $this->queryStr){
$this->error .= "\n [ SQL语句 ] : ".$this->queryStr;
}
trace($this->error,'','ERR');
return $this->error;
}
public function escapeString($str) {
if($this->_linkID) {
return mysql_real_escape_string($str,$this->_linkID);
}else{
return mysql_escape_string($str);
}
}
protected function parseKey(&$key) {
$key = trim($key);
if(!is_numeric($key) && !preg_match('/[,\'\"\*\(\)`.\s]/',$key)) {
$key = '`'.$key.'`';
}
return $key;
}
}