Fixed: fix empty result in household api search

fix https://gitlab.com/Chill-Projet/chill-bundles/-/issues/85
This commit is contained in:
Julien Fastré 2023-04-07 17:34:12 +02:00
parent 839b0fc826
commit a42a4ab9bd
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
3 changed files with 32 additions and 19 deletions

View File

@ -30,7 +30,7 @@ class SearchApi
private PaginatorFactory $paginator; private PaginatorFactory $paginator;
private iterable $providers = []; private iterable $providers;
public function __construct( public function __construct(
EntityManagerInterface $em, EntityManagerInterface $em,
@ -42,9 +42,6 @@ class SearchApi
$this->paginator = $paginator; $this->paginator = $paginator;
} }
/**
* @return Model/Result[]
*/
public function getResults(string $pattern, array $types, array $parameters): Collection public function getResults(string $pattern, array $types, array $parameters): Collection
{ {
$queries = $this->findQueries($pattern, $types, $parameters); $queries = $this->findQueries($pattern, $types, $parameters);
@ -53,10 +50,10 @@ class SearchApi
throw new SearchApiNoQueryException($pattern, $types, $parameters); throw new SearchApiNoQueryException($pattern, $types, $parameters);
} }
$total = $this->countItems($queries, $types, $parameters); $total = $this->countItems($queries);
$paginator = $this->paginator->create($total); $paginator = $this->paginator->create($total);
$rawResults = $this->fetchRawResult($queries, $types, $parameters, $paginator); $rawResults = $this->fetchRawResult($queries, $types, $paginator);
$this->prepareProviders($rawResults); $this->prepareProviders($rawResults);
$results = $this->buildResults($rawResults); $results = $this->buildResults($rawResults);
@ -64,7 +61,7 @@ class SearchApi
return new Collection($results, $paginator); return new Collection($results, $paginator);
} }
private function buildCountQuery(array $queries, $types, $parameters) private function buildCountQuery(array $queries): array
{ {
$query = 'SELECT SUM(c) AS count FROM ({union_unordered}) AS sq'; $query = 'SELECT SUM(c) AS count FROM ({union_unordered}) AS sq';
$unions = []; $unions = [];
@ -88,7 +85,7 @@ class SearchApi
$items = []; $items = [];
foreach ($rawResults as $r) { foreach ($rawResults as $r) {
foreach ($this->providers as $k => $p) { foreach ($this->providers as $p) {
if ($p->supportsResult($r['key'], $r['metadata'])) { if ($p->supportsResult($r['key'], $r['metadata'])) {
$items[] = (new SearchApiResult($r['pertinence'])) $items[] = (new SearchApiResult($r['pertinence']))
->setResult( ->setResult(
@ -103,7 +100,7 @@ class SearchApi
return $items; return $items;
} }
private function buildUnionQuery(array $queries, $types, $parameters, Paginator $paginator) private function buildUnionQuery(array $queries, Paginator $paginator): array
{ {
$query = '{unions} ORDER BY pertinence DESC LIMIT ? OFFSET ?'; $query = '{unions} ORDER BY pertinence DESC LIMIT ? OFFSET ?';
$unions = []; $unions = [];
@ -126,9 +123,9 @@ class SearchApi
]; ];
} }
private function countItems($providers, $types, $parameters): int private function countItems($providers): int
{ {
[$countQuery, $parameters] = $this->buildCountQuery($providers, $types, $parameters); [$countQuery, $parameters] = $this->buildCountQuery($providers);
$rsmCount = new ResultSetMappingBuilder($this->em); $rsmCount = new ResultSetMappingBuilder($this->em);
$rsmCount->addScalarResult('count', 'count'); $rsmCount->addScalarResult('count', 'count');
$countNq = $this->em->createNativeQuery($countQuery, $rsmCount); $countNq = $this->em->createNativeQuery($countQuery, $rsmCount);
@ -137,9 +134,9 @@ class SearchApi
return (int) $countNq->getSingleScalarResult(); return (int) $countNq->getSingleScalarResult();
} }
private function fetchRawResult($queries, $types, $parameters, Paginator $paginator): array private function fetchRawResult($queries, $types, Paginator $paginator): array
{ {
[$union, $parameters] = $this->buildUnionQuery($queries, $types, $parameters, $paginator); [$union, $parameters] = $this->buildUnionQuery($queries, $paginator);
$rsm = new ResultSetMappingBuilder($this->em); $rsm = new ResultSetMappingBuilder($this->em);
$rsm->addScalarResult('key', 'key', Types::STRING) $rsm->addScalarResult('key', 'key', Types::STRING)
->addScalarResult('metadata', 'metadata', Types::JSON) ->addScalarResult('metadata', 'metadata', Types::JSON)
@ -172,7 +169,7 @@ class SearchApi
); );
} }
private function prepareProviders(array $rawResults) private function prepareProviders(array $rawResults): void
{ {
$metadatas = []; $metadatas = [];
$providers = []; $providers = [];

View File

@ -16,6 +16,18 @@ use function count;
use function implode; use function implode;
use function strtr; use function strtr;
/**
* This create a query optimized for searching for the api response.
*
* When build, this class generate a SQL string and a list of a parameters which is suitable for running
* a native SQL query. This have usually the form of
*
* `SELECT '<key>' as key, <metadata> as metadata, <pertinence> as pertinence FROM <from clause> WHERE <where clause>`.
*
* The clause between `<>` are provided through the dedicated method in this class (@link{self::setSelectKey},
* @link{self::setFromClause}), etc.).
*
*/
class SearchApiQuery class SearchApiQuery
{ {
private ?string $fromClause = null; private ?string $fromClause = null;

View File

@ -84,15 +84,19 @@ class SearchHouseholdApiProvider implements SearchApiInterface
count($phoneResult->getFound()) > 0 ? $phoneResult->getFound()[0] : null count($phoneResult->getFound()) > 0 ? $phoneResult->getFound()[0] : null
); );
$previousFrom = $query->getFromClause();
$previousParams = $query->getFromParams();
$query $query
->setDistinct(true, 'household_id') ->setDistinct(true, 'cpphm.household_id')
->setFromClause( ->setFromClause(
'view_chill_person_household_address AS vcpha ' . $previousFrom . ' '.
'JOIN chill_person_person AS person ON vcpha.person_id = person.id' 'JOIN chill_person_household_members AS cpphm ON cpphm.person_id = person.id',
$previousParams
) )
->andWhereClause('(cpphm.startDate <= NOW() AND (cpphm.endDate IS NULL or cpphm.endDate > NOW()))')
->setSelectKey('household') ->setSelectKey('household')
->andWhereClause('vcpha.validTo IS NULL', []) ->setSelectJsonbMetadata("jsonb_build_object('id', cpphm.household_id)");
->setSelectJsonbMetadata("jsonb_build_object('id', vcpha.household_id)");
return $query; return $query;
} }