<?php

/**
 *--------------------------------------
 * MySQL 数据库类
 *--------------------------------------
 * @project		: pfa
 * @author		: cblee
 * @created		: 2012-9-24
 * @copyright	: (c)2012 AsThis
 *--------------------------------------
 */

class DbMysql extends Db
{
	/* 构造函数 读取数据库配置信息 */
	public function __construct($dbCfg='')
	{
		if(!extension_loaded('mysql'))
		{
			halt(L('_NOT_SUPPERT_').':mysql');
		}
		if(!empty($dbCfg))
		{
			$this->dbCfg = $dbCfg;
			if(empty($this->dbCfg['params']))
			{
				$this->dbCfg['params'] = '';
			}
		}
		$this->init_connect();
	}

	/* 连接数据库 */
	public function connect($dbCfg = '', $linkNum = 0)
	{
		if(!isset($this->linkID[$linkNum]))
		{
			if(empty($dbCfg))
			{
				$dbCfg = $this->dbCfg;
			}
			$host = $dbCfg['hostname'].($dbCfg['hostport'] ? ":{$dbCfg['hostport']}" : '');
			$pconnect = !empty($dbCfg['params']['persist']) ? $dbCfg['params']['persist'] : false;
			if($pconnect)
			{
				$this->linkID[$linkNum] = mysql_pconnect($host, $dbCfg['username'], $dbCfg['password'], 131072);
			}
			else
			{
				$this->linkID[$linkNum] = mysql_connect($host, $dbCfg['username'], $dbCfg['password'], true, 131072);
			}
			if(!$this->linkID[$linkNum] || (!empty($dbCfg['database']) && !mysql_select_db($dbCfg['database'], $this->linkID[$linkNum])))
			{
				halt(mysql_error());
			}
 
			$dbVersion = mysql_get_server_info($this->linkID[$linkNum]);
			mysql_query("SET NAMES '".C('DB.CHARSET')."'", $this->linkID[$linkNum]);
			if($dbVersion >'5.0.1')
			{
				mysql_query("SET sql_mode=''", $this->linkID[$linkNum]); /* 设置 sql_model */
			}
			$this->connected = true; /* 标记连接成功 */
			if(1 != C('DB.DEPLOY_TYPE'))
			{
				unset($this->dbCfg); /* 注销数据库安全信息*/
			}
		}
		return $this->linkID[$linkNum];
	}

	/* 查询 */
	public function query($sql)
	{
		/* 存储过程查询支持 */
		if(0 === stripos($sql, 'call'))
		{
			$this->close();
			$this->connected = false;
		}
		$this->init_connect(false);
		if(!$this->_linkID)
		{
			return false;
		}
		$this->queryStr = $sql;
		if($this->queryID)
		{
			$this->free(); /* 释放前次查询结果 */
		}
		N('db_query', 1); /* 记录数据库操作次数 */
		G('queryStartTime'); /* 记录开始执行时间 */
		$this->queryID = mysql_query($sql, $this->_linkID);
		$this->debug();
		if(false === $this->queryID)
		{
			$this->error();
			return false;
		}
		else
		{
			$this->numRows = mysql_num_rows($this->queryID);
			$this->numCols = mysql_num_fields($this->queryID);
			return $this->get_all();
		}
	}

	/* 执行 */
	public function execute($sql)
	{
		$this->init_connect(true);
		if(!$this->_linkID)
		{
			return false;
		}
		$this->queryStr = $sql;
		if($this->queryID)
		{
			$this->free(); /* 释放前次查询结果*/
		}
		N('db_write', 1); /* 记录数据库操作次数 */
		G('queryStartTime'); /* 记录开始执行时间 */
		$result = mysql_query($sql, $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 replace($data, $options = array())
	{
		foreach($data as $key => $val)
		{
			$value = $this->parse_value($val);
			if(is_scalar($value)) /* 过滤非标量数据 */
			{
				$values[] = $value;
				$fields[] = $this->parse_key($key);
			}
		}
		$sql = 'REPLACE INTO '.$this->parse_table($options['table']).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')';
		return $this->execute($sql);
	}

	/* 获得所有的查询数据 */
	private function get_all()
	{
		$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 get_tables($dbName = '')
	{
		$sql = !empty($dbName) ? 'SHOW TABLES FROM '.$dbName : 'SHOW TABLES ';
		$result = $this->query($sql);
		$info = array();
		if($result)
		{
			foreach($result as $key => $val)
			{
				$info[$key] = current($val);
			}
		}
		return $info;
	}

	/* 取得数据表的字段信息 */
	public function get_fields($tableName)
	{
		$result = $this->query('SHOW COLUMNS FROM '.$this->parse_key($tableName));
		$info = array();
		if($result)
		{
			foreach($result as $key => $val)
			{
				$info[$val['Field']] = array(
					'name'	=> $val['Field'],
					'type'	=> $val['Type'],
					'notnull' => (bool)($val['Null'] === ''), /* not null is empty, null is yes */
					'default' => $val['Default'],
					'primary' => (strtolower($val['Key']) == 'pri'),
					'autoinc' => (strtolower($val['Extra']) == 'auto_increment'),
				);
			}
		}
		return $info;
	}

	/* 启动事务 */
	public function start_trans()
	{
		$this->initConnect(true);

		if(!$this->_linkID)
		{
			return false;
		}
		/* 数据rollback 支持  */
		if(0 == $this->transTimes)
		{
			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)
			{
				halt($this->error());
			}
		}
		return true;
	}

	/* 事务回滚 */
	public function rollback()
	{
		if($this->transTimes > 0)
		{
			$result = mysql_query('ROLLBACK', $this->_linkID);
			$this->transTimes = 0;
			if(!$result)
			{
				halt($this->error());
			}
		}
		return true;
	}

	/* 插入记录 */
	public function insert_all($datas, $options = array(), $replace = false)
	{
		if(!is_array($datas[0]))
		{
			return false;
		}
		$fields = array_keys($datas[0]);
		array_walk($fields, array($this, 'parse_key'));
		$values =  array();
		foreach($datas as $data)
		{
			$value = array();
			foreach($data as $val)
			{
				$val = $this->parse_value($val);
				if(is_scalar($val)) /* 过滤非标量数据 */
				{
					$value[] = $val;
				}
			}
			$values[] = '('.implode(',', $value).')';
		}
		$sql = ($replace ? 'REPLACE':'INSERT').' INTO '.$this->parse_table($options['table']).' ('.implode(',', $fields).') VALUES '.implode(',',$values);
		return $this->execute($sql);
	}

	/* 字段名和表名处理 */
	protected function parse_key(&$key)
	{
		$key = trim($key);
		if(!preg_match('/[,\'\"\*\(\)`.\s]/', $key))
		{
			$key = '`'.$key.'`';
		}
		return $key;
	}

	/* 转义SQL特殊字符 */
	protected function escape_string($str)
	{
		if($this->_linkID)
		{
			return mysql_real_escape_string($str, $this->_linkID);
		}
		else
		{
			return mysql_escape_string($str);
		}
	}

	/* 释放查询结果 */
	public function free()
	{
		mysql_free_result($this->queryID);
		$this->queryID = null;
	}

	/* 关闭数据库 */
	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->debug && '' != $this->queryStr)
		{
			$this->error .= "\r\n [ SQL ] : ".$this->queryStr;
		}
		return $this->error;
	}
}

?>