Completed
Push — master ( cb9b5d...96560d )
by Jared
03:28
created

SelectQuery::getHaving()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/**
4
 * @author Jared King <[email protected]>
5
 *
6
 * @link http://jaredtking.com
7
 *
8
 * @copyright 2015 Jared King
9
 * @license MIT
10
 */
11
namespace JAQB\Query;
12
13
use JAQB\Operations\Executable;
14
use JAQB\Operations\Fetchable;
15
use JAQB\Statement\SelectStatement;
16
use JAQB\Statement\FromStatement;
17
use JAQB\Statement\WhereStatement;
18
use JAQB\Statement\OrderStatement;
19
use JAQB\Statement\LimitStatement;
20
use JAQB\Statement\UnionStatement;
21
use JAQB\Query\Traits\From;
22
use JAQB\Query\Traits\Limit;
23
use JAQB\Query\Traits\OrderBy;
24
use JAQB\Query\Traits\Where;
25
26
class SelectQuery extends AbstractQuery
27
{
28
    use Executable, Fetchable, From, Limit, OrderBy, Where;
29
30
    /**
31
     * @var SelectStatement
32
     */
33
    protected $select;
34
35
    /**
36
     * @var WhereStatement
37
     */
38
    protected $having;
39
40
    /**
41
     * @var OrderStatement
42
     */
43
    protected $groupBy;
44
45
    /**
46
     * @var UnionStatement
47
     */
48
    protected $union;
49
50
    public function __construct()
51
    {
52
        $this->select = new SelectStatement();
53
        $this->from = new FromStatement();
54
        $this->where = new WhereStatement();
55
        $this->having = new WhereStatement(true);
56
        $this->orderBy = new OrderStatement();
57
        $this->groupBy = new OrderStatement(true);
58
        $this->limit = new LimitStatement();
59
        $this->union = new UnionStatement();
60
    }
61
62
    /**
63
     * Sets the fields to be selected for the query.
64
     *
65
     * @param array|string $fields fields
66
     *
67
     * @return self
68
     */
69
    public function select($fields)
70
    {
71
        $this->select->clearFields()->addFields($fields);
72
73
        return $this;
74
    }
75
76
    /**
77
     * Sets the selected fields to an aggregate function.
78
     *
79
     * @param $function
80
     * @param string $field
81
     *
82
     * @return self
83
     */
84
    function aggregate($function, $field = '*')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
85
    {
86
        $this->select->clearFields()->addFields($function.'('.$field.')');
87
88
        return $this;
89
    }
90
91
    /**
92
     * Sets a COUNT() query.
93
     *
94
     * @param $field
95
     *
96
     * @return self
97
     */
98
    function count($field = '*')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
99
    {
100
        return $this->aggregate('COUNT', $field);
101
    }
102
103
    /**
104
     * Sets a SUM() query.
105
     *
106
     * @param $field
107
     *
108
     * @return self
109
     */
110
    function sum($field)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
111
    {
112
        return $this->aggregate('SUM', $field);
113
    }
114
115
    /**
116
     * Sets an AVG() query.
117
     *
118
     * @param $field
119
     *
120
     * @return self
121
     */
122
    function average($field)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
123
    {
124
        return $this->aggregate('AVG', $field);
125
    }
126
127
    /**
128
     * Sets a MIN() query.
129
     *
130
     * @param $field
131
     *
132
     * @return self
133
     */
134
    function min($field)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
135
    {
136
        return $this->aggregate('MIN', $field);
137
    }
138
139
    /**
140
     * Sets a MAX() query.
141
     *
142
     * @param $field
143
     *
144
     * @return self
145
     */
146
    function max($field)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
147
    {
148
        return $this->aggregate('MAX', $field);
149
    }
150
151
    /**
152
     * Adds a join to the query.
153
     *
154
     * @param string $table table name
155
     * @param string $on    ON condition
156
     * @param string $using USING columns
157
     * @param string $type  optional join type if not JOIN
158
     *
159
     * @return self
160
     */
161
    public function join($table, $on = null, $using = null, $type = 'JOIN')
162
    {
163
        $this->from->addJoin($table, $on, $using, $type);
164
165
        return $this;
166
    }
167
168
    /**
169
     * Sets the group by fields for the query.
170
     *
171
     * @param string|array $fields
172
     * @param string       $direction
173
     *
174
     * @return self
175
     */
176
    public function groupBy($fields, $direction = false)
177
    {
178
        $this->groupBy->addFields($fields, $direction);
179
180
        return $this;
181
    }
182
183
    /**
184
     * Sets the having conditions for the query.
185
     *
186
     * @param array|string $field
187
     * @param string|bool  $condition condition value (optional)
188
     * @param string       $operator  operator (optional)
189
     *
190
     * @return self
191
     */
192 View Code Duplication
    public function having($field, $condition = false, $operator = '=')
193
    {
194
        if (func_num_args() >= 2) {
195
            $this->having->addCondition($field, $condition, $operator);
196
        } else {
197
            $this->having->addCondition($field);
198
        }
199
200
        return $this;
201
    }
202
203
    /**
204
     * Unions another select query with this query.
205
     *
206
     * @param SelectQuery $query
207
     * @param string      $type  optional union type
208
     *
209
     * @return self
210
     */
211
    public function union(SelectQuery $query, $type = '')
212
    {
213
        $this->union->addQuery($query, $type);
214
215
        return $this;
216
    }
217
218
    /**
219
     * Gets the select statement for the query.
220
     *
221
     * @return SelectStatement
222
     */
223
    public function getSelect()
224
    {
225
        return $this->select;
226
    }
227
228
    /**
229
     * Gets the group by statement for the query.
230
     *
231
     * @return GroupByStatement
232
     */
233
    public function getGroupBy()
234
    {
235
        return $this->groupBy;
236
    }
237
238
    /**
239
     * Gets the having statement for the query.
240
     *
241
     * @return WhereStatement
242
     */
243
    public function getHaving()
244
    {
245
        return $this->having;
246
    }
247
248
    /**
249
     * Gets the union statement for the query.
250
     *
251
     * @return UnionStatement
252
     */
253
    public function getUnion()
254
    {
255
        return $this->union;
256
    }
257
258
    /**
259
     * Generates the raw SQL string for the query.
260
     *
261
     * @return string
262
     */
263
    public function build()
264
    {
265
        $sql = [
266
            $this->select->build(),
267
            $this->from->build(),
268
            $this->where->build(),
269
            $this->groupBy->build(),
270
            $this->having->build(),
271
            $this->orderBy->build(),
272
            $this->limit->build(),
273
            $this->union->build(),
274
        ];
275
276
        $this->values = array_merge(
277
            $this->where->getValues(),
278
            $this->having->getValues(),
279
            $this->union->getValues());
280
281
        $sql = implode(' ', array_filter($sql));
282
283
        // when there is no select statement then the query
284
        // is probably just a where subquery, thus does
285
        // not need to be prefixed with WHERE
286
        if (substr($sql, 0, 6) === 'WHERE ') {
287
            return substr($sql, 6);
288
        }
289
290
        return $sql;
291
    }
292
293
    public function __clone()
294
    {
295
        $this->select = clone $this->select;
296
        $this->from = clone $this->from;
297
        $this->where = clone $this->where;
298
        $this->groupBy = clone $this->groupBy;
299
        $this->having = clone $this->having;
300
        $this->orderBy = clone $this->orderBy;
301
        $this->limit = clone $this->limit;
302
        $this->union = clone $this->union;
303
    }
304
}
305