1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354 |
- <?php
- namespace KIF\Db;
- use KIF\Core\Config;
- use MySQLi as MySQLiResource;
- use KIF\Debug\Debug;
- use KIF\Core\Request;
- use KIF\Cookie;
- use Exception;
- class MySQLi {
-
- private $link;
-
- private $dbname;
-
- static public $queries = 0;
-
- private static $intQueriesTotalTime = 0;
-
- static private $links;
-
- public $debug_level = 1;
-
- private $last_sql;
-
- private $result;
-
- private $arrDsn;
-
- private $masterDBInfo;
-
- static private $masterDBInfos = array();
-
- static private $slaveDBInfos;
-
- private $slaveDBInfo;
-
- private function getCurrentSlaveInfo() {
- $arrInvalidSlaveInfos = $this->getCurrentInvalidSlaveInfos();
- if (isset($this->slaveDBInfo)) {
-
- if (!$arrInvalidSlaveInfos || !in_array($this->slaveDBInfo['host'], $arrInvalidSlaveInfos)) {
- return $this->slaveDBInfo;
- }
- }
- $strUniqueFlagOfCluster = $this->getUniqueFlagOfCurrentCluster();
- if (!isset(self::$slaveDBInfos[$strUniqueFlagOfCluster])) {
-
- return false;
- }
-
- if ($arrInvalidSlaveInfos) {
- foreach (self::$slaveDBInfos[$strUniqueFlagOfCluster] as $key => $arrSlaveInfo) {
- $strSlaveHost = $arrSlaveInfo['host'];
- if (in_array($strSlaveHost, $arrInvalidSlaveInfos)) {
- unset(self::$slaveDBInfos[$strUniqueFlagOfCluster][$key]);
- }
- }
- }
- if (count(self::$slaveDBInfos[$strUniqueFlagOfCluster]) == 0) {
- return false;
- }
- $intRandPos = array_rand(self::$slaveDBInfos[$strUniqueFlagOfCluster]);
- $this->slaveDBInfo = & self::$slaveDBInfos[$strUniqueFlagOfCluster][$intRandPos];
- if (!isset($this->slaveDBInfo['user']) || !isset($this->slaveDBInfo['pass'])) {
- $this->slaveDBInfo['user'] = $this->masterDBInfo['user'];
- $this->slaveDBInfo['pass'] = $this->masterDBInfo['pass'];
- }
- if (!isset($this->slaveDBInfo['port'])) {
- $this->slaveDBInfo['port'] = $this->masterDBInfo['port'];
- }
- return $this->slaveDBInfo;
- }
-
- static private $invalidSlaveInfos;
-
- private function addInvalidSlaveInfo($strHost) {
- $strUniqueFlagOfCluster = $this->getUniqueFlagOfCurrentCluster();
- if (!isset(self::$invalidSlaveInfos[$strUniqueFlagOfCluster])
- || !in_array($strHost, self::$invalidSlaveInfos[$strUniqueFlagOfCluster])
- ) {
- self::$invalidSlaveInfos[$strUniqueFlagOfCluster][] = $strHost;
- }
- return true;
- }
-
- private function getUniqueFlagOfCurrentCluster() {
-
- return "{$this->masterDBInfo['host']}:{$this->masterDBInfo['port']}";
- }
-
- private function getCurrentInvalidSlaveInfos() {
- $strUniqueFlagOfCluster = $this->getUniqueFlagOfCurrentCluster();
- if (!isset(self::$invalidSlaveInfos[$strUniqueFlagOfCluster])) {
- return false;
- }
- return self::$invalidSlaveInfos[$strUniqueFlagOfCluster];
- }
-
- public function setCharset($charset = null) {
- if (is_null($charset)) {
- if (isset($this->arrDsn['params']['charset']) && $this->arrDsn['params']['charset']) {
- $charset = $this->arrDsn['params']['charset'];
- } else {
- $charset = "utf8";
- }
- }
- return $boolResult = mysqli_set_charset($this->link, $charset);
- }
-
- public function getCharset() {
- return $strResult = mysqli_character_set_name($this->link);
- }
-
- private function getUniqueFlagOfLink() {
- return "{$this->arrDsn['host']}_{$this->arrDsn['port']}_{$this->arrDsn['user']}_{$this->arrDsn['pass']}";
- }
-
- public function __construct($dsn) {
- $arrUrlInfo = parse_url($dsn);
- if (!is_array($arrUrlInfo) || !isset($arrUrlInfo['host']) || !isset($arrUrlInfo['user'])
- || !isset($arrUrlInfo['pass']) || !isset($arrUrlInfo['path']))
- {
- $this->_halt("构造参数不正确:{$dsn}");
- return false;
-
- }
- $this->arrDsn['host'] = $arrUrlInfo['host'];
- $this->arrDsn['user'] = $arrUrlInfo['user'];
- $this->arrDsn['pass'] = $arrUrlInfo['pass'];
- $dbname = substr($arrUrlInfo['path'], 1);
- if (empty($dbname)) {
- return $this->_halt('请先设置数据库名', '21');
- }
- $this->dbname = $dbname;
- isset($arrUrlInfo['scheme']) && $this->arrDsn['prefix'] = $arrUrlInfo['scheme'];
- if (!isset($arrUrlInfo['port'])) {
- $this->arrDsn['port'] = 3306;
- } else {
- $this->arrDsn['port'] = $arrUrlInfo['port'];
- }
-
-
- if (isset($arrUrlInfo['query'])) {
- parse_str($arrUrlInfo['query'], $this->arrDsn['params']);
- } else {
- $this->arrDsn['params'] = array();
- }
- $strUniqueFlagOfCluster = $this->arrDsn['host'];
- $strUniqueFlagOfMaster = $this->getUniqueFlagOfLink();
- if (!isset(self::$masterDBInfos[$strUniqueFlagOfCluster][$strUniqueFlagOfMaster])) {
- self::$masterDBInfos[$strUniqueFlagOfCluster][$strUniqueFlagOfMaster] = array(
- 'host' => $this->arrDsn['host']
- , 'port' => $this->arrDsn['port']
- , 'user' => $this->arrDsn['user']
- , 'pass' => $this->arrDsn['pass']
- , 'transactionIds' => null
- , 'isRunOnMaster' => false
- , 'isUseMaster' => false
- , 'arrStatusOfUseMaster' => null
- );
- }
- $this->masterDBInfo = & self::$masterDBInfos[$strUniqueFlagOfCluster][$strUniqueFlagOfMaster];
- if (!isset(self::$slaveDBInfos)) {
- $this->initSlaveDBInfos();
- }
- }
-
- private function initSlaveDBInfos() {
- try {
- $dbslavesConfig = Config::getInstance()->get('dbslaves');
- } catch (Exception $e) {
- return false;
- }
- if (!is_array($dbslavesConfig)) {
- return false;
- }
-
- $db_cluster_maps = $dbslavesConfig;
- if (isset($_SERVER['Cluster_User_Level']) && $_SERVER['Cluster_User_Level'] == 3) {
- $cluster_level = 3;
- $strType = 'delay_mixed';
- } else {
- $cluster_level = 2;
- $strType = 'mixed';
- }
- foreach ($db_cluster_maps as $arrClusterInfo) {
- if (!isset($arrClusterInfo['master']) || !isset($arrClusterInfo[$strType]) || !is_array($arrClusterInfo[$strType]) || (count($arrClusterInfo[$strType]) == 0)) {
-
- continue;
- }
- foreach($arrClusterInfo[$strType] as $mixConnectInfo) {
- if (is_string($mixConnectInfo)) {
- self::$slaveDBInfos[$arrClusterInfo['master']][] = array(
- 'host' => $mixConnectInfo
- , 'port' => null
- , 'user' => null
- , 'pass' => null
- );
- } elseif (is_array($mixConnectInfo)) {
- if (isset($mixConnectInfo['host']) && isset($mixConnectInfo['user']) && isset($mixConnectInfo['pass'])) {
- $tmpPort = isset($mixConnectInfo['port']) ? $mixConnectInfo['port'] : 3306;
- self::$slaveDBInfos[$arrClusterInfo['master']][] = array(
- 'host' => $mixConnectInfo['host']
- , 'port' => $tmpPort
- , 'user' => $mixConnectInfo['user']
- , 'pass' => $mixConnectInfo['pass']
- );
- } else {
-
- continue;
- }
- } else {
-
- continue;
- }
- }
- }
- }
-
- private function getUniqueFlagOfCurrentMaster() {
- return "{$this->masterDBInfo['host']}_{$this->masterDBInfo['port']}_{$this->masterDBInfo['user']}_{$this->masterDBInfo['pass']}";
- }
-
- private function getCurrentMasterLink() {
- $strUniqueFlagOfCurrentMaster = $this->getUniqueFlagOfCurrentMaster();
- if (isset(self::$links[$strUniqueFlagOfCurrentMaster])) {
- if ($this->isLink(self::$links[$strUniqueFlagOfCurrentMaster])) {
- return self::$links[$strUniqueFlagOfCurrentMaster];
- } else {
-
- if (!empty($this->masterDBInfo['transactionIds'])) {
- return $this->_halt("到主库的连接已失效,且该主库上存在事务,必须中断!");
- }
- }
- }
- return false;
- }
-
- private function isRunOnMaster() {
- return (boolean) $this->masterDBInfo['isRunOnMaster'];
- }
-
- private function getTransactions() {
- if ($this->getCurrentMasterLink()) {
- if (!empty($this->masterDBInfo['transactionIds'])) {
- return $this->masterDBInfo['transactionIds'];
- }
- }
- return false;
- }
-
- private function isRunOnTransaction() {
- if ($this->isRunOnMaster() && $this->getTransactions()) {
- return true;
- }
- return false;
- }
- private function isLink($link) {
- if (!($link instanceof MySQLiResource)) return false;
- $sinfo = @mysqli_get_host_info($link);
- return !empty($sinfo);
- }
- private function isReadSql($sql) {
- static $r_ops = array('select','show','desc');
- $sql = strtolower(trim($sql));
- foreach ($r_ops as $op) {
- if (strpos($sql,$op)===0) return true;
- }
- return false;
- }
-
- private function connect() {
-
- $objMysqli = mysqli_init();
- $connect_rs = mysqli_real_connect($objMysqli, $this->arrDsn['host'], $this->arrDsn['user'], $this->arrDsn['pass']
- , null, $this->arrDsn['port'], null
- , MYSQLI_CLIENT_COMPRESS);
- if (!$connect_rs) {
- return false;
- }
-
- $this->link = $objMysqli;
- $this->setCharset();
- return $this->link;
- }
-
- private function beginRunOnMaster() {
- $this->masterDBInfo['isRunOnMaster'] = true;
- return true;
- }
-
- private function endRunOnMaster() {
- $this->masterDBInfo['isRunOnMaster'] = false;
- return true;
- }
-
- private function connectMaster() {
-
-
- $this->arrDsn['host'] = $this->masterDBInfo['host'];
- $this->arrDsn['port'] = $this->masterDBInfo['port'];
- $this->arrDsn['user'] = $this->masterDBInfo['user'];
- $this->arrDsn['pass'] = $this->masterDBInfo['pass'];
- $objCurrentMasterLink = $this->getCurrentMasterLink();
- if ($objCurrentMasterLink) {
- $this->link = $objCurrentMasterLink;
- } else {
- if (false === $this->connect()) {
- return false;
- }
- $strUniqueFlagOfLink = $this->getUniqueFlagOfLink();
- self::$links[$strUniqueFlagOfLink] = $this->link;
- }
- $this->beginRunOnMaster();
- return true;
- }
-
- private function connectSlave() {
- $arrCurrentSlaveInfo = $this->getCurrentSlaveInfo();
- if ($arrCurrentSlaveInfo) {
- $this->arrDsn['host'] = $arrCurrentSlaveInfo['host'];
- $this->arrDsn['port'] = $arrCurrentSlaveInfo['port'];
- $this->arrDsn['user'] = $arrCurrentSlaveInfo['user'];
- $this->arrDsn['pass'] = $arrCurrentSlaveInfo['pass'];
- $strUniqueFlagOfLink = $this->getUniqueFlagOfLink();
- if (isset(self::$links[$strUniqueFlagOfLink]) && $this->isLink(self::$links[$strUniqueFlagOfLink])) {
- $this->link = self::$links[$strUniqueFlagOfLink];
- } else {
- if(false === $this->connect()) {
- return false;
- }
- self::$links[$strUniqueFlagOfLink] = $this->link;
- }
- return true;
- } else {
- return $this->connectMaster();
- }
- }
-
-
- private function reConnect() {
- if (false === $this->connect()) {
- return false;
- }
- $strUniqueFlagOfLink = $this->getUniqueFlagOfLink();
- self::$links[$strUniqueFlagOfLink] = $this->link;
- return true;
- }
-
- private function isUseMaster() {
- return (boolean) $this->masterDBInfo['isUseMaster'];
- }
-
- private function changeStatusOfUseMaster($status) {
- ($status === true) || $status = false;
-
- $strMasterStatusId = $this->getUniqueMasterStatusId();
- $this->masterDBInfo['arrStatusOfUseMaster'][$strMasterStatusId] = $this->masterDBInfo['isUseMaster'];
- $this->masterDBInfo['isUseMaster'] = $status;
- return $strMasterStatusId;
- }
-
- public function beginUseMaster() {
- return $this->changeStatusOfUseMaster(true);
- }
-
- public function restore($strMasterStatusId) {
-
- if (isset($this->masterDBInfo['arrStatusOfUseMaster'][$strMasterStatusId])) {
- $this->masterDBInfo['isUseMaster'] = $this->masterDBInfo['arrStatusOfUseMaster'][$strMasterStatusId];
- unset($this->masterDBInfo['arrStatusOfUseMaster'][$strMasterStatusId]);
- return true;
- }
- return false;
- }
-
- public function beginUseSlave() {
- return $this->changeStatusOfUseMaster(false);
- }
-
- protected function xconnect($sql) {
- $isUseSlave = $this->isReadSql($sql) && !$this->isUseMaster() ? true : false;
- $intConnectErrorNum = 0;
- while(true) {
- if ($isUseSlave) {
- $isConnect = $this->connectSlave();
- } else {
- $isConnect = $this->connectMaster();
- }
- if (!$isConnect) {
- ++$intConnectErrorNum;
- $strMasterHost = $this->masterDBInfo['host'];
- if(4 >= $intConnectErrorNum
- && $this->arrDsn['host'] != $strMasterHost
- ) {
- $this->addInvalidSlaveInfo($this->arrDsn['host']);
- continue;
- }
- return $this->_halt('服务器连接失败', '01');
- }
-
- break;
- }
- }
-
- public function query($sql) {
-
- $sql .= '/* ' . $_SERVER['HTTP_HOST'] . ' in '.$_SERVER['PHP_SELF'] . ' */';
-
- if (Debug::$open && preg_match('#^\s*select\s#i', $sql)) {
- $explain_query = true;
- } else {
- $explain_query = false;
- }
- if ($explain_query) {
-
- $sql = preg_replace('#select #i', 'select sql_no_cache ', $sql);
- }
- $this->last_sql = $sql;
- $intQueryErrorNum = 0;
- $intSelectErrorNum = 0;
- while (true) {
- $this->xconnect($sql);
- $isSelect = mysqli_select_db($this->link, $this->dbname);
-
- if (!$isSelect) {
- if ($this->isRunOnTransaction()) {
- return $this->_halt('进入数据库失败:存在事务,直接停机', '02');
- }
-
- ++$intSelectErrorNum;
- if ($intSelectErrorNum > 4) {
- return $this->_halt('进入数据库失败后,重试多次后仍然失败', '02');
- }
-
-
- if ($this->errno() == 2006) {
- if ($this->reConnect()) {
- continue;
- }
- }
-
- if ($this->isRunOnMaster()) {
- return $this->_halt('进入数据库失败', '02');
- }
-
-
- $this->addInvalidSlaveInfo($this->arrDsn['host']);
- continue;
- }
- if (!$this->isReadSql($sql)) {
-
- if ($this->isRunOnTransaction()) {
- $this->masterDBInfo['arrTransactionSqls'][] = $sql;
- }
- }
- $query = mysqli_query($this->link, $sql);
-
- if (!$query) {
- if ($this->isRunOnTransaction()) {
- return $this->_halt('查询数据库失败:存在事务,直接停机', '21');
- }
- ++$intQueryErrorNum;
- if ($intQueryErrorNum > 4) {
- return $this->_halt('查询数据库失败后,重试多次后仍然失败', '21');
- }
-
-
- if (in_array($this->errno(), array(2006, 2013))) {
- if ($this->reConnect()) {
- continue;
- }
- }
- static $arrConnectErrnos = array(
- 1053
- , 1030
- , 126
- );
-
- if ($this->isRunOnMaster()) {
- return $this->_halt('查询主数据库失败', '21');
- }
-
-
- if(in_array($this->errno(), $arrConnectErrnos)) {
- $this->addInvalidSlaveInfo($this->arrDsn['host']);
- continue;
- }
- return $this->_halt('查询数据库失败,不能处理的错误类型', '21');
- }
- break;
- }
-
- if ($this->canSetCookieForMasterDBHasWrite($sql)) {
- $tmp_expiration = 2*60;
- Cookie::set(KIF_MASTER_DB_HAS_WRITE_COOKIE_KEY, '1', $tmp_expiration);
- }
- self::$queries++;
- if ($explain_query) {
- $begin_microtime = Debug::getTime();
- self::$intQueriesTotalTime += $begin_microtime;
- $explainSql = 'explain ' . $sql;
- $equery = mysqli_query($this->link, $explainSql);
- $explain = $this->fetch($equery);
- $this->freeResult($equery);
- Debug::db($this->getLinkDesc(), $this->dbname, $explainSql, Debug::getTime() - $begin_microtime, $explain);
- }
- if (!$this->isReadSql($sql)) {
- $begin_microtime = Debug::getTime();
- Debug::db($this->getLinkDesc(), $this->dbname, $sql, Debug::getTime() - $begin_microtime, $query);
- }
- $this->isRunOnMaster() && $this->endRunOnMaster();
- return $query;
- }
-
- private function canSetCookieForMasterDBHasWrite($sql) {
- if (Request::isCLI()) {
- return false;
- }
- if ($this->isReadSql($sql)) {
- return false;
- }
-
- if (preg_match('#(xhprof_logs)#', strtolower($sql))) {
- return false;
- }
- return true;
- }
- public function fetchOne($sql) {
- $begin_microtime = Debug::getTime();
- $res = $this->query($sql);
- if (!$res) {
- return false;
- }
- $result = $this->fetch($res);
- $this->freeResult($res);
- Debug::db($this->getLinkDesc(), $this->dbname, $this->last_sql, Debug::getTime() - $begin_microtime, $result);
- return $result;
- }
-
- private function getLinkDesc() {
- $thread_id = mysqli_thread_id($this->link);
- return "mysqli://{$this->arrDsn['user']}:{$this->arrDsn['port']}@{$this->arrDsn['host']} (thread_id: {$thread_id})";
- }
-
- public function fetchAll($sql, $associateKey = null) {
- $begin_microtime = Debug::getTime();
- $res = $this->query($sql);
- if (!$res) {
- return false;
- }
- $result = array();
- if ($associateKey) {
- while (true) {
- $row = $this->fetch($res);
- if (!$row) {
- break;
- }
- if (isset($row[$associateKey])) {
- $result[$row[$associateKey]] = $row;
- } else {
- $result[] = $row;
- }
- }
- } else {
- while (true) {
- $row = $this->fetch($res);
- if (!$row) {
- break;
- }
- $result[] = $row;
- }
- }
- $this->freeResult($res);
- Debug::db($this->getLinkDesc(), $this->dbname, $this->last_sql, Debug::getTime() - $begin_microtime, $result);
- return $result;
- }
-
- public function fetchSclare($sql) {
- $begin_microtime = Debug::getTime();
- $result = $this->fetchOne($sql);
- if (!$result) {
- return false;
- }
- $result = array_shift($result);
- Debug::db($this->getLinkDesc(), $this->dbname, $this->last_sql, Debug::getTime() - $begin_microtime, $result);
- return $result;
- }
-
- public function insertId() {
- return mysqli_insert_id($this->link);
- }
-
- public function getLastInsertId() {
- return $this->insertId();
- }
-
- public function affectedRows()
- {
- return mysqli_affected_rows($this->link);
- }
- public function fetch($query, $resulttype = MYSQLI_ASSOC) {
- return mysqli_fetch_array($query, $resulttype);
- }
- protected function freeResult($query) {
- return mysqli_free_result($query);
- }
-
- static private function getUniqueTransactionId() {
- return self::getUniqueId('TAId');
- }
-
- static private function getUniqueMasterStatusId() {
- return self::getUniqueId('MSId');
- }
-
- static private function getUniqueId($prefix = '') {
- if(!is_string($prefix)) {
- $prefix = '';
- }
- return uniqid($prefix . '_'.rand());
- }
-
- public function error() {
- return @mysqli_error($this->link);
- }
-
- public function errno() {
- return @mysqli_errno($this->link);
- }
-
- public function connect_error() {
- return @mysqli_connect_error();
- }
-
- public function connect_errno() {
- return @mysqli_connect_errno();
- }
-
- function _halt($msg, $errorcode = '00') {
- switch ($this->debug_level) {
- case 1:
- ob_clean();
- header("HTTP/1.0 500 Server Error");
- header("Expires: ".gmdate("D, d M Y H:i:s", time())." GMT");
- header("Last-Modified: ".gmdate("D, d M Y H:i:s", time())." GMT");
- header("Cache-Control: private");
- $out = '$the_error';
- $out = str_replace('$the_error', $msg.'<hr />'.$this->error().' No.'.$this->errno()."<!-- {$this->last_sql} -->", $out);
- echo $out;
- exit;
- break;
- case 2:
- ob_clean();
- header("HTTP/1.0 500 Server Error");
- header("Expires: ".gmdate("D, d M Y H:i:s", time())." GMT");
- header("Last-Modified: ".gmdate("D, d M Y H:i:s", time())." GMT");
- header("Cache-Control: private");
- echo $this->connect_error(), "<br />";
- echo $this->connect_errno(), "<br />";
- echo "{$msg}<br />";
- exit('MySQL.');
- break;
- default:
- $this->errorcode = array($errorcode, $msg.':'.$this->last_sql, $this->errno().": ".$this->error());
- return false;
- break;
- }
- }
-
-
- public function startTransaction() {
- $strTransactionId = self::getUniqueTransactionId();
- if ($this->getTransactions()) {
- if ($this->setSavePoint($strTransactionId)) {
- $this->masterDBInfo['transactionIds'][$strTransactionId] = false;
- return $strTransactionId;
- }
- } else {
-
- if (true === $this->query('START TRANSACTION;')) {
- $this->masterDBInfo['transactionIds'][$strTransactionId] = true;
- return $strTransactionId;
- }
- }
-
- return false;
- }
-
- private function _rollbackRootTransaction($strTransactionId) {
- if ($this->isRootTransaction($strTransactionId)) {
- $this->masterDBInfo['transactionIds'] = null;
- $this->masterDBInfo['arrTransactionSqls'] = array();
- return $this->query('ROLLBACK;');
- }
- return false;
- }
-
- private function _rollbackSubTransaction($strTransactionId) {
- if($this->isSubTransaction($strTransactionId)) {
- $boolStatusTmp = $this->rollbackToSavePoint($strTransactionId);
- $this->releaseSavePoint($strTransactionId);
- unset($this->masterDBInfo['transactionIds'][$strTransactionId]);
- return $boolStatusTmp;
- }
- return false;
- }
-
- public function rollback($strTransactionId) {
- if ($this->isRootTransaction($strTransactionId)) {
- return $this->_rollbackRootTransaction($strTransactionId);
- } elseif ($this->isSubTransaction($strTransactionId)) {
- return $this->_rollbackSubTransaction($strTransactionId);
- } else {
- return false;
- }
- }
-
- private function _commitRootTransaction($strTransactionId) {
- if ($this->isRootTransaction($strTransactionId)) {
- $this->masterDBInfo['transactionIds'] = null;
- $this->masterDBInfo['arrTransactionSqls'] = array();
- return $this->query('COMMIT;');
- }
- return false;
- }
-
- private function _commitSubTransaction($strTransactionId) {
- if ($this->isSubTransaction($strTransactionId)) {
- $this->releaseSavePoint($strTransactionId);
- unset($this->masterDBInfo['transactionIds'][$strTransactionId]);
- return true;
- }
- return false;
- }
-
- public function commit($strTransactionId) {
- if ($this->isRootTransaction($strTransactionId)) {
- return $this->_commitRootTransaction($strTransactionId);
- } elseif ($this->isSubTransaction($strTransactionId)) {
- return $this->_commitSubTransaction($strTransactionId);
- } else {
- return false;
- }
- }
-
- private function setSavePoint($SPId) {
- if (true === $this->query("SAVEPOINT {$SPId}")) {
- return true;
- }
- return false;
- }
-
- private function getTransactionTypeById($strTransactionId) {
- if ($this->getCurrentMasterLink()) {
- if (isset($this->masterDBInfo['transactionIds'][$strTransactionId])) {
- return $this->masterDBInfo['transactionIds'][$strTransactionId];
- }
- }
- return null;
- }
-
- private function isRootTransaction($strTransactionId) {
- if (true === $this->getTransactionTypeById($strTransactionId)) {
- return true;
- }
- return false;
- }
-
- private function isSubTransaction($strTransactionId) {
- if (false === $this->getTransactionTypeById($strTransactionId)) {
- return true;
- }
- return false;
- }
-
- private function rollbackToSavePoint($SPId) {
-
- if ($this->isSubTransaction($SPId)) {
- if (true === $this->query("ROLLBACK TO SAVEPOINT {$SPId}")) {
- return true;
- }
- }
- return false;
- }
-
- private function releaseSavePoint($SPId) {
-
- if ($this->isSubTransaction($SPId)) {
- if (true === $this->query("RELEASE SAVEPOINT {$SPId}")) {
- return true;
- }
- }
- return false;
- }
- }
|