addColumn($expressions); } foreach ($expressions as $expression) { $this->addColumn($expression); } return $this; } public function from(string $table): Select { $this->table = $table; return $this; } public function joined(array|string $joins): Select { if (is_string($joins)) { return $this->addJoin($joins); } foreach ($joins as $join) { $this->addJoin($join); } return $this; } public function where(array|string $conditions): Select { if (is_string($conditions)) { return $this->addCondition($conditions); } foreach ($conditions as $condition) { $this->addCondition($condition); } return $this; } public function group(array|string $grouping): Select { if (is_string($grouping)) { return $this->addGroup($grouping); } foreach ($grouping as $group) { $this->addGroup($group); } return $this; } public function having(array|string $conditions): Select { if (is_string($conditions)) { return $this->addCondition($conditions); } foreach ($conditions as $condition) { $this->addCondition($condition); } return $this; } public function order(array|string $sorting): Select { if (is_string($sorting)) { return $this->addOrder($sorting); } foreach ($sorting as $order) { $this->addOrder($order); } return $this; } public function limit(int $limit, ?int $offset = null): Select { $this->limit = $limit; if ($offset !== null) { return $this->offset($offset); } return $this; } public function offset(int $offset): Select { $this->offset = $offset; return $this; } public function build(): string { $query = [ "SELECT {$this->getColumns()} FROM {$this->table}", $this->getJoins(), $this->getConditions(), $this->getGroups(), $this->getHaving(), $this->getOrder(), $this->getLimit() ]; return implode('', $query); } protected function addColumn(string $expression): Select { if (!isset($this->columns)) { $this->columns = []; } $this->columns []= $expression; return $this; } protected function addJoin(string $join): Select { if (!isset($this->joins)) { $this->joins = []; } $this->joins []= $join; return $this; } protected function addCondition(string $condition): Select { if (!isset($this->coditions)) { $this->conditions = []; } $this->conditions []= $condition; return $this; } protected function addGroup(string $group): Select { if (!isset($this->groups)) { $this->groups = []; } $this->groups []= $group; return $this; } protected function addHaving(string $having): Select { if (!isset($this->haves)) { $this->haves = []; } $this->haves []= $having; return $this; } protected function addOrder(string $order): Select { if (!isset($this->orders)) { $this->orders = []; } $this->orders []= $order; return $this; } protected function getColumns(): string { if (!isset($this->columns) or count($this->columns) === 0) { return '*'; } return implode(', ', $this->columns); } protected function getJoins(): string { if (!isset($this->joins) or count($this->joins) === 0) { return ''; } return ' ' . implode(' ', $this->joins); } protected function getConditions(): string { if (!isset($this->conditions) or count($this->conditions) === 0) { return ''; } return ' WHERE ' . implode(' AND ', $this->conditions); } protected function getGroups(): string { if (!isset($this->groups) or count($this->groups) === 0) { return ''; } return ' GROUP BY ' . implode(', ', $this->groups); } protected function getHaving(): string { if (!isset($this->haves) or count($this->haves) === 0) { return ''; } return ' HAVING ' . implode(' AND ', $this->haves); } protected function getOrder(): string { if (!isset($this->orders) or count($this->orders) === 0) { return ''; } return ' ORDER BY ' . implode(', ', $this->orders); } protected function getLimit(): string { if (!isset($this->limit) or $this->limit <= 0) { return ''; } return " LIMIT {$this->limit}{$this->getOffset()}"; } protected function getOffset(): string { if (!isset($this->offset) or $this->offset <= 0) { return ''; } return " OFFSET {$this->offset}"; } }