TableGateway::getLastValues()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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