Passed
Push — master ( 6464dd...1b5140 )
by RN
02:05
created

Dolphin::buildQuery()   B

Complexity

Conditions 9
Paths 192

Size

Total Lines 54
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 33
nc 192
nop 0
dl 0
loc 54
rs 7.2888
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * The Query builder API.
4
 *
5
 * @author RN Kushwaha <[email protected]>
6
 *
7
 * @since v0.0.1
8
 */
9
10
namespace Dolphin\Mapper;
11
12
use Dolphin\Connections\Connection;
13
use Dolphin\Builders\QueryBuilder;
14
use Dolphin\Builders\WhereQueryBuilder;
15
use Dolphin\Builders\JoinQueryBuilder;
16
use Dolphin\Builders\InsertQueryBuilder;
17
use Dolphin\Utils\Utils;
18
use \Exception;
19
20
/**
21
 * This class provides some nice features to interact with the Database
22
 * Elegant Query builder
23
 * Method Chaining
24
 * Prepared Statement using named parameter like status = :status
25
 * Raw Query Option
26
 * Join Clause
27
 * Where Clause
28
 * WhereRaw Clause
29
 * orWhere Clause [TODO]
30
 * WhereIn Clause
31
 * WhereNotIn Clause
32
 * WhereNull Clause
33
 * WhereNotNull Clause
34
 * GroupBy Clause
35
 * Having Clause
36
 * OrderBy Clause.
37
 *
38
 * Aggregations like
39
 * Count()
40
 * Max() [TODO]
41
 * Min() [TODO]
42
 * First()
43
 * Last() [TODO]
44
 * Avg() [TODO]
45
 * fetchColumn [TODO]
46
 * union() [TODO]
47
 * delete()
48
 * update()
49
 * insert()
50
 * truncate()
51
 * havingRaw() [TODO]
52
 * exists() [TODO]
53
 */
54
class Dolphin
55
{
56
    protected $fields = array();
57
    protected $table;
58
    public $tableName;
59
    protected $groupBy;
60
    protected $orderBy;
61
    protected $having;
62
    protected $join = array();
63
    protected $leftJoin = array();
64
    protected $rightJoin = array();
65
    protected $crossJoin = array();
66
    protected $where = array();
67
    protected $whereIn = array();
68
    protected $whereNotIn = array();
69
    protected $whereNull = array();
70
    protected $whereNotNull = array();
71
    protected $limit;
72
    protected $offset;
73
    protected $results;
74
75
    /**
76
     * It returns the table name to Query from
77
     * Used internally
78
     */
79
    protected function table()
80
    {
81
        $class = $this->tableName;
82
        $ref   = new \ReflectionClass($class);
83
        $qb    = new QueryBuilder();
84
        $util  = new Utils();
85
86
        if ($ref->hasProperty('table')) {
87
            $tableCheck = $ref->getProperty('table');
88
            $tableCheck->setAccessible(true);
89
            $tableName = $tableCheck->getValue(new $class());
90
        } else {
91
            $tableName = explode('\\', $class);
92
            $tableName = $util->decamelize(end($tableName));
93
        }
94
95
        $prefix = $qb->getPrefix();
96
        $this->table = $prefix.$tableName;
97
98
        return $this->table;
99
    }
100
101
    public function select()
102
    {
103
        $args = func_get_args();
104
        $fldAr = array();
105
        $qb = new QueryBuilder();
106
107
        foreach ($args as $arg) {
108
            $argsAr = explode(',', $arg);
109
            foreach ($argsAr as $ar) {
110
                $fldAr[] = $qb->quote(trim($ar));
111
            }
112
        }
113
114
        $this->fields = array_merge($this->fields, $fldAr);
115
116
        return $this;
117
    }
118
119
    public function selectRaw()
120
    {
121
        $args = func_get_args();
122
        $fldAr = array();
123
124
        foreach ($args as $arg) {
125
            $argsAr = explode(',', $arg);
126
            foreach ($argsAr as $ar) {
127
                $fldAr[] = trim($ar);
128
            }
129
        }
130
131
        $this->fields = array_merge($this->fields, $fldAr);
132
133
        return $this;
134
    }
135
136
    public function join($join, $mixedParam, $param3 = null, $param4 = null, $mixedParam2 = null)
137
    {
138
        $this->join = array_merge($this->join, [[$join, $mixedParam, $param3, $param4, $mixedParam2]]);
139
140
        return $this;
141
    }
142
143
    public function leftJoin($leftJoin, $mixedParam, $param3 = null, $param4 = null, $mixedParam2 = null)
144
    {
145
        $this->leftJoin = array_merge($this->leftJoin, [[$leftJoin, $mixedParam, $param3, $param4, $mixedParam2]]);
146
147
        return $this;
148
    }
149
150
    public function rightJoin($rightJoin, $mixedParam, $param3 = null, $param4 = null, $mixedParam2 = null)
151
    {
152
        $this->rightJoin = array_merge($this->rightJoin, [[$rightJoin, $mixedParam, $param3, $param4, $mixedParam2]]);
153
154
        return $this;
155
    }
156
157
    public function crossJoin($crossJoin, $params = null)
158
    {
159
        $this->crossJoin = array_merge($this->crossJoin, [[$crossJoin, $params]]);
160
161
        return $this;
162
    }
163
164
    public function where($where, $params = null)
165
    {
166
        $this->where = array_merge($this->where, [[$where, $params]]);
167
168
        return $this;
169
    }
170
171
    public function whereIn($whereIn, $params = array())
172
    {
173
        $this->whereIn = array_merge($this->whereIn, [[$whereIn, $params]]);
174
175
        return $this;
176
    }
177
178
    public function whereNotIn($whereNotIn, $params = array())
179
    {
180
        $this->whereNotIn = array_merge($this->whereNotIn, [[$whereNotIn, $params]]);
181
182
        return $this;
183
    }
184
185
    public function whereNull($whereNull)
186
    {
187
        $this->whereNull = array_merge($this->whereNull, [$whereNull]);
188
189
        return $this;
190
    }
191
192
    public function whereNotNull($whereNotNull)
193
    {
194
        $this->whereNotNull = array_merge($this->whereNotNull, [$whereNotNull]);
195
196
        return $this;
197
    }
198
199
    public function offset($offset)
200
    {
201
        $this->offset = $offset;
202
203
        return $this;
204
    }
205
206
    public function limit($limit)
207
    {
208
        $this->limit = $limit;
209
210
        return $this;
211
    }
212
213
    public function orderBy($orderBy)
214
    {
215
        $this->orderBy = $orderBy;
216
217
        return $this;
218
    }
219
220
    public function groupBy($groupBy)
221
    {
222
        $this->groupBy = $groupBy;
223
224
        return $this;
225
    }
226
227
    public function having($having)
228
    {
229
        $this->having = $having;
230
231
        return $this;
232
    }
233
234
    protected function buildAllWhereQuery()
235
    {
236
        $wqb = new WhereQueryBuilder();
237
        return $wqb->buildAllWhereQuery($this->where, 
238
                                        $this->whereIn, 
239
                                        $this->whereNotIn, 
240
                                        $this->whereNull, 
241
                                        $this->whereNotNull
242
                                    );
243
    }
244
245
    protected function buildAllJoinQuery()
246
    {
247
        $jqb = new JoinQueryBuilder();
248
        return $jqb->buildAllJoinQuery($this->join, 
249
                                        $this->leftJoin, 
250
                                        $this->rightJoin, 
251
                                        $this->crossJoin
252
                                    );
253
    }
254
255
    /**
256
     * Builds Query added by method chaining.
257
     * It has the main logic of ORM
258
     */
259
    protected function buildQuery()
260
    {
261
        $query = array();
262
        $tblWithPrefix = $this->table();
263
        $qb     = new QueryBuilder();
264
        $prefix = $qb->getPrefix();
265
        $tbl    = str_replace($prefix, '', $tblWithPrefix);
266
267
        $query[] = 'SELECT';
268
        if (empty($this->fields)) {
269
            $query[] = $qb->quote($tbl).'.*';
270
        } else {
271
            $query[] = join(', ', $this->fields);
272
        }
273
274
        $query[] = 'FROM';
275
        $query[] = $qb->quote($tblWithPrefix).' AS '.$qb->quote($tbl);
276
277
        $allJoinQuery = $this->buildAllJoinQuery();
278
        if (count($allJoinQuery)) {
279
            $query = array_merge($query, $allJoinQuery);
280
        }
281
282
        $allWhereQuery = $this->buildAllWhereQuery();
283
        if (count($allWhereQuery)) {
284
            $query = array_merge($query, $allWhereQuery);
285
        }
286
287
        if (!empty($this->groupBy)) {
288
            $query[] = 'GROUP BY';
289
            $query[] = $this->groupBy;
290
        }
291
292
        if (!empty($this->having)) {
293
            $query[] = 'HAVING';
294
            $query[] = $this->having;
295
        }
296
297
        if (!empty($this->orderBy)) {
298
            $query[] = 'ORDER BY';
299
            $query[] = $this->orderBy;
300
        }
301
302
        if (!empty($this->limit)) {
303
            $query[] = 'LIMIT';
304
305
            if (!empty($this->offset)) {
306
                $query[] = $this->offset.',';
307
            }
308
309
            $query[] = $this->limit;
310
        }
311
312
        return join(' ', $query);
313
    }
314
315
    protected function reset()
316
    {
317
        $this->fields = array();
318
        $this->table = null;
319
        $this->tableName = null;
320
        $this->groupBy = null;
321
        $this->orderBy = null;
322
        $this->having = null;
323
        $this->join = array();
324
        $this->leftJoin = array();
325
        $this->rightJoin = array();
326
        $this->crossJoin = array();
327
        $this->where = array();
328
        $this->whereIn = array();
329
        $this->whereNotIn = array();
330
        $this->whereNull = array();
331
        $this->whereNotNull = array();
332
        $this->limit = null;
333
        $this->offset = null;
334
    }
335
336
    public function prepare($query, $fetchMode = 'FETCH_OBJ', $fetchRows = 'all')
337
    {
338
        $qb = new QueryBuilder();
339
        $wqb = new WhereQueryBuilder();
340
        $fetch = $qb->fetchType($fetchMode);
341
        $util = new Utils();
342
        
343
        try {
344
            $ar = $wqb->parseWhereQuery($this->where);
345
            $stmt = Connection::get()->prepare($qb->queryPrefix($query));
346
            $stmt->execute($ar);
347
348
            if ($fetchRows == 'first') {
349
                $rows = $stmt->fetch($fetch);
350
                $this->results = $rows;
351
                // now turn this stdClass object to the object type of calling model
352
                $rows = $util->turnObject($this->tableName, $rows);
0 ignored issues
show
Unused Code introduced by
The assignment to $rows is dead and can be removed.
Loading history...
353
            } else {
354
                $rows = $stmt->fetchAll($fetch);
355
                $this->results = $rows;
356
            }
357
358
            // Reset class variables
359
            $this->reset();
360
361
            return $this;
362
        } catch (\PDOException $ex) {
363
            throw new \PDOException($ex->getMessage(), 1);
364
        } catch (Exception $e) {
365
            throw new Exception($e->getMessage(), 1);
366
        }
367
    }
368
369
    public function query($query, $fetchMode = 'FETCH_OBJ', $fetchRows = 'all')
370
    {
371
        $qb = new QueryBuilder();
372
        $fetch = $qb->fetchType($fetchMode);
373
374
        try {
375
            $obj = Connection::get()->query($qb->queryPrefix($query), $fetch);
376
377
            if ($fetchRows == 'count') {
378
                $data = $obj->fetchColumn();
379
            }
380
381
            // Reset class variables
382
            $this->reset();
383
384
            return isset($data) ? $data : $obj;
385
        } catch (\PDOException $ex) {
386
            throw new \PDOException($ex->getMessage(), 1);
387
        } catch (Exception $e) {
388
            throw new Exception($e->getMessage(), 1);
389
        }
390
    }
391
392
    public function get()
393
    {
394
        return $this->prepare($this->buildQuery(), 'FETCH_OBJ');
395
    }
396
397
    public function first()
398
    {
399
        $query = $this->buildQuery();
400
401
        if (strripos($query, 'LIMIT 1')) {
402
            // [TODO]
403
        } else {
404
            $query .= ' LIMIT 1';
405
        }
406
407
        return $this->prepare($query, 'FETCH_OBJ', 'first');
408
    }
409
410
    /**
411
     * It fetches the row by primary key
412
     * 
413
     * @author RN Kushwaha <[email protected]>
414
     * @since v0.0.5 
415
     */
416
    public function find($id)
417
    {
418
        $this->where('id = :id', $id);
419
        
420
        return $this->first();
421
    }
422
423
    /**
424
     * It fetches the row by primary key
425
     * 
426
     * @param int $id
427
     * @return object $row
428
     * @throws Exception
429
     * @author RN Kushwaha <[email protected]>
430
     * @since v0.0.5 
431
     */
432
    public function findOrFail($id)
433
    {
434
        $this->where('id = :id', $id);
435
        
436
        $row = $this->first();
437
438
        if($row == null ){
439
            throw new Exception("The record does not exists!");
440
        }
441
442
        return $row;
443
    }
444
445
    public function count()
446
    {
447
        $this->fields = null;
448
        $query = $this->buildQuery();
449
        $query = str_replace('SELECT * ', 'SELECT COUNT(*) as count ', $query);
450
451
        return $this->query($query, 'FETCH_OBJ', 'count');
452
    }
453
454
    public function asArray()
455
    {
456
        return json_decode(json_encode($this->results), true);
457
    }
458
459
    public function asJSON()
460
    {
461
        return json_encode($this->results);
462
    }
463
464
    /**
465
     * It truncates the table
466
     * 
467
     * @return boolean
468
     * @throws Exception
469
     * @author RN Kushwaha <[email protected]>
470
     * @since v0.0.5 
471
     */
472
    public function truncate()
473
    {
474
        $qb = new QueryBuilder();
475
        $query = "TRUNCATE ".$this->table();
476
        
477
        try{
478
            Connection::get()->query($qb->queryPrefix($query));
479
        } catch(Exception $e){
480
            throw new Exception($e->getMessage());
481
        }
482
483
        return true;
484
    }
485
486
    /**
487
     * It inserts the new rows
488
     * 
489
     * @param array $rows
490
     * @return integer $lastInsertedId
491
     * @throws Exception
492
     * @author RN Kushwaha <[email protected]>
493
     * @since v0.0.5 
494
     */
495
    public function insert($rows)
496
    {
497
        $iqb = new InsertQueryBuilder();
498
        return $iqb->insert($rows, $this->table());
499
    }
500
501
    /**
502
     * It updates the rows
503
     * 
504
     * @param array $row
505
     * @return boolean
506
     * @throws Exception
507
     * @author RN Kushwaha <[email protected]>
508
     * @since v0.0.5 
509
     */
510
    public function update($row)
511
    {
512
        $qb = new QueryBuilder();
513
        $query = "UPDATE ".$this->table()." SET ";
514
        $ar = array();
515
        
516
        foreach($row as $key => $val){
517
            $ar[':'.$key] = $val;
518
            $query.= $qb->quote($key)." =:".$key.",";
519
        }
520
521
        $query = rtrim($query, ",");
522
        
523
        try{
524
            $whereQuery = $this->buildAllWhereQuery();
525
            $query.= " ".join(" ", $whereQuery);
526
            $stmt = Connection::get()->prepare($qb->queryPrefix($query));
527
            $stmt->execute($ar);
528
            $this->reset();
529
        } catch(Exception $e){
530
            throw new Exception($e->getMessage());
531
        }
532
533
        return true;
534
    }
535
536
    /**
537
     * It deleted the rows matched by where clause
538
     * 
539
     * @return boolean
540
     * @throws Exception
541
     * @author RN Kushwaha <[email protected]>
542
     * @since v0.0.5 
543
     */
544
    public function delete()
545
    {
546
        $qb = new QueryBuilder();
547
        $query = "DELETE FROM ".$this->table();
548
        
549
        try{
550
            $whereQuery = $this->buildAllWhereQuery();
551
            $query.= " ".join(" ", $whereQuery);
552
            Connection::get()->query($qb->queryPrefix($query));
553
            $this->reset();
554
        } catch(Exception $e){
555
            throw new Exception($e->getMessage());
556
        }
557
558
        return true;
559
    }
560
}
561