mirror of
https://github.com/maelgangloff/domain-watchdog.git
synced 2025-12-29 16:15:04 +00:00
perf: prevent N+1 on watchlist fetch
This commit is contained in:
@@ -11,7 +11,6 @@ use App\Repository\DomainRepository;
|
|||||||
use App\Repository\WatchlistRepository;
|
use App\Repository\WatchlistRepository;
|
||||||
use App\Service\CalendarService;
|
use App\Service\CalendarService;
|
||||||
use App\Service\RDAPService;
|
use App\Service\RDAPService;
|
||||||
use Doctrine\Common\Collections\Collection;
|
|
||||||
use Eluceo\iCal\Domain\Entity\Calendar;
|
use Eluceo\iCal\Domain\Entity\Calendar;
|
||||||
use Eluceo\iCal\Presentation\Component\Property;
|
use Eluceo\iCal\Presentation\Component\Property;
|
||||||
use Eluceo\iCal\Presentation\Component\Property\Value\TextValue;
|
use Eluceo\iCal\Presentation\Component\Property\Value\TextValue;
|
||||||
@@ -36,23 +35,6 @@ class WatchlistController extends AbstractController
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route(
|
|
||||||
path: '/api/watchlists',
|
|
||||||
name: 'watchlist_get_all_mine',
|
|
||||||
defaults: [
|
|
||||||
'_api_resource_class' => Watchlist::class,
|
|
||||||
'_api_operation_name' => 'get_all_mine',
|
|
||||||
],
|
|
||||||
methods: ['GET']
|
|
||||||
)]
|
|
||||||
public function getWatchlists(): Collection
|
|
||||||
{
|
|
||||||
/** @var User $user */
|
|
||||||
$user = $this->getUser();
|
|
||||||
|
|
||||||
return $user->getWatchlists();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws ParseException
|
* @throws ParseException
|
||||||
* @throws EofException
|
* @throws EofException
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use ApiPlatform\Metadata\Patch;
|
|||||||
use ApiPlatform\Metadata\Post;
|
use ApiPlatform\Metadata\Post;
|
||||||
use ApiPlatform\Metadata\Put;
|
use ApiPlatform\Metadata\Put;
|
||||||
use App\Repository\WatchlistRepository;
|
use App\Repository\WatchlistRepository;
|
||||||
|
use App\State\MyWatchlistsProvider;
|
||||||
use App\State\WatchlistUpdateProcessor;
|
use App\State\WatchlistUpdateProcessor;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
@@ -25,7 +26,6 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||||||
shortName: 'Watchlist',
|
shortName: 'Watchlist',
|
||||||
operations: [
|
operations: [
|
||||||
new GetCollection(
|
new GetCollection(
|
||||||
routeName: 'watchlist_get_all_mine',
|
|
||||||
normalizationContext: [
|
normalizationContext: [
|
||||||
'groups' => [
|
'groups' => [
|
||||||
'watchlist:list',
|
'watchlist:list',
|
||||||
@@ -34,6 +34,7 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
name: 'get_all_mine',
|
name: 'get_all_mine',
|
||||||
|
provider: MyWatchlistsProvider::class,
|
||||||
),
|
),
|
||||||
new GetCollection(
|
new GetCollection(
|
||||||
uriTemplate: '/tracked',
|
uriTemplate: '/tracked',
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Repository;
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\User;
|
||||||
use App\Entity\Watchlist;
|
use App\Entity\Watchlist;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
@@ -33,6 +34,24 @@ class WatchlistRepository extends ServiceEntityRepository
|
|||||||
->getQuery()->execute();
|
->getQuery()->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Watchlist[]
|
||||||
|
*/
|
||||||
|
public function fetchWatchlistsForUser(User $user): array
|
||||||
|
{
|
||||||
|
return $this->createQueryBuilder('w')
|
||||||
|
->addSelect('d')
|
||||||
|
->addSelect('e')
|
||||||
|
->addSelect('p')
|
||||||
|
->leftJoin('w.domains', 'd')
|
||||||
|
->leftJoin('d.events', 'e')
|
||||||
|
->leftJoin('d.domainPurchases', 'p')
|
||||||
|
->where('w.user = :user')
|
||||||
|
->setParameter('user', $user)
|
||||||
|
->getQuery()
|
||||||
|
->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * @return Watchlist[] Returns an array of Watchlist objects
|
// * @return Watchlist[] Returns an array of Watchlist objects
|
||||||
// */
|
// */
|
||||||
|
|||||||
24
src/State/MyWatchlistsProvider.php
Normal file
24
src/State/MyWatchlistsProvider.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\State;
|
||||||
|
|
||||||
|
use ApiPlatform\Metadata\Operation;
|
||||||
|
use ApiPlatform\State\ProviderInterface;
|
||||||
|
use App\Entity\User;
|
||||||
|
use App\Repository\WatchlistRepository;
|
||||||
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
|
|
||||||
|
readonly class MyWatchlistsProvider implements ProviderInterface
|
||||||
|
{
|
||||||
|
public function __construct(private Security $security, private WatchlistRepository $watchlistRepository)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = $this->security->getUser();
|
||||||
|
|
||||||
|
return $this->watchlistRepository->fetchWatchlistsForUser($user);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user