SelectQuery   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 285
Duplicated Lines 3.51 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 13
dl 10
loc 285
rs 10
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A select() 0 6 1
A aggregate() 0 6 1
A count() 0 4 1
A sum() 0 4 1
A average() 0 4 1
A min() 0 4 1
A max() 0 4 1
A join() 0 6 1
A groupBy() 0 6 1
A having() 10 10 2
A union() 0 6 1
A getSelect() 0 4 1
A getGroupBy() 0 4 1
A getHaving() 0 4 1
A getUnion() 0 4 1
A build() 0 30 2
A __clone() 0 11 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/**
4
 * @author Jared King <[email protected]>
5
 *
6
 * @see http://jaredtking.com
7
 *
8
 * @copyright 2015 Jared King
9
 * @license MIT
10
 */
11
12
namespace JAQB\Query;
13
14
use JAQB\Operations\Executable;
15
use JAQB\Operations\Fetchable;
16
use JAQB\Query\Traits\From;
17
use JAQB\Query\Traits\Limit;
18
use JAQB\Query\Traits\OrderBy;
19
use JAQB\Query\Traits\Where;
20
use JAQB\Statement\FromStatement;
21
use JAQB\Statement\LimitStatement;
22
use JAQB\Statement\OrderStatement;
23
use JAQB\Statement\SelectStatement;
24
use JAQB\Statement\UnionStatement;
25
use JAQB\Statement\WhereStatement;
26
27
class SelectQuery extends AbstractQuery
28
{
29
    use Executable;
30
    use Fetchable;
31
    use From;
32
    use Limit;
33
    use OrderBy;
34
    use Where;
35
36
    /**
37
     * @var SelectStatement
38
     */
39
    protected $select;
40
41
    /**
42
     * @var WhereStatement
43
     */
44
    protected $having;
45
46
    /**
47
     * @var OrderStatement
48
     */
49
    protected $groupBy;
50
51
    /**
52
     * @var UnionStatement
53
     */
54
    protected $union;
55
56
    public function __construct()
57
    {
58
        $this->select = new SelectStatement();
59
        $this->from = new FromStatement();
60
        $this->where = new WhereStatement();
61
        $this->having = new WhereStatement(true);
62
        $this->orderBy = new OrderStatement();
63
        $this->groupBy = new OrderStatement(true);
64
        $this->limit = new LimitStatement();
65
        $this->union = new UnionStatement();
66
    }
67
68
    /**
69
     * Sets the fields to be selected for the query.
70
     *
71
     * @param array|string $fields fields
72
     *
73
     * @return self
74
     */
75
    public function select($fields)
76
    {
77
        $this->select->clearFields()->addFields($fields);
78
79
        return $this;
80
    }
81
82
    /**
83
     * Sets the selected fields to an aggregate function.
84
     *
85
     * @param $function
86
     * @param string $field
87
     *
88
     * @return self
89
     */
90
    public function aggregate($function, $field = '*')
91
    {
92
        $this->select->clearFields()->addFields($function.'('.$field.')');
93
94
        return $this;
95
    }
96
97
    /**
98
     * Sets a COUNT() query.
99
     *
100
     * @param $field
101
     *
102
     * @return self
103
     */
104
    public function count($field = '*')
105
    {
106
        return $this->aggregate('COUNT', $field);
107
    }
108
109
    /**
110
     * Sets a SUM() query.
111
     *
112
     * @param $field
113
     *
114
     * @return self
115
     */
116
    public function sum($field)
117
    {
118
        return $this->aggregate('SUM', $field);
119
    }
120
121
    /**
122
     * Sets an AVG() query.
123
     *
124
     * @param $field
125
     *
126
     * @return self
127
     */
128
    public function average($field)
129
    {
130
        return $this->aggregate('AVG', $field);
131
    }
132
133
    /**
134
     * Sets a MIN() query.
135
     *
136
     * @param $field
137
     *
138
     * @return self
139
     */
140
    public function min($field)
141
    {
142
        return $this->aggregate('MIN', $field);
143
    }
144
145
    /**
146
     * Sets a MAX() query.
147
     *
148
     * @param $field
149
     *
150
     * @return self
151
     */
152
    public function max($field)
153
    {
154
        return $this->aggregate('MAX', $field);
155
    }
156
157
    /**
158
     * Adds a join to the query.
159
     *
160
     * @param string $table table name
161
     * @param string $on    ON condition
162
     * @param string $using USING columns
163
     * @param string $type  optional join type if not JOIN
164
     *
165
     * @return self
166
     */
167
    public function join($table, $on = null, $using = null, $type = 'JOIN')
168
    {
169
        $this->from->addJoin($table, $on, $using, $type);
170
171
        return $this;
172
    }
173
174
    /**
175
     * Sets the group by fields for the query.
176
     *
177
     * @param string|array $fields
178
     * @param string       $direction
179
     *
180
     * @return self
181
     */
182
    public function groupBy($fields, $direction = false)
183
    {
184
        $this->groupBy->addFields($fields, $direction);
185
186
        return $this;
187
    }
188
189
    /**
190
     * Sets the having conditions for the query.
191
     *
192
     * @param array|string $field
193
     * @param string|bool  $condition condition value (optional)
194
     * @param string       $operator  operator (optional)
195
     *
196
     * @return self
197
     */
198 View Code Duplication
    public function having($field, $condition = false, $operator = '=')
199
    {
200
        if (func_num_args() >= 2) {
201
            $this->having->addCondition($field, $condition, $operator);
202
        } else {
203
            $this->having->addCondition($field);
204
        }
205
206
        return $this;
207
    }
208
209
    /**
210
     * Unions another select query with this query.
211
     *
212
     * @param SelectQuery $query
213
     * @param string      $type  optional union type
214
     *
215
     * @return self
216
     */
217
    public function union(self $query, $type = '')
218
    {
219
        $this->union->addQuery($query, $type);
220
221
        return $this;
222
    }
223
224
    /**
225
     * Gets the select statement for the query.
226
     *
227
     * @return SelectStatement
228
     */
229
    public function getSelect()
230
    {
231
        return $this->select;
232
    }
233
234
    /**
235
     * Gets the group by statement for the query.
236
     *
237
     * @return OrderStatement
238
     */
239
    public function getGroupBy()
240
    {
241
        return $this->groupBy;
242
    }
243
244
    /**
245
     * Gets the having statement for the query.
246
     *
247
     * @return WhereStatement
248
     */
249
    public function getHaving()
250
    {
251
        return $this->having;
252
    }
253
254
    /**
255
     * Gets the union statement for the query.
256
     *
257
     * @return UnionStatement
258
     */
259
    public function getUnion()
260
    {
261
        return $this->union;
262
    }
263
264
    /**
265
     * Generates the raw SQL string for the query.
266
     *
267
     * @return string
268
     */
269
    public function build()
270
    {
271
        $sql = [
272
            $this->select->build(),
273
            $this->from->build(),
274
            $this->where->build(),
275
            $this->groupBy->build(),
276
            $this->having->build(),
277
            $this->orderBy->build(),
278
            $this->limit->build(),
279
            $this->union->build(),
280
        ];
281
282
        $this->values = array_merge(
283
            $this->where->getValues(),
284
            $this->having->getValues(),
285
            $this->union->getValues()
286
        );
287
288
        $sql = implode(' ', array_filter($sql));
289
290
        // when there is no select statement then the query
291
        // is probably just a where subquery, thus does
292
        // not need to be prefixed with WHERE
293
        if ('WHERE ' === substr($sql, 0, 6)) {
294
            return substr($sql, 6);
295
        }
296
297
        return $sql;
298
    }
299
300
    public function __clone()
301
    {
302
        $this->select = clone $this->select;
303
        $this->from = clone $this->from;
304
        $this->where = clone $this->where;
305
        $this->groupBy = clone $this->groupBy;
306
        $this->having = clone $this->having;
307
        $this->orderBy = clone $this->orderBy;
308
        $this->limit = clone $this->limit;
309
        $this->union = clone $this->union;
310
    }
311
}
312