Passed
Push — master ( 169181...4782ef )
by Rougin
03:08
created

Query::andOrderBy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Rougin\Windstorm\Doctrine;
4
5
use Doctrine\DBAL\Query\QueryBuilder;
6
use Rougin\Windstorm\QueryInterface;
7
use Rougin\Windstorm\ResultInterface;
8
9
/**
10
 * Query
11
 *
12
 * @package Windstorm
13
 * @author  Rougin Gutib <[email protected]>
14
 */
15
class Query implements QueryInterface
16
{
17
    /**
18
     * @var \Rougin\Windstorm\Doctrine\Builder
19
     */
20
    protected $builder;
21
22
    /**
23
     * @var string
24
     */
25
    protected $initial = '';
26
27
    /**
28
     * @var string
29
     */
30
    protected $table = '';
31
32
    /**
33
     * Returns the safe and compiled SQL.
34
     *
35
     * @return string
36
     */
37 45
    public function __toString()
38
    {
39 45
        return $this->sql();
40
    }
41
42
    /**
43
     * Initializes the query instance.
44
     *
45
     * @param \Doctrine\DBAL\Query\QueryBuilder $builder
46
     */
47 129
    public function __construct(QueryBuilder $builder)
48
    {
49 129
        $this->builder = $builder;
0 ignored issues
show
Documentation Bug introduced by
$builder is of type Doctrine\DBAL\Query\QueryBuilder, but the property $builder was declared to be of type Rougin\Windstorm\Doctrine\Builder. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
50 129
    }
51
52
    /**
53
     * Generates a SELECT query.
54
     *
55
     * @param  array  $fields
56
     * @return self
57
     */
58 105
    public function select(array $fields)
59 3
    {
60 105
        $this->reset();
61
62 102
        $this->builder->select($fields);
63
64 102
        return $this;
65
    }
66
67
    /**
68
     * Generates a FROM query.
69
     *
70
     * @param  string      $table
71
     * @param  string|null $alias
72
     * @return self
73
     */
74 102
    public function from($table, $alias = null)
75
    {
76 102
        if ($alias === null)
77 102
        {
78 102
            $alias = $table[0];
79 102
        }
80
81 102
        $this->initial = $alias;
82
83 102
        $this->table = $table;
84
85 102
        $this->builder->from($table, $alias);
86
87 102
        return $this;
88
    }
89
90
    /**
91
     * Generates an INNER JOIN query.
92
     *
93
     * @param  string $table
94
     * @param  string $local
95
     * @param  string $foreign
96
     * @return self
97
     */
98 3
    public function innerJoin($table, $local, $foreign)
99
    {
100 3
        list($alias, $where) = $this->condition($table, $local, $foreign);
101
102 3
        $this->builder->innerJoin($this->initial, $table, $alias, $where);
103
104 3
        return $this;
105
    }
106
107
    /**
108
     * Generates a LEFT JOIN query.
109
     *
110
     * @param  string $table
111
     * @param  string $local
112
     * @param  string $foreign
113
     * @return self
114
     */
115 3
    public function leftJoin($table, $local, $foreign)
116
    {
117 3
        list($alias, $where) = $this->condition($table, $local, $foreign);
118
119 3
        $this->builder->leftJoin($this->initial, $table, $alias, $where);
120
121 3
        return $this;
122
    }
123
124
    /**
125
     * Generates a RIGHT JOIN query.
126
     *
127
     * @param  string $table
128
     * @param  string $local
129
     * @param  string $foreign
130
     * @return self
131
     */
132 3
    public function rightJoin($table, $local, $foreign)
133
    {
134 3
        list($alias, $where) = $this->condition($table, $local, $foreign);
135
136 3
        $this->builder->rightJoin($this->initial, $table, $alias, $where);
137
138 3
        return $this;
139
    }
140
141
    /**
142
     * Generates an INSERT INTO query.
143
     *
144
     * @param  string $table
145
     * @return \Rougin\Windstorm\InsertInterface
146
     */
147 6
    public function insertInto($table)
148
    {
149 6
        $this->reset();
150
151 6
        return new Insert($this, $this->builder, $table);
152
    }
153
154
    /**
155
     * Generates an UPDATE query.
156
     *
157
     * @param  string      $table
158
     * @param  string|null $alias
159
     * @return \Rougin\Windstorm\UpdateInterface
160
     */
161 6
    public function update($table, $alias = null)
162
    {
163 6
        $this->reset();
164
165 6
        $initial = $this->alias($table);
166
167 6
        $this->initial = (string) $initial;
168
169 6
        $this->table = (string) $table;
170
171 6
        return new Update($this, $this->builder, $table, $initial);
172
    }
173
174
    /**
175
     * Generates a DELETE FROM query.
176
     *
177
     * @param  string      $table
178
     * @param  string|null $alias
179
     * @return self
180
     */
181 15
    public function deleteFrom($table, $alias = null)
182
    {
183 15
        $this->reset();
184
185 15
        $this->initial = $this->alias((string) $table);
186
187 15
        $this->table = $table;
188
189 15
        $this->builder->delete($table, $this->initial);
190
191 15
        return $this;
192
    }
193
194
    /**
195
     * Generates a WHERE query.
196
     *
197
     * @param  string $key
198
     * @return \Rougin\Windstorm\WhereInterface
199
     */
200 75
    public function where($key)
201
    {
202 75
        return new Where($this, $this->builder, $key, $this->initial);
203
    }
204
205
    /**
206
     * Generates an AND WHERE query.
207
     *
208
     * @param  string $key
209
     * @return \Rougin\Windstorm\WhereInterface
210
     */
211 3
    public function andWhere($key)
212
    {
213 3
        return new Where($this, $this->builder, $key, $this->initial, 'AND');
214
    }
215
216
    /**
217
     * Generates an OR WHERE query.
218
     *
219
     * @param  string $key
220
     * @return \Rougin\Windstorm\WhereInterface
221
     */
222 3
    public function orWhere($key)
223
    {
224 3
        return new Where($this, $this->builder, $key, $this->initial, 'OR');
225
    }
226
227
    /**
228
     * Generates a GROUP BY query.
229
     *
230
     * @param  array $fields
231
     * @return self
232
     */
233 3
    public function groupBy(array $fields)
234
    {
235 3
        foreach ($fields as $key => $field)
236
        {
237 3
            if (strpos($field, '.') === false)
238 3
            {
239 3
                $fields[$key] = $this->initial . '.' . $field;
240 3
            }
241 3
        }
242
243 3
        $this->builder->groupBy($fields);
244
245 3
        return $this;
246
    }
247
248
    /**
249
     * Generates a HAVING query.
250
     *
251
     * @param  string $key
252
     * @return \Rougin\Windstorm\HavingInterface
253
     */
254 9
    public function having($key)
255
    {
256 9
        return new Having($this, $this->builder, $key, $this->initial);
257
    }
258
259
    /**
260
     * Generates an AND HAVING query.
261
     *
262
     * @param  string $key
263
     * @return \Rougin\Windstorm\HavingInterface
264
     */
265 3
    public function andHaving($key)
266
    {
267 3
        return new Having($this, $this->builder, $key, $this->initial, 'AND');
268
    }
269
270
    /**
271
     * Generates an OR HAVING query.
272
     *
273
     * @param  string $key
274
     * @return \Rougin\Windstorm\HavingInterface
275
     */
276 3
    public function orHaving($key)
277
    {
278 3
        return new Having($this, $this->builder, $key, $this->initial, 'OR');
279
    }
280
281
    /**
282
     * Generates an ORDER BY query.
283
     *
284
     * @param  string $key
285
     * @return \Rougin\Windstorm\OrderInterface
286
     */
287 15
    public function orderBy($key)
288
    {
289 15
        return new Order($this, $this->builder, $key, $this->initial);
290
    }
291
292
    /**
293
     * Generates a multiple ORDER BY query.
294
     *
295
     * @param  string $key
296
     * @return \Rougin\Windstorm\OrderInterface
297
     */
298 3
    public function andOrderBy($key)
299
    {
300 3
        return new Order($this, $this->builder, $key, $this->initial, 'ADD');
301
    }
302
303
    /**
304
     * Performs a LIMIT query.
305
     *
306
     * @param  integer      $limit
307
     * @param  integer|null $offset
308
     * @return self
309
     */
310 15
    public function limit($limit, $offset = null)
311
    {
312 15
        $this->builder->setMaxResults($limit);
313
314 15
        if ($offset !== null)
315 15
        {
316 12
            $this->builder->setFirstResult($offset);
317 12
        }
318
319 15
        return $this;
320
    }
321
322
    /**
323
     * Sets the Builder instance.
324
     *
325
     * @param  \Doctrine\DBAL\Query\QueryBuilder $builder
326
     * @return self
327
     */
328 105
    public function builder(QueryBuilder $builder)
329
    {
330 105
        $this->builder = $builder;
0 ignored issues
show
Documentation Bug introduced by
$builder is of type Doctrine\DBAL\Query\QueryBuilder, but the property $builder was declared to be of type Rougin\Windstorm\Doctrine\Builder. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
331
332 105
        return $this;
333
    }
334
335 6
    public function execute(ResultInterface $result)
336
    {
337 6
        return $result->execute($this->sql(), $this->bindings(), $this->types());
338
    }
339
340
    /**
341
     * Returns the safe and compiled SQL.
342
     *
343
     * @return string
344
     */
345 123
    public function sql()
346
    {
347 123
        return $this->builder->getSql();
348
    }
349
350
    /**
351
     * Returns the SQL bindings specified.
352
     *
353
     * @return array
354
     */
355 9
    public function bindings()
356
    {
357 9
        return $this->builder->getParameters();
358
    }
359
360
    /**
361
     * Returns the data types of the bindings.
362
     *
363
     * @return array
364
     */
365 9
    public function types()
366
    {
367 9
        return $this->builder->getParameterTypes();
368
    }
369
370
    /**
371
     * Returns an available table alias.
372
     *
373
     * @param  string $table
374
     * @return string
375
     */
376 30
    protected function alias($table)
377
    {
378 30
        $characters = str_split($table);
379
380 30
        $result = $characters[0];
381
382 30
        foreach ($characters as $character)
383
        {
384 30
            $character = strtolower($character);
385
386 30
            if ($this->initial !== $character)
387 30
            {
388 30
                $result = $character; break;
389
            }
390 30
        }
391
392 30
        return (string) $result;
393
    }
394
395
    /**
396
     * Returns a JOIN condition.
397
     *
398
     * @param  string $table
399
     * @param  string $local
400
     * @param  string $foreign
401
     * @return string
402
     */
403 9
    protected function condition($table, $local, $foreign)
404
    {
405 9
        $condition = (string) $this->initial . '.' . $local;
406
407 9
        $alias = $this->alias((string) $table);
408
409 9
        $condition .= ' = ' . $alias . '.' . $foreign;
410
411 9
        return array($alias, (string) $condition);
412
    }
413
414
    /**
415
     * Resets the whole query builder.
416
     *
417
     * @return self
418
     */
419 129
    public function reset()
420
    {
421 129
        $this->builder->setMaxResults(null);
422
423 129
        $this->builder->setFirstResult(null);
424
425 129
        $this->initial = (string) '';
426
427 129
        $this->builder->resetQueryParts();
428
429 129
        $this->table = (string) '';
430
431 129
        $this->builder->setParameters(array());
432
433 129
        return $this;
434
    }
435
}
436