예제 #1
0
 /**
  * 执行
  */
 public function execute()
 {
     //参数重载
     if (func_num_args() == 1) {
         return $this->_executeParam1(func_get_arg(0));
     }
     switch (trim($this->action)) {
         case 'SELECT':
             $databaseObject = CDatabase::getDatabase($this->configName, false);
             $sql = $this->_sql = $this->_createSelectSQL();
             $rsReult = array();
             $btime = $etime = 0;
             //检查缓存
             if (!empty($this->_cache)) {
                 //尝试直接从缓存获取
                 $cacheData = Cache::getInstance()->get($this->_cache);
                 if (null != $cacheData) {
                     //查询结果对象
                     $resultObject = new CResult();
                     $resultObject->setIsMaster(false);
                     $resultObject->setSql($sql);
                     $resultObject->setIsCache(true);
                     $resultObject->setValue($cacheData->asArray());
                     $resultObject->setCastTime($etime > $btime ? round($etime - $btime, 6) : 0);
                     //执行查询后钩子函数
                     CHooks::callHooks(HOOKS_EXECUTE_END, $resultObject);
                     $this->_clearSelf();
                     return $cacheData;
                 }
             }
             try {
                 //执行查询前钩子函数
                 CHooks::callHooks(HOOKS_EXECUTE_BEFORE, $this);
                 $btime = microtime(true);
                 $rs = $databaseObject->prepare($this->_sql);
                 if (!$rs) {
                     $errorData = $databaseObject->errorInfo();
                     //发生SQL错误时 触发钩子
                     $dbError = new CDBError();
                     $dbError->setSQLErrorCode($errorData[0]);
                     $dbError->setDriverErrorCode($errorData[1]);
                     $dbError->setErrorMessage($errorData[2]);
                     $dbError->setSql($this->_sql);
                     CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError);
                     throw new PDOException('[' . $errorData[1] . '] ' . $errorData[2] . ' with SQL [' . $this->_sql . ']');
                 }
                 $rs->execute($this->whereValue);
                 $rs->setFetchMode(PDO::FETCH_OBJ);
                 $rsReult = $rs->fetchAll();
                 $etime = microtime(true);
             } catch (PDOException $pdoException) {
                 throw new CDbException($pdoException->getMessage());
             }
             //查询结果对象
             $resultObject = new CResult();
             $resultObject->setIsMaster(false);
             $resultObject->setSql($sql);
             $resultObject->setWhereValue($this->whereValue);
             $resultObject->setValue($rsReult);
             $resultObject->setCastTime($etime > $btime ? round($etime - $btime, 6) : 0);
             //执行查询后钩子函数
             CHooks::callHooks(HOOKS_EXECUTE_END, $resultObject);
             //缓存结果
             if (!empty($this->_cache)) {
                 $cacheData = Cache::getInstance()->set($this->_cache, $resultObject, $this->_cacheTime);
             }
             //清理
             $this->_clearSelf();
             return $resultObject;
             break;
         case 'INSERT INTO':
             // 强制主库操作新增
             $this->isMaster = true;
             $databaseObject = CDatabase::getDatabase($this->configName, $this->isMaster);
             $sql = $this->_sql = $this->_createInsertSQL();
             //执行查询前钩子函数
             CHooks::callHooks(HOOKS_EXECUTE_BEFORE, $this);
             $insertStatus = $databaseObject->exec($this->_sql);
             if ($insertStatus > 0) {
                 //执行操作
                 $execObject = new CExec();
                 $execObject->setSql($sql);
                 $execObject->setRow($insertStatus);
                 $execObject->setStatus(true);
                 $execObject->setLastInsertId($databaseObject->lastInsertId());
                 //执行查询后钩子函数
                 CHooks::callHooks(HOOKS_EXECUTE_END, $execObject);
                 //清理
                 $this->_clearSelf();
                 return $execObject;
             } else {
                 //发生错误
                 $errorData = $databaseObject->errorInfo();
                 //发生SQL错误时 触发钩子
                 $dbError = new CDBError();
                 $dbError->setSQLErrorCode($errorData[0]);
                 $dbError->setDriverErrorCode($errorData[1]);
                 $dbError->setErrorMessage($errorData[2]);
                 $dbError->setSql($this->_sql);
                 CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError);
                 throw new CDbException('[' . $errorData[1] . '] ' . $errorData[2] . ' with SQL [' . $this->_sql . ']');
             }
             //清理
             $this->_clearSelf();
             break;
         case 'UPDATE':
             // 强制主库操作更新
             $this->isMaster = true;
             $databaseObject = CDatabase::getDatabase($this->configName, $this->isMaster);
             $sql = $this->_sql = $this->_createUpdateSQL();
             //执行查询前钩子函数
             CHooks::callHooks(HOOKS_EXECUTE_BEFORE, $this);
             $rs = $databaseObject->prepare($this->_sql);
             $updateStatus = $rs->execute($this->whereValue);
             if (false === $updateStatus) {
                 $errorData = $databaseObject->errorInfo();
                 //发生SQL错误时 触发钩子
                 $dbError = new CDBError();
                 $dbError->setSQLErrorCode($errorData[0]);
                 $dbError->setDriverErrorCode($errorData[1]);
                 $dbError->setErrorMessage($errorData[2]);
                 $dbError->setSql($this->_sql);
                 CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError);
                 throw new CDbException('[' . $errorData[1] . '] ' . $errorData[2] . ' with SQL [' . $this->_sql . ']');
             } else {
                 $execObject = new CExec();
                 $execObject->setSql($sql);
                 $execObject->setRow($updateStatus);
                 $execObject->setWhereValue($this->whereValue);
                 $execObject->setStatus(true);
                 //执行查询后钩子函数
                 CHooks::callHooks(HOOKS_EXECUTE_END, $execObject);
                 $this->_clearSelf();
                 return $execObject;
             }
             $this->_clearSelf();
             break;
         case 'DELETE':
             // 强制主库操作删除
             $this->isMaster = true;
             $databaseObject = CDatabase::getDatabase($this->configName, $this->isMaster);
             $sql = $this->_sql = $this->_createDeleteSQL();
             //执行查询前钩子函数
             CHooks::callHooks(HOOKS_EXECUTE_BEFORE, $this);
             //echo '<pre>';print_r($this->whereValue);exit;
             $rs = $databaseObject->prepare($this->_sql);
             $deleteStatus = $rs->execute($this->whereValue);
             if (false === $deleteStatus) {
                 $errorData = $databaseObject->errorInfo();
                 //发生SQL错误时 触发钩子
                 $dbError = new CDBError();
                 $dbError->setSQLErrorCode($errorData[0]);
                 $dbError->setDriverErrorCode($errorData[1]);
                 $dbError->setErrorMessage($errorData[2]);
                 $dbError->setSql($this->_sql);
                 CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError);
                 throw new CDbException('[' . $errorData[1] . '] ' . $errorData[2] . ' with SQL [' . $this->_sql . ']');
             } else {
                 $execObject = new CExec();
                 $execObject->setSql($sql);
                 $execObject->setWhereValue($this->whereValue);
                 $execObject->setRow($deleteStatus);
                 $execObject->setStatus(true);
                 //执行查询后钩子函数
                 CHooks::callHooks(HOOKS_EXECUTE_END, $execObject);
                 $this->_clearSelf();
                 return $execObject;
             }
             $this->_clearSelf();
             break;
         default:
             if (!empty($this->prepare)) {
             }
             throw new CDbException('[查询错误]未指定操作方法');
             break;
     }
     $this->_clearSelf();
 }
예제 #2
0
 /**
  * 获取PDO对象
  */
 public static function getDatabase($configName = 'main', $isMaster = true)
 {
     if (empty($configName)) {
         $configName = 'main';
     }
     if (isset(self::$objectPdo[intval($isMaster) . $configName])) {
         return self::$objectPdo[intval($isMaster) . $configName];
     }
     $dbConfig = CConfig::getInstance()->load('DB.' . $configName);
     if (!isset($dbConfig['master'])) {
         throw new CDbException('[配置错误]getDataBase方法尝试获取不存在的配置项:[Config->DB->master]');
     }
     if (true == $isMaster) {
         $thisConfigData = $dbConfig['master'];
         self::$configData[intval($isMaster) . $configName] = $thisConfigData;
         self::$configData[intval(!$isMaster) . $configName] = $dbConfig['slaves'];
     }
     if (false == $isMaster) {
         $thisConfigData = !isset($dbConfig['slaves']) ? $dbConfig['master'] : $dbConfig['slaves'];
         self::$configData[intval($isMaster) . $configName] = $thisConfigData;
         self::$configData[intval(!$isMaster) . $configName] = $dbConfig['master'];
     }
     try {
         $pdoObject = new PDO($thisConfigData['connectionString'], $thisConfigData['username'], $thisConfigData['password']);
         $pdoObject->query('set names ' . $thisConfigData['charset']);
     } catch (PDOException $pdoException) {
         //尝试启用备用库
         if (true == $isMaster) {
             //是否允许启用备库
             $writeConf = self::$configData[intval($isMaster) . $configName];
             if (isset($writeConf['slavesWrite']) && true == $writeConf['slavesWrite']) {
                 //尝试连接备库
                 try {
                     //从库配置
                     $slaverConf = self::$configData[intval(!$isMaster) . $configName];
                     $pdoObject = new PDO($slaverConf['connectionString'], $slaverConf['username'], $slaverConf['password']);
                     $pdoObject->query('set names ' . $slaverConf['charset']);
                 } catch (PDOException $pdoExceptionAgain) {
                     $dbError = new CDBError();
                     $dbError->setSQLErrorCode('CMyFrame');
                     $dbError->setDriverErrorCode('CMyFrame');
                     $dbError->setErrorMessage('主库连接失败后,尝试连接从库,连接从库依旧失败');
                     CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError);
                     //切换数据依旧无法连接
                     throw new CDbException('[数据库错误]主库连接失败后,尝试连接从库依旧失败:' . $pdoExceptionAgain->getMessage());
                 }
             } else {
                 //不允许使用备库
                 $dbError = new CDBError();
                 $dbError->setSQLErrorCode('CMyFrame');
                 $dbError->setDriverErrorCode('CMyFrame');
                 $dbError->setErrorMessage('主库连接失败后,不允许尝试连接从库');
                 CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError);
                 throw new CDbException('[数据库错误]连接主数据库失败,且不允许尝试使用从库:' . $pdoException->getMessage());
             }
         } else {
             //是否使用主库进行读取
             $readConf = self::$configData[intval($isMaster) . $configName];
             if (isset($readConf['masterRead']) && true == $readConf['masterRead']) {
                 $errorMessage = '从库连接失败后,尝试连接主库,主库连接成功';
                 try {
                     //主库配置
                     $masterConf = self::$configData[intval(!$isMaster) . $configName];
                     $pdoObject = new PDO($masterConf['connectionString'], $masterConf['username'], $masterConf['password']);
                     $pdoObject->query('set names ' . $masterConf['charset']);
                 } catch (PDOException $pdoExceptionAgain) {
                     $dbError = new CDBError();
                     $dbError->setSQLErrorCode('CMyFrame');
                     $dbError->setDriverErrorCode('CMyFrame');
                     $dbError->setErrorMessage('从库连接失败后,尝试连接主库,连接主库依旧失败');
                     CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError);
                     //切换数据依旧无法连接
                     throw new CDbException('[数据库错误]从库连接失败后,尝试连接主库依旧失败:' . $pdoExceptionAgain->getMessage());
                 }
             } else {
                 //发生SQL错误时 触发钩子
                 $dbError = new CDBError();
                 $dbError->setSQLErrorCode('CMyFrame');
                 $dbError->setDriverErrorCode('CMyFrame');
                 $dbError->setErrorMessage('从库连接失败后,不允许尝试连接主库');
                 CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError);
                 throw new CDbException('[数据库错误]连接从数据库失败,且不允许尝试使用主库:' . $pdoException->getMessage());
             }
             //发生SQL错误时 触发钩子
             $dbError = new CDBError();
             $dbError->setSQLErrorCode('CMyFrame');
             $dbError->setDriverErrorCode('CMyFrame');
             $dbError->setErrorMessage($errorMessage);
             CHooks::callHooks(HOOKS_EXECUTE_ERROR, $dbError);
         }
     }
     self::$objectPdo[intval($isMaster) . $configName] = $pdoObject;
     return $pdoObject;
 }