Passed
Push — master ( 910238...2d3e1b )
by Darío
02:38
created

TableGateway::update()   D

Complexity

Conditions 26
Paths 112

Size

Total Lines 129
Code Lines 75

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 26
eloc 75
nc 112
nop 2
dl 0
loc 129
rs 4.0666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
 * 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
     * Entity instance
26
     *
27
     * @var Entity
28
     */
29
    private $entity;
30
31
    /**
32
     * Returns the entity
33
     *
34
     * @return Entity
35
     */
36
    public function getEntity()
37
    {
38
        return $this->entity;
39
    }
40
41
    /**
42
     * Constructor
43
     *
44
     * @param Entity $entity
45
     * @param boolean $auto_connect
46
     */
47
    public function __construct(Entity $entity, $auto_connect = true)
48
    {
49
        parent::__construct($entity->getConnectionIdentifier(), $auto_connect);
50
        $this->entity = $entity;
51
    }
52
53
    /**
54
     * Select statement
55
     *
56
     * @param array $where
57
     *
58
     * @return array With all results
59
     */
60
    public function select(Array $where = [])
61
    {
62
        $bind_values = [];
63
64
        $driver = $this->getDriver()->getDriverName();
65
66
        if (count($where))
67
        {
68
            $parsed_where = [];
69
70
            $k = 0;
71
72
            foreach ($where as $key => $value)
73
            {
74
                $k++;
75
76
                if (is_null($value))
77
                    $parsed_where[] = "$key IS NULL";
78
                elseif ($value instanceof SQLFunction)
79
                    $parsed_where[] = "$key = " . $value->getStatement();
80
                elseif (is_array($value))
81
                {
82
                    $parsed_in = [];
83
84
                    foreach ($value as $in_value)
85
                    {
86
                        switch ($driver)
87
                        {
88
                            case 'Oci8':
89
                                $parsed_in[] = ":$k";
90
                                $bind_values[":$k"] = $in_value;
91
                                break;
92
93
                            case 'Mysqli' || 'Sqlsrv':
94
                                $parsed_in[] = "?";
95
                                $bind_values[] = $in_value;
96
                                break;
97
                        }
98
99
                        $k++;
100
                    }
101
102
                    $parsed_where[] = "$key IN (" . implode(", ", $parsed_in) . ")";
103
                }
104
                else
105
                {
106
                    switch ($driver)
107
                    {
108
                        case 'Oci8':
109
                            $parsed_where[] = "$key = :$k";
110
                            $bind_values[":$k"] = $value;
111
                            break;
112
113
                        case 'Mysqli' || 'Sqlsrv':
114
                            $parsed_where[] = "$key = ?";
115
                            $bind_values[] = $value;
116
                            break;
117
                    }
118
                }
119
            }
120
121
            $where = "WHERE \r\n\t" . implode(" AND\r\n\t", $parsed_where);
122
        }
123
        else
124
            $where = "";
125
126
        $table = $this->entity->getTableName();
127
128
        $sql = "SELECT * \r\nFROM {$table}\r\n$where";
129
130
        if (count($bind_values))
131
            $this->getDriver()->getDb()->execute($sql, $bind_values);
132
        else
133
            $this->getDriver()->getDb()->execute($sql);
134
135
        return $this->getDriver()->getDb()->getArrayResult();
136
    }
137
138
    /**
139
     * Insert statement
140
     *
141
     * @param array $data
142
     *
143
     * @throws RuntimeException from internal execute()
144
     * @throws LogicException
145
     *
146
     * @return resource|object
147
     */
148
    public function insert(Array $data)
149
    {
150
        if (!count($data))
151
            throw new \LogicException("Missing values for INSERT statement!");
152
153
        $bind_values = [];
154
155
        $driver = $this->getDriver()->getDriverName();
156
157
        $k = 0;
158
159
        $null_keys = [];
160
161
        foreach ($data as $key => $value)
162
        {
163
            $k++;
164
165
            # insert NULL values cause problems when BEFORE INSERT triggers are
166
            # defined to assigns values over fields. For SQLServer is better not
167
            # pass NULL values
168
            if ($driver == 'Sqlsrv' && is_null($value))
169
            {
170
                $null_keys[] = $key;
171
                continue;
172
            }
173
174
            if (is_null($value))
175
                $value = "NULL";
176
            elseif ($value instanceof SQLFunction)
177
                $value = $value->getStatement();
178
            else {
179
180
                switch ($driver)
181
                {
182
                    case 'Oci8':
183
                        $bind_values[":$k"] = $value;
184
                        $value = ":$k";
185
                        break;
186
187
                    case 'Mysqli' || 'Sqlsrv':
188
                        $bind_values[] = $value;
189
                        $value = "?";
190
                        break;
191
                }
192
            }
193
194
            $data[$key] = $value;
195
        }
196
197
        foreach ($null_keys as $key)
198
        {
199
            unset($data[$key]);
200
        }
201
202
        $cols = implode(",\r\n\t", array_keys($data));
203
        $vals = implode(",\r\n\t", array_values($data));
204
205
        $table = $this->entity->getTableName();
206
207
        $sql = "INSERT INTO {$table} \r\n(\r\n\t$cols\r\n) \r\nVALUES \r\n(\r\n\t$vals\r\n)";
208
209
        return $this->getDriver()->getDb()->execute($sql, $bind_values);
210
    }
211
212
    /**
213
     * Update statement
214
     *
215
     * @param array $set
216
     * @param array $where
217
     *
218
     * @throws RuntimeException from internal execute()
219
     * @throws LogicException
220
     * @throws SecurityException
221
     *
222
     * @return resource|object
223
     */
224
    public function update(Array $set, Array $where)
225
    {
226
        $parsed_set = [];
227
228
        if (!count($set))
229
            throw new \LogicException("You cannot update rows without SET clause");
230
231
        if (!count($where))
232
            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...
233
234
        $bind_values = [];
235
236
        $driver = $this->getDriver()->getDriverName();
237
238
        $k = 0;
239
240
        foreach ($set as $key => $value)
241
        {
242
            $k++;
243
244
            if (is_null($value))
245
                $parsed_set[] = "$key = NULL";
246
            elseif ($value instanceof SQLFunction)
247
                $parsed_set[] = "$key = " . $value->getStatement();
248
            elseif (is_array($value))
249
            {
250
                $parsed_in = [];
251
252
                foreach ($value as $in_value)
253
                {
254
                    switch ($driver)
255
                    {
256
                        case 'Oci8':
257
258
                            # [POSSIBLE BUG] - To Future revision (What about non-string values ?)
259
                            if (is_string($in_value))
260
                                $parsed_in[] = ":$k";
261
262
                            $bind_values[":$k"] = $in_value;
263
                            break;
264
265
                        case 'Mysqli' || 'Sqlsrv':
266
                            $parsed_in[] = "?";
267
                            $bind_values[] = $in_value;
268
                            break;
269
                    }
270
271
                    $k++;
272
                }
273
274
                $parsed_set[] = "$key IN (" . implode(", ", $parsed_in) . ")";
275
            }
276
            else
277
            {
278
                switch ($driver)
279
                {
280
                    case 'Oci8':
281
                        $parsed_set[] = "$key = :$k";
282
                        $bind_values[":$k"] = $value;
283
                        break;
284
285
                    case 'Mysqli' || 'Sqlsrv':
286
                        $parsed_set[] = "$key = ?";
287
                        $bind_values[] = $value;
288
                        break;
289
                }
290
            }
291
        }
292
293
        $parsed_set = implode(",\r\n\t", $parsed_set);
294
295
        $parsed_where = [];
296
297
        foreach ($where as $key => $value)
298
        {
299
            $k++;
300
301
            if (is_null($value))
302
                $parsed_where[] = "$key IS NULL";
303
            elseif ($value instanceof SQLFunction)
304
                $parsed_where[] = "$key = " . $value->getStatement();
305
            elseif (is_array($value))
306
            {
307
                $parsed_in = [];
308
309
                foreach ($value as $in_value)
310
                {
311
                    switch ($driver)
312
                    {
313
                        case 'Oci8':
314
                            $parsed_in[] = ":$k";
315
                            $bind_values[":$k"] = $in_value;
316
                            break;
317
318
                        case 'Mysqli' || 'Sqlsrv':
319
                            $parsed_in[] = "?";
320
                            $bind_values[] = $in_value;
321
                            break;
322
                    }
323
324
                    $k++;
325
                }
326
327
                $parsed_where[] = "$key IN (" . implode(", ", $parsed_in) . ")";
328
            }
329
            else
330
            {
331
                switch ($driver)
332
                {
333
                    case 'Oci8':
334
                        $parsed_where[] = "$key = :$k";
335
                        $bind_values[":$k"] = $value;
336
                        break;
337
338
                    case 'Mysqli' || 'Sqlsrv':
339
                        $parsed_where[] = "$key = ?";
340
                        $bind_values[] = $value;
341
                        break;
342
                }
343
            }
344
        }
345
346
        $parsed_where = implode(" AND\r\n\t", $parsed_where);
347
348
        $table = $this->entity->getTableName();
349
350
        $sql = "UPDATE {$table} \r\nSET \r\n\t$parsed_set \r\nWHERE \r\n\t$parsed_where";
351
352
        return $this->getDriver()->getDb()->execute($sql, $bind_values);
353
    }
354
355
    /**
356
     * Delete statement
357
     *
358
     * @param array $where
359
     *
360
     * @throws RuntimeException from internal execute()
361
     * @throws SecurityException
362
     *
363
     * @return resource|object
364
     */
365
    public function delete(Array $where)
366
    {
367
        if (count($where))
368
        {
369
            $parsed_where = [];
370
371
            $bind_values = [];
372
373
            $driver = $this->getDriver()->getDriverName();
374
375
            $k = 0;
376
377
            foreach ($where as $key => $value)
378
            {
379
                $k++;
380
381
                if (is_null($value))
382
                    $parsed_where[] = "$key IS NULL";
383
                elseif ($value instanceof SQLFunction)
384
                    $parsed_where[] = "$key = " . $value->getStatement();
385
                elseif (is_array($value))
386
                {
387
                    $parsed_in = [];
388
389
                    foreach ($value as $in_value)
390
                    {
391
                        switch ($driver)
392
                        {
393
                            case 'Oci8':
394
                                $parsed_in[] = ":$k";
395
                                $bind_values[":$k"] = $in_value;
396
                                break;
397
398
                            case 'Mysqli' || 'Sqlsrv':
399
                                $parsed_in[] = "?";
400
                                $bind_values[] = $in_value;
401
                                break;
402
                        }
403
404
                        $k++;
405
                    }
406
407
                    $parsed_where[] = "$key IN (" . implode(", ", $parsed_in) . ")";
408
                }
409
                else
410
                {
411
                    switch ($driver)
412
                    {
413
                        case 'Oci8':
414
                            $parsed_where[] = "$key = :$k";
415
                            $bind_values[":$k"] = $value;
416
                            break;
417
418
                        case 'Mysqli' || 'Sqlsrv':
419
                            $parsed_where[] = "$key = ?";
420
                            $bind_values[] = $value;
421
                            break;
422
                    }
423
                }
424
            }
425
426
            $where = "\r\nWHERE \r\n\t" . implode(" AND\r\n\t", $parsed_where);
427
        }
428
        else
429
            throw new SecurityException("You cannot delete rows without WHERE clause!. Use TRUNCATE statement instead.");
430
431
        $table = $this->entity->getTableName();
432
433
        $sql = "DELETE FROM {$table} $where";
434
435
        return $this->getDriver()->getDb()->execute($sql, $bind_values);
436
    }
437
}