/** * * @param \Sooh\Base\Log\Data $logData */ public function write($logData) { $resChg = $logData->resChanged; $arr = $logData->toArray(); unset($arr['resChanged']); unset($arr['logGuid']); \Sooh\DB\Cases\LogStorage::$__YMD = \Sooh\Base\Time::getInstance()->YmdFull; \Sooh\DB\Cases\LogStorage::$__id_in_dbByObj = 'dbgrpForLog'; \Sooh\DB\Cases\LogStorage::$__type = 'a'; \Sooh\DB\Cases\LogStorage::$__nSplitedBy = $this->tbSplit; //\Sooh\DB\Cases\LogStorage::$__fields=array(.....); $tmp = \Sooh\DB\Cases\LogStorage::getCopy($logData->logGuid); foreach ($arr as $k => $v) { $tmp->setField($k, $v); } $ret = $tmp->writeLog(); if ($ret) { $tbSub = str_replace('_a_', '_b_', $tmp->tbname()); foreach ($resChg as $r) { $r['logGuid'] = $logData->logGuid; try { \Sooh\DB\Broker::errorMarkSkip(\Sooh\DB\Error::tableNotExists); $tmp->db()->addRecord($tbSub, $r); } catch (\ErrorException $e) { if (\Sooh\DB\Broker::errorIs($e, \Sooh\DB\Error::tableNotExists)) { $tmp->db()->ensureObj($tbSub, array('logGuid' => 'bigint unsigned not null default 0', 'resName' => "varchar(36) not null default ''", 'resChg' => "int not null default 0", 'resNew' => "int not null default 0")); $tmp->db()->addRecord($tbSub, $r); } else { error_log("write log failed:" . $e->getMessage() . "\n" . \Sooh\DB\Broker::lastCmd()); } } } } }
/** * 记录报表数据 * | mainType | subType | ymd | rptdata | flg1 | flg2 | flg3 | * @param \Sooh\DB\Interfaces\All $db * @param int $ymd yyyymmdd * @param array $rptData * @param string $mainType * @param string $subType * @param array $flgs 标志位字段,不参与任何统计 * @param array $conditionCanOverwrite 满足条件的才可以覆盖,null表示始终不能覆盖,空数组表示始终可以覆盖 * @return boolean */ public function save($db, $ymd, $rptData, $mainType, $subType, $flgs = array(), $conditionCanOverwrite = array()) { $pkey = array('mainType' => $mainType, 'subType' => $subType, 'ymd' => $ymd); $fields = $flgs; if (!isset($fields['flg1'])) { $fields['flg1'] = 0; } if (!isset($fields['flg2'])) { $fields['flg2'] = 0; } if (!isset($fields['flg3'])) { $fields['flg3'] = 0; } $fields['rptdata'] = json_encode($rptData); $exists = $db->getOne($this->tbName, 'ymd', $pkey); if ($exists) { if (is_array($conditionCanOverwrite)) { if (empty($conditionCanOverwrite)) { foreach ($pkey as $k => $v) { $conditionCanOverwrite[$k] = $v; } $exists = $db->getOne($this->tbName, 'ymd', $conditionCanOverwrite); if (!$exists) { return false; } } $db->updRecords($this->tbName, $fields, $pkey); } else { return false; } } else { try { \Sooh\DB\Broker::errorMarkSkip($v); foreach ($pkey as $k => $v) { $fields[$k] = $v; } $db->addRecord($this->tbName, $fields); } catch (ErrorException $e) { if (\Sooh\DB\Broker::errorIs($e)) { $this->save($db, $ymd, $mainType, $subType, $rptData); } else { error_log($e->getMessage() . '#' . \Sooh\DB\Broker::lastCmd() . "\n" . $e->getTraceAsString()); return false; } } } }
public function writeLog() { try { \Sooh\DB\Broker::errorMarkSkip(\Sooh\DB\Error::tableNotExists); $this->update(); return true; } catch (\Sooh\DB\Error $e) { if (\Sooh\DB\Broker::errorIs($e, \Sooh\DB\Error::tableNotExists)) { $this->createTable(); $this->update(); return true; } else { error_log("ErrorOnWriteLog:" . $e->getMessage() . "\n" . \Sooh\DB\Broker::lastCmd() . "\n" . $e->getTraceAsString()); return false; } } }
function var_log($var, $prefix = '') { if (is_a($var, "\\Exception")) { $s = $var->__toString(); if (strpos($s, '[Sooh_Base_Error]')) { if (class_exists('\\Sooh\\DB\\Broker', false)) { $sql = "\n" . \Sooh\DB\Broker::lastCmd() . "\n"; } else { $sql = "\n"; } error_log(str_replace('[Sooh_Base_Error]', $sql, $s)); } else { error_log($prefix . $var->getMessage() . "\n" . $s); } } else { error_log($prefix . "\n" . var_export($var, true)); } }
/** * 实际保存到数据库的执行代码 * @return int * @throws \ErrorException * @throws \Sooh\Base\ErrException 锁定了,又或诸如没什么要更改的确调用了save */ protected function trySave() { $tbDisk = $this->tbname(); $dbDisk = $this->db(); if ($this->cacheWhenVerIDIs) { $tbCache = $this->tbname(true); $dbCache = $this->db(true); } else { $tbCache = null; $dbCache = null; } $class = get_called_class(); if (empty($this->chged)) { throw new \ErrorException($class . ':nothing needs to do'); } try { if ($this->lock && !$this->lock->lockedByThisProcess) { throw new \ErrorException("Can not update as record is locked"); } if (!isset($this->r[$this->fieldName_verid])) { $verCurrent = array($this->fieldName_verid => 1); $fields = $this->fieldsForSqlUpds($this->chged); $pkeyBak = $dbDisk->kvoNew($tbDisk, $fields, $this->pkey, $verCurrent, $this->fieldAutoInc); $this->r[$this->fieldName_verid] = 1; foreach ($this->pkey as $k => $v) { $this->r[$k] = $v; } $md5Key0 = md5(json_encode($this->pkey)); $md5Key2 = md5(json_encode($pkeyBak)); if ($md5Key0 !== $md5Key2) { unset(self::$_copies[$class][$md5Key0]); self::$_copies[$class][$md5Key2] = $this; $this->pkey = $pkeyBak; } if ($this->cacheWhenVerIDIs > 0) { $dbCache->kvoNew($tbCache, $fields, $this->pkey, $verCurrent, $this->fieldAutoInc); } return 1; } else { $verCurrent = array($this->fieldName_verid => $this->r[$this->fieldName_verid]); $whereForUpdate = $this->pkey; if ($this->lock) { if (!$this->lock->lockedByThisProcess) { throw new \Sooh\Base\ErrException(\Sooh\Base\ErrException::msgLocked); } else { $this->setField($this->fieldName_lockmsg, ''); } } // else{ // $whereForUpdate[$this->fieldName_lockmsg]=''; // } if ($this->cacheWhenVerIDIs <= 1) { if ($dbDisk->kvoFieldSupport()) { $fields = $this->fieldsForSqlUpds($this->chged); $_ret = $dbDisk->kvoUpdate($tbDisk, $fields, $whereForUpdate, $verCurrent); $nextVerId = $fields[$this->fieldName_verid]; } else { $fieldsAll = $this->fieldsForSqlUpds(array_keys($this->r)); $_ret = $dbDisk->kvoUpdate($tbDisk, $this->r, $whereForUpdate, $verCurrent); $nextVerId = $fieldsAll[$this->fieldName_verid]; } if ($this->cacheWhenVerIDIs) { if ($dbCache->kvoFieldSupport()) { if (empty($fields)) { $fields = $this->fieldsForSqlUpds($this->chged); $nextVerId = $fields[$this->fieldName_verid]; } $dbCache->kvoUpdate($tbCache, $fields, $whereForUpdate, $verCurrent, true); } else { if (empty($fieldsAll)) { $fieldsAll = $this->fieldsForSqlUpds(array_keys($this->r)); $nextVerId = $fieldsAll[$this->fieldName_verid]; } $dbCache->kvoUpdate($tbCache, $fieldsAll, $whereForUpdate, $verCurrent, true); } } $this->r[$this->fieldName_verid] = $nextVerId; } else { if ($dbCache->kvoFieldSupport()) { $fields = $this->fieldsForSqlUpds($this->chged); $nextVerId = $fields[$this->fieldName_verid]; $_ret = $dbCache->kvoUpdate($tbCache, $fields, $whereForUpdate, $verCurrent); } else { $fieldsAll = $this->fieldsForSqlUpds(array_keys($this->r)); $nextVerId = $fieldsAll[$this->fieldName_verid]; $_ret = $dbCache->kvoUpdate($tbCache, $fieldsAll, $whereForUpdate, $verCurrent); } if ($this->r[$this->fieldName_verid] % $this->cacheWhenVerIDIs == 0) { try { if ($dbDisk->kvoFieldSupport()) { if (empty($fields)) { $fields = $this->fieldsForSqlUpds($this->chged); $nextVerId = $fields[$this->fieldName_verid]; } $_ret = $dbDisk->kvoUpdate($tbDisk, $fields, $whereForUpdate, $verCurrent, true); } else { if (empty($fieldsAll)) { $fieldsAll = $this->fieldsForSqlUpds(array_keys($this->r)); $nextVerId = $fieldsAll[$this->fieldName_verid]; } $_ret = $dbDisk->kvoUpdate($tbDisk, $fieldsAll, $whereForUpdate, $verCurrent, true); } } catch (\ErrorException $e) { error_log("fatal error: {$class} : update disk failed after cache updated"); throw $e; } } $this->r[$this->fieldName_verid] = $nextVerId; } } $this->lock = null; error_log("[KVObjV2 - save]" . implode("\n", \Sooh\DB\Broker::lastCmd(false))); return $_ret; } catch (\ErrorException $e) { //key duplicate -> add failed throw $e; } }
/** * 发放失败,收回 * @param string $userIdentifier * @param string $logMsg 日志记录说明 * @return bool */ public function use_rollback($logMsg) { try { $log = \Prj\Data\ShopPointLog::getCopy($this->userIdentifier); $ret = $log->updateStatus($this->sn, \Prj\Data\ShopPointLog::status_cancel, $logMsg); if ($ret !== 1) { error_log("confirm shopPoint to {$this->userIdentifier} failed(none changed):" . \Sooh\DB\Broker::lastCmd() . "\n"); return false; } $this->rs[$this->sn]['finalStatus'] = \Prj\Data\ShopPointLog::status_cancel; $this->_nleft -= $this->rs[$this->sn]['changed']; return true; } catch (\ErrorException $e) { error_log("confirm shopPoint to {$this->userIdentifier} failed:" . $e->getMessage() . "\n" . \Sooh\DB\Broker::lastCmd() . "\n" . $e->getTraceAsString()); return false; } }
protected function _chkErr($skip = 0) { $errno = mysqli_errno($this->_connection); if ($errno) { $message = mysqli_error($this->_connection); switch ($errno) { case 1054: $err = sooh_dbErr::fieldNotExists; break; case 1045: $err = sooh_dbErr::connectError; break; case 1049: $err = sooh_dbErr::connectError; break; case 1050: $err = sooh_dbErr::tableExists; break; case 1146: $err = sooh_dbErr::tableNotExists; break; case 1060: $err = sooh_dbErr::fieldExists; break; case 1062: case 1022: case 1069: //[1062]Duplicate entry '2' for key 'PRIMARY'' $dupKey = explode('for key ', $message); $dupKey = trim(array_pop($dupKey), '\''); $err = sooh_dbErr::duplicateKey; break; default: $err = sooh_dbErr::otherError; break; } if (empty($skip) || !isset($skip[$err])) { $lastCmd = sooh_broker::lastCmd(); $err = new sooh_dbErr($err, '[' . $errno . ']' . $message, $lastCmd); if (!empty($dupKey)) { $err->keyDuplicated = $dupKey; } error_log("[" . $err->getCode() . "]" . $err->getMessage() . "\n" . $lastCmd . "\n" . $err->getTraceAsString()); throw $err; } elseif ($skip[$err] === false) { $lastCmd = sooh_broker::lastCmd(); $err = new sooh_dbErr($err, '[' . $errno . ']' . $message, $lastCmd); if (!empty($dupKey)) { $err->keyDuplicated = $dupKey; } throw $err; } } }
/** * 签到 * @param boolean $withBonus 返回里是否带奖励物品列表 * @param \Prj\Data\User $userOrAccountId accountId 或 \Prj\Data\User * @return array */ public function doCheckIn($withBonus, $userOrAccountId) { if ($this->rpc !== null) { return $this->rpc->initArgs(array('withBonus' => $withBonus, 'userOrAccountId' => $userOrAccountId))->send(__FUNCTION__); } else { if (is_scalar($userOrAccountId)) { $userOrAccountId = \Prj\Data\User::getCopy($userOrAccountId); } $userOrAccountId->load(); if ($userOrAccountId->exists() === false) { $userOrAccountId->setField(self::fieldUser, array()); $userOrAccountId->update(); } $this->decode($userOrAccountId->getField(self::fieldUser, true)); if ($this->r['ymd'] == $this->today) { \Sooh\Base\Log\Data::getInstance()->ret = "checkin already"; return $this->errFound(self::errTodayDone, 400, $withBonus); } elseif (sizeof($this->r['checked']) >= self::maxMonth) { \Sooh\Base\Log\Data::getInstance()->ret = 'checkin of this month:all done'; return $this->errFound(self::errMonthDone, 400, $withBonus); } $accountId = $userOrAccountId->getAccountId(); $idCheckThisTime = array_sum($this->r['checked']); $bonusThisTime = $this->getBonusList()[$idCheckThisTime]; if (false === $userOrAccountId->lock('chkinBonus:' . http_build_query($bonusThisTime))) { \Sooh\Base\Log\Data::getInstance()->ret = "lock user for checkin failed"; \Prj\Loger::alarm('[LockFailed] user-table on checkin' . \Sooh\DB\Broker::lastCmd()); return $this->errFound(\Sooh\Base\ErrException::msgServerBusy, 500, $withBonus); } //\Lib\Items\Broker::iniForGiven('Voucher', array('iniDefaultForGive_a'=>60));// 如果有道具发放时有额外参数要设置(比如有效期不同) $givedThisTime = \Lib\Items\Broker::batchGive_pre($bonusThisTime, $accountId); if (sizeof($givedThisTime) == sizeof($bonusThisTime)) { if (\Lib\Items\Broker::batchGive_confirm($givedThisTime, $accountId)) { try { $this->r['checked'][$idCheckThisTime] = 1; $this->r['bonusGot'][$idCheckThisTime] = $bonusThisTime; $this->r['ymd'] = $this->today; $userOrAccountId->setField(self::fieldUser, $this->r); $userOrAccountId->update(); \Sooh\Base\Log\Data::getInstance()->ret = "done"; return $this->allDone(self::msgCheckinDone, $withBonus); } catch (\ErrorException $errOnUpdate) { \Prj\Loger::alarm('[CheckInFailed] on update user:'******'[GiveItemFailed] on checkin'); \Sooh\Base\Log\Data::getInstance()->ret = "give item failed"; } else { \Sooh\Base\Log\Data::getInstance()->ret = "update user failed"; } if (\Lib\Items\Broker::batchGive_rollback('GiveItemFailedOnCheckin', $givedThisTime, $accountId)) { $userOrAccountId->unlock(); return $this->errFound(\Sooh\Base\ErrException::msgServerBusy, 500, $withBonus); } else { return $this->errFound(\Sooh\Base\ErrException::msgServerBusy, 500, $withBonus); } } }
define("APP_PATH", dirname(__DIR__)); /* 指向public的上一级 */ if (!defined('SOOH_INDEX_FILE')) { define('SOOH_INDEX_FILE', 'index.php'); } define('SOOH_ROUTE_VAR', '__'); error_log("-------------------------------------------------------tart:route=" . $_GET['__'] . " cmd=" . $_GET['cmd'] . " pid=" . getmypid()); include dirname(__DIR__) . '/conf/globals.php'; $ini = \Sooh\Base\Ini::getInstance(); $app = new Yaf_Application(APP_PATH . "/conf/application.ini"); $dispatcher = $app->getDispatcher(); if (!empty($reqeustReal)) { $dispatcher->setRequest($reqeustReal); } $view = \SoohYaf\SoohPlugin::initYafBySooh($dispatcher); $dispatcher->returnResponse(TRUE); try { $response = $app->run(); } catch (\ErrorException $e) { $view->assign('code', $e->getCode()); $view->assign('msg', $e->getMessage()); error_log("Error Caught at index.php:" . $e->getMessage() . "\n" . \Sooh\DB\Broker::lastCmd() . "\n" . $e->getTraceAsString() . "\n"); $response = new Yaf_Response_Http(); $response->setBody($view->render('ctrl/action.phtml')); } if ($ini->viewRenderType() === 'json') { header('Content-type: application/json'); } $response->response(); \Sooh\Base\Ini::registerShutdown(null, null); error_log("====================================================================end:route=" . $_GET['__'] . " cmd=" . $_GET['cmd'] . " pid=" . getmypid());
protected function _chkErr($skip = 0) { $message = sqlsrv_errors(); if (is_array($message) && 5701 != $message[0]['code']) { switch ($message[0]['code']) { //case :$err=sooh_dbErr::connectError;break; case 18456: $err = sooh_dbErr::connectError; break; case 2714: $err = sooh_dbErr::tableExists; break; case 208: $err = sooh_dbErr::tableNotExists; break; case 2705: $err = sooh_dbErr::fieldExists; break; case 207: $err = sooh_dbErr::fieldNotExists; break; case 2627: //ODBC Driver 11 for SQL Server][SQL Server]Violation of PRIMARY KEY constraint 'PK__test1231__3BD0198EF085A699'. Cannot insert duplicate key in object 'dbo.test12314'. The duplicate key value is (7).done //Violation of UNIQUE KEY constraint 'b'. Cannot insert duplicate key in object 'dbo.test12314'. The duplicate key $dupKey = explode(' KEY constraint \'', $message[0]['message']); if (substr($dupKey[0], -7) == 'PRIMARY') { $dupKey = 'PRIMARY_KEY'; } else { $dupKey = explode('\'. Cannot insert', $dupKey[1]); $dupKey = array_shift($dupKey); } $err = sooh_dbErr::duplicateKey; break; default: $err = sooh_dbErr::otherError; $message[0]['message'] = "(err:" . $message[0]['code'] . ")" . $message[0]['message']; break; } if (empty($skip) || !isset($skip[$err])) { $lastCmd = sooh_broker::lastCmd(); $err = new sooh_dbErr($err, $message[0]['message'], $lastCmd); if (!empty($dupKey)) { $err->keyDuplicated = $dupKey; } error_log("[" . $err->getCode() . "]" . $err->getMessage() . "\n" . $lastCmd . "\n" . $err->getTraceAsString()); throw $err; } elseif ($skip[$err] === false) { $lastCmd = sooh_broker::lastCmd(); $err = new sooh_dbErr($err, $message[0]['message'], $lastCmd); if (!empty($dupKey)) { $err->keyDuplicated = $dupKey; } throw $err; } } }
/** * 账号登入, 失败抛出异常(密码错误,账号找不到等等) * @param $loginName * @param $cameFrom * @param $password * @param array $customArgs * @return mixed * @throws \ErrorException * @throws \Sooh\Base\ErrException * @throws array */ public function login($loginName, $cameFrom, $password, $customArgs = ['contractId']) { if ($this->rpc !== null) { return $this->rpc->initArgs(['loginName' => $loginName, 'cameFrom' => $cameFrom, 'password' => $password, 'customArgs' => $customArgs])->send(__FUNCTION__); } else { $objLogin = \Sooh\DB\Cases\AccountAlias::getCopy($loginName, $cameFrom); $objLogin->load(); if ($objLogin->exists()) { $accountId = $objLogin->getField('accountId'); $this->setAccountStorage($accountId); $this->account->load(); if ($this->account->exists()) { $dt = \Sooh\Base\Time::getInstance(); $cmp = md5($password . $this->account->getField('passwdSalt')); $loginFailed = $this->account->getField('loginFailed'); if ($loginFailed) { $cd = new \Sooh\Base\CD($loginFailed, 750, 3600); if ($cd->isRed()) { throw new \Sooh\Base\ErrException(self::errAccountOrPasswordError); } } else { $cd = new \Sooh\Base\CD(0, 750, 3600); } $ymdhForbidden = $this->account->getField('dtForbidden'); if ($ymdhForbidden) { if ($dt->YmdH <= $ymdhForbidden) { throw new \Sooh\Base\ErrException(self::errAccountLock, 404); } } if ($cmp != $this->account->getField('passwd')) { $cd->add(1); $ret = new \Sooh\Base\ErrException(self::errAccountOrPasswordError, 404); } else { $nickname = $this->account->getField('nickname'); $ret = array('accountId' => $this->account->getField('accountId'), 'nickname' => $nickname); if (!empty($customArgs)) { if (is_string($customArgs)) { $customArgs = explode(',', $customArgs); } foreach ($customArgs as $k) { $ret[$k] = $this->account->getField('contractId'); } } } $this->account->setField('lastIP', \Sooh\Base\Tools::remoteIP()); $this->account->setField('lastDt', $dt->timestamp()); $this->account->setField('loginFailed', $cd->toString()); try { $this->account->update(); } catch (\ErrorException $ex) { \Sooh\Base\Log\Data::error("error on update account when login:"******"\n" . \Sooh\DB\Broker::lastCmd() . "\n" . $ex->getTraceAsString()); } if (is_array($ret)) { return $ret; } else { throw $ret; } } else { throw new \Sooh\Base\ErrException(self::errAccountOrPasswordError, 400); } } else { throw new \Sooh\Base\ErrException(self::errAccountOrPasswordError, 400); } } }