Passed
Push — master ( 6bb1e5...501c0f )
by RN
02:37
created

Dolphin::all()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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