public function customErrorHander($errno, $errstr, $errfile, $errline)
 {
     $msg = sprintf("%s: \nIn file %s line %s\nMessage:%s", $this->getErrorLevel($errno), $errfile, $errline, $errstr);
     if ($this->logger) {
         $this->logger->writeError($msg);
     }
 }
 private function getNextIdFromDb()
 {
     try {
         $next_id = $this->dbhelper->executeInsert("INSERT INTO " . $this->key_prefix . $this->table_name . " VALUES (null)");
     } catch (DBException $e) {
         $next_id = 0;
         $this->logger->writeError("db exception happens while generate sequence id." . $e->getMessage());
     }
     return $next_id;
 }
 public function flush()
 {
     $this->connect();
     $res = $this->cache->flush();
     if ($res === false) {
         $this->logger->writeError("failed to flush memcache server[" . implode(',', $this->host) . "].");
     }
     if ($this->logger->isDebugEnabled()) {
         $this->logger->writeDebug("[flush]");
     }
     return $res;
 }
 protected function getSQL($sql, $params = null)
 {
     $format_sql = $sql;
     if (is_array($params)) {
         $format_sql = vsprintf($sql, $params);
     } elseif (!is_null($params)) {
         $format_sql = sprintf($sql, $params);
     }
     if ($format_sql === false) {
         $this->logger->writeError("the composit sql is false, check it:[sql={$sql}, param={$params}]");
     }
     if ($this->logger->isDebugEnabled()) {
         $this->logger->writeDebug("trying to exectue sql[db_helper=%s,host=%s,db=%s] : %s", array(spl_object_hash($this), $this->config['host'], $this->config['database'], $format_sql));
     }
     return $format_sql;
 }
 /**
  * @param $params
  */
 public function execute($params = null)
 {
     try {
         if ($this->isServiceClosed($params['gameuid'])) {
             return $this->getReturnArray(GameStatusCode::SYSTEM_MAINTAIN, 'service closed.');
         }
         //				return $this->getReturnArray(0,'ok',"test");
         if (isset($params['gameuid'])) {
             $gameuid = intval($params['gameuid']);
             if ($gameuid <= 0) {
                 $this->throwException("user[{$gameuid}] not exists", GameStatusCode::USER_NOT_EXISTS);
             }
             if (isset($params['friend_gameuid'])) {
                 if (empty($params['friend_gameuid']) || $params['friend_gameuid'] <= 0) {
                     $this->throwException("friend user[" . $params['friend_gameuid'] . "] not exist", GameStatusCode::USER_NOT_EXISTS);
                 }
             }
             $this->action_logger = new UserActionLogManager($gameuid);
             $this->user_account = $this->user_account_mgr->getUserAccount($gameuid);
             if (empty($this->user_account)) {
                 $this->throwException("user[{$gameuid}] not exists", GameStatusCode::USER_NOT_EXISTS);
             }
             //				//是否被禁用
             //				if($this->user_account['disabled'] == "1"){
             //					return $this->getReturnArray(GameStatusCode::USER_NOT_EXISTS,"user[$gameuid] is disbaled.");
             //				}
             //				$this->checkSession($gameuid);
         }
         // 对参数做处理
         $this->params = $params;
         //			if(!$this->isPerfTestMode($params['gameuid'])){
         //				if(!get_app_config()->getGlobalConfig("debug_mode")){
         //					$this->checkSignature($params);
         //				}
         //				$this->validate();
         //			}
         $now = time();
         //调用游戏接口
         $result = $this->_exec();
         //			// 根据动作的定义,获取用户的经验值和金币的修改值
         //			$modify = array_intersect_key($result,array('coin'=>0,'money'=>0,'coupon'=>0,'experience'=>0));
         //			if (isset($this->params['action_id'])) {
         //		       	if (intval($this->action_def['coin']) != 0) $modify['coin'] += intval($this->action_def['coin']);
         //		       	if (intval($this->action_def['experience']) != 0) $modify['experience'] += intval($this->action_def['experience']);
         //			}
         //
         //		    //修改用户的经验值和金币数量
         //		    if (count($modify) > 0) {
         //		       	$this->user_account_mgr->updateUserStatus($gameuid, $modify);
         //		       	$result = array_merge($result, $modify);
         //		    }
         //
         //			//检查action是否要进行计数
         //			if (isset($this->params['action_id'])&&in_array($this->params['action_id'], $this->action_record_count)){
         //				UserActionCountManager::updateActionCount($this->params['gameuid'],$this->params['action_id']);
         //			}
         //			//判断是否要写actionlog日志
         //			if (!empty($modify) && isset($this->params['action_id'])){
         //				$action_log_params=array();
         //				$action_log_params=$modify;
         //				if (isset($result['action_log_params'])){
         //					$action_log_params['content']=$result['action_log_params']['content'];
         //					unset($result['action_log_params']);
         //				}
         //				$this->action_logger->writeLog($this->params['action_id'], $action_log_params);
         //			}
         //如果有eventlog,则写log日志,同时将返回值中的相关信息删除
         if (isset($result['event_log_params']) && is_array($result['event_log_params'])) {
             $event_log_params = $result['event_log_params'];
             $event_gameuid = $event_log_params['gameuid'];
             $event_action_id = $event_log_params['action_id'];
             $event_params = $event_log_params['params'];
             $event_logger = new UserEventLogManager($event_gameuid);
             $event_logger->writeLog($event_action_id, $event_params);
             unset($result['event_log_params']);
         }
         return $this->getReturnArray(0, 'ok', $result);
     } catch (DBException $e) {
         // 数据库类型的错误特殊处理
         $this->logger->writeError("database exception happens while execute sql, error_msg:" . $e->getMessage());
         $this->logger->writeError("and the stack trace is as below:\n" . $e->getTraceAsString());
         if (get_app_config()->getGlobalConfig("debug_mode")) {
             return $this->getReturnArray(GameStatusCode::DATABASE_ERROR, $e->getMessage());
         } else {
             return $this->getReturnArray(GameStatusCode::DATABASE_ERROR, 'database error');
         }
     } catch (GameException $e) {
         $this->logger->writeError("game exception happens while execute action:" . $e);
         //log输出过多,关闭之
         return $this->getReturnArray($e->getCode(), $e->getMessage());
     } catch (Exception $e) {
         // 其他的错误
         $this->logger->writeError("unknown exception happens while execute action." . $e->getTraceAsString());
         return $this->getReturnArray(GameStatusCode::UNKNOWN_ERROR, $e->getMessage());
     }
     return $this->getReturnArray(GameStatusCode::UNKNOWN_ERROR, '');
 }
 private function getListFromCache($list, $update_list = false)
 {
     $cache = $this->getCacheInstance();
     // 取得根据table名字开始的缓存key:
     // 例如:uid_gameuid_mapping_1,uid_gameuid_mapping_2,uid_gameuid_mapping_3
     $keys = array_map(array($this, 'getTableMemkey'), $list);
     $result = $cache->get($keys);
     // 没有一个值在缓存中
     if (empty($result)) {
         return false;
     }
     $ret = array_values($result);
     // 部分在缓存中
     if (count($result) != count($keys)) {
         // not all data in the cache, get from database
         $cond = '';
         $primary_key = $this->getPrimaryKey();
         $fields = array_keys($primary_key);
         if (empty($fields)) {
             $this->throwException("get list from cache call must provide the primary key.");
         }
         $db_datas = array();
         $new_list = array();
         // $idx=0, $k=uid_gameuid_mapping_1
         foreach ($keys as $idx => $k) {
             // 表示不在缓存中
             if (!array_key_exists($k, $result)) {
                 $db_datas[] = $list[$idx];
             } else {
                 $new_list[] = $list[$idx];
             }
         }
         if ($this->logger->isDebugEnabled()) {
             $this->logger->writeDebug("[TCRequest.getListFromCache]tring to get expire cache rows from db[" . print_r($db_datas, true) . "]");
         }
         $cond = '';
         if (count($fields) > 1) {
             $or_clauses = '';
             foreach ($db_datas as $or_value) {
                 $and_clause = '';
                 foreach ($or_value as $or_value_k => $or_value_v) {
                     $or_value_v = $this->prepareForSql($or_value_k, $or_value_v);
                     if (isset($and_clause[0])) {
                         $and_clause .= " AND ";
                     }
                     $and_clause .= "{$or_value_k}={$or_value_v}";
                 }
                 if (isset($or_clauses[0])) {
                     $or_clauses .= " OR ";
                 }
                 $or_clauses .= "({$and_clause})";
             }
             if (isset($or_clauses[0])) {
                 if (count($db_datas) > 1) {
                     $cond .= "({$or_clauses})";
                 } else {
                     $cond .= "{$or_clauses}";
                 }
             }
         } else {
             $field = $fields[0];
             if (count($db_datas) == 1) {
                 $cond .= "{$field}=" . $this->prepareForSql($field, $db_datas[0][$field]);
             } else {
                 $in_values = array();
                 foreach ($db_datas as $db_data) {
                     $in_values[] = $db_data[$field];
                 }
                 $cond .= "{$field} IN (" . $this->prepareForSql($field, $in_values) . ")";
             }
         }
         $sql = sprintf('SELECT %s from %s ', $this->getColumns(), $this->getTableServer()->getTableName());
         if (empty($cond)) {
             $sql .= "where {$this->key} = {$this->key_value}";
         } else {
             $sql .= "where {$cond}";
         }
         $db_result = $this->getDBHelperInstance()->getAll($sql);
         if (is_array($db_result) && count($db_result) > 0) {
             $this->setCacheList($this->unpackEntries($db_result), false);
             $ret = array_merge($ret, $db_result);
         }
         if ($update_list) {
             //在有些时候,调用TCDeleteRequest的时候,删除记录,但是list缓存没有被删除,
             //那么这里也会导致请求数据库,而且是每次都会请求数据库。
             //所以在这里判断下,数据库取出的记录和未命中缓存的元素是否相等。不相等就需要将相应的未命中缓存记录删除
             if (is_array($db_result) && count($db_result) > 0) {
                 foreach ($db_result as $entry) {
                     $new_list[] = array_intersect_key($entry, $primary_key);
                 }
             }
             if (count($new_list) != count($list)) {
                 $this->logger->writeError("tring to repair cache key list[old_list=" . print_r($list, true) . ",new_list=" . print_r($new_list, true) . "]");
                 $cache->set($this->getListCacheKey(), $new_list, 0);
             }
         }
     }
     return $ret;
 }