<?php
/*
* Copyright (C) 2002-2004
* @author chenxi
* @version $Id: Connection.class.php,v 0.1 2004/11/03 18:58:07
*/
#require_once ('Object.class.php');
require_once ('util/StringBuffer.class.php');
class mysql_Connection extends Object {
/* mysqlæ°æ®åºè¿æ¥ */
var $conn = null;
/* æ°æ®åºé©±å¨å¯¹è±¡ */
var $driver = null;
/* é»è®¤æ°æ®åºè¿æ¥è¶
æ¶ç§æ°, é»è®¤3ç§, å¯éè¿setConnectionconntimeout()æ¹æ³è®¾ç½® */
var $connconntimeout = 3;
/* æ è¯æ°æ®åºè¿æ¥æ¯å¦ä»¥å
³éï¼ture为已å
³éï¼false为为å
³é */
var $isClosed = true;
/* æ è¯æ°æ®åºè¿æ¥æ¯å¦ä¸ºåªè¯» */
var $readOnly = false;
/* 设置å½åæ¯å¦ä¸ºaotucommitç¶æ */
var $autoCommit = true;
/* ç±å½åConnection对象åå»ºçæ¥è¯¢å¯¹è±¡(Statement) */
var $stmt = null;
/* ç±å½åConnection对象å建ç颿¥è¯¢å¯¹è±¡(PreparedStatement) */
var $pstmt = null;
/* 设置æ¯å¦æ¯æäºå¡ */
var $transactionsSupported = false;
/* äºå¡æä½ */
var $transaction_opcount = 0;
/* å½åConnection对象å建çStatement对象éå */
var $openStatements = null;
/**
* æé 彿°
* @param æ°æ®åºè¿æ¥
*/
function &mysql_Connection(&$driver) {
$this->driver = $driver;
$this->realConnect($this->driver->getUrlProps());
}
/**
* ææå½æ°
* éæ¾mysqlè¿æ¥ä»¥ådriver对象
*/
function __destruct() {
if (@version_compare('5.0.0', phpversion(), '>='))
$this->close();
$this->driver = null;
}
/**
* Singleton
*/
function getInstance(&$driver) {
if (null === $this->conn) {
return new mysql_Connection($driver);
}
return $this;
}
/**
* è·åå½åmysqlè¿æ¥
* @return mysql_connect
*/
function getConnection() {
return $this->conn;
}
/**
* 夿å½åè¿æ¥æ¯å¦å·²å
³é
* @return void
*/
function checkClosed() {
$this->ping();
if ($this->isClosed) {
$msgbuf = new StringBuffer($lang['CONNECTION_ALREADY_CLOSE']);
$this->throws($msgbuf->toString());
}
}
/**
* ping MySQLæå¡å¨ï¼ä»¥å¤æå½åè¿æ¥æ¯å¦å¯ç¨
* @return trueå¯ç¨ï¼falseä¸å¯ç¨
*/
function ping() {
$this->isClosed = !mysql_ping($this->conn);
}
/**
* å
³éå½åæ°æ®åºè¿æ¥
* @return void
*/
function close() {
$this->realClose(true, true);
}
/**
* å
³éå½åConnection对象åå»ºçææStatement对象
* @access private
*/
function closeAllOpenStatements() {
if (null !== $this->openStatements) {
for ($i = 0; $i < $this->openStatements->size(); $i++) {
$currentOpenedStatement = $this->openStatements->get($i);
if ($GLOBALS['debug'] && (int)3 >= $GLOBALS['debug']) {
$this->debug('closeStatement '.$i.': ('.$currentOpenedStatement.')');
}
$ret = $currentOpenedStatement->realClose();
if (is_a($ret, 'EXCEPTIONS'))
$exp = $ret; //å
å
³éæææ´»å¨çStatement对象ï¼ç¨ååæåºå¼å¸¸
}
if (isset($exp) && null !== $exp)
$this->throws($exp->getMessage(), $exp->getCode(), $exp->getMode());
}
}
/**
* å
³éå½åPreparedStatment对象
* @return void
*/
function closePrepareStatement() {
$this->pstmt = null;
}
/**
* å¼å§ä¸ç»äºå¡
* @return void
*/
function startTransaction() {
$this->checkClosed();
#$stmt =& $this->createStatement();
#$ret = $stmt->executeUpdate('START TRANSACTION;');
$ret = mysql_query('START TRANSACTION;', $this->conn);
if (!$ret)
$this->throws(mysql_errno($this->conn) .': '.mysql_error($this->conn), null, EXCEPTION_DIE);
$this->transaction_opcount++;
}
/**
* æäº¤å½åäºå¡
* @return void
*/
function commit() {
if ($this->transaction_opcount > 0) {
$this->checkClosed();
//$stmt =& $this->createStatement();
//$ret = $stmt->exexuteUpdate('COMMIT;');
//$ret = $stmt->exexuteUpdate('SET AUTOCOMMIT=1;');
$ret = mysql_query('COMMIT;', $this->conn) && mysql_query('SET AUTOCOMMIT=1', $this->conn);
if ($GLOBALS['debug'] && (int) 3 < $GLOBALS['debug']) {
$this->debug('commit');
}
if (!$ret)
$this->throws(mysql_errno($this->conn) .': '.mysql_error($this->conn), null, EXCEPTION_DIE);
$this->transaction_opcount = 0;
}
}
/**
* åæ»å½åäºå¡
* @accedd pubic
* @see rollback()
* @return void
*/
function rollback() {
if ($this->transaction_opcount > 0) {
$this->checkClosed();
if (null !== $this->openStatements) {
$lastNum = $this->openStatements->size() - 1;
if (is_object($lastStatement = $this->openStatements->get($lastNum)))
$ok = !$lastStatement->isClosed();
}
if ($ok) {
$stmt =& $this->createStatement();
$ret = $stmt->executeUpdate('ROLLBACK;');
$ret = $stmt->executeUpdate('SET AUTOCOMMIT=1;');
} else {
$ret = mysql_query('ROLLBACK;', $this->conn) && mysql_query('SET AUTOCOMMIT=1;', $this->conn);
}
$this->transaction_opcount = 0;
if ($GLOBALS['debug'] && (int)3 <= $GLOBALS['debug']) {
$this->debug('rollback');
}
if (!$ret) {
$errbuf = new StringBuffer('#ErrorNo '.mysql_errno($this->conn).': ');
$errbuf->append(mysql_error($this->conn));
$this->throws($errbuf->toString(), null, EXCEPTION_DIE, null, __FILE__, __LINE__);
}
}
}
/**
* è¿åmysql_Statement对象
* @return mysql_Statement
* @access public
* @see createPrepareStatement()
*/
function &createStatement() {
$this->checkClosed();
require_once ('pdbc/mysql/Statement.class.php');
//if (!$this->stmt && !is_object($this->pstmt) && !is_a($this->stmt, 'mysql_Statement')) {
$stmt =& new mysql_Statement($this);
if (null === $this->openStatements || !is_a($this->openStatements, 'Vector')) {
require_once ('util/Vector.class.php');
$this->openStatements = new Vector();
}
$this->openStatements->add($stmt);
//}
//return $this->stmt;
return $stmt;
}
/**
* è¿åå½åConnection对象çcommit模å¼
* @return boolean
* @access public
*/
function getAutoCommit() {
return $this->autoCommit;
}
function getRelaxAutoCommit() {
if ((int)32315 < $this->getServerVersionInt())
return true;
return false;
}
function getDriverProperty($property_key) {
if ((bool)$property_key) {
return $this->driver->getDriverProperty();
} else {
return $this->driver->getDriverProperty($property_key);
}
}
/**
* è·åå½åMySQLæå¡å¨æ°åçæ¬å·
* @return int
*/
function getServerVersionInt() {
$numerics = array('.', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0');
$fullversion = $this->getServerVersionString();
for ($i = 0; $i < strlen($fullversion); $i++) {
if (!in_array($fullversion[$i], $numerics)) {
break;
}
}
$version = substr($fullversion, 0, $i);
$version = explode('.', $version);
foreach ($version as $key => $val) {
if ((int)1 == $key || (int)2 == $key) {
$val = ((int)1 == strlen($version[$key])) ? '0'.$version[$key]: $version[$key];
}
$vid .= $val;
}
return $vid;
}
/**
* è·åå½åMySQLæå¡å¨çæ¬å
¨ç§°
* @return String
*/
function getServerVersionString() {
return @mysql_get_server_info();
}
/**
* è·åç³»ç»è¦å
*/
function getWarnings() {
//not impelment yet
}
/**
* 夿å½åè¿æ¥æ¯å¦å·²å
³é
* @return trueå
³éï¼falseæªå
³é
*/
function isClosed() {
return $this->isClosed;
}
/**
* @retrun 妿æ¯è¯¥è¿æ¥ä¸ºåªè¯»ï¼è¿åtrueï¼å¦åè¿åfalse
*/
function isReadOnly() {
return $this->readOnly;
}
/**
* @param $sql
*/
function prepareCall($sql) {
//not implement yet
}
/**
* @param $sql
*/
function prepareStatement($sql) {
$this->checkClosed();
require_once ('pdbc/mysql/PreparedStatement.class.php');
if ($this->pstmt && is_object($this->pstmt)) {
$this->pstmt->setOriginalSQL($sql);
} else {
$this->pstmt = new mysql_PreparedStatement($this, $sql);
}
#print '$conn->prepareStatement: <br/>';
#var_dump($this->pstmt);
print_r($this->pstmt->sqlBatch);
print '<br/>';
return $this->pstmt;
}
/**
* æ ¹æ®$urlPropsä¸çä¿¡æ¯æå¼æ°æ®åºè¿æ¥
* @param Array $urlProps
* @return void
* @access private
*/
function realConnect($urlProps) {
$this->conn = @mysql_connect($urlProps['dbhost'].':'
.$urlProps['dbport'],
$urlProps['dbuser'],
$urlProps['dbpass']
);
if (!$this->conn) {
$msgbuf = new StringBuffer();
$msgbuf->append('#ErrorNo '.mysql_errno().': ');
$msgbuf->append(mysql_error());
$this->throws($msgbuf->toString(), null, EXCEPTION_DIE, null, __FILE__, __LINE__);
}
$ret = mysql_select_db($urlProps['dbname'],
$this->conn
);
if (!$ret) {
$msgbuf = new StringBuffer();
$msgbuf->append('#ErrorNo '.mysql_errno($this->conn).': ');
$msgbuf->append(mysql_error($this->conn));
mysql_close($this->conn);
return $this->throws($msgbuf->toString(), null, EXCEPTION_DIE, NULL, 'Exceptions', __FILE__, __LINE__);
}
$this->isClosed = false;
}
/**
* 设置å½åè¿æ¥æ¯å¦ä¸ºèªå¨æäº¤æ¨¡å¼ï¼true为èªå¨æäº¤ï¼falseåä¹
* @param $autoCommit
* @return void
* @access public
*/
function setAutoCommit($autoCommit=false) {
$this->checkClosed();
if ($this->transactionsSupported) {
$this->autoCommit = $autoCommit;
} else {
if ($autoCommit && !$this->getRelaxAutoCommit()) {
$this->throws('MySQL Versions Older than 3.23.15, do not support transactions', null, EXCEPTION_DIE);
}
}
$this->autocommit($autoCommit);
}
function autocommit($autoCommit) {
$sql = $autoCommit ? 'SET autocommit = 1' : 'SET autocommit = 0';
return mysql_query($sql, $this->conn);
}
function exeSQL($sql) {
//not in Connection interface
//not implement yet
}
/**
* å
³éå½åConnection对象
* @param boolean $calledExplicitly
* @param boolean $issueRollback
* @return void
* @accept protected
* @see close()
*/
function realClose($calledExplicitly, $issueRollback) {
if (!$this->isClosed()) {
if (!$this->getAutoCommit() && $issueRollback) {
$this->rollback();
}
}
$this->closeAllOpenStatements();
$this->openStatements = null;
mysql_close($this->conn);
$this->isClosed = true;
}
/**
* è®¾ç½®æ°æ®åºè¿æ¥æ¯å¦ä¸ºåªè¯»æ¨¡å¼
* @param boolean $readOnly
*/
function setReadOnly($readOnly=true) {
if (!is_bool($readOnly)) {
$readOnly = StringUtils::isNumeric($readOnly);
if ((int)0 != $readOnly || (float)0.0 != $readOnly)
$this->readOnly = true;
else
$this->readOnly = false;
} else {
$this->readOnly = $readOnly;
}
}
/**
* è®¾ç½®æ°æ®åºè¿æ¥è¶
æ¶æ¶é´
* @param int $conntimeout
*/
function setConnectionconntimeout($conntimeout) {
$this->conntimeout = $conntimeout;
}
}
?>