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

View File

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

View File

@ -45,24 +45,62 @@ class PersistentDataManager
return $this->selectFromDb($select, $type, $withRelations); 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(); $relations = $model::getRelations();
$relationData = []; $relationData = [];
foreach ($data as $key => $value) { while (key($data)) {
if ($this->extractRelationData($key, $value, $relationData, $relations)) { $key = key($data);
continue; $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, '_')); $method = 'set' . str_replace('_', '', ucwords($key, '_'));
if (method_exists($model, $method)) { if (method_exists($model, $method)) {
$model->$method($value); $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(); $model->saveSnapshot();
} }
@ -133,15 +171,9 @@ class PersistentDataManager
$table = call_user_func([$type, 'getTable']); $table = call_user_func([$type, 'getTable']);
$fields = call_user_func([$type, 'getFields']); $fields = call_user_func([$type, 'getFields']);
array_walk($fields, function (&$value, $key, $table) { // array_walk($fields, function (&$value, $key, $table) {
$value = [$table, $value]; // $value = [$table, $value];
}, $table); // }, $table);
$select->from($table);
//TODO: only with some relations?
if ($withRelations) {
$relations = call_user_func([$type, 'getRelations']);
$columns = []; $columns = [];
@ -149,12 +181,25 @@ class PersistentDataManager
$columns[] = [$table, $field]; $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)); $columns = array_merge($columns, $this->getRelationColumns($relations));
$this->leftJoinRelations($select, $table, $relations); $this->leftJoinRelations($select, $table, $relations);
$select->columns($columns); $select->columns($columns);
} else { } else {
$select->columns($fields); // $select->columns($fields);
$select->columns($columns);
} }
return $select; return $select;
@ -169,6 +214,9 @@ class PersistentDataManager
foreach (call_user_func([$relationType, 'getFields']) as $relationField) { foreach (call_user_func([$relationType, 'getFields']) as $relationField) {
$columns[] = [$relationTable, $relationField, $relation . '__' . $relationField]; $columns[] = [$relationTable, $relationField, $relation . '__' . $relationField];
} }
$nextOrderRelations = call_user_func([$relationType, 'getRelations']);
$columns = array_merge($columns, $this->getRelationColumns($nextOrderRelations));
} }
return $columns; return $columns;
@ -179,6 +227,9 @@ class PersistentDataManager
foreach ($relations as $relation => $relationType) { foreach ($relations as $relation => $relationType) {
$relationTable = call_user_func([$relationType, 'getTable']); $relationTable = call_user_func([$relationType, 'getTable']);
$select->leftJoin($relationTable, [$relationTable, 'id'], '=', [$table, $relation . '_id']); $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 public function getAllInChallenge(Challenge $challenge): Generator
{ {
$select = new Select(\Container::$dbConnection); $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->where('challenge_id', '=', $challenge->getId());
$select->orderBy('order'); $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 public function getAllInChallengeByRound(int $round, Challenge $challenge): Generator

View File

@ -199,4 +199,13 @@ class PlaceRepository
yield from $this->pdm->selectMultipleFromDb($select, Place::class); 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); 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 public function isUserParticipatingInChallenge(int $userId, Challenge $challenge): bool
{ {
$select = new Select(\Container::$dbConnection, 'user_in_challenge'); $select = new Select(\Container::$dbConnection, 'user_in_challenge');