<?php
/* * *********************************************************
 * [cml] (C)2012 - 3000 cml http://linhecheng.com
 * @Author  linhecheng<linhechengbush@gmail.com>
 * @Date: 13-6-26 上午11:23
 * @version  1.0 
 * cml框架 Db抽象基类
 * *********************************************************** */

defined('CML_PATH') || exit();

abstract class DbBase
{
	/**
	 * @var array
	 */
	protected  $conf; //配置

	/**
	 * @var string 表前缀方便外部读取
	 */
	public $tablepre;

	/**
	 * @var array sql组装
	 */
	protected  $_sql = array(
		'where' => '',
		'columns' => '*',
		'limit' => '',
		'orderBy' => '',
		'groupBy' => '',
		'having' => '',
	);

	/**
	 * @var array 操作的表
	 */
	protected  $_table = array();

	/**
	 * @var array 是否内联 array(表名 => 1)
	 */
	protected  $_join = array();

	/**
	 * @var array 是否左联结 array(表名 => 1)
	 */
	protected  $_leftJoin = array();

	/**
	 * @var array 是否右联 array(表名 => 1)
	 */
	protected  $_rightJoin = array();

	/**
	 * @var array 各个联结的on
	 */
	protected  $_joinOn = array();

	/**
	 * @var bool 当前驱动是否为pdo
	 */
	protected  $isPdo = false;


	abstract public function __construct($conf);

	/**
	 * 定义操作的表
	 *
	 * @param string|array $table 表名 要取别名时使用 array(不带前缀表名 => 别名)
	 * @param string $tablepre 表前缀
	 *
	 * @return $this
	 */
	public function table($table = '', $tablepre = null)
	{
		$hasAlias = is_array($table) ? true : false;
		is_null($tablepre) && $tablepre = $this->tablepre;
		$tablename = $tablepre.($hasAlias  ? key($table) : $table);
		if(!isset($this->_table[$tablename])) {
			$this->_table[$tablename] = $hasAlias ? current($table) : null;
		}
		return $this;
	}

	/**
	 * 获取当前db所有表名
	 *
	 * @return string
	 */
	abstract public function getTables();

	/**
	 * 获取表字段
	 *
	 * @param type string $table
	 * @param type mixed $table 表前缀 为null时代表table已经带了前缀
	 * @param type int $filter 0 获取表字段详细信息数组 1获取字段以,号相隔组成的字符串
	 * @return mixed
	 */
	abstract public function getDbFields($table, $tablepre = null, $filter = 0);



	/**
	 * 魔术方法 自动获取相应db实例
	 *
	 * @return  MySQL 连接标识
	 */
	public function __get($db)
	{
		if($db == 'rlink') {
			//如果没有指定从数据库，则使用 MASTER
			if(empty($this->conf['SLAVES'])) {
				$this->rlink = $this->wlink;
				return $this->rlink;
			}

			$n = mt_rand(0, count($this->conf['SLAVES']) - 1);
			$conf = $this->conf['SLAVES'][$n];
			empty($conf['ENGINE']) && $conf['ENGINE'] = '';
			$this->rlink = $this->connect($conf['HOST'], $conf['USERNAME'], $conf['PASSWORD'], $conf['DBNAME'], $conf['CHARSET'], $conf['ENGINE'], $conf['PCONNECT']);
			return $this->rlink;
		} else if($db == 'wlink') {
			$conf = $this->conf['MASTER'];
			empty($conf['ENGINE']) && $conf['ENGINE'] = '';
			$this->wlink = $this->connect($conf['HOST'], $conf['USERNAME'], $conf['PASSWORD'], $conf['DBNAME'], $conf['CHARSET'], $conf['ENGINE'], $conf['PCONNECT']);
			return $this->wlink;
		}
		return false;
	}

	/**
	 * 根据key取出数据
	 *
	 * @param string $key get('user-uid-123');
	 * @param bool $and 多个条件之间是否为and  true为and false为or
	 *
	 * @return array array('uid'=>123, 'username'=>'abc')
	 */
	abstract public function get($key, $and = true);

	/**
	 * 根据key 新增/更新 一条数据
	 *
	 * @param string $key eg 'user-uid-$uid'
	 * @param array $data eg: array('username'=>'admin', 'email'=>'linhechengbush@live.com')
	 * @param bool $and 多个条件之间是否为and  true为and false为or
	 *
	 * @return bool
	 */
	abstract public function set($key, $data, $and = true);

	/**
	 * 根据key更新一条数据
	 *
	 * @param string $key eg 'user-uid-$uid'
	 * @param array $data eg: array('username'=>'admin', 'email'=>'linhechengbush@live.com')
	 * @param bool $and 多个条件之间是否为and  true为and false为or
	 *
	 * @return boolean
	 */
	abstract public function update($key, $data, $and = true);

	/**
	 * 根据key值删除数据
	 *
	 * @param string $key eg: 'user-uid-$uid'
	 * @param bool $and 多个条件之间是否为and  true为and false为or
	 *
	 * @return boolean
	 */
	abstract public function delete($key, $and = true);

	/**
	 * 根据表名删除数据
	 *
	 * @param string $tablename
	 *
	 * @return boolean
	 */
	abstract public function truncate($tablename);

	/**
	 * 获取多条数据
	 *
	 * @return array
	 */
	abstract public function select();

	/**
	 * 获取表主键
	 *
	 * @param type string $table
	 * @param type string $tablepre
	 *
	 * @return string || false
	 */
	public function getPk($table, $tablepre = null)
	{
		$tablename = is_null($tablepre) ? $this->tablepre.$table : $tablepre.$table;
		$rows = $this->getDbFields($tablename);
		foreach($rows as $val) {
			if($val['primary']) {
				return $val['name'];
			}
		}
		return false;
	}

	/**
	 * where条件组装 相等
	 *
	 * @param string|array $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名) 当$column为数组时 批量设置
	 * @param string |int $value 当$column为数组时  此时$value为false时条件为or 否则为and
	 *
	 * @return $this
	 */
	public function where($column, $value)
	{
		if(is_array($column)) {
			foreach($column as $key => $val) {
				!empty($this->_sql['where']) && ($this->_sql['where'] .= ($value === false ? '  OR ' : ' AND '));
				$this->conditionFactory($key, $val, '=');
			}
		} else {
			$this->conditionFactory($column, $value, '=');
		}
		return $this;
	}

	/**
	 * where条件组装 不等
 	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 * @param string |int $value
	 *
	 * @return $this
	 */
	public function whereNot($column, $value)
	{
		$this->conditionFactory($column, $value, '!=');
		return $this;
	}

	/**
	 * where条件组装 大于
	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 * @param string |int $value
	 *
	 * @return $this
	 */
	public function whereGt($column, $value)
	{
		$this->conditionFactory($column, $value, '>');
		return $this;
	}

	/**
	 * where条件组装 小于
	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 * @param string |int $value
	 *
	 * @return $this
	 */
	public function whereLt($column, $value)
	{
		$this->conditionFactory($column, $value, '<');
		return $this;
	}

	/**
	 * where条件组装 大于等于
	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 * @param string |int $value
	 *
	 * @return $this
	 */
	public function whereGte($column, $value)
	{
		$this->conditionFactory($column, $value, '>=');
		return $this;
	}

	/**
	 * where条件组装 小于等于
	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 * @param string |int $value
	 *
	 * @return $this
	 */
	public function whereLte($column, $value)
	{
		$this->conditionFactory($column, $value, '<=');
		return $this;
	}

	/**
	 * where条件组装 in
	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 * @param array $value
	 *
	 * @return $this
	 */
	public function whereIn($column, $value)
	{
		$this->conditionFactory($column, $value, 'IN');
		return $this;
	}

	/**
	 * where条件组装 not in
	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
 	 * @param array $value array(1,2,3)
	 *
	 * @return $this
	 */
	public function whereNotIn($column, $value)
	{
		$this->conditionFactory($column, $value, 'NOT IN');
		return $this;
	}

	/**
	 * where条件组装 LIKE
	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 * @param string |int $value
	 *
	 * @return $this
	 */
	public function whereLike($column, $leftDeper = false, $value, $rightDeper = false)
	{
		$left = $leftDeper ? '%' : '';
		$right = $rightDeper ? '%' : '';
		$this->conditionFactory($column, $left.$this->filterLike($value).$right, 'LIKE');
		return $this;
	}

	/**
	 * where条件组装 LIKE
	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 * @param string |int $value
	 *
	 * @return $this
	 */
	public function whereNotLike($column, $leftDeper = false, $value, $rightDeper = false)
	{
		$left = $leftDeper ? '%' : '';
		$right = $rightDeper ? '%' : '';
		$this->conditionFactory($column, $left.$this->filterLike($value).$right, 'NOT LIKE');
		return $this;
	}

	/**
	 * where 用户输入过滤
	 *
	 * @param string $val
	 *
	 * @return string
	 */
	private function filterLike($val)
	{
		return str_replace(array('_', '%'), '', $val);
	}

	/**
	 * where条件组装 BETWEEN
	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 * @param string |int | array $value
	 * @param string |int | null $value2
	 *
	 * @return $this
	 */
	public function whereBetween($column, $value, $value2 = null)
	{
		if(is_null($value2)) {
			is_array($value) || throw_exception(L('_DB_PRARM_ERROR_WHEREBETWEEN_'));
			$val = $value;
		} else {
			$val = array($value, $value2);
		}
		$this->conditionFactory($column, $val, 'BETWEEN');
		return $this;
	}

	/**
	 * where条件组装 NOT BETWEEN
	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 * @param string |int | array $value
	 * @param string |int | null $value2
	 *
	 * @return $this
	 */
	public function whereNotBetween($column, $value, $value2 = null)
	{
		if(is_null($value2)) {
			is_array($value) || throw_exception(L('_DB_PRARM_ERROR_WHEREBETWEEN_'));
			$val = $value;
		} else {
			$val = array($value, $value2);
		}
		$this->conditionFactory($column, $val, 'NOT BETWEEN');
		return $this;
	}

	/**
	 * where条件组装 IS NULL
	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 *
	 * @return $this
	 */
	public function whereNull($column)
	{
		$this->conditionFactory($column, $value = 'IS', ' NULL');
		return $this;
	}

	/**
	 * where条件组装 IS NOT NULL
	 *
	 * @param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 *
	 * @return $this
	 */
	public function whereNotNull($column)
	{
		$this->conditionFactory($column, $value = 'IS', ' NOT NULL');
		return $this;
	}

	/**
	 *where 语句组装工厂
	 *
	 *@param string $column  如 id  user.id (这边的user为表别名如表pre_user as user 这边用user而非带前缀的原表名)
	 *@param string |int|array $value
	 *@param string $deper
	 *
	 *@return void
	 */
	public function conditionFactory($column, $value, $deper = '=')
	{
		if($this->_sql['where'] == '') $this->_sql['where'] = 'WHERE ';
		if(strpos($column, '.')) {
			$columnArr = explode('.', $column);
			$column = '`'.$columnArr[0].'`.`'.$columnArr[1].'`';
		} else {
			$column = "`{$column}`";
		}

		if($deper == 'IN' || $deper == 'NOT IN') {
			$inValue = '(';
			foreach($value as $val) {
				if($this->isPdo) {
					$inValue .= '? ,';
					$this->bindParams[] = $val;
				} else {
					$inValue .= "'".addslashes($val)."',";
				}
			}
			$this->_sql['where'] .= "{$column} {$deper} ".rtrim($inValue, ',').') ';
		} else if($deper == 'BETWEEN' || $deper == 'NOT BETWEEN') {
			if($this->isPdo) {
				$betweenValue = '? AND ? ';
				$this->bindParams[] = $value[0];
				$this->bindParams[] = $value[1];
			} else {
				$betweenValue = "'".addslashes($value[0])."' AND '".addslashes($value[1])."' ";
			}
			$this->_sql['where'] .= "{$column} {$deper} $betweenValue";
		} else {
			if($this->isPdo) {
				$this->bindParams[] = $value;
				$value = '?';
			} else {
				$value = "'".addslashes($value)."'";
			}
			$this->_sql['where'] .= "{$column} {$deper} {$value} ";
		}
	}

	/**
	 *增加 and条件操作符
	 *
	 * @return $this
	 */
	public function _and()
	{
		$this->_sql['where'] .= ' AND ';
		return $this;
	}

	/**
	 * 增加or条件操作符
	 *
	 * @return $this
	 */
	public function _or()
	{
		$this->_sql['where'] .= ' OR ';
		return $this;
	}

	/**
	 * 选择列
	 *
	 * @param string|array $columns * 选取所有 array('id, 'name')选取id,name两列，array('article.id' => 'aid', 'article.title' =>　'atitle') 别名
	 *
	 * @return $this
	 */
	public function columns($columns = '*')
	{
		$result = '';
		if(is_array($columns)) {
			foreach($columns as $key => $val) {
				if(is_int($key)) {
					$argArr = explode('.', $val);
					$result .= ($result == '' ? '' : ', ')."`{$argArr[0]}`".( isset($argArr[1]) ? ".`{$argArr[1]}`" : '');
				} else {
					$argArr = explode('.', $key);
					$result .= ($result == '' ? '' : ', ')."`$argArr[0]`".( isset($argArr[1]) ? ".`{$argArr[1]}`" : '')." AS `{$val}`";
				}
			}
		} else {
			if(func_num_args() > 1) {
				$args = func_get_args();
				while($arg = current($args)) {
					$argArr = explode('.', $arg);
					$result .= ($result == '' ? '' : ', ')."`{$argArr[0]}`".( isset($argArr[1]) ? ".`{$argArr[1]}`" : '');
					next($args);
				}
			} else {
				$result = "`{$columns}`";
			}
		}
		$this->_sql['columns'] = $result;
		return $this;
	}

	/**
	 * LIMIT
	 *
	 * @param int $limit
	 * @param int $offset
	 *
	 * @return $this
	 */
	public function limit($limit = 0, $offset = 10)
	{
		$limit = intval($limit);
		$offset = intval($offset);
		$limit < 0 && $limit = 0;
		($offset < 1 || $offset > 100) && $offset = 10;
		$this->_sql['limit'] = "LIMIT {$limit}, {$offset}";
		return $this;
	}

	/**
	 * 排序
	 *
	 * @param $column
	 * @param string $order
	 *
	 * @return $this
	 */
	public function orderBy($column, $order = 'ASC')
	{
		if($this->_sql['orderBy'] == '') {
			$this->_sql['orderBy'] = "ORDER BY `{$column}` {$order} ";
		} else {
			$this->_sql['orderBy'] .= ",`{$column}` {$order} ";
		}
		return $this;
	}

	/**
	 * 分组
	 *
	 * @param $column
	 *
	 * @return $this
	 */
	public function groupBy($column)
	{
		if($this->_sql['groupBy'] == '') {
			$this->_sql['groupBy'] = "GROUP BY {$column} ";
		} else {
			$this->_sql['orderBy'] .= ",{$column} ";
		}
		return $this;
	}

	/**
	 * having语句
	 *
	 * @param string $column
	 * @param string $operate
	 * @param string $value
	 *
	 * @return $this
	 */
	public function having($column, $operate = '=', $value)
	{
		$deper = $this->_sql['having'] == '' ? 'HAVING' : ',';
		if($this->isPdo) {
			$this->_sql['having'] = "{$deper} {$column}{$operate}? ";
			$this->bindParams[] = $value;
		} else {
			$value = addslashes($value);
			$this->_sql['having'] = "{$deper} {$column}{$operate}'{$value}' ";
		}
		return $this;
	}

	/**
	 * join内联结
	 *
	 * @param string|array $table 表名 要取别名时使用 array(不带前缀表名 => 别名)
	 * @param string $on 如：'c.cid = a.cid'
	 *
	 * @return $this
	 */
	public function join($table, $on)
	{
		$this->table($table);
		$hasAlias = is_array($table) ? true : false;
		$tablename = $this->tablepre.($hasAlias  ? key($table) : $table);
		$this->_join[$tablename] = 1;
		$this->_joinOn[] = addslashes($on); //这边是程序员自己写死的数据以防万一还是过滤一下
		return $this;
	}

	/**
	 * leftJoin左联结
	 *
	 * @param string|array $table 表名 要取别名时使用 array(不带前缀表名 => 别名)
	 * @param string $on
	 *
	 * @return $this
	 */
	public function leftJoin($table, $on)
	{
		$this->table($table);
		$hasAlias = is_array($table) ? true : false;
		$tablename = $this->tablepre.($hasAlias  ? key($table) : $table);
		$this->_leftJoin[$tablename] = 1;
		$this->_joinOn[] = addslashes($on);
		return $this;
	}

	/**
	 * rightJoin右联结
	 *
	 * @param string|array $table 表名 要取别名时使用 array(不带前缀表名 => 别名)
	 * @param string $on
	 *
	 * @return $this
	 */
	public function rightJoin($table, $on)
	{
		$this->table($table);
		$hasAlias = is_array($table) ? true : false;
		$tablename = $this->tablepre.($hasAlias  ? key($table) : $table);
		$this->_rightJoin[$tablename] = 1;
		$this->_joinOn[] = addslashes($on);
		return $this;
	}

	/**
	 * orm参数重置
	 *
	 */
	protected  function reset()
	{
		$this->_sql = array(  //sql组装
			'where' => '',
			'columns' => '*',
			'limit' => '',
			'orderBy' => '',
			'groupBy' => '',
			'having' => '',
		);

		$this->_table = array(); //操作的表
		$this->_join = array(); //是否内联 array(表名 => 1)
		$this->_leftJoin = array(); //是否左联结 array(表名 => 1)
		$this->_rightJoin = array(); //是否右联 array(表名 => 1)
		$this->_joinOn = array(); //各个联结的on
	}

	/**
	 *SQL语句条件组装
	 *
	 *@param array $arr; 要组装的数组
	 *@param string $tablename 当前操作的数据表名
	 *@param string $tablepre 表前缀
	 *
	 *@return string
	 */
	protected function arrToCondition($arr, $tablename, $tablepre)
	{
		empty($tablename) && $tablename = CML_CONTROLLER_NAME;
		$dbFields = M()->db()->getDbFields($tablepre.$tablename);
		foreach(array_keys($arr) as $key) {
			if(!isset($dbFields[$key]))  unset($arr[$key]); //过滤db表中不存在的字段
		}
		$s = '';
		foreach($arr as $k => $v) {
			if($this->isPdo) {
				$s .= (empty($s) ? '' : ',')."`{$k}`= ?";
				$this->bindParams[] = $v;
			} else  {
				$s .= (empty($s) ? '' : ',')."`{$k}`='".addslashes($v)."'";
			}
		}
		return $s;
	}

	/**
	 *SQL语句条件组装
	 *
	 *@param string $key eg: 'forum-fid-1-uid-2'
	 *@param bool $and 多个条件之间是否为and  true为and false为or
	 *@param bool $NoCondition 是否为无条件操作  set/delete/update操作的时候 condition为空是正常的不报异常
	 *@param bool $noTable 是否可以没有数据表 当delete/update等操作的时候已经执行了table() table为空是正常的
	 *
	 *@return array eg: array('forum', "`fid` = '1' AND `uid` = '2'")
	 */
	protected function parseKey($key, $and = true, $NoCondition = false, $noTable = false)
	{
		$condition = '';
		$arr = explode('-', $key);
		$len = count($arr);
		for($i = 1; $i < $len; $i += 2) {
			if($this->isPdo) {
				isset($arr[$i + 1]) &&	$condition .= ($condition ? ($and ? ' AND ' : ' OR ') : '')."`{$arr[$i]}` = ?";
				$this->bindParams[] = $arr[$i + 1];
			} else {
				isset($arr[$i + 1]) &&	$condition .= ($condition ? ($and ? ' AND ' : ' OR ') : '')."`{$arr[$i]}` = '".addslashes($arr[$i + 1])."'";
			}
		}
		$table = strtolower($arr[0]);
		(empty($table) && $noTable !=1)&& throw_exception(L('_DB_PRARM_ERROR_PARSE_KEY_', null, $key, 'table'));
		(empty($condition) && $NoCondition !=1) && throw_exception(L('_DB_PRARM_ERROR_PARSE_KEY_', null, $key, 'condition'));
		empty($condition) || $condition = "($condition)";
		return array($table, $condition);
	}

	/**
	 *获取一条数据
	 *
	 *@param string $sql sql语句
	 *
	 *@return  array
	 */
	abstract public function one($sql, $link = null);

	/**
	 *统计符合条件的数据有多少条
	 *
	 *@param string $tablename 表名
	 *
	 *@return int
	 */
	abstract public function count($tablename = '');

	/**
	 *取出表某列的最大值
	 *
	 *@param string $key eg： user-id
	 *
	 *@return int
	 */
	abstract public function max($key = '');

	/**
	 *取出表某列的最小值
	 *
	 *@param string $key eg： user-id
	 *
	 *@return int
	 */
	abstract public function min($key = '');

	/**
	 *执行sql并返回资源标识符 适用于select
	 *
	 * @param string $sql
	 * @param object $link
	 *
	 * @return mixed
	 */
	abstract public function query($sql, $link = null);

	/**
	 * 执行一条sql语句并返回受影响的行数 适用于 update|insert|delete php_mysql统一用mysql_query
	 *
	 * @param string $sql
	 * @param object $link
	 *
	 * @return int||false
	 */
	abstract public function exec($sql, $link = null);

	/**
	 * 获取query执行的结果
	 *
	 * @param $handle mysql result
	 *
	 * @return array
	 */
	abstract public function getQuery($handle);



	/**
	 * 返回select语句返回结果集中行的数目
	 *
	 * @param $handle mysql result
	 *
	 * @return int
	 */
	abstract public function numRows($handle);

	/**
	 * 返回INSERT，UPDATE 或 DELETE 查询所影响的记录行数。
	 *
	 * @param resource $handle mysql link
	 *
	 * @return int
	 */
	abstract public function affectedRows($handle);



	/**
	 * 返回结果集中一个字段的值
	 *
	 * @param resource $result 结果标识符
	 * @param int $row 行号
	 * @param string | int 要获取的字段
	 *
	 * @return string
	 */
	abstract public function result($result, $row = 1, $field = 0);

	/**
	 *获取上一INSERT的主键值
	 *
	 *@param resource $link
	 *
	 *@return int
	 */
	abstract public function insertId($link = null);

	/**
	 * 指定字段的值+1
	 *
	 * @param string $key user-id-1
	 * @param int $val
	 * @param string $field 要改变的字段
	 *
	 * @return bool
	 */
	abstract public function increment($key, $val = 1, $field = null);

	/**
	 * 指定字段的值-1
	 *
	 * @param string $key user-id-1
	 * @param int $val
	 * @param string $field 要改变的字段
	 *
	 * @return bool
	 */
	abstract public function decrement($key, $val = 1, $field = null);

	/**
	 * Db连接
	 *
	 * @param string $host
	 * @param string $user,
	 * @param string $password
	 * @param string $name
	 * @param string $charset
	 * @param string $engine
	 *
	 * @return resource
	 */
	abstract public function connect($host, $username, $password, $dbname, $charset = 'utf8', $engine = '', $pconnect = false);

	/**
	 *析构函数
	 *
	 */
	abstract public function __destruct();

	/**
	 *获取mysql 版本
	 *
	 *@param resource $link
	 *
	 *@return string
	 */
	abstract public function version($link = null);

	/**
	 * 开启事务
	 *
	 * @return bool
	 */
	abstract public function  startTransAction();

	/**
	 * 提交事务
	 *
	 * @return bool
	 */
	abstract public function commit();

	/**
	 * 回滚事务
	 *
	 * @return bool
	 */
	abstract public function rollBack();

}