<?php
/*
 * 数据处理类 Dao
 * Fisher 2013-5-27
*/
class Dao
{
	public	$db;
	public	$dbback;

	public	$mc;

	private $db_type;
	private $debug;

	public function __construct($db_type = "mysql")
	{
		$this->db_type = $db_type;
		$this->setDebug();
	}
	
	//开启Debug
	public function setDebug($debug = false)
	{
		$this->debug = $debug;
	}
	
	//初始化数据库
	public function initDb($db_class_path = "", $db_conf = array(), $dbback_conf = array())
	{
		if(!is_object($this->db) && !is_object($this->dbback))
		{
			if($db_class_path != "")
			{
				$this->_autoLoad($db_class_path);
				
				if(class_exists("TINY_ADODB"))
				{
					if(is_array($db_conf) && !empty($db_conf))
					{
						$this->db = $this->_initDb($db_conf);

						if(is_array($dbback_conf) && !empty($dbback_conf))
						{
							$this->dbback = $this->_initDb($dbback_conf);
						}
						else
						{
							$this->dbback = $this->db;
						}
					}
					else
					{
						$this->_showError("主库配置必须设置!");
					}
				}
				else
				{
					$this->_showError("DB类不存在!");
				}
			}
			else
			{
				$this->_showError("DB类路径必须设置!");
			}
		}
	}

	//初始化MC缓存
	public function initMc($localhost = "", $port = "")
	{
		if(!is_object($this->mc) && $localhost != "" && $port != "")
		{
			$this->mc = new Memcache;
			$this->mc->connect($localhost, $port) or $this->_showError("Memcache初始化失败!");
		}
	}
	
	//实例化数据库对象，不同数据库类定义不同init方法即可
	private function _initDb($db_conf)
	{
		$dbobj = new TINY_ADODB($db_conf['conf_db_type'],$db_conf['conf_db_host'],$db_conf['conf_db_user'],$db_conf['conf_db_password'],$db_conf['conf_db_name'],$db_conf['conf_db_charset'],$db_conf['conf_db_debug'],$db_conf['conf_db_connect']);
		return $dbobj;
	}

	//加载文件
	private function _autoLoad($file_path)
	{
		if($file_path != "")
		{
			include_once($file_path);
		}
		else
		{
			$this->_showError("DB类路径必须设置!");
		}
	}
	
	//错误信息
	private function _showError($errormsg)
	{
		if($this->debug)
		{
			die($errormsg);
		}
		else
		{
			header('HTTP/1.1 404 Not Found');
			header("status: 404 Not Found");
			exit;
		}
		
	}
	
	//查询多条记录
	public function getAll($tablename, $sswhere = "", $params = " * ", $memkey = "", $memsec = 0, $delcache = false)
	{
		return $this->_selectDb("assoc", $tablename, $sswhere, $params, $memkey, $memsec, $delcache);
	}
	
	//查询一条记录
	public function getRow($tablename, $sswhere = "", $params = " * ", $memkey = "", $memsec = 0, $delcache = false)
	{
		return $this->_selectDb("row", $tablename, $sswhere, $params, $memkey, $memsec, $delcache);
	}

	//查询一个值
	public function getOne($tablename, $sswhere = "", $params = " * ", $memkey = "", $memsec = 0, $delcache = false)
	{
		return $this->_selectDb("one", $tablename, $sswhere, $params, $memkey, $memsec, $delcache);
	}

	//查询操作
	private function _selectDb($type, $tablename, $sswhere, $params, $memkey, $memsec, $delcache)
	{
		if(is_object($this->dbback))
		{
			$data = array();
			$need_mc = $memkey != "" && $memsec > 0 && is_object($this->mc) ? true : false;
			
			if($delcache && $need_mc)
			{
				$this->mc->delete($memkey);
			}

			$cache = $need_mc ? $this->mc->get($memkey) : array();
			if($cache['isok'] == 1)
			{
				$data = $cache['data'];
			}
			else
			{
				$sql  = $this->selectSql($tablename, $sswhere, $params);

				switch($type)
				{
					case "assoc" :	$data = $this->dbback->GetAssoc($sql);
									$data = is_array($data) ? $data : array();
									break;
					case "row" :	$data = $this->dbback->GetRow($sql);
									$data = is_array($data) ? $data : array();
									break;
					case "one" :	$data = $this->dbback->GetOne($sql);
									break;
					default :		$data = array();
									break;
				}

				if($need_mc)
				{
					$this->mc->add($memkey, array("isok"=>1, "data"=>$data), false, $memsec);
				}
			}

			return $data;
		}
		else
		{
			$this->_showError("没有初始化数据库连接!");
		}
	}
	
	//查询SQL
	public function selectSql($tablename, $sswhere = "", $params = " * ")
	{
		if($tablename == "")
		{
			$this->_showError("查询SQL存在问题!");
		}
		else
		{
			$wheresql = $sswhere != "" ? " WHERE ".$sswhere : $sswhere;
			$sql = "SELECT ".$params." FROM `".$tablename."`".$wheresql;
		}

		return $sql;
	}

	//更新操作
	public function update($tablename, $field, $sswhere)
	{
		if(is_object($this->db))
		{
			$sql = $this->updateSql($tablename, $field, $sswhere);
			return $this->db->Execute($sql);
		}
		else
		{
			$this->_showError("没有初始化数据库连接!");
		}
	}
	
	//更新SQL
	public function updateSql($tablename, $field, $sswhere)
	{
		if($tablename == "" || !is_array($field) || empty($field) || $sswhere == "")
		{
			$this->_showError("更新SQL存在问题!");
		}
		else
		{
			for($i=1; $i<=count($field); $i++)
			{
				if($i == 1)
				{
					$ss =" ".key($field)."='".$this->qstr($field[key($field)],$this->db_type)."' ";
				}
				else
				{
					$ss.=",".key($field)."='".$this->qstr($field[key($field)],$this->db_type)."' ";
				}
				next($field);
			}

			$wheresql = $sswhere != "" ? " WHERE ".$sswhere : $sswhere;
			$sql  = "UPDATE `".$tablename."` set ".$ss.$wheresql;

			return $sql;
		}
	}
	
	//插入操作
	public function insert($tablename, $field)
	{
		if(is_object($this->db))
		{
			$sql = $this->insertSql($tablename, $field);
			$this->db->Execute($sql);
			return $this->db->Insert_ID();
		}
		else
		{
			$this->_showError("没有初始化数据库连接!");
		}
	}

	//插入SQL
	public function insertSql($tablename, $field)
	{
		if($tablename == "" || !is_array($field) || empty($field))
		{
			$this->_showError("插入SQL存在问题!");
		}
		else
		{
			for($i=1; $i<=count($field); $i++)
			{
				if($i == 1)
				{
					$ss1 = key($field);
				}
				else
				{
					$ss1.=",".key($field);
				}

				if($i == 1)
				{
					$ss2 =" '".$this->qstr($field[key($field)],$this->db_type)."'";
				}
				else
				{
					$ss2.=",'".$this->qstr($field[key($field)],$this->db_type)."'";
				}
				next($field);
			}

			$sql = "INSERT INTO `".$tablename."` ( ".$ss1." ) VALUES ( ".$ss2." ) ";
			return $sql;
		}
	}
	
	//删除操作
	public function delete($tablename,$sswhere)
	{
		if(is_object($this->db))
		{
			$sql = $this->deleteSql($tablename,$sswhere);
			return $this->db->Execute($sql);
		}
		else
		{
			$this->_showError("没有初始化数据库连接!");
		}
	}

	//删除SQL
	public function deleteSql($tablename,$sswhere)
	{
		if($tablename == "" || $sswhere == "")
		{
			$this->_showError("删除SQL存在问题!");
		}
		else
		{
			$sql = "delete from `$tablename` WHERE ".$sswhere;
			return $sql;
		}
	}

	//插入操作
	public function replace($tablename, $field)
	{
		if(is_object($this->db))
		{
			$sql = $this->replaceSql($tablename, $field);
			$this->db->Execute($sql);
			return $this->db->Insert_ID();
		}
		else
		{
			$this->_showError("没有初始化数据库连接!");
		}
	}
	
	//插入SQL
	public function replaceSql($tablename, $field)
	{
		if($tablename == "" || !is_array($field) || empty($field))
		{
			$this->_showError("插入SQL存在问题!");
		}
		else
		{
			for ($i=1; $i<=count($field); $i++)
			{
				if ($i == 1)
				{
					$ss1 =key($field);
				}
				else
				{
					$ss1.=",".key($field);
				}

				if($i == 1)
				{
					$ss2 =" '".$this->qstr($field[key($field)],$this->db_type)."'";
				}
				else
				{
					$ss2.=",'".$this->qstr($field[key($field)],$this->db_type)."'";
				}

				next($field);
			}

			$sql = "REPLACE `".$tablename."` ( ".$ss1." ) VALUES ( ".$ss2." ) ";
			return $sql;
		}
	}

	private function qstr($ss,$slash_flag=true)
	{
		/*
		stripslashes是用于去掉多余的slash，大多是form提交时产生的，他们不能存入数据库)
		无论是那种数据库，存进去的数据都是没有slash的。例如 abc'def"fff\hhh
		查询条件为'
		mssql：则查询语句需要写成select * from test where  col_1 like '%''%'
		mysql：则查询语句需要写成select * from test where  col_1 like '%\'%'
		查询条件为"
		mssql：则查询语句需要写成select * from test where  col_1 like '%"%'
		mysql：则查询语句需要写成select * from test where  col_1 like '%\"%'

		也就是说mysql查询时需要addslashes，mssql需要将'转化为''
		如果  是post过来的数据，会自动加上slash，因此无论mssql或是mysql都需要先stripslashes
		如果不是post过来的数据，不会加上slash  ，因此无需stripslashes
		这也就是$slash_flag开关的用途:post过来的数据$slashes_flag=true,其他=false
		(mysql的addslashes和mssql的''都是为了查询不出错)

		2001.8.1
		slash_flag参数已经去掉，because of stripslash_vars()
		stripslash_vars()将所有post,get过来的变量做了stripslashes处理，所以此处无需再strip
		*/
		$replaceQuote["mssql"]	="''";
		$replaceQuote["ibase"]	="\'";
		$replaceQuote["sybase"]	="''";
		$replaceQuote["vfp"]	="'+chr(39)+'";
		$replaceQuote["oracle"]	="\'";

		if ($this->db_type=="mssql")
		return str_replace("'",$replaceQuote[$this->db_type],$ss);

		if ($this->db_type=="mysql") //针对mysql数据库，addslashes是用于sql查询不出错，相当于replaceQuote的操作
		return addslashes($ss);

	}

	public function __destruct()
	{
		if(is_object($this->db))
		{
			//$this->db->close();
		}
		if(is_object($this->dbback))
		{
			//$this->dbback->close();
		}
		if(is_object($this->mc))
		{
			$this->mc->close();
		}
	}
}
?>