*/ private ?array $fields; private ?Join $join = null; private string $where = ''; /** * @var list */ private array $orderBy = []; /** * @var ?positive-int */ private ?int $limit = null; public function __construct( private readonly QueryBuilder $sql, private readonly string|Select $table, ) { } public function leftJoin(string $table, string $on): self { $this->join = new Join('LEFT JOIN', $table, $on); return $this; } /** * @param list $fields */ public function fields(array $fields): self { $this->fields = $fields; return $this; } public function where(string $where): self { $this->where = $where; return $this; } /** * @param list $orderBy */ public function orderBy(array $orderBy): self { $this->orderBy = $orderBy; return $this; } /** * @param positive-int $limit */ public function limit(int $limit): self { $this->limit = $limit; return $this; } public function first(): SelectFirst { $this->limit = 1; return new SelectFirst($this); } /** * @param array $params * @return list> */ public function execute(array $params = []): array { return $this->sql->_executeSelect($this, $params); } /** * @internal */ public function _getTable(): string|Select { return $this->table; } /** * @internal * @return list */ public function _getFields(): array { if (!isset($this->fields)) { throw new InvalidSqlException('SELECT: $fields must be set before calling execute()'); } return $this->fields; } /** * @internal */ public function _getJoin(): ?Join { return $this->join; } /** * @internal */ public function _getWhere(): string { return $this->where; } /** * @internal * @return list */ public function _getOrderBy(): array { return $this->orderBy; } /** * @return ?positive-int */ public function _getLimit(): ?int { return $this->limit; } }