Passed
Push — master ( 84ef81...00604e )
by Darío
01:38
created

TableGateway::getLastQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * DronePHP (http://www.dronephp.com)
4
 *
5
 * @link      http://github.com/Pleets/DronePHP
6
 * @copyright Copyright (c) 2016-2018 Pleets. (http://www.pleets.org)
7
 * @license   http://www.dronephp.com/license
8
 * @author    Darío Rivera <[email protected]>
9
 */
10
11
namespace Drone\Db\TableGateway;
12
13
use Drone\Db\Entity;
14
use Drone\Db\SQLFunction;
15
use Drone\Exception;
16
17
/**
18
 * TableGateway class
19
 *
20
 * This class is a query builder for CRUD (create, read, update, delete)
21
 */
22
class TableGateway extends AbstractTableGateway implements TableGatewayInterface
23
{
24
    /**
25
     * The text with the last query executed
26
     *
27
     * @var string
28
     */
29
    protected $lastQuery;
30
31
    /**
32
     * An array with the last binded values
33
     *
34
     * @var array
35
     */
36
    protected $lastValues;
37
38
    /**
39
     * Returns the lastQuery
40
     *
41
     * @return string
42
     */
43
    public function getLastQuery()
44
    {
45
        return $this->lastQuery;
46
    }
47
48
    /**
49
     * Returns the lastValues
50
     *
51
     * @return array
52
     */
53
    public function getLastValues()
54
    {
55
        return $this->lastValues;
56
    }
57
58
    /**
59
     * Select statement
60
     *
61
     * @param array $where
62
     *
63
     * @return array With all results
64
     */
65
    public function select(Array $where = [])
66
    {
67
        $bind_values = [];
68
69
        $driver = $this->getDb()->getDriverName();
70
71
        if (count($where))
72
        {
73
            $parsed_where = [];
74
75
            $k = 0;
76
77
            foreach ($where as $key => $value)
78
            {
79
                $k++;
80
81
                if (is_null($value))
82
                    $parsed_where[] = "$key IS NULL";
83
                elseif ($value instanceof SQLFunction)
84
                    $parsed_where[] = "$key = " . $value->getStatement();
85
                elseif (is_array($value))
86
                {
87
                    $parsed_in = [];
88
89
                    foreach ($value as $in_value)
90
                    {
91
                        switch ($driver)
92
                        {
93
                            case 'Oci8':
94
                                $parsed_in[] = ":$k";
95
                                $bind_values[":$k"] = $in_value;
96
                                break;
97
98
                            case 'Mysqli' || 'Sqlsrv':
99
                                $parsed_in[] = "?";
100
                                $bind_values[] = $in_value;
101
                                break;
102
                        }
103
104
                        $k++;
105
                    }
106
107
                    $parsed_where[] = "$key IN (" . implode(", ", $parsed_in) . ")";
108
                }
109
                else
110
                {
111
                    switch ($driver)
112
                    {
113
                        case 'Oci8':
114
                            $parsed_where[] = "$key = :$k";
115
                            $bind_values[":$k"] = $value;
116
                            break;
117
118
                        case 'Mysqli' || 'Sqlsrv':
119
                            $parsed_where[] = "$key = ?";
120
                            $bind_values[] = $value;
121
                            break;
122
                    }
123
                }
124
            }
125
126
            $where = "WHERE \r\n\t" . implode(" AND\r\n\t", $parsed_where);
127
        }
128
        else
129
            $where = "";
130
131
        $table = $this->entity->getTableName();
132
133
        $sql = "SELECT * \r\nFROM {$table}\r\n$where";
134
135
        $this->lastQuery = $sql;
136
        $this->lastValues = $bind_values;
137
138
        if (count($bind_values))
139
            $this->getDb()->execute($sql, $bind_values);
140
        else
141
            $this->getDb()->execute($sql);
142
143
        return $this->getDb()->getArrayResult();
144
    }
145
146
    /**
147
     * Insert statement
148
     *
149
     * @param array $data
150
     *
151
     * @throws RuntimeException from internal execute()
152
     * @throws LogicException
153
     *
154
     * @return resource|object
155
     */
156
    public function insert(Array $data)
157
    {
158
        if (!count($data))
159
            throw new \LogicException("Missing values for INSERT statement!");
160
161
        $bind_values = [];
162
163
        $driver = $this->getDb()->getDriverName();
164
165
        $k = 0;
166
167
        $null_keys = [];
168
169
        foreach ($data as $key => $value)
170
        {
171
            $k++;
172
173
            # insert NULL values cause problems when BEFORE INSERT triggers are
174
            # defined to assigns values over fields. For SQLServer is better not
175
            # pass NULL values
176
            if ($driver == 'Sqlsrv' && is_null($value))
177
            {
178
                $null_keys[] = $key;
179
                continue;
180
            }
181
182
            if (is_null($value))
183
                $value = "NULL";
184
            elseif ($value instanceof SQLFunction)
185
                $value = $value->getStatement();
186
            else {
187
188
                switch ($driver)
189
                {
190
                    case 'Oci8':
191
                        $bind_values[":$k"] = $value;
192
                        $value = ":$k";
193
                        break;
194
195
                    case 'Mysqli' || 'Sqlsrv':
196
                        $bind_values[] = $value;
197
                        $value = "?";
198
                        break;
199
                }
200
            }
201
202
            $data[$key] = $value;
203
        }
204
205
        foreach ($null_keys as $key)
206
        {
207
            unset($data[$key]);
208
        }
209
210
        $cols = implode(",\r\n\t", array_keys($data));
211
        $vals = implode(",\r\n\t", array_values($data));
212
213
        $table = $this->entity->getTableName();
214
215
        $sql = "INSERT INTO {$table} \r\n(\r\n\t$cols\r\n) \r\nVALUES \r\n(\r\n\t$vals\r\n)";
216
217
        $this->lastQuery = $sql;
218
        $this->lastValues = $bind_values;
219
220
        return $this->getDb()->execute($sql, $bind_values);
221
    }
222
223
    /**
224
     * Update statement
225
     *
226
     * @param array $set
227
     * @param array $where
228
     *
229
     * @throws RuntimeException from internal execute()
230
     * @throws LogicException
231
     * @throws SecurityException
232
     *
233
     * @return resource|object
234
     */
235
    public function update(Array $set, Array $where)
236
    {
237
        $parsed_set = [];
238
239
        if (!count($set))
240
            throw new \LogicException("You cannot update rows without SET clause");
241
242
        if (!count($where))
243
            throw new SecurityException("You cannot update rows without WHERE clause!");
0 ignored issues
show
Bug introduced by
The type Drone\Db\TableGateway\SecurityException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
244
245
        $bind_values = [];
246
247
        $driver = $this->getDb()->getDriverName();
248
249
        $k = 0;
250
251
        foreach ($set as $key => $value)
252
        {
253
            $k++;
254
255
            if (is_null($value))
256
                $parsed_set[] = "$key = NULL";
257
            elseif ($value instanceof SQLFunction)
258
                $parsed_set[] = "$key = " . $value->getStatement();
259
            elseif (is_array($value))
260
            {
261
                $parsed_in = [];
262
263
                foreach ($value as $in_value)
264
                {
265
                    switch ($driver)
266
                    {
267
                        case 'Oci8':
268
269
                            # [POSSIBLE BUG] - To Future revision (What about non-string values ?)
270
                            if (is_string($in_value))
271
                                $parsed_in[] = ":$k";
272
273
                            $bind_values[":$k"] = $in_value;
274
                            break;
275
276
                        case 'Mysqli' || 'Sqlsrv':
277
                            $parsed_in[] = "?";
278
                            $bind_values[] = $in_value;
279
                            break;
280
                    }
281
282
                    $k++;
283
                }
284
285
                $parsed_set[] = "$key IN (" . implode(", ", $parsed_in) . ")";
286
            }
287
            else
288
            {
289
                switch ($driver)
290
                {
291
                    case 'Oci8':
292
                        $parsed_set[] = "$key = :$k";
293
                        $bind_values[":$k"] = $value;
294
                        break;
295
296
                    case 'Mysqli' || 'Sqlsrv':
297
                        $parsed_set[] = "$key = ?";
298
                        $bind_values[] = $value;
299
                        break;
300
                }
301
            }
302
        }
303
304
        $parsed_set = implode(",\r\n\t", $parsed_set);
305
306
        $parsed_where = [];
307
308
        foreach ($where as $key => $value)
309
        {
310
            $k++;
311
312
            if (is_null($value))
313
                $parsed_where[] = "$key IS NULL";
314
            elseif ($value instanceof SQLFunction)
315
                $parsed_where[] = "$key = " . $value->getStatement();
316
            elseif (is_array($value))
317
            {
318
                $parsed_in = [];
319
320
                foreach ($value as $in_value)
321
                {
322
                    switch ($driver)
323
                    {
324
                        case 'Oci8':
325
                            $parsed_in[] = ":$k";
326
                            $bind_values[":$k"] = $in_value;
327
                            break;
328
329
                        case 'Mysqli' || 'Sqlsrv':
330
                            $parsed_in[] = "?";
331
                            $bind_values[] = $in_value;
332
                            break;
333
                    }
334
335
                    $k++;
336
                }
337
338
                $parsed_where[] = "$key IN (" . implode(", ", $parsed_in) . ")";
339
            }
340
            else
341
            {
342
                switch ($driver)
343
                {
344
                    case 'Oci8':
345
                        $parsed_where[] = "$key = :$k";
346
                        $bind_values[":$k"] = $value;
347
                        break;
348
349
                    case 'Mysqli' || 'Sqlsrv':
350
                        $parsed_where[] = "$key = ?";
351
                        $bind_values[] = $value;
352
                        break;
353
                }
354
            }
355
        }
356
357
        $parsed_where = implode(" AND\r\n\t", $parsed_where);
358
359
        $table = $this->entity->getTableName();
360
361
        $sql = "UPDATE {$table} \r\nSET \r\n\t$parsed_set \r\nWHERE \r\n\t$parsed_where";
362
363
        $this->lastQuery = $sql;
364
        $this->lastValues = $bind_values;
365
366
        return $this->getDb()->execute($sql, $bind_values);
367
    }
368
369
    /**
370
     * Delete statement
371
     *
372
     * @param array $where
373
     *
374
     * @throws RuntimeException from internal execute()
375
     * @throws SecurityException
376
     *
377
     * @return resource|object
378
     */
379
    public function delete(Array $where)
380
    {
381
        if (count($where))
382
        {
383
            $parsed_where = [];
384
385
            $bind_values = [];
386
387
            $driver = $this->getDb()->getDriverName();
388
389
            $k = 0;
390
391
            foreach ($where as $key => $value)
392
            {
393
                $k++;
394
395
                if (is_null($value))
396
                    $parsed_where[] = "$key IS NULL";
397
                elseif ($value instanceof SQLFunction)
398
                    $parsed_where[] = "$key = " . $value->getStatement();
399
                elseif (is_array($value))
400
                {
401
                    $parsed_in = [];
402
403
                    foreach ($value as $in_value)
404
                    {
405
                        switch ($driver)
406
                        {
407
                            case 'Oci8':
408
                                $parsed_in[] = ":$k";
409
                                $bind_values[":$k"] = $in_value;
410
                                break;
411
412
                            case 'Mysqli' || 'Sqlsrv':
413
                                $parsed_in[] = "?";
414
                                $bind_values[] = $in_value;
415
                                break;
416
                        }
417
418
                        $k++;
419
                    }
420
421
                    $parsed_where[] = "$key IN (" . implode(", ", $parsed_in) . ")";
422
                }
423
                else
424
                {
425
                    switch ($driver)
426
                    {
427
                        case 'Oci8':
428
                            $parsed_where[] = "$key = :$k";
429
                            $bind_values[":$k"] = $value;
430
                            break;
431
432
                        case 'Mysqli' || 'Sqlsrv':
433
                            $parsed_where[] = "$key = ?";
434
                            $bind_values[] = $value;
435
                            break;
436
                    }
437
                }
438
            }
439
440
            $where = "\r\nWHERE \r\n\t" . implode(" AND\r\n\t", $parsed_where);
441
        }
442
        else
443
            throw new SecurityException("You cannot delete rows without WHERE clause!. Use TRUNCATE statement instead.");
444
445
        $table = $this->entity->getTableName();
446
447
        $sql = "DELETE FROM {$table} $where";
448
449
        $this->lastQuery = $sql;
450
        $this->lastValues = $bind_values;
451
452
        return $this->getDb()->execute($sql, $bind_values);
453
    }
454
}