<?php
namespace Qii\Driver\Mysql;

use Qii\Driver\Base;
use Qii\Driver\ConnIntf;
use Qii\Driver\Intf;
use Qii\Driver\Response;


class Driver extends Base implements Intf
{
	const VERSION = '1.2';
	private static $_instance;
	protected $connection;
	private $sysConfigure;
	private $rs;
	public $db;
	/**
	 * 是否开启调试
	 *
	 * @var BOOL
	 */
	public $_debugSQL = false;
	/**
	 * 执行SQL的列表
	 *
	 * @var Array
	 */
	public $_exeSQL = array();
	/**
	 * 查询次数
	 *
	 * @var int $queryTimes
	 */
	public $queryTimes = 0;
	/**
	 * 查询耗时
	 *
	 * @var array $querySeconds
	 */
	public $querySeconds = array();

	/**
	 * 最后一次执行的SQL
	 *
	 * @var unknown_type
	 */
	private $sql;
	/**
	 * 是否开启执行SQL的时间
	 *
	 * @var BOOL
	 */
	public $_debugTime = false;
	public $_errorInfo = array();
	/**
	 * 保存未定义变量
	 *
	 * @var Array
	 */
	private $_undefined;
	/**
	 * @var string $charset 数据库默认编码
	 */
	public $charset = 'utf8mb4';
	/**
	 * @var array $currentDB 当前数据库信息
	 */
	public $currentDB;
	/**
	 * @var string $markKey 用于保存数据库执行相关信息
	 */
	public $markKey = '__model';
	/**
	 * @var string $response Response对象
	 */
	public $response;

	public function __construct(ConnIntf $connection)
	{
		parent::__construct();
		$this->connection = $connection;
		$this->sysConfigure = $this->connection->getDBInfo();
		$this->currentDB = $this->sysConfigure['master']['db'];
		$this->response = new Response();
	}

	/**
	 * 用户直接输出这个实例化的类后会输出当前类的名称
	 *
	 * @return String
	 */
	public function __toString()
	{
		return get_class($this);
	}

	public function setQuery($sql)//查询预处理
	{
		return $this->query($sql);
	}

	public function query($sql)//查询
	{
		/**
		 * 如果调试SQL的话就启用时间的记录
		 */
		if ($this->_debugSQL) {
			$startTime = microtime(true);
		}
		$this->sql = $sql;
		$this->db['CURRENT'] = $this->connection->getConnectionBySQL($this->sql);
		if (!empty($this->sysConfigure['charset'])) {
			\mysql_query($this->db['CURRENT'], "SET CHARACTER SET {$this->sysConfigure['charset']}");
		} else {
			\mysql_query($this->db['CURRENT'], "SET CHARACTER SET utf8mb4");
		}

		$this->rs = $rs = \mysql_query($this->db['CURRENT'], $sql);
		$this->setError();
		if (!$rs) {
			$error = $this->getError('error');
			return \Qii::setError(false, __LINE__, 1509, $sql, $error[2] == '' ? 'NULL' : $error[2]);
		}
		$this->queryTimes++;
		/**
		 * 如果调试SQL的话就启用时间的记录
		 */
		if ($this->_debugSQL) {
			$endTime = microtime(true);
			$costTime = sprintf('%.4f', ($endTime - $startTime));
			$this->querySeconds[$this->queryTimes]['sql'] = $sql;
			$this->querySeconds[$this->queryTimes]['costTime'] = $costTime;
			$this->querySeconds[$this->queryTimes]['startTime'] = $startTime;
			$this->querySeconds[$this->queryTimes]['endTime'] = $endTime;
		}
		return $rs;
	}

	/**
	 * 执行SQL
	 *
	 * @param String $sql
	 * @return Int
	 */
	public function exec($sql)
	{
		$this->setQuery($sql);
		return $this->affectedRows();
	}

	public function getRow($sql)//获取一行
	{
		if (!preg_match("/LIMIT(\s){1,}(\d){1,},(\s){0,}(\d){1,}/u", $sql) && !preg_match("/LIMIT(\s){1,}(\d){1,}/u", $sql)) {
			$sql = $sql . " LIMIT 1";
		}
		$rs = $this->query($sql);
        if (!$rs) {
            return false;
        }
		return \mysql_fetch_assoc($rs);
	}

	public function getOne($sql)//获取一列
	{
		$data = $this->getRow($sql);
        if (!$data) {
            return null;
        }
		return array_shift($data);
	}

	public function getAll($sql)//获取所有的行
	{
		$data = array();
		$rs = $this->query($sql);
        if (!$rs) {
            return $data;
        }
		while ($row = \mysql_fetch_assoc($rs)) {
			$data[] = $row;
		}
		return $data;
	}

	/**
	 * 获取一行
	 *
	 * @param Resource $rs
	 * @return Array
	 */
	public function fetch($rs = null)
	{
		if (!$rs) return \mysql_fetch_assoc($this->rs);
		return \mysql_fetch_assoc($rs);
	}

	public function transaction()//事务处理
	{
		return \mysql_query('begin');
	}

	public function commit()//事务提交
	{
		$r1 = \mysql_query('commit');
        $r2 = \mysql_query('end');
        return $r1 && $r2;
	}

	public function rollback()//事务回滚
	{
		return \mysql_query('rollback');
	}

	public function affectedRows()//返回影响的行数
	{
		return \mysql_affected_rows($this->db['CURRENT']);
	}

	public function lastInsertId()//返回自增长ID
	{
		return \mysql_insert_id($this->db['CURRENT']);
	}

	/**
	 * 获取最后一次出错的信息
	 *
	 * @return Array
	 */
	public function getError($key = '')
	{
		$errorInfo = array_pop($this->_errorInfo);
		if ($errorInfo) {
			//将错误加回来
			array_push($this->_errorInfo, $errorInfo);
			if (!empty($key)) {
				return $errorInfo[$key];
			}
			return $errorInfo;
		}
		return false;
	}

	/**
	 * 是否有错，有错误的话存储错误
	 *
	 */
	public function setError()//设置错误
	{
		if (\mysql_errno($this->db['CURRENT'])) {
			$this->_errorInfo[$this->queryTimes]['sql'] = $this->sql;
			$this->_errorInfo[$this->queryTimes]['error'][2] = $this->iconv(\mysql_error($this->db['CURRENT']));
			$this->response = Response::Fail('mysql.error', $this->_errorInfo);
		}
	}

	/**
	 * 是否执行出错
	 *
	 * @return Bool
	 */
	public function isError()
	{
		if ($this->getError()) {
			return true;
		}
		return false;
	}

	/**
	 * 返回response对象
	 *
	 * @return Bool
	 */
	public function getResponse()
	{
		return $this->response;
	}
}