mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
264 lines
6.5 KiB
PHP
264 lines
6.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\MainBundle\Search;
|
|
|
|
use function array_push;
|
|
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;
|
|
|
|
private array $fromClauseParams = [];
|
|
|
|
private bool $isDistinct = false;
|
|
|
|
private ?string $isDistinctKey = null;
|
|
|
|
private ?string $jsonbMetadata = null;
|
|
|
|
private array $jsonbMetadataParams = [];
|
|
|
|
private ?string $pertinence = null;
|
|
|
|
private array $pertinenceParams = [];
|
|
|
|
private array $select = [];
|
|
|
|
private ?string $selectKey = null;
|
|
|
|
private array $selectKeyParams = [];
|
|
|
|
private array $selectParams = [];
|
|
|
|
private array $whereClauses = [];
|
|
|
|
private array $whereClausesParams = [];
|
|
|
|
public function addSelectClause(string $select, array $params = []): self
|
|
{
|
|
$this->select[] = $select;
|
|
$this->selectParams = [...$this->selectParams, ...$params];
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Add a where clause.
|
|
*
|
|
* This will add to previous where clauses with and `AND` join
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function andWhereClause(string $whereClause, array $params = []): self
|
|
{
|
|
$this->whereClauses[] = $whereClause;
|
|
array_push($this->whereClausesParams, ...$params);
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function buildParameters(bool $countOnly = false): array
|
|
{
|
|
if (!$countOnly) {
|
|
return [
|
|
...$this->buildSelectParams($countOnly),
|
|
...$this->fromClauseParams,
|
|
...$this->whereClausesParams,
|
|
];
|
|
}
|
|
|
|
return [
|
|
...$this->fromClauseParams,
|
|
...$this->whereClausesParams,
|
|
];
|
|
}
|
|
|
|
public function buildQuery(bool $countOnly = false): string
|
|
{
|
|
$isMultiple = count($this->whereClauses);
|
|
$where =
|
|
($isMultiple ? '(' : '') .
|
|
implode(
|
|
($isMultiple ? ')' : '') . ' AND ' . ($isMultiple ? '(' : ''),
|
|
$this->whereClauses
|
|
) .
|
|
($isMultiple ? ')' : '');
|
|
|
|
$select = $this->buildSelectClause($countOnly);
|
|
|
|
return strtr('SELECT
|
|
{select}
|
|
FROM {from}
|
|
WHERE {where}
|
|
', [
|
|
'{select}' => $select,
|
|
'{from}' => $this->fromClause,
|
|
'{where}' => $where,
|
|
]);
|
|
}
|
|
|
|
public function getDistinct(): bool
|
|
{
|
|
return $this->isDistinct;
|
|
}
|
|
|
|
public function getFromClause(): string
|
|
{
|
|
return $this->fromClause;
|
|
}
|
|
|
|
public function getFromParams(): array
|
|
{
|
|
return $this->fromClauseParams;
|
|
}
|
|
|
|
public function getSelectClauses(): array
|
|
{
|
|
return $this->select;
|
|
}
|
|
|
|
public function getSelectParams(): array
|
|
{
|
|
return $this->selectParams;
|
|
}
|
|
|
|
public function resetSelectClause(): self
|
|
{
|
|
$this->select = [];
|
|
$this->selectParams = [];
|
|
$this->selectKey = null;
|
|
$this->selectKeyParams = [];
|
|
$this->jsonbMetadata = null;
|
|
$this->jsonbMetadataParams = [];
|
|
$this->pertinence = null;
|
|
$this->pertinenceParams = [];
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setDistinct(bool $distinct, string $distinctKey): self
|
|
{
|
|
$this->isDistinct = $distinct;
|
|
$this->isDistinctKey = $distinctKey;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setFromClause(string $fromClause, array $params = []): self
|
|
{
|
|
$this->fromClause = $fromClause;
|
|
$this->fromClauseParams = $params;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setSelectJsonbMetadata(string $jsonbMetadata, array $params = []): self
|
|
{
|
|
$this->jsonbMetadata = $jsonbMetadata;
|
|
$this->jsonbMetadataParams = $params;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setSelectKey(string $selectKey, array $params = []): self
|
|
{
|
|
$this->selectKey = $selectKey;
|
|
$this->selectKeyParams = $params;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setSelectPertinence(string $pertinence, array $params = []): self
|
|
{
|
|
$this->pertinence = $pertinence;
|
|
$this->pertinenceParams = $params;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set the where clause and replace all existing ones.
|
|
*/
|
|
public function setWhereClauses(string $whereClause, array $params = []): self
|
|
{
|
|
$this->whereClauses = [$whereClause];
|
|
$this->whereClausesParams = $params;
|
|
|
|
return $this;
|
|
}
|
|
|
|
private function buildSelectClause(bool $countOnly = false): string
|
|
{
|
|
if ($countOnly) {
|
|
if (!$this->isDistinct) {
|
|
return 'count(*) AS c';
|
|
}
|
|
|
|
return 'count(distinct ' . $this->isDistinctKey . ') AS c';
|
|
}
|
|
|
|
$selects = $this->getSelectClauses();
|
|
|
|
if (null !== $this->selectKey) {
|
|
$selects[] = strtr("'{key}' AS key", ['{key}' => $this->selectKey]);
|
|
}
|
|
|
|
if (null !== $this->jsonbMetadata) {
|
|
$selects[] = strtr('{metadata} AS metadata', ['{metadata}' => $this->jsonbMetadata]);
|
|
}
|
|
|
|
if (null !== $this->pertinence) {
|
|
$selects[] = strtr('{pertinence} AS pertinence', ['{pertinence}' => $this->pertinence]);
|
|
}
|
|
|
|
return ($this->isDistinct ? 'DISTINCT ' : '') . implode(', ', $selects);
|
|
}
|
|
|
|
private function buildSelectParams(bool $count = false): array
|
|
{
|
|
if ($count) {
|
|
return [];
|
|
}
|
|
|
|
$args = $this->getSelectParams();
|
|
|
|
if (null !== $this->selectKey) {
|
|
$args = [...$args, ...$this->selectKeyParams];
|
|
}
|
|
|
|
if (null !== $this->jsonbMetadata) {
|
|
$args = [...$args, ...$this->jsonbMetadataParams];
|
|
}
|
|
|
|
if (null !== $this->pertinence) {
|
|
$args = [...$args, ...$this->pertinenceParams];
|
|
}
|
|
|
|
return $args;
|
|
}
|
|
}
|