forked from devsam/core
내부 코드 사용례에서 General 테이블의 column을 일부만 가져오는 경우가 다수 있습니다. 다만 General 클래스에서 각종 iAction에 해당하는 트리거 함수 호출을 위해서는 모든 column을 다 가져와야 정상 동작이 가능한 만큼, iAction interface를 구현한 General 클래스와, 구현하지 않은 GeneralLite 클래스 둘로 나눕니다. 또한 General 클래스에서는 필요한 column을 다 가져오도록 변경합니다. Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/236
180 lines
5.9 KiB
PHP
180 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace sammo;
|
|
|
|
use Ds\Map;
|
|
use sammo\Enums\GeneralLiteQueryMode;
|
|
use sammo\Enums\RankColumn;
|
|
|
|
class GeneralLite extends GeneralBase
|
|
{
|
|
/**
|
|
* @param array $raw DB row값.
|
|
* @param null|array $city DB city 테이블의 row값
|
|
* @param int|null $year 게임 연도
|
|
* @param int|null $month 게임 월
|
|
*/
|
|
public function __construct(array $raw, ?Map $rawRank, ?array $city, ?array $nation, ?int $year, ?int $month)
|
|
{
|
|
if ($nation === null) {
|
|
$nation = getNationStaticInfo($raw['nation']);
|
|
}
|
|
|
|
$this->raw = $raw;
|
|
$this->rawCity = $city;
|
|
|
|
if ($year !== null && $month !== null) {
|
|
$this->initLogger($year, $month);
|
|
}
|
|
|
|
if ($rawRank) {
|
|
$this->rankVarRead = $rawRank;
|
|
} else {
|
|
$this->rankVarRead = new Map();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param \MeekroDB $db
|
|
*/
|
|
function applyDB($db): bool
|
|
{
|
|
$updateVals = $this->getUpdatedValues();
|
|
|
|
|
|
$generalID = $this->getID();
|
|
$result = false;
|
|
|
|
if ($updateVals) {
|
|
$db->update('general', $updateVals, 'no=%i', $generalID);
|
|
$result = $result || $db->affectedRows() > 0;
|
|
if (key_exists('nation', $updateVals)) {
|
|
$db->update('rank_data', [
|
|
'nation_id' => $updateVals['nation']
|
|
], 'general_id = %i', $generalID);
|
|
$result = true;
|
|
}
|
|
$this->flushUpdateValues();
|
|
}
|
|
|
|
$this->getLogger()->flush();
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* @param ?int[] $generalIDList
|
|
* @param null|array<string|RankColumn> $column
|
|
* @param GeneralLiteQueryMode $queryMode
|
|
* @return \sammo\GeneralLite[]
|
|
* @throws MustNotBeReachedException
|
|
*/
|
|
static public function createObjListFromDB(?array $generalIDList, ?array $column = null, GeneralLiteQueryMode $queryMode = GeneralLiteQueryMode::Full): array
|
|
{
|
|
if ($generalIDList === []) {
|
|
return [];
|
|
}
|
|
|
|
if($queryMode > GeneralLiteQueryMode::Full){
|
|
throw new \InvalidArgumentException('지원하지 않는 queryMode:' . $queryMode->name);
|
|
}
|
|
|
|
$db = DB::db();
|
|
if ($queryMode->value > 0) {
|
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
|
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
|
|
} else {
|
|
$year = null;
|
|
$month = null;
|
|
}
|
|
|
|
/**
|
|
* @var string[] $column
|
|
*/
|
|
[$column, $rankColumn,] = static::mergeQueryColumn($column, $queryMode);
|
|
|
|
if ($generalIDList === null) {
|
|
$rawGenerals = Util::convertArrayToDict(
|
|
$db->query('SELECT %l FROM general WHERE 1', Util::formatListOfBackticks($column)),
|
|
'no'
|
|
);
|
|
|
|
$generalIDList = array_keys($rawGenerals);
|
|
} else {
|
|
$rawGenerals = Util::convertArrayToDict(
|
|
$db->query('SELECT %l FROM general WHERE no IN %li', Util::formatListOfBackticks($column), $generalIDList),
|
|
'no'
|
|
);
|
|
}
|
|
|
|
/** @var Map<int,Map<RankColumn,int|float>> */
|
|
$rawRanks = new Map();
|
|
if ($rankColumn) {
|
|
$rawValue = $db->queryAllLists(
|
|
'SELECT `general_id`, `type`, `value` FROM rank_data WHERE general_id IN %li AND `type` IN %ls',
|
|
$generalIDList,
|
|
array_map(fn (\BackedEnum $e) => $e->value, $rankColumn)
|
|
);
|
|
foreach ($rawValue as [$generalID, $rawRankType, $rankValue]) {
|
|
if (!$rawRanks->hasKey($generalID)) {
|
|
$rawRanks[$generalID] = new Map();
|
|
}
|
|
|
|
$rankType = RankColumn::from($rawRankType);
|
|
$rawRanks[$generalID][$rankType] = $rankValue;
|
|
}
|
|
}
|
|
|
|
$result = [];
|
|
foreach ($generalIDList as $generalID) {
|
|
if (!key_exists($generalID, $rawGenerals)) {
|
|
$result[$generalID] = new DummyGeneral($queryMode->value > 0);
|
|
continue;
|
|
}
|
|
$result[$generalID] = new static($rawGenerals[$generalID], $rawRanks[$generalID] ?? null, null, null, $year, $month);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
static public function createObjFromDB(int $generalID, ?array $column = null, GeneralLiteQueryMode $queryMode = GeneralLiteQueryMode::Full): self
|
|
{
|
|
$db = DB::db();
|
|
if ($queryMode->value > 0) {
|
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
|
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
|
|
} else {
|
|
$year = null;
|
|
$month = null;
|
|
}
|
|
|
|
/**
|
|
* @var string[] $column
|
|
* @var RankColumn[] $rankColumn
|
|
*/
|
|
[$column, $rankColumn,] = static::mergeQueryColumn($column, $queryMode);
|
|
|
|
$rawGeneral = $db->queryFirstRow('SELECT %l FROM general WHERE no = %i', Util::formatListOfBackticks($column), $generalID);
|
|
|
|
if (!$rawGeneral) {
|
|
return new DummyGeneralLite($queryMode->value > 0);
|
|
}
|
|
|
|
$rawRankValues = new Map();
|
|
if ($rankColumn) {
|
|
$rawValue = $db->queryAllLists(
|
|
'SELECT `type`, `value` FROM rank_data WHERE general_id = %i AND `type` IN %ls',
|
|
$generalID,
|
|
array_map(fn (\BackedEnum $e) => $e->value, $rankColumn)
|
|
);
|
|
foreach ($rawValue as [$rawRankType, $rankValue]) {
|
|
$rankType = RankColumn::tryFrom($rawRankType);
|
|
$rawRankValues->put($rankType, $rankValue);
|
|
}
|
|
}
|
|
|
|
$general = new static($rawGeneral, $rawRankValues, null, null, $year, $month);
|
|
|
|
return $general;
|
|
}
|
|
}
|