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 iterable $providers = [];
private iterable $providers;
public function __construct(
EntityManagerInterface $em,
@ -42,9 +42,6 @@ class SearchApi
$this->paginator = $paginator;
}
/**
* @return Model/Result[]
*/
public function getResults(string $pattern, array $types, array $parameters): Collection
{
$queries = $this->findQueries($pattern, $types, $parameters);
@ -53,10 +50,10 @@ class SearchApi
throw new SearchApiNoQueryException($pattern, $types, $parameters);
}
$total = $this->countItems($queries, $types, $parameters);
$total = $this->countItems($queries);
$paginator = $this->paginator->create($total);
$rawResults = $this->fetchRawResult($queries, $types, $parameters, $paginator);
$rawResults = $this->fetchRawResult($queries, $types, $paginator);
$this->prepareProviders($rawResults);
$results = $this->buildResults($rawResults);
@ -64,7 +61,7 @@ class SearchApi
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';
$unions = [];
@ -88,7 +85,7 @@ class SearchApi
$items = [];
foreach ($rawResults as $r) {
foreach ($this->providers as $k => $p) {
foreach ($this->providers as $p) {
if ($p->supportsResult($r['key'], $r['metadata'])) {
$items[] = (new SearchApiResult($r['pertinence']))
->setResult(
@ -103,7 +100,7 @@ class SearchApi
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 ?';
$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->addScalarResult('count', 'count');
$countNq = $this->em->createNativeQuery($countQuery, $rsmCount);
@ -137,9 +134,9 @@ class SearchApi
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->addScalarResult('key', 'key', Types::STRING)
->addScalarResult('metadata', 'metadata', Types::JSON)
@ -172,7 +169,7 @@ class SearchApi
);
}
private function prepareProviders(array $rawResults)
private function prepareProviders(array $rawResults): void
{
$metadatas = [];
$providers = [];

View File

@ -16,6 +16,18 @@ use function count;
use function implode;
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
{
private ?string $fromClause = null;

View File

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