From d4eddaf6718dec9fe993b21c07d19726af45a518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 15 Aug 2025 23:17:10 +0200 Subject: [PATCH] [WIP] Add PostalCodeForAddressReferenceRepository and associated tests Introduced `PostalCodeForAddressReferenceRepository` and its interface to support optimized postal code search using materialized views. Updated `AddressReferenceRepository` to improve query handling. Added test coverage for the new repository functionality. --- .../Repository/AddressReferenceRepository.php | 2 +- ...ostalCodeForAddressReferenceRepository.php | 67 +++++++++++++++++++ ...ForAddressReferenceRepositoryInterface.php | 20 ++++++ ...lCodeForAddressReferenceRepositoryTest.php | 61 +++++++++++++++++ 4 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 src/Bundle/ChillMainBundle/Repository/PostalCodeForAddressReferenceRepository.php create mode 100644 src/Bundle/ChillMainBundle/Repository/PostalCodeForAddressReferenceRepositoryInterface.php create mode 100644 src/Bundle/ChillMainBundle/Tests/Repository/PostalCodeForAddressReferenceRepositoryTest.php diff --git a/src/Bundle/ChillMainBundle/Repository/AddressReferenceRepository.php b/src/Bundle/ChillMainBundle/Repository/AddressReferenceRepository.php index 6877b8032..d55068e0f 100644 --- a/src/Bundle/ChillMainBundle/Repository/AddressReferenceRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/AddressReferenceRepository.php @@ -85,7 +85,7 @@ final readonly class AddressReferenceRepository implements AddressReferenceRepos $paramId = 0; - foreach ($terms as $k => $term) { + foreach ($terms as $term) { $qb->andWhere('var.address like ?'); $qb->setParameter(++$paramId, "%{$term}%"); } diff --git a/src/Bundle/ChillMainBundle/Repository/PostalCodeForAddressReferenceRepository.php b/src/Bundle/ChillMainBundle/Repository/PostalCodeForAddressReferenceRepository.php new file mode 100644 index 000000000..e78fd1115 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/PostalCodeForAddressReferenceRepository.php @@ -0,0 +1,67 @@ +buildTermsFromSearchString($search); + if ([] === $terms) { + return []; + } + + $qb = $this->connection->createQueryBuilder(); + + $qb->from('chill_main_postal_code', 'cmpc') + ->join('cmpc', 'view_chill_main_address_reference', 'vcmar', 'vcmar.postcode_id = cmpc.id') + ->join('vcmar', 'country', 'country', condition: 'cmpc.country_id = country.id') + ->setFirstResult($firstResult) + ->setMaxResults($maxResults) + ; + + $qb->select( + 'DISTINCT ON (cmpc.code, cmpc.label) cmpc.id AS postcode_id', + 'cmpc.code AS code', + 'cmpc.label AS label', + 'country.id AS country_id', + 'country.countrycode AS country_code', + 'country.name AS country_name' + ); + + $paramId = 0; + + foreach ($terms as $term) { + $qb->andWhere('vcmar.address like ?'); + $qb->setParameter(++$paramId, "%{$term}%"); + } + + $result = $qb->executeQuery(); + + return $result->iterateAssociative(); + } + + private function buildTermsFromSearchString(string $search): array + { + return array_filter( + array_map( + static fn (string $term) => trim($term), + explode(' ', $search) + ), + static fn (string $term) => '' !== $term + ); + } +} diff --git a/src/Bundle/ChillMainBundle/Repository/PostalCodeForAddressReferenceRepositoryInterface.php b/src/Bundle/ChillMainBundle/Repository/PostalCodeForAddressReferenceRepositoryInterface.php new file mode 100644 index 000000000..4f56356c3 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/PostalCodeForAddressReferenceRepositoryInterface.php @@ -0,0 +1,20 @@ +connection = self::getContainer()->get(Connection::class); + } + + /** + * @return iterable + */ + public static function provideSearches(): iterable + { + yield ['']; + yield [' ']; + yield ['hugo']; + yield [' hugo']; + yield ['hugo ']; + yield ['rue victor hugo']; + yield ['rue victor hugo']; + } + + #[DataProvider('provideSearches')] + public function testFindPostalCodeDoesNotErrorAndIsIterable(string $search): void + { + $repository = new PostalCodeForAddressReferenceRepository($this->connection); + + $result = $repository->findPostalCode($search); + + self::assertIsIterable($result); + + // Ensure it can be converted to an array (and iterate without error) + $rows = \is_array($result) ? $result : iterator_to_array($result, false); + self::assertIsArray($rows); + } +}