<?php
class mysql
{
	private  $mlink=null;//主库
	private	$slink=null;//从库
	public	$dbconfig=array();//配置
	public	$charset="utf8";//编码
	public	$testmodel=false;//测试模式 开启后将会输出错误的sql语句
	public $cache;
	public $base;
	/**
	*mysql初始化 
	*/
	 public function __construct($data=array("charset"=>"utf8")){
		 
		 if(!defined("TABLE_PRE")){
			 define("TABLE_PRE","");
		 }
		 $this->charset=$data['charset'];
		 if(defined("TESTMODEL") && TESTMODEL==true){
			 $this->testmodel=true;
		 }
		 
	 }
	 
	 public function setCache(){
		 if($this->base->cache){
			 $this->cache=$this->base->cache;
		 }else{
			 require_once(ROOT_PATH."skymvc/class/cls_cache.php");
			 $this->cache=new cache();
		 }
	 }
	 /**
	  * 设置参数
	  * $config=array(
	  * 	"master"=>array("localhost","root","password","database"),//主数据库 必须的 以下从数据库非必须
	  * 	"slave"=>array(
	  * 				array("slave1","root","password","database"),
	  * 				array("slave2","root","password","database"),
	  * 			),
	  * )
	  */
	 public function set($config){
		 $this->dbconfig=$config;
	 }
	 /*
	  * 连接mysql
	  * */
	 public function connect(){
	 	//主库	 	 
	 	$master=$this->dbconfig['master'];
	 	$this->mlink=$this->slink=mysql_connect($master[0],$master[1],$master[2],true);
		if(!$this->mlink){
			 exit('mysql服务器配置出错');
		}
	 	if($this->mlink){
			$db=mysql_select_db($master[3]) or die('mysql数据库选择出错');
	 		if($db){
	 			mysql_query("SET sql_mode=''",$this->mlink);
	 			mysql_query("SET NAMES ".$this->charset,$this->mlink);
	 		}
	 	}
	 	//从库
	 	if(!empty($this->dbconfig['slave'])){
			$k=rand(0,count($this->dbconfig['slave'])-1);
	 		$slave=$this->dbconfig['slave'][$k];
		 	$this->slink=@mysql_connect($slave[0],$slave[1],$slave[2]) ;
		 	if($this->slink){
		 		if(mysql_select_db($slave[3])  ){
		 			mysql_query("SET sql_mode=''",$this->slink);
		 			mysql_query("SET NAMES ".$this->charset,$this->slink);
		 		}else{
					$this->slink=$this->mlink;
				}
		 	}
	 	}
	 	/*主从防止出错*/
	 	$this->slink=$this->slink?$this->slink:$this->mlink;
	 	$this->mlink=$this->mlink?$this->mlink:$this->slink;
	 }
	 /**
	  * 执行sql语句
	  */
	 public function query($sql){
		if($this->testmodel){
			$this->base->skysqlrun .="\r\n".$sql;
			$this->base->skysqlnum ++;
		}
	 	if($this->isselect($sql)){
	 		return $this->slave_query($sql);
	 	}else{
	 		return $this->master_query($sql);
	 	}
	 }
	 
	 /**
	  * 主库执行sql
	  */
	 public function master_query($sql){
		$s=microtime(true);
	 	if(@!mysql_ping($this->mlink)){
			@mysql_close($this->mlink);
			$this->connect();					
		}
		 
		$res=mysql_query($sql,$this->mlink);
		if($this->error($this->mlink)){
			if($this->testmodel){
				echo str_replace(TABLE_PRE,"",$sql).$this->error($this->mlink);
			}
			exit("sql语句出错了");
		}
		$_ENV['query_time']+=microtime(true)-$s;
		return $res;
	 }
	 
	 
	 
	 
	 /**
	  * 从库执行sql
	  */
	 public function slave_query($sql){
	 	$s=microtime(true);
		if(@!mysql_ping($this->slink)){
			@mysql_close($this->slink);
			$this->connect();					
		}
		$res=mysql_query($sql,$this->slink);
		if($this->error($this->slink)){
			if($this->testmodel){
				echo str_replace(TABLE_PRE,"",$sql).$this->error($this->mlink);
			}
			exit("sql语句出错了");
		} 
		$_ENV['query_time']+=microtime(true)-$s;
		return $res;
	 }
	 
	 /**
	  * 返回结果集中的数目
	  */
	public function num_rows($res){
		return mysql_num_rows($res);
	}
	
	/**
	 * 将结果集解析成数组
	 */
	public function fetch_array($res,$result_type=MYSQL_ASSOC){
		return mysql_fetch_array($res,$result_type);	
	}
	
	/**
	 * 从结果集中取一行
	 */
	public function fetch_row($res){
		return mysql_fetch_row($res);	
	}
	
	/**
	 * 取得结果集中字段的数目
	 */
	public function num_fields($res){
		return mysql_num_fields($res);
	}
	
	/*
	 * 插入数据
	 * */
	public function insert($table,$data){
		$fields=$this->compile_array($data);
		$this->query("INSERT INTO ".TABLE_PRE.$table." SET $fields ",$this->mlink);
		return $this->insert_id($this->mlink);
	}
	/**
	 * 更新数据
	 */
	public function update($table,$data,$w=""){
		$fields=$this->compile_array($data);
		$where=$w?" WHERE ".$this->compile_array($w," AND"):"";
		$this->query("UPDATE ".TABLE_PRE.$table." SET {$fields} {$where} ",$this->mlink);
		return $this->affected_rows($this->mlink);
	}
	/**
	 * 删除数据
	 */
	public function delete($table,$w=''){
		$where=$w?" WHERE ".$this->compile_array($w," AND "):"";
		$this->query("DELETE FROM ".TABLE_PRE."$table {$where} ");
		return $this->affected_rows($this->mlink);		
	} 
	
	/**
	 * 获取全部数据
	 *array("table","where"=>array(),"order","start","pagesize","fields")
	*/
	public function SELECT($table,$data=array(),&$rscount=false,$cache=0,$expire=60){		
		$start=isset($data['start'])?$data['start']:0;
		$pagesize=isset($data['limit'])?$data['limit']:1000;
		$fields=isset($data['fields'])?$data['fields']:" * ";
		$where=(!isset($data['where']) or empty($data['where']))?"":" where ".$this->compile_array($data['where']," AND ");
		$order=isset($data['order']) && !empty($data['order'])?" ORDER BY ".$data['order']:"";
		if($rscount){
			$rscount=$this->getCount($table,isset($data['where'])?$data['where']:'',$cache,$expire);
		}
		return $this->getAll("SELECT {$fields} FROM ".TABLE_PRE."{$table}  $where {$order} LIMIT $start,$pagesize ",$cache,$expire);
		
	}
	/**
	 * 获取一个数据
	 *array("table","where","order","start","pagesize","fields")
	*/
	public function selectOne($table,$data=array(),$cache=0,$expire=60){
		$start=isset($data['start'])?$data['start']:0;
		$pagesize=isset($data['limit'])?$data['limit']:1;
		$fields=isset($data['fields'])?$data['fields']:" * ";
		$where=(!isset($data['where']) or empty($data['where']))?"":" where ".$this->compile_array($data['where']," AND ");
		$order=isset($data['order']) && !empty($data['order'])?" ORDER BY ".$data['order']:"";
		return $this->getOne("SELECT {$fields} FROM ".TABLE_PRE."{$table}  {$where} {$order} LIMIT 1 ",$cache,$expire);
	}
	/**
	 * 获取一行数据
	 *array("table","where","order","start","pagesize","fields")
	*/
	public function selectRow($table,$data=array(),$cache=0,$expire=60){
		$start=isset($data['start'])?$data['start']:0;
		$pagesize=isset($data['limit'])?$data['limit']:1;
		$fields=isset($data['fields'])?$data['fields']:" * ";
		$where=(!isset($data['where']) or empty($data['where']))?"":" where ".$this->compile_array($data['where']," AND ");
		$order=isset($data['order']) && !empty($data['order'])?" ORDER BY ".$data['order']:"";
		return $this->getRow("SELECT {$fields} FROM ".TABLE_PRE."{$table}  {$where} {$order} LIMIT 1 ",$cache,$expire);
	}
	/**
	 * 获取一列数据
	 *array("table","where","order","start","pagesize","fields")
	*/	
	public function selectCols($table,$data=array(),&$rscount=false,$cache=0,$expire=60){
		$start=isset($data['start'])?$data['start']:0;
		$pagesize=isset($data['limit'])?$data['limit']:1000;
		$fields=isset($data['fields'])?$data['fields']:" * ";
		$where=(!isset($data['where']) or empty($data['where']))?"":" where ".$this->compile_array($data['where']," AND ");
		$order=isset($data['order']) && !empty($data['order'])?" ORDER BY ".$data['order']:"";
		if($rscount){
			$rscount=$this->getCount($table,isset($data['where'])?$data['where']:'',$cache,$expire);
		}
		return $this->getCols("SELECT {$fields} FROM ".TABLE_PRE."{$table}  {$where} {$order} LIMIT $start,$pagesize ",$cache,$expire);
	}
	
	
	
	/**
	 * 获取统计数据
	 */	
	public function getCount($table,$w=array(),$cache=0,$expire=60){
		
		$where=empty($w)?"":" where ".$this->compile_array($w," AND ");
		return $this->getOne("SELECT COUNT(*) FROM ".TABLE_PRE.$table." $where ",$cache,$expire);
	}
	/**
	 * 获取全部数据
	 */
	public function getAll($sql,$cache=0,$expire=60){
		if($cache){
			$key=$this->md5key($sql);
			if($data=$this->cache->get($key)) return $data;
		}
		$res=$this->query($sql);
		if($res!==false)
		{
			$arr=array();
			while ($rs=mysql_fetch_array($res,MYSQL_ASSOC))
			{
				$arr []=$rs;
			}
			if($cache) $this->cache->set($key,$arr,$expire);
			return $arr;
		}else
		 {
			return false;
			
		}
	}

	/**
	 * 获取一个字段
	 */
	public function getOne($sql,$cache=0,$expire=60){
		if($cache){
			$key=$this->md5key($sql);
			if($data=$this->cache->get($key)) return $data;
		}
		$res=$this->query($sql);
		if($res !==false){
			$rs=mysql_fetch_row($res);
			if($rs!==false){
				if($cache) $this->cache->set($key,$rs[0],$expire);
				return $rs[0];
			}else{
				return '';
			}
		}
		else {
			return false;
		}
		
	}
		
	/*获取一行*/
	 public function getRow($sql,$cache=0,$expire=60){
		 if($cache){
			$key=$this->md5key($sql);
			if($data=$this->cache->get($key)) return $data;
		}
        $res = $this->query($sql);
        if ($res !== false){
			$arr=mysql_fetch_array($res,MYSQL_ASSOC);
			if($cache) $this->cache->set($key,$arr,$expire);
            return $arr;
        }else{
            return false;
        }
    }
    /*获取一列*/
    public function getCols($sql)
	{
		if($cache){
			$key=$this->md5key($sql);
			if($data=$this->cache->get($key)) return $data;
		}
		$res=$this->query($sql);
		if($res!==false){
			$arr=array();
			while($rs=mysql_fetch_array($res)){
				$arr[]=$rs[0];
			}
			if($cache) $this->cache->set($key,$arr,$expire);
			return $arr;
		}else{
			return false;
		}
	}
	
	/**
	 * 获取影响的行数
	 */
	public function affected_rows($link){
		return  mysql_affected_rows($link);
	}
	/*
	 * 最新插入的函数
	 * */
	public function insert_id( ){
        return mysql_insert_id($this->mlink);
    }
    /*
     * 获取错误信息
     * */
    public function error($link=null){
        return mysql_error($link);
    }
	/*
	 * 获取错误代号
	 * */
    public function errno($link=null){
        return mysql_errno($link);
    }
	
	
	 /*
	  * 判断是否查询语句
	  * */
	 public function isselect($sql){ 		
		preg_match("/^[ ]*(select).*/i",$sql,$a);
		if($a)
		{
			return true;
		}else{
			return false;
		}
 
	 }
	/*字符串转义*/ 
	public function newaddslashes($value){
		 
		if(empty($value)){
			return $value;
		}else{
			if(is_array($value)){
				 return array_map('newaddslashes', $value);
			}else{				
				$value=stripslashes($value);
				$value=str_replace("\'","'",$value);  
				$value=str_replace('\"','"',$value);
				$value=addslashes(trim($value));				
				return $value;	
			}
		}	 
	}
	
	public function compile_array($data,$d=","){
		
		$dot=$fields="";
		$i=0;
		if(is_array($data)){ 
			foreach($data as $k=>$v){
				if($i>0) $dot=$d;
				if(preg_match("/[<|>]/",$k)){
					$fields.="$dot {$k}'".$this->newaddslashes($v)."' ";
				}else{
					$fields.="$dot $k='".$this->newaddslashes($v)."' ";
				}
				$i++;	
			}
			return $fields;
		}else{
			return $data;
		}
	}
	
	public function __destruct(){
		 
	}
	
	public function close(){
		@mysql_close($this->mlink);
		@mysql_close($this->slink);
	}
	/*生成md5缓存的key*/
	public function md5key($sql){
		$key=md5($sql);
		preg_match("/from(.*)where/i",$sql,$data);
		$table=trim($data[1]);
		return "sql".$table."_".$key;
	}
	 

}	



