' as key, as metadata, as pertinence FROM WHERE `. * * 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; } }