| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 | <?phpclass LtDbHandle{	public $configHandle;	public $group;	public $node;	public $role = "master";	public $connectionAdapter;	public $connectionResource;	public $sqlAdapter;	protected $connectionManager;	private $servers;	public function __construct()	{	}	public function init()	{		if(empty($this->servers))		{			$this->servers = $this->configHandle->get("db.servers");		}		$this->connectionManager = new LtDbConnectionManager;		$this->connectionManager->configHandle = $this->configHandle;		$this->sqlAdapter = $this->getCurrentSqlAdapter();		$connectionInfo = $this->connectionManager->getConnection($this->group, $this->node, $this->role);		$this->connectionAdapter = $connectionInfo["connectionAdapter"];		$this->connectionResource = $connectionInfo["connectionResource"];	}	/**	 * Trancaction methods	 */	public function beginTransaction()	{		return $this->connectionAdapter->exec($this->sqlAdapter->beginTransaction(), $this->connectionResource);	}	public function commit()	{		return $this->connectionAdapter->exec($this->sqlAdapter->commit(), $this->connectionResource);	}	public function rollBack()	{		return $this->connectionAdapter->exec($this->sqlAdapter->rollBack(), $this->connectionResource);	}	/**	 * Execute an sql query	 * 	 * @param  $sql 	 * @param  $bind 	 * @param  $forceUseMaster 	 * @return false on query failed	 *           --sql type--                         --return value--	 *           SELECT, SHOW, DESECRIBE, EXPLAIN     rowset or NULL when no record found	 *           INSERT                               the ID generated for an AUTO_INCREMENT column	 *           UPDATE, DELETE, REPLACE              affected count	 *           USE, DROP, ALTER, CREATE, SET etc    true	 * @notice 每次只能执行一条SQL	 *           不要通过此接口执行USE DATABASE, SET NAMES这样的语句	 */	public function query($sql, $bind = null, $forceUseMaster = false)	{		$sql = trim($sql);		if (empty($sql))		{			trigger_error('Empty the SQL statement');		}		$queryType = $this->sqlAdapter->detectQueryType($sql);		switch ($queryType)		{			case "SELECT":				if (!$forceUseMaster && isset($this->servers[$this->group][$this->node]["slave"]))				{					$this->role = "slave";				}				$queryMethod = "select";				break;			case "INSERT":				$this->role = "master";				$queryMethod = "insert";				break;			case "CHANGE_ROWS":				$this->role = "master";				$queryMethod = "changeRows";				break;			case "SET_SESSION_VAR":				$queryMethod = "setSessionVar";				break;			case "OTHER":			default:				$this->role = "master";				$queryMethod = "other";				break;		}		$connectionInfo = $this->connectionManager->getConnection($this->group, $this->node, $this->role);		$this->connectionAdapter = $connectionInfo["connectionAdapter"];		$this->connectionResource = $connectionInfo["connectionResource"];		if (is_array($bind) && 0 < count($bind))		{			$sql = $this->bindParameter($sql, $bind);		}		return $this->$queryMethod($sql, $this->connectionResource);	}	/**	 * function posted by renlu	 */	public function escape($str)	{		return $this->connectionAdapter->escape($str, $this->connectionResource);	}	/**	 * function posted by renlu	 */	public function insertid()	{		return $this->connectionAdapter->lastInsertId($this->connectionResource);	}	/**	 * Generate complete sql from sql template (with placeholder) and parameter	 * 	 * @param  $sql 	 * @param  $parameter 	 * @return string 	 * @todo 兼容pgsql等其它数据库,pgsql的某些数据类型不接受单引号引起来的值	 */	public function bindParameter($sql, $parameter)	{ 		// 注意替换结果尾部加一个空格		$sql = preg_replace("/:([a-zA-Z0-9_\-\x7f-\xff][a-zA-Z0-9_\-\x7f-\xff]*)\s*([,\)]?)/", "\x01\x02\x03\\1\x01\x02\x03\\2 ", $sql);		foreach($parameter as $key => $value)		{			$find[] = "\x01\x02\x03$key\x01\x02\x03";			if ($value instanceof LtDbSqlExpression)			{				$replacement[] = $value->__toString();			}			else			{				$replacement[] = "'" . $this->connectionAdapter->escape($value, $this->connectionResource) . "'";			}		}		$sql = str_replace($find, $replacement, $sql);		return $sql;	}	protected function getCurrentSqlAdapter()	{		$factory = new LtDbAdapterFactory;		$host = key($this->servers[$this->group][$this->node][$this->role]);		return $factory->getSqlAdapter($this->servers[$this->group][$this->node][$this->role][$host]["sql_adapter"]);	}	protected function select($sql, $connResource)	{		$result = $this->connectionAdapter->query($sql, $connResource);		if (empty($result))		{			return null;		}		else		{			return $result;		}	}	protected function insert($sql, $connResource)	{		if ($result = $this->connectionAdapter->exec($sql, $connResource))		{			return $this->connectionAdapter->lastInsertId($connResource);		}		else		{			return $result;		}	}	protected function changeRows($sql, $connResource)	{		return $this->connectionAdapter->exec($sql, $connResource);	}	/**	 * 	 * @todo 更新连接缓存	 */	protected function setSessionVar($sql, $connResource)	{		return false === $this->connectionAdapter->exec($sql, $connResource) ? false : true;	}	protected function other($sql, $connResource)	{		return false === $this->connectionAdapter->exec($sql, $connResource) ? false : true;	}}
 |