Passed
Push — master ( c0bcf8...f6b2ac )
by RN
01:58
created

Dolphin::getFields()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 6
c 0
b 0
f 0
nc 4
nop 2
dl 0
loc 11
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\JoinQueryBuilder;
15
use Dolphin\Builders\InsertQueryBuilder;
16
use Dolphin\Parsers\WhereQueryParser;
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
    public $table;
58
    public $className;
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
    private function getFields(array $args, bool $quote = true){
76
        $fldAr = array();
77
        $qb = new QueryBuilder();
78
79
        foreach ($args as $arg) {
80
            foreach (explode(',', $arg) as $ar) {
81
                $fldAr[] = ($quote === true) ? $qb->quote(trim($ar)) : trim($ar);
82
            }
83
        }
84
85
        return $fldAr;
86
    }
87
88
    public function select()
89
    {
90
        $args = func_get_args();
91
        $fldAr = $this->getFields($args, true);
92
        $this->fields = array_merge($this->fields, $fldAr);
93
94
        return $this;
95
    }
96
97
    public function selectRaw()
98
    {
99
        $args = func_get_args();
100
        $fldAr = $this->getFields($args, false);
101
        $this->fields = array_merge($this->fields, $fldAr);
102
103
        return $this;
104
    }
105
106
    public function join($join, $mixedParam, $param3 = null, $param4 = null, $mixedParam2 = null)
107
    {
108
        $this->join = array_merge($this->join, [[$join, $mixedParam, $param3, $param4, $mixedParam2]]);
109
110
        return $this;
111
    }
112
113
    public function leftJoin($leftJoin, $mixedParam, $param3 = null, $param4 = null, $mixedParam2 = null)
114
    {
115
        $this->leftJoin = array_merge($this->leftJoin, [[$leftJoin, $mixedParam, $param3, $param4, $mixedParam2]]);
116
117
        return $this;
118
    }
119
120
    public function rightJoin($rightJoin, $mixedParam, $param3 = null, $param4 = null, $mixedParam2 = null)
121
    {
122
        $this->rightJoin = array_merge($this->rightJoin, [[$rightJoin, $mixedParam, $param3, $param4, $mixedParam2]]);
123
124
        return $this;
125
    }
126
127
    public function crossJoin($crossJoin, $params = null)
128
    {
129
        $this->crossJoin = array_merge($this->crossJoin, [[$crossJoin, $params]]);
130
131
        return $this;
132
    }
133
134
    /**
135
     * @throws Exception
136
     */
137
    public function where()
138
    {
139
        $args = func_get_args();
140
        if(func_num_args()===2){
141
            $this->where = array_merge($this->where, [[$args[0], '=', $args[1]]]);
142
            return $this;
143
        } elseif(func_num_args()===3){
144
            $this->where = array_merge($this->where, [[$args[0], $args[1], $args[2]]]);
145
            return $this;
146
        }
147
148
        throw new Exception('Where parameter contains invalid number of parameters', 1);
149
    }
150
151
    public function whereIn($whereIn, $params = array())
152
    {
153
        $this->whereIn = array_merge($this->whereIn, [[$whereIn, $params]]);
154
155
        return $this;
156
    }
157
158
    public function whereNotIn($whereNotIn, $params = array())
159
    {
160
        $this->whereNotIn = array_merge($this->whereNotIn, [[$whereNotIn, $params]]);
161
162
        return $this;
163
    }
164
165
    public function whereNull($whereNull)
166
    {
167
        $this->whereNull = array_merge($this->whereNull, [$whereNull]);
168
169
        return $this;
170
    }
171
172
    public function whereNotNull($whereNotNull)
173
    {
174
        $this->whereNotNull = array_merge($this->whereNotNull, [$whereNotNull]);
175
176
        return $this;
177
    }
178
179
    public function offset($offset)
180
    {
181
        $this->offset = $offset;
182
183
        return $this;
184
    }
185
186
    public function limit($limit)
187
    {
188
        $this->limit = $limit;
189
190
        return $this;
191
    }
192
193
    public function orderBy($orderBy)
194
    {
195
        $this->orderBy = $orderBy;
196
197
        return $this;
198
    }
199
200
    public function groupBy($groupBy)
201
    {
202
        $this->groupBy = $groupBy;
203
204
        return $this;
205
    }
206
207
    public function having($having)
208
    {
209
        $this->having = $having;
210
211
        return $this;
212
    }
213
214
    /**
215
     * Builds Query added by method chaining.
216
     * It has the main logic of ORM
217
     */
218
    protected function buildQuery()
219
    {
220
        $qb     = new QueryBuilder();
221
222
        $query  = $qb->buildQuery([
223
            'table' => $this->table,
224
            'fields' => $this->fields,
225
            'join' => $this->join, 
226
            'leftJoin' => $this->leftJoin, 
227
            'rightJoin' => $this->rightJoin, 
228
            'crossJoin' => $this->crossJoin,
229
            'where' => $this->where, 
230
            'whereIn' => $this->whereIn, 
231
            'whereNotIn' => $this->whereNotIn, 
232
            'whereNull' => $this->whereNull, 
233
            'whereNotNull' => $this->whereNotNull,
234
            'groupBy' => $this->groupBy,
235
            'having' => $this->having,
236
            'orderBy' => $this->orderBy,
237
            'limit' => $this->limit,
238
            'offset' => $this->offset
239
        ]);
240
241
        return join(' ', $query);
242
    }
243
244
    protected function reset()
245
    {
246
        $this->fields = array();
247
        $this->table = null;
248
        $this->className = null;
249
        $this->groupBy = null;
250
        $this->orderBy = null;
251
        $this->having = null;
252
        $this->join = array();
253
        $this->leftJoin = array();
254
        $this->rightJoin = array();
255
        $this->crossJoin = array();
256
        $this->where = array();
257
        $this->whereIn = array();
258
        $this->whereNotIn = array();
259
        $this->whereNull = array();
260
        $this->whereNotNull = array();
261
        $this->limit = null;
262
        $this->offset = null;
263
    }
264
265
    public function prepare($query, $fetchRows = 'all')
266
    {
267
        $qb   = new QueryBuilder();
268
        $wqp  = new WhereQueryParser();
269
        $util = new Utils();
270
        
271
        try {
272
            $ar = $wqp->parseWhereQuery($this->where);
273
            $stmt = Connection::get()->prepare($qb->queryPrefix($query));
274
            $stmt->execute($ar);
275
276
            if ($fetchRows == 'first') {
277
                $rows = $stmt->fetch(\PDO::FETCH_OBJ);
278
                $this->results = $rows;
279
                // now turn this stdClass object to the object type of calling model
280
                $rows = $util->turnObject($this->className, $rows);
281
                // Reset class variables
282
                $this->reset();
283
284
                return $rows;
285
            }
286
287
            $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
288
            $this->results = $rows;
289
            $rows = $util->turnObjects($this->className, $rows);
290
291
            // Reset class variables
292
            $this->reset();
293
294
            return $rows;
295
        } catch (\PDOException $ex) {
296
            throw new \PDOException($ex->getMessage(), 1);
297
        } catch (Exception $e) {
298
            throw new Exception($e->getMessage(), 1);
299
        }
300
    }
301
302
    public function query($query, $fetchRows = 'all')
303
    {
304
        $qb = new QueryBuilder();
305
306
        try {
307
            $obj = Connection::get()->query($qb->queryPrefix($query), \PDO::FETCH_OBJ);
308
309
            if ($fetchRows == 'count') {
310
                $data = $obj->fetchColumn();
311
            }
312
313
            // Reset class variables
314
            $this->reset();
315
316
            return isset($data) ? $data : $obj;
317
        } catch (\PDOException $ex) {
318
            throw new \PDOException($ex->getMessage(), 1);
319
        } catch (Exception $e) {
320
            throw new Exception($e->getMessage(), 1);
321
        }
322
    }
323
324
    public function get()
325
    {
326
        return $this->prepare($this->buildQuery());
327
    }
328
329
    public function first()
330
    {
331
        $query = $this->buildQuery();
332
333
        if (!strripos($query, 'LIMIT 1')) {
334
            $query .= ' LIMIT 1';
335
        }
336
337
        return $this->prepare($query, 'first');
338
    }
339
340
    /**
341
     * It fetches the row by primary key
342
     * 
343
     * @since v0.0.5 
344
     */
345
    public function find($id)
346
    {
347
        $this->where('id = :id', $id);
348
        
349
        return $this->first();
350
    }
351
352
    /**
353
     * It fetches the row by primary key
354
     * 
355
     * @param int $id
356
     * @return object $row
357
     * @throws Exception
358
     * @since v0.0.5 
359
     */
360
    public function findOrFail($id)
361
    {
362
        $this->where('id = :id', $id);
363
        
364
        $row = $this->first();
365
366
        if($row == null ){
367
            throw new Exception("The record does not exists!");
368
        }
369
370
        return $row;
371
    }
372
373
    public function count()
374
    {
375
        $this->fields = null;
376
        $query = $this->buildQuery();
377
        $query = str_replace('SELECT * ', 'SELECT COUNT(*) as count ', $query);
378
379
        return $this->query($query, 'count');
380
    }
381
382
    /**
383
     * It truncates the table
384
     * 
385
     * @return boolean
386
     * @throws Exception
387
     * @since v0.0.5 
388
     */
389
    public function truncate()
390
    {
391
        $qb = new QueryBuilder();
392
        $query = "TRUNCATE ".$this->table;
393
        
394
        try{
395
            Connection::get()->query($qb->queryPrefix($query));
396
        } catch(Exception $e){
397
            throw new Exception($e->getMessage());
398
        }
399
400
        return true;
401
    }
402
403
    /**
404
     * It inserts the new rows
405
     * 
406
     * @param array $rows
407
     * @return integer $lastInsertedId
408
     * @throws Exception
409
     * @since v0.0.5 
410
     */
411
    public function insert($rows)
412
    {
413
        $iqb = new InsertQueryBuilder();
414
        return $iqb->insert($rows, $this->table);
415
    }
416
417
    /**
418
     * It updates the rows
419
     * 
420
     * @param array $row
421
     * @return boolean
422
     * @throws Exception
423
     * @since v0.0.5 
424
     */
425
    public function update($row)
426
    {
427
        $qb    = new QueryBuilder();
428
        $wqb   = new WhereQueryBuilder();
429
        $query = "UPDATE ".$this->table." SET ";
430
        $ar    = array();
431
        
432
        foreach($row as $key => $val){
433
            $ar[':'.$key] = $val;
434
            $query.= $qb->quote($key)." =:".$key.",";
435
        }
436
437
        $query = rtrim($query, ",");
438
        
439
        try{
440
            $whereQuery = $wqb->buildAllWhereQuery(
441
                                $this->where, 
442
                                $this->whereIn, 
443
                                $this->whereNotIn, 
444
                                $this->whereNull, 
445
                                $this->whereNotNull
446
                            );
447
            $query.= " ".join(" ", $whereQuery);
448
            $stmt = Connection::get()->prepare($qb->queryPrefix($query));
449
            $stmt->execute($ar);
450
            $this->reset();
451
        } catch(Exception $e){
452
            throw new Exception($e->getMessage());
453
        }
454
455
        return true;
456
    }
457
458
    /**
459
     * It deleted the rows matched by where clause
460
     * 
461
     * @return boolean
462
     * @throws Exception
463
     * @since v0.0.5 
464
     */
465
    public function delete()
466
    {
467
        $qb = new QueryBuilder();
468
        $wqb = new WhereQueryBuilder();
469
        $query = "DELETE FROM ".$this->table;
470
        
471
        try{
472
            $whereQuery = $wqb->buildAllWhereQuery(
473
                                    $this->where, 
474
                                    $this->whereIn, 
475
                                    $this->whereNotIn, 
476
                                    $this->whereNull, 
477
                                    $this->whereNotNull
478
                                );
479
            $query.= " ".join(" ", $whereQuery);
480
            Connection::get()->query($qb->queryPrefix($query));
481
            $this->reset();
482
        } catch(Exception $e){
483
            throw new Exception($e->getMessage());
484
        }
485
486
        return true;
487
    }
488
489
}
490