From df4f5e7cf83fce572343844fb7e3bac4885b418b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 3 Nov 2022 13:59:16 +0100 Subject: [PATCH] Fixed: [export] improve memory footprint for filter by Geographical Unit --- .../SimpleGeographicalUnitDTO.php | 52 +++++++++++++++++++ .../Export/Helper/ExportAddressHelper.php | 1 + .../Repository/GeographicalUnitRepository.php | 2 +- .../GeographicalUnitStatFilter.php | 24 +++++---- .../PersonFilters/GeographicalUnitFilter.php | 24 +++++---- 5 files changed, 84 insertions(+), 19 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Entity/GeographicalUnit/SimpleGeographicalUnitDTO.php diff --git a/src/Bundle/ChillMainBundle/Entity/GeographicalUnit/SimpleGeographicalUnitDTO.php b/src/Bundle/ChillMainBundle/Entity/GeographicalUnit/SimpleGeographicalUnitDTO.php new file mode 100644 index 000000000..34f16a0fb --- /dev/null +++ b/src/Bundle/ChillMainBundle/Entity/GeographicalUnit/SimpleGeographicalUnitDTO.php @@ -0,0 +1,52 @@ +id = $id; + $this->unitName = $unitName; + $this->unitRefId = $unitRefId; + $this->layerId = $layerId; + } +} diff --git a/src/Bundle/ChillMainBundle/Export/Helper/ExportAddressHelper.php b/src/Bundle/ChillMainBundle/Export/Helper/ExportAddressHelper.php index 7d4245aa6..701f9ed07 100644 --- a/src/Bundle/ChillMainBundle/Export/Helper/ExportAddressHelper.php +++ b/src/Bundle/ChillMainBundle/Export/Helper/ExportAddressHelper.php @@ -205,6 +205,7 @@ class ExportAddressHelper case 'floor': case '_lat': case '_lon': + case 'steps': case 'postcode_code': case 'postcode_name': return static function ($value) use ($sanitizedKey, $translationPrefix) { diff --git a/src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepository.php b/src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepository.php index 17d29356b..b422b8649 100644 --- a/src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepository.php @@ -41,7 +41,7 @@ class GeographicalUnitRepository implements GeographicalUnitRepositoryInterface { return $this->repository ->createQueryBuilder('gu') - ->select('PARTIAL gu.{id,unitName,unitRefId,layer}') + ->select(sprintf('NEW %s(gu.id, gu.unitName, gu.unitRefId, IDENTITY(gu.layer))', GeographicalUnit\SimpleGeographicalUnitDTO::class)) ->addOrderBy('IDENTITY(gu.layer)') ->addOrderBy(('gu.unitName')) ->getQuery() diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php index a1347ca99..ee420e63e 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php @@ -13,8 +13,10 @@ namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters; use Chill\MainBundle\Entity\Address; use Chill\MainBundle\Entity\GeographicalUnit; +use Chill\MainBundle\Entity\GeographicalUnit\SimpleGeographicalUnitDTO; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Form\Type\ChillDateType; +use Chill\MainBundle\Repository\GeographicalUnitLayerRepositoryInterface; use Chill\MainBundle\Repository\GeographicalUnitRepositoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; @@ -23,7 +25,7 @@ use Chill\PersonBundle\Export\Declarations; use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; -use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; /** @@ -33,6 +35,8 @@ class GeographicalUnitStatFilter implements FilterInterface { private EntityManagerInterface $em; + private GeographicalUnitLayerRepositoryInterface $geographicalUnitLayerRepository; + private GeographicalUnitRepositoryInterface $geographicalUnitRepository; private TranslatableStringHelperInterface $translatableStringHelper; @@ -40,10 +44,12 @@ class GeographicalUnitStatFilter implements FilterInterface public function __construct( EntityManagerInterface $em, GeographicalUnitRepositoryInterface $geographicalUnitRepository, + GeographicalUnitLayerRepositoryInterface $geographicalUnitLayerRepository, TranslatableStringHelperInterface $translatableStringHelper ) { $this->em = $em; $this->geographicalUnitRepository = $geographicalUnitRepository; + $this->geographicalUnitLayerRepository = $geographicalUnitLayerRepository; $this->translatableStringHelper = $translatableStringHelper; } @@ -62,7 +68,7 @@ class GeographicalUnitStatFilter implements FilterInterface WITH IDENTITY(acp_geog_filter_location_history.personLocation) = IDENTITY(acp_geog_filter_address_person_location.person) LEFT JOIN ' . Address::class . ' acp_geog_filter_address WITH COALESCE(IDENTITY(acp_geog_filter_address_person_location.address), IDENTITY(acp_geog_filter_location_history.addressLocation)) = acp_geog_filter_address.id - LEFT JOIN ' . GeographicalUnit::class . ' acp_geog_filter_units WITH ST_CONTAINS(acp_geog_units.geom, acp_geog_filter_address.point) = TRUE + LEFT JOIN ' . GeographicalUnit::class . ' acp_geog_filter_units WITH ST_CONTAINS(acp_geog_filter_units.geom, acp_geog_filter_address.point) = TRUE WHERE (acp_geog_filter_location_history.startDate <= :acp_geog_filter_date AND ( acp_geog_filter_location_history.endDate IS NULL OR acp_geog_filter_location_history.endDate < :acp_geog_filter_date @@ -78,7 +84,7 @@ class GeographicalUnitStatFilter implements FilterInterface $qb ->andWhere($qb->expr()->exists($subQueryDql)) ->setParameter('acp_geog_filter_date', $data['date_calc']) - ->setParameter('acp_geog_filter_units', $data['units']); + ->setParameter('acp_geog_filter_units', array_map(static fn (SimpleGeographicalUnitDTO $unitDTO) => $unitDTO->id, $data['units'])); } public function applyOn(): string @@ -95,13 +101,13 @@ class GeographicalUnitStatFilter implements FilterInterface 'data' => new DateTimeImmutable('today'), 'input' => 'datetime_immutable', ]) - ->add('units', EntityType::class, [ + ->add('units', ChoiceType::class, [ 'label' => 'Geographical unit', 'placeholder' => 'Select a geographical unit', - 'class' => GeographicalUnit::class, 'choices' => $this->geographicalUnitRepository->findAll(), - 'choice_label' => function (GeographicalUnit $item) { - return $this->translatableStringHelper->localize($item->getLayer()->getName()) . ' > ' . $item->getUnitName(); + 'choice_value' => static fn (SimpleGeographicalUnitDTO $item) => $item->id, + 'choice_label' => function (SimpleGeographicalUnitDTO $item) { + return $this->translatableStringHelper->localize($this->geographicalUnitLayerRepository->find($item->layerId)->getName()) . ' > ' . $item->unitName; }, 'attr' => [ 'class' => 'select2', @@ -117,8 +123,8 @@ class GeographicalUnitStatFilter implements FilterInterface '%units' => implode( ', ', array_map( - function (GeographicalUnit $item) { - return $this->translatableStringHelper->localize($item->getLayer()->getName()) . ' > ' . $item->getUnitName(); + function (SimpleGeographicalUnitDTO $item) { + return $this->translatableStringHelper->localize($this->geographicalUnitLayerRepository->find($item->layerId)->getName()) . ' > ' . $item->unitName; }, $data['units'] ) diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php index 96a9f5a1c..03d9ab568 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php @@ -12,27 +12,33 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Filter\PersonFilters; use Chill\MainBundle\Entity\GeographicalUnit; +use Chill\MainBundle\Entity\GeographicalUnit\SimpleGeographicalUnitDTO; use Chill\MainBundle\Form\Type\ChillDateType; +use Chill\MainBundle\Repository\GeographicalUnitLayerRepositoryInterface; use Chill\MainBundle\Repository\GeographicalUnitRepositoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress; use Chill\PersonBundle\Export\Declarations; use DateTimeImmutable; use Doctrine\ORM\QueryBuilder; -use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; class GeographicalUnitFilter implements \Chill\MainBundle\Export\FilterInterface { + private GeographicalUnitLayerRepositoryInterface $geographicalUnitLayerRepository; + private GeographicalUnitRepositoryInterface $geographicalUnitRepository; private TranslatableStringHelperInterface $translatableStringHelper; public function __construct( GeographicalUnitRepositoryInterface $geographicalUnitRepository, + GeographicalUnitLayerRepositoryInterface $geographicalUnitLayerRepository, TranslatableStringHelperInterface $translatableStringHelper ) { $this->geographicalUnitRepository = $geographicalUnitRepository; + $this->geographicalUnitLayerRepository = $geographicalUnitLayerRepository; $this->translatableStringHelper = $translatableStringHelper; } @@ -65,7 +71,7 @@ class GeographicalUnitFilter implements \Chill\MainBundle\Export\FilterInterface $qb->expr()->exists($subQuery) ) ->setParameter('person_filter_geog_date', $data['date_calc']) - ->setParameter('person_filter_geog_units', $data['units']); + ->setParameter('person_filter_geog_units', array_map(static fn (SimpleGeographicalUnitDTO $unitDTO) => $unitDTO->id, $data['units'])); } public function applyOn() @@ -82,13 +88,13 @@ class GeographicalUnitFilter implements \Chill\MainBundle\Export\FilterInterface 'data' => new DateTimeImmutable('today'), 'input' => 'datetime_immutable', ]) - ->add('units', EntityType::class, [ + ->add('units', ChoiceType::class, [ 'label' => 'Geographical unit', 'placeholder' => 'Select a geographical unit', - 'class' => GeographicalUnit::class, 'choices' => $this->geographicalUnitRepository->findAll(), - 'choice_label' => function (GeographicalUnit $item) { - return $this->translatableStringHelper->localize($item->getLayer()->getName()) . ' > ' . $item->getUnitName(); + 'choice_value' => static fn (SimpleGeographicalUnitDTO $item) => $item->id, + 'choice_label' => function (SimpleGeographicalUnitDTO $item) { + return $this->translatableStringHelper->localize($this->geographicalUnitLayerRepository->find($item->layerId)->getName()) . ' > ' . $item->unitName; }, 'attr' => [ 'class' => 'select2', @@ -106,10 +112,10 @@ class GeographicalUnitFilter implements \Chill\MainBundle\Export\FilterInterface 'units' => implode( ', ', array_map( - function (GeographicalUnit $item) { - return $this->translatableStringHelper->localize($item->getLayer()->getName()) . ' > ' . $item->getUnitName(); + function (SimpleGeographicalUnitDTO $item) { + return $this->translatableStringHelper->localize($this->geographicalUnitLayerRepository->find($item->layerId)->getName()) . ' > ' . $item->unitName; }, - $data['units']->toArray() + $data['units'] ) ), ],