MAPG-235 queries with relations on any recursion level implemented

This commit is contained in:
Balázs Vigh 2021-05-15 11:32:41 +02:00
parent 21e41b7c36
commit 44df94eb98
6 changed files with 102 additions and 26 deletions

View File

@ -143,7 +143,7 @@ class GameController
// select places
$mapId = (int) $this->request->post('mapId');
$map = $this->mapRepository->getById($mapId);
// $map = $this->mapRepository->getById($mapId);
$places = $this->placeRepository->getRandomNPlaces($mapId, static::NUMBER_OF_ROUNDS, $userId);
@ -242,6 +242,7 @@ class GameController
$challenge = $this->challengeRepository->getByTokenStr($challengeToken_str);
if(!$this->userInChallengeRepository->isUserParticipatingInChallenge($userId, $challenge)) {
// new player is joining
$userInChallenge = new UserInChallenge();
$userInChallenge->setUserId($userId);
$userInChallenge->setChallenge($challenge);

View File

@ -146,13 +146,13 @@ class GameFlowController
$session = $this->request->session();
$userId = $session->get('userId');
$challengeToken_str = $this->request->query('challengeToken');
$challenge = $this->challengeRepository->getByTokenStr($challengeToken_str);
$userInChallenge = $this->userInChallengeRepository->getByUserIdAndToken($userId, $challengeToken_str);
if (!isset($challenge)) {
if (!isset($userInChallenge)) {
return new JsonContent(['error' => 'game_not_found']);
}
$userInChallenge = $this->userInChallengeRepository->getByUserIdAndChallenge($userId, $challenge);
$challenge = $userInChallenge->getChallenge();
$currentRound = $userInChallenge->getRound();
$currentPlace = $this->placeRepository->getByRoundInChallenge($challenge, $currentRound);
@ -160,6 +160,7 @@ class GameFlowController
$response['history'] = [];
$allGuessesInChallenge = iterator_to_array($this->guessRepository->getAllInChallenge($challenge));
$guessesByUser = iterator_to_array($this->guessRepository->getAllInChallengeByUser($userId, $challenge));
$places = iterator_to_array($this->placeRepository->getAllInChallenge($challenge));
@ -205,6 +206,9 @@ class GameFlowController
public function guess(): IContent
{
// testing
$testPlace = $this->placeRepository->getByIdWithMap(5);
$mapId = (int) $this->request->query('mapId');
$session = $this->request->session();
@ -305,13 +309,13 @@ class GameFlowController
$session = $this->request->session();
$userId = $session->get('userId');
$challengeToken_str = $this->request->query('challengeToken');
$challenge = $this->challengeRepository->getByTokenStr($challengeToken_str);
$userInChallenge = $this->userInChallengeRepository->getByUserIdAndToken($userId, $challengeToken_str);
if (!isset($challenge)) {
if (!isset($userInChallenge)) {
return new JsonContent(['error' => 'game_not_found']);
}
$userInChallenge = $this->userInChallengeRepository->getByUserIdAndChallenge($userId, $challenge);
$challenge = $userInChallenge->getChallenge();
$currentRound = $userInChallenge->getRound();
$currentPlace = $this->placeRepository->getByRoundInChallenge($challenge, $currentRound);
$map = $this->mapRepository->getByPlace($currentPlace);

View File

@ -45,24 +45,62 @@ class PersistentDataManager
return $this->selectFromDb($select, $type, $withRelations);
}
public function fillWithData(array $data, Model $model): void
public function fillWithData(array &$data, Model $model, ?string $modelKey = null): void
{
$relations = $model::getRelations();
$relationData = [];
foreach ($data as $key => $value) {
if ($this->extractRelationData($key, $value, $relationData, $relations)) {
continue;
while (key($data)) {
$key = key($data);
$value = current($data);
$relation = key($relations);
if (strpos($key, '__') == false) {
$method = 'set' . str_replace('_', '', ucwords($key, '_'));
if (method_exists($model, $method)) {
$model->$method($value);
}
next($data);
} else if (isset($modelKey) && substr($key, 0, strlen($modelKey . '__')) === $modelKey . '__') {
$key = substr($key, strlen($modelKey) + 2);
$method = 'set' . str_replace('_', '', ucwords($key, '_'));
if (method_exists($model, $method)) {
$model->$method($value);
}
next($data);
} else if (substr($key, 0, strlen($relation . '__')) === $relation . '__') {
// $relation = current($relations);
$relationType = current($relations);
$relationModel = new $relationType();
$this->fillWithData($data, $relationModel, $relation);
$method = 'set' . str_replace('_', '', ucwords($relation, '_'));
$model->$method($relationModel);
next($relations);
} else {
return;
}
}
$this->setRelations($model, $relationData);
// foreach ($data as $key => $value) {
// if ($this->extractRelationData($key, $value, $relationData, $relations)) {
// continue;
// }
// $method = 'set' . str_replace('_', '', ucwords($key, '_'));
// if (method_exists($model, $method)) {
// $model->$method($value);
// }
// }
// $this->setRelations($model, $relationData);
$model->saveSnapshot();
}
@ -133,15 +171,9 @@ class PersistentDataManager
$table = call_user_func([$type, 'getTable']);
$fields = call_user_func([$type, 'getFields']);
array_walk($fields, function (&$value, $key, $table) {
$value = [$table, $value];
}, $table);
$select->from($table);
//TODO: only with some relations?
if ($withRelations) {
$relations = call_user_func([$type, 'getRelations']);
// array_walk($fields, function (&$value, $key, $table) {
// $value = [$table, $value];
// }, $table);
$columns = [];
@ -149,12 +181,25 @@ class PersistentDataManager
$columns[] = [$table, $field];
}
$select->from($table);
//TODO: only with some relations?
if ($withRelations) {
$relations = call_user_func([$type, 'getRelations']);
// $columns = [];
// foreach ($fields as $field) {
// $columns[] = [$table, $field];
// }
$columns = array_merge($columns, $this->getRelationColumns($relations));
$this->leftJoinRelations($select, $table, $relations);
$select->columns($columns);
} else {
$select->columns($fields);
// $select->columns($fields);
$select->columns($columns);
}
return $select;
@ -169,6 +214,9 @@ class PersistentDataManager
foreach (call_user_func([$relationType, 'getFields']) as $relationField) {
$columns[] = [$relationTable, $relationField, $relation . '__' . $relationField];
}
$nextOrderRelations = call_user_func([$relationType, 'getRelations']);
$columns = array_merge($columns, $this->getRelationColumns($nextOrderRelations));
}
return $columns;
@ -179,6 +227,9 @@ class PersistentDataManager
foreach ($relations as $relation => $relationType) {
$relationTable = call_user_func([$relationType, 'getTable']);
$select->leftJoin($relationTable, [$relationTable, 'id'], '=', [$table, $relation . '_id']);
$nextOrderRelations = call_user_func([$relationType, 'getRelations']);
$this->leftJoinRelations($select, $relationTable, $nextOrderRelations);
}
}

View File

@ -53,11 +53,11 @@ class GuessRepository
public function getAllInChallenge(Challenge $challenge): Generator
{
$select = new Select(\Container::$dbConnection);
$select->innerJoin('place_in_challenge', ['guesses', 'place_in_challenge_id'], '=', ['place_in_challenge', 'id']);
// $select->innerJoin('place_in_challenge', ['guesses', 'place_in_challenge_id'], '=', ['place_in_challenge', 'id']);
$select->where('challenge_id', '=', $challenge->getId());
$select->orderBy('order');
yield from $this->pdm->selectMultipleFromDb($select, Guess::class);
yield from $this->pdm->selectMultipleFromDb($select, Guess::class, true);
}
public function getAllInChallengeByRound(int $round, Challenge $challenge): Generator

View File

@ -199,4 +199,13 @@ class PlaceRepository
yield from $this->pdm->selectMultipleFromDb($select, Place::class);
}
public function getByIdWithMap(int $placeId): ?Place
{
$select = new Select(\Container::$dbConnection);
// $select->innerJoin('maps', ['maps', 'id'], '=', ['places', 'map_id']);
$select->where(['places', 'id'], '=', $placeId);
return $this->pdm->selectFromDb($select, Place::class, true);
}
}

View File

@ -41,6 +41,17 @@ class UserInChallengeRepository
return $this->pdm->selectFromDb($select, UserInChallenge::class);
}
public function getByUserIdAndToken(int $userId, string $token_str): ?UserInChallenge
{
$token = hexdec($token_str);
$select = new Select(\Container::$dbConnection);
$select->where('user_id', '=', $userId);
$select->where('token', '=', $token);
return $this->pdm->selectFromDb($select, UserInChallenge::class, true);
}
public function isUserParticipatingInChallenge(int $userId, Challenge $challenge): bool
{
$select = new Select(\Container::$dbConnection, 'user_in_challenge');