Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
Select
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
4 / 4
11
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 __toString
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 create
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 statement
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
8
1<?php
2
3declare(strict_types=1);
4
5namespace Projom\Storage\SQL\Statement;
6
7use Stringable;
8
9use Projom\Storage\SQL\Component\Column;
10use Projom\Storage\SQL\Component\Filter;
11use Projom\Storage\SQL\Component\Group;
12use Projom\Storage\SQL\Component\Join;
13use Projom\Storage\SQL\Component\Limit;
14use Projom\Storage\SQL\Component\Offset;
15use Projom\Storage\SQL\Component\Order;
16use Projom\Storage\SQL\Component\Table;
17use Projom\Storage\SQL\Statement\StatementInterface;
18use Projom\Storage\SQL\QueryObject;
19use Projom\Storage\SQL\Util;
20
21class Select implements StatementInterface, Stringable
22{
23    private readonly Table $table;
24    private readonly Column $column;
25    private readonly Join $join;
26    private readonly Filter $filter;
27    private readonly Group $group;
28    private readonly Order $order;
29    private readonly Limit $limit;
30    private readonly Offset $offset;
31
32    public function __construct(QueryObject $querySelect)
33    {
34        $this->table = Table::create($querySelect->collections);
35        $this->column = Column::create($querySelect->fields);
36        $this->join = Join::create($querySelect->joins);
37        $this->filter = Filter::create($querySelect->filters);
38        $this->group = Group::create($querySelect->groups);
39        $this->order = Order::create($querySelect->sorts);
40        $this->limit = Limit::create($querySelect->limit);
41        $this->offset = Offset::create($querySelect->offset);
42    }
43
44    public function __toString(): string
45    {
46        [$statement, $params] = $this->statement();
47        return $statement;
48    }
49
50    public static function create(QueryObject $querySelect): Select
51    {
52        return new Select($querySelect);
53    }
54
55    public function statement(): array
56    {
57        $queryParts[] = "SELECT {$this->column} FROM {$this->table}";
58
59        if (!$this->join->empty())
60            $queryParts[] = "{$this->join}";
61
62        if (!$this->filter->empty())
63            $queryParts[] = "WHERE {$this->filter}";
64
65        if (!$this->group->empty())
66            $queryParts[] = "GROUP BY {$this->group}";
67
68        if (!$this->order->empty())
69            $queryParts[] = "ORDER BY {$this->order}";
70
71        if (!$this->limit->empty())
72            $queryParts[] = "LIMIT {$this->limit}";
73
74        if (!$this->offset->empty())
75            $queryParts[] = "OFFSET {$this->offset}";
76
77        $query = Util::join($queryParts, ' ');
78        $params = $this->filter->params() ?: null;
79
80        return [
81            $query,
82            $params
83        ];
84    }
85}