Select::getCurrentStatement()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 16
cts 16
cp 1
rs 9.536
c 0
b 0
f 0
cc 4
nc 8
nop 1
crap 4
1
<?php
2
declare(strict_types=1);
3
4
namespace Sirius\Sql;
5
6
use BadMethodCallException;
7
use Generator;
8
use Sirius\Sql\Component\From;
9
10
/**
11
 * @method array fetchAll()
12
 * @method int fetchAffected()
13
 * @method array fetchColumn(int $column = 0)
14
 * @method array fetchGroup(int $style = PDO::FETCH_COLUMN)
15
 * @method array fetchKeyPair()
16
 * @method mixed fetchObject(string $class = 'stdClass', array $args = [])
17
 * @method array fetchObjects(string $class = 'stdClass', array $args = [])
18
 * @method array|null fetchOne()
19
 * @method array fetchUnique()
20
 * @method mixed fetchValue(int $column = 0)
21
 * @method Generator yieldAll()
22
 * @method Generator yieldColumn(int $column = 0)
23
 * @method Generator yieldKeyPair()
24
 * @method Generator yieldObjects(string $class = 'stdClass', array $args = [])
25
 * @method Generator yieldUnique()
26
 */
27
class Select extends Query
28
{
29
    use Clause\SelectColumns;
30
    use Clause\Where;
31
    use Clause\GroupBy;
32
    use Clause\Having;
33
    use Clause\OrderBy;
34
    use Clause\Limit;
35
36
    protected $as;
37
    /**
38
     * @var From
39
     */
40
    protected $from;
41
    protected $unions = [];
42
    protected $forUpdate = false;
43
44 1
    public function __clone()
45
    {
46 1
        $vars = get_object_vars($this);
47 1
        unset($vars['bindings']);
48 1
        foreach ($vars as $name => $prop) {
49 1
            if (is_object($prop)) {
50 1
                $this->$name = clone $prop;
51
            }
52
        }
53 1
    }
54
55 1
    public function __call(string $method, array $params)
56
    {
57 1
        $prefix = substr($method, 0, 5);
58 1
        if ($prefix == 'fetch' || $prefix == 'yield') {
59 1
            return $this->connection->$method(
60 1
                $this->getStatement(),
61 1
                $this->getBindValues(),
62 1
                ...$params
63
            );
64
        }
65
66
        throw new BadMethodCallException($method);
67
    }
68
69 1
    public function forUpdate(bool $enable = true)
70
    {
71 1
        $this->forUpdate = $enable;
72
73 1
        return $this;
74
    }
75
76
    /**
77
     * Makes the query select distinct rows
78
     *
79
     * @param bool $enable
80
     *
81
     * @return $this
82
     */
83 1
    public function distinct(bool $enable = true)
84
    {
85 1
        $this->setFlag('DISTINCT', $enable);
86
87 1
        return $this;
88
    }
89
90 17
    public function from(string $ref)
91
    {
92 17
        $this->from->table($ref);
93
94 17
        return $this;
95
    }
96
97
    /**
98
     * Joins a table/subselect based on a condition
99
     * The condition can have named bindable placeholders (eg: :some_column) to be bound later
100
     * OR sprintf-like placholders (ie: %s) that can be bound immediately with $bindInline
101
     *
102
     * @param string $join
103
     * @param string $ref
104
     * @param string $condition
105
     * @param mixed ...$bindInline
106
     *
107
     * @return $this
108
     */
109 2
    public function join(string $join, $ref, string $condition = '', ...$bindInline)
110
    {
111 2
        $join = strtoupper(trim($join));
112 2
        if (substr($join, -4) != 'JOIN') {
113 1
            $join .= ' JOIN';
114
        }
115
116 2
        if ($ref instanceof Select) {
117 1
            $ref = $ref->getStatement();
118
        }
119
120 2
        $this->from->join($join, $ref, $condition, ...$bindInline);
121
122 2
        return $this;
123
    }
124
125 1
    public function union()
126
    {
127 1
        $this->unions[] = $this->getCurrentStatement(
128 1
            PHP_EOL . 'UNION' . PHP_EOL
129
        );
130 1
        $this->reset();
131
132 1
        return $this;
133
    }
134
135 1
    public function unionAll()
136
    {
137 1
        $this->unions[] = $this->getCurrentStatement(
138 1
            PHP_EOL . 'UNION ALL' . PHP_EOL
139
        );
140 1
        $this->reset();
141
142 1
        return $this;
143
    }
144
145 1
    public function as(string $as)
146
    {
147 1
        $this->as = $as;
148
149 1
        return $this;
150
    }
151
152 17
    public function resetFrom()
153
    {
154 17
        $this->from = new From($this->bindings);
155
156 17
        return $this;
157
    }
158
159 17
    public function resetAs()
160
    {
161 17
        $this->as = null;
162
163 17
        return $this;
164
    }
165
166 1
    public function subSelect(): Select
167
    {
168 1
        return new Select($this->connection, $this->bindings, $this->indent . '    ');
169
    }
170
171 16
    public function getStatement(): string
172
    {
173 16
        return implode('', $this->unions) . $this->getCurrentStatement();
174
    }
175
176 16
    protected function getCurrentStatement(string $suffix = ''): string
177
    {
178
        $stm = 'SELECT'
179 16
               . $this->flags->build()
180 16
               . $this->limit->buildEarly()
181 16
               . $this->columns->build()
182 16
               . $this->from->build()
183 16
               . $this->where->build()
184 16
               . $this->groupBy->build()
185 16
               . $this->having->build()
186 16
               . $this->orderBy->build()
187 16
               . $this->limit->build()
188 16
               . ($this->forUpdate ? PHP_EOL . 'FOR UPDATE' : '');
189
190 16
        if ($this->as !== null) {
191 1
            $stm = "(" . PHP_EOL . $stm . PHP_EOL . ") AS {$this->as}";
192
        }
193
194 16
        if ($this->indent) {
195 1
            $stm = $this->indent . str_replace(PHP_EOL, PHP_EOL . $this->indent, $stm);
196
        }
197
198 16
        return $stm . $suffix;
199
    }
200
}
201