Completed
Push — master ( 49228f...024767 )
by Henry Stivens
02:39
created

DbMySQLi   C

Complexity

Total Complexity 66

Size/Duplication

Total Lines 448
Duplicated Lines 31.92 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 143
loc 448
rs 5.7474
c 0
b 0
f 0
wmc 66
lcom 1
cbo 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like DbMySQLi often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DbMySQLi, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * KumbiaPHP web & app Framework
4
 *
5
 * LICENSE
6
 *
7
 * This source file is subject to the new BSD license that is bundled
8
 * with this package in the file LICENSE.txt.
9
 * It is also available through the world-wide-web at this URL:
10
 * http://wiki.kumbiaphp.com/Licencia
11
 * If you did not receive a copy of the license and are unable to
12
 * obtain it through the world-wide-web, please send an email
13
 * to [email protected] so we can send you a copy immediately.
14
 *
15
 * @category   Kumbia
16
 * @package    Db
17
 * @subpackage Adapters
18
 * @copyright  Copyright (c) 2005 - 2017 Kumbia Team (http://www.kumbiaphp.com)
19
 * @license    http://wiki.kumbiaphp.com/Licencia     New BSD License
20
 */
21
22
/**
23
 * MySQL Improved Database Support
24
 *
25
 * @category   Kumbia
26
 * @package    Db
27
 * @subpackage Adapters
28
 */
29
class DbMySQLi extends DbBase implements DbBaseInterface
30
{
31
32
    /**
33
     * Resource de la Conexión a MySQL
34
     *
35
     * @var resource
36
     */
37
    public $id_connection;
38
    /**
39
     * Último Resultado de una Query
40
     *
41
     * @var resource
42
     */
43
    public $last_result_query;
44
    /**
45
     * Última sentencia SQL enviada a MySQL
46
     *
47
     * @var string
48
     */
49
    protected $last_query;
50
    /**
51
     * Último error generado por MySQL
52
     *
53
     * @var string
54
     */
55
    public $last_error;
56
57
    /**
58
     * Resultado de Array Asociativo
59
     *
60
     */
61
    const DB_ASSOC = MYSQLI_ASSOC;
62
63
    /**
64
     * Resultado de Array Asociativo y Númerico
65
     *
66
     */
67
    const DB_BOTH = MYSQLI_BOTH;
68
69
    /**
70
     * Resultado de Array Númerico
71
     *
72
     */
73
    const DB_NUM = MYSQLI_NUM;
74
75
76
    /**
77
     * Tipo de Dato Integer
78
     *
79
     */
80
    const TYPE_INTEGER = 'INTEGER';
81
82
    /**
83
     * Tipo de Dato Date
84
     *
85
     */
86
    const TYPE_DATE = 'DATE';
87
88
    /**
89
     * Tipo de Dato Varchar
90
     *
91
     */
92
    const TYPE_VARCHAR = 'VARCHAR';
93
94
    /**
95
     * Tipo de Dato Decimal
96
     *
97
     */
98
    const TYPE_DECIMAL = 'DECIMAL';
99
100
    /**
101
     * Tipo de Dato Datetime
102
     *
103
     */
104
    const TYPE_DATETIME = 'DATETIME';
105
106
    /**
107
     * Tipo de Dato Char
108
     *
109
     */
110
    const TYPE_CHAR = 'CHAR';
111
112
    /**
113
     * Hace una conexión a la base de datos de MySQL
114
     *
115
     * @param array $config
116
     * @return bool
117
     */
118
    public function connect($config)
119
    {
120
        if (!extension_loaded('mysqli')) throw new KumbiaException('Debe cargar la extensión de PHP llamada php_mysqli');
121
122
        $this->id_connection = new mysqli($config['host'], $config['username'], $config['password'], $config['name'], $config['port']);
123
        //no se usa $object->error() ya que solo funciona a partir de 5.2.9 y 5.3
124
        if (mysqli_connect_error ()) throw new KumbiaException(mysqli_connect_error());
125
        //Selecciona charset
126
        if (isset($config['charset'])) $this->id_connection->set_charset($config['charset']);
127
        return TRUE;
128
    }
129
130
    /**
131
     * Efectua operaciones SQL sobre la base de datos
132
     *
133
     * @param string $sql_query
134
     * @return resource or false
135
     */
136
    public function query($sql_query)
137
    {
138
        $this->debug($sql_query);
139
        if ($this->logger) {
140
            Logger::debug($sql_query);
141
        }
142
143
        $this->last_query = $sql_query;
144
        if ($result_query = mysqli_query($this->id_connection, $sql_query)) {
145
            $this->last_result_query = $result_query;
146
            return $result_query;
147
        } else {
148
            throw new KumbiaException($this->error(" al ejecutar <em>\"$sql_query\"</em>"));
149
        }
150
    }
151
152
    /**
153
     * Cierra la Conexión al Motor de Base de datos
154
     *
155
     * @return boolean
156
     */
157
    public function close()
158
    {
159
        if ($this->id_connection) {
160
            return mysqli_close($this->id_connection);
161
        }
162
    }
163
164
    /**
165
     * Devuelve fila por fila el contenido de un select
166
     *
167
     * @param resource $result_query
168
     * @param int $opt
169
     * @return array
170
     */
171
    public function fetch_array($result_query='', $opt=MYSQLI_BOTH)
172
    {
173
        if (!$result_query) {
174
            $result_query = $this->last_result_query;
175
            if (!$result_query) {
176
                return false;
177
            }
178
        }
179
        return mysqli_fetch_array($result_query, $opt);
180
    }
181
182
    /**
183
     * Constructor de la Clase
184
     *
185
     * @param array $config
186
     */
187
    public function __construct($config)
188
    {
189
        $this->connect($config);
190
    }
191
192
    /**
193
     * Devuelve el numero de filas de un select
194
     */
195
    public function num_rows($result_query='')
196
    {
197
        if (!$result_query) {
198
            $result_query = $this->last_result_query;
199
            if (!$result_query) {
200
                return false;
201
            }
202
        }
203
        if (($number_rows = mysqli_num_rows($result_query)) !== false) {
204
            return $number_rows;
205
        } else {
206
            throw new KumbiaException($this->error());
207
        }
208
    }
209
210
    /**
211
     * Devuelve el nombre de un campo en el resultado de un select
212
     *
213
     * @param int $number
214
     * @param resource $result_query
215
     * @return string
216
     */
217
    public function field_name($number, $result_query='')
218
    {
219
220
        if (!$result_query) {
221
            $result_query = $this->last_result_query;
222
            if (!$result_query) {
223
                return false;
224
            }
225
        }
226
        if (($fieldName = mysqli_field_seek($result_query, $number)) !== false) {
227
            $field = mysqli_fetch_field($result_query);
228
            return $field->name;
229
        } else {
230
            throw new KumbiaException($this->error());
231
        }
232
    }
233
234
    /**
235
     * Se Mueve al resultado indicado por $number en un select
236
     *
237
     * @param int $number
238
     * @param resource $result_query
239
     * @return boolean
240
     */
241
    public function data_seek($number, $result_query='')
242
    {
243
        if (!$result_query) {
244
            $result_query = $this->last_result_query;
245
            if (!$result_query) {
246
                return false;
247
            }
248
        }
249
        if (($success = mysqli_data_seek($result_query, $number)) !== false) {
250
            return $success;
251
        } else {
252
            throw new KumbiaException($this->error());
253
        }
254
    }
255
256
    /**
257
     * Numero de Filas afectadas en un insert, update o delete
258
     *
259
     * @param resource $result_query
260
     * @return int
261
     */
262
    public function affected_rows($result_query='')
263
    {
264
        if (($numberRows = mysqli_affected_rows($this->id_connection)) !== false) {
265
            return $numberRows;
266
        } else {
267
            throw new KumbiaException($this->error());
268
        }
269
    }
270
271
    /**
272
     * Devuelve el error de MySQL
273
     *
274
     * @return string
275
     */
276
    public function error($err='')
277
    {
278
        $this->last_error = mysqli_error($this->id_connection) ? mysqli_error($this->id_connection) : "[Error Desconocido en MySQL: $err]";
279
        $this->last_error.= $err;
280
        if ($this->logger) {
281
            Logger::error($this->last_error);
282
        }
283
        return $this->last_error;
284
    }
285
286
    /**
287
     * Devuelve el no error de MySQL
288
     *
289
     * @return int
290
     */
291
    public function no_error()
292
    {
293
        return mysqli_errno($this->id_connection);
294
    }
295
296
    /**
297
     * Devuelve el ultimo id autonumerico generado en la BD
298
     *
299
     * @return int
300
     */
301
    public function last_insert_id($table='', $primary_key='')
302
    {
303
        return mysqli_insert_id($this->id_connection);
304
    }
305
306
    /**
307
     * Verifica si una tabla existe o no
308
     *
309
     * @param string $table
310
     * @return boolean
311
     */
312
    public function table_exists($table, $schema='')
313
    {
314
        $table = addslashes("$table");
315
        if ($schema == '') {
316
            $num = $this->fetch_one("select count(*) from information_schema.tables where table_name = '$table'");
317
        } else {
318
            $schema = addslashes("$schema");
319
            $num = $this->fetch_one("select count(*) from information_schema.tables where table_name = '$table' and table_schema = '$schema'");
320
        }
321
        return $num[0];
322
    }
323
324
    /**
325
     * Devuelve un LIMIT valido para un SELECT del RBDM
326
     *
327
     * @param string $sql consulta sql
328
     * @return string
329
     */
330
    public function limit($sql)
331
    {
332
        $params = Util::getParams(func_get_args());
333
        $sql_new = $sql;
334
335
        if (isset($params['limit']) && is_numeric($params['limit'])) {
336
            $sql_new.=" LIMIT $params[limit]";
337
        }
338
339
        if (isset($params['offset']) && is_numeric($params['offset'])) {
340
            $sql_new.=" OFFSET $params[offset]";
341
        }
342
343
        return $sql_new;
344
    }
345
346
    /**
347
     * Borra una tabla de la base de datos
348
     *
349
     * @param string $table
350
     * @return resource
351
     */
352
    public function drop_table($table, $if_exists=true)
353
    {
354
        if ($if_exists) {
355
            return $this->query("DROP TABLE IF EXISTS $table");
356
        } else {
357
            return $this->query("DROP TABLE $table");
358
        }
359
    }
360
361
    /**
362
     * Crea una tabla utilizando SQL nativo del RDBM
363
     *
364
     * TODO:
365
     * - Falta que el parametro index funcione. Este debe listar indices compuestos multipes y unicos
366
     * - Agregar el tipo de tabla que debe usarse (MySQL)
367
     * - Soporte para campos autonumericos
368
     * - Soporte para llaves foraneas
369
     *
370
     * @param string $table
371
     * @param array $definition
372
     * @return resource
373
     */
374
    public function create_table($table, $definition, $index=array())
375
    {
376
        $create_sql = "CREATE TABLE $table (";
377
        if (!is_array($definition)) {
378
            throw new KumbiaException("Definición invalida para crear la tabla '$table'");
379
        }
380
        $create_lines = array();
381
        $index = array();
382
        $unique_index = array();
383
        $primary = array();
384
        //$not_null = "";
385
        //$size = "";
386
        foreach ($definition as $field => $field_def) {
387
            if (isset($field_def['not_null'])) {
388
                $not_null = $field_def['not_null'] ? 'NOT NULL' : '';
389
            } else {
390
                $not_null = "";
391
            }
392
            if (isset($field_def['size'])) {
393
                $size = $field_def['size'] ? '(' . $field_def['size'] . ')' : '';
394
            } else {
395
                $size = "";
396
            }
397
            if (isset($field_def['index'])) {
398
                if ($field_def['index']) {
399
                    $index[] = "INDEX(`$field`)";
400
                }
401
            }
402
            if (isset($field_def['unique_index'])) {
403
                if ($field_def['unique_index']) {
404
                    $index[] = "UNIQUE(`$field`)";
405
                }
406
            }
407
            if (isset($field_def['primary'])) {
408
                if ($field_def['primary']) {
409
                    $primary[] = "`$field`";
410
                }
411
            }
412
            if (isset($field_def['auto'])) {
413
                if ($field_def['auto']) {
414
                    $field_def['extra'] = isset($field_def['extra']) ? $field_def['extra'] . " AUTO_INCREMENT" : "AUTO_INCREMENT";
415
                }
416
            }
417
            if (isset($field_def['extra'])) {
418
                $extra = $field_def['extra'];
419
            } else {
420
                $extra = "";
421
            }
422
            $create_lines[] = "`$field` " . $field_def['type'] . $size . ' ' . $not_null . ' ' . $extra;
423
        }
424
        $create_sql.= join(',', $create_lines);
425
        $last_lines = array();
426
        if (count($primary)) {
427
            $last_lines[] = 'PRIMARY KEY(' . join(",", $primary) . ')';
428
        }
429
        if (count($index)) {
430
            $last_lines[] = join(',', $index);
431
        }
432
        if (count($unique_index)) {
433
            $last_lines[] = join(',', $unique_index);
434
        }
435
        if (count($last_lines)) {
436
            $create_sql.= ',' . join(',', $last_lines) . ')';
437
        }
438
        return $this->query($create_sql);
439
    }
440
441
    /**
442
     * Listar las tablas en la base de datos
443
     *
444
     * @return array
445
     */
446
    public function list_tables()
447
    {
448
        return $this->fetch_all("SHOW TABLES");
449
    }
450
451
    /**
452
     * Listar los campos de una tabla
453
     *
454
     * @param string $table
455
     * @return array
456
     */
457
    public function describe_table($table, $schema='')
458
    {
459
        if ($schema == '') {
460
            return $this->fetch_all("DESCRIBE `$table`");
461
        } else {
462
            return $this->fetch_all("DESCRIBE `$schema`.`$table`");
463
        }
464
    }
465
466
    /**
467
     * Devuelve la ultima sentencia sql ejecutada por el Adaptador
468
     *
469
     * @return string
470
     */
471
    public function last_sql_query()
472
    {
473
        return $this->last_query;
474
    }
475
476
}
477