Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
14.78% covered (danger)
14.78%
17 / 115
7.41% covered (danger)
7.41%
2 / 27
CRAP
0.00% covered (danger)
0.00%
0 / 1
ia_singleread
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
ia_singleton
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
ia_singletonFull
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
ia_sqlArray
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
ia_sqlArrayIndx
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
ia_sqlVector
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
ia_sqlKeyValue
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
ia_sqlSelectMultiKey
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
ia_transaction
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
3.07
ia_begin
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
ia_commit
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
ia_rollback
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
ia_query
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
ia_nontransaction
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
ia_insertIded
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
trace_sql
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
sql_trace_get
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
last_inserted_id
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
affected_rows
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
getMetaData
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
metaDataOnSet
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
assoc_mysql2mysqli
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
ia_SqlOptions
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
132
ia_echoSqlOptions
n/a
0 / 0
n/a
0 / 0
5
sqlMysqli
16.67% covered (danger)
16.67%
3 / 18
0.00% covered (danger)
0.00%
0 / 3
67.87
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 log_sql_error
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 log_trace
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
5.02
1<?php
2
3/** @noinspection PhpMissingReturnTypeInspection */
4/** @noinspection PhpMissingParamTypeInspection */
5
6
7/**
8 * 2021-12-18 todo verde
9 */
10
11/**
12 * Funciones para accesar los metodos de la clase IacMysqli
13 *
14 * @version 2021-12-02
15 */
16
17
18use Iac\inc\sql\IacMysqli;
19use Iac\inc\sql\IacSqlException;
20
21if(!defined('MYSQL_ASSOC'))
22        define('MYSQL_ASSOC', MYSQLI_ASSOC);
23    if(!defined('MYSQL_NUM'))
24        define('MYSQL_NUM', MYSQLI_NUM);
25    if(!defined('MYSQL_BOTH'))
26        define('MYSQL_BOTH', MYSQLI_BOTH);
27require_once(__DIR__.'/sql/IacMysqli.php');
28require_once(__DIR__.'/sql/IacSqlInfo.php');
29require_once(__DIR__.'/sql/IacSQLMultipleInsert.php');
30require_once(__DIR__.'/sql/IacSqlBuilder.php');
31
32    class sqlMysqli extends IacMysqli {
33
34        public function __construct($host=null, $username=null, $passwd=null, $dbname='', $port=null, $socket=null) {
35        global $gIAsql;
36            if(isset($gIAsql['trace']))
37                $this->traceOn = true;
38            @parent::__construct($host,$username,$passwd,$dbname,$port,$socket);
39            if(isset($gIAsql['trace']))
40                $this->traceOn = true;
41
42        }
43
44        /**
45         * IacMysqli::log_sql_error()
46         * Stores an error for later processing
47         *
48         * @param string $sql sql command that caused the error
49         * @param int $retries number of times this command has been re-sent to the server
50         * @param bool $putMysqliError true include the error from mysqli, false the error is included in $sql
51         * @return void
52         * @see IacMysqli::$errorLog IacMysqli::$errorLog
53         * @access public
54         */
55        public function log_sql_error($sql, $retries=0, $putMysqliError=true) {
56            /** @noinspection DuplicatedCode */ global
57            $gIAsql;
58
59            $retry = $retries === 0 ? '' : " -- retries: $retries";
60            if($putMysqliError === false) {
61                $gIAsql['err'].='<li>'.$sql.$retry;
62            } else {
63                $gIAsql['err'].='<li>'.$this->mysqli->errno.' '.$this->mysqli->error.'<br />'.$sql.$retry;
64                $gIAsql['errno'] = $this->mysqli->errno;
65                $gIAsql['error'] = $this->mysqli->error;
66                $gIAsql['sql_error'] = $sql;
67            }
68            parent::log_sql_error($sql, $retries, $putMysqliError);
69        }
70
71        public function log_trace($sql, $retries=0) {
72            if(!$this->traceOn || strpos($sql,'brain_store'))
73                return;
74            if($retries === 0)
75                $this->trace[] = $sql;
76            else
77                $this->trace[] = $sql." -- retry $retries";
78        }
79    }
80
81    global $gSqlClass,$gIAsql;
82    try {
83        $gSqlClass = new sqlMysqli($gIAsql['host'],$gIAsql['user'],$gIAsql['pwd'],$gIAsql['dbname'],$gIAsql['port']);
84        $gSqlClass->connect();
85    } catch(Throwable $e) {
86        header('DB error al conectarme', true, 501);
87       echo "\r\n\r\n<pre style='color:red'> Error al conectarme a la base de datos: " . $e->getMessage() ."</pre>";
88       die();
89    }
90
91
92// select into array
93    /**
94     * select colRegresaDePrimerRow, otraCol FROM
95    *  regresa la primera columna del primer row
96    * 
97    * 
98    * @param string $sql el sql string a ejecutar
99    * @param mixed $dflt='' resultado a regresar si el sql da not found. DEFAULT ''
100    * @param mixed $errResult=FALSE' resultado a regresar si el sql da error. DEFAULT FALSE
101    * @return mixed $errResult normalmente false on error, el resultado del query.
102     */
103    function ia_singleread($sql,$dflt='',$errResult=FALSE) { //,$getNumRows=true,$showError=true
104    global $gIAsql,$gSqlClass;
105        try { $ret = $gSqlClass->single_read($sql,$dflt); }
106        catch(IacSqlException) {
107            return $errResult;
108        }
109        $gIAsql['selected_rows'] = $gSqlClass->num_rows;
110        if($ret === false)
111            return $errResult;
112        return $ret;
113    }
114
115
116    /**
117    * Regresa el primer row en un array
118    *
119    * @param string $sql el sql string a ejecutar
120    * @param int $assoc=MYSQL_ASSOC como asociar el array MYSQLI_ASSOC,MYSQL_NUM,MYSQL_BOTH Default MYSQL_ASSOC
121    * @return bool|array FALSE on error, el resultado del query en un array o null array en not found.
122     */
123    function ia_singleton($sql, $assoc = MYSQLI_ASSOC) { /* returns select fields in array (first row) */
124    global $gIAsql,$gSqlClass;
125        try {
126            $ret = $gSqlClass->singleton($sql,array(), assoc_mysql2mysqli($assoc));
127        } catch(IacSqlException) { return false; }
128        $gIAsql['selected_rows'] = $gSqlClass->num_rows;
129        return $ret;
130    }
131
132    /**
133    *  Regresa todas las columnas seleccionadas del primer row SELECT col1,col2 da: [col1 => v1,col2 => v2]
134     * De no existir regresa [col1 => $enNull, cold2 => $enNull]
135     * 
136    * @param string $sql el sql string a ejecutar
137    * @param mixed $enNull='' que poner si el campo es null. Defaullt '-'
138    * @return bool|array FALSE on error, el resultado del query en un array o null array en not found.
139     */
140    function ia_singletonFull($sql,$enNull='') { //,$assoc=MYSQL_ASSOC
141    global $gIAsql,$gSqlClass;
142        try {
143            $ret = $gSqlClass->singleton_full($sql, $enNull);
144        } catch(IacSqlException) { return false; }
145        $gIAsql['selected_rows'] = $gSqlClass->num_rows;
146        return $ret;
147    }
148
149    /**
150     * [ 'byValor1'=>[col1=>v1,col2=>v2, $by=>byValor1], ... ]
151    * returns 2 dim array con key $by del $sql con MYSQL_ASSOC.
152    *
153    * @param string $sql el sql string a ejecutar
154     * @param string $by
155     * @param mixed $assoc
156     * @return array|false false on error, el 2 dim array con key $by del query $sql. null array en not found
157     */
158    function ia_sqlArray($sql,$by='id',$assoc=MYSQL_ASSOC) { // ,$showErrors=true,&$fieldInfo=null
159    global $gIAsql,$gSqlClass;
160        try {
161            $ret = $gSqlClass->selectArrayKey($sql,$by,array(),assoc_mysql2mysqli($assoc));
162        } catch(IacSqlException) { return false; }
163        $gIAsql['selected_rows'] = $gSqlClass->num_rows;
164        return $ret;
165    }
166
167    /**
168     * ia_sqlArrayIndx()
169     *
170     * @param string $sql el sql string a ejecutar
171     * @param mixed $assoc
172     * @return array|false FALSE on error, el 2 dim array con key num row del query $sql. null array en not found
173     */
174    function ia_sqlArrayIndx($sql,$assoc=MYSQL_ASSOC) { // ,$showError=true
175        global $gIAsql,$gSqlClass;
176        try {
177            $ret = $gSqlClass->selectArrayIndex($sql,array(), assoc_mysql2mysqli($assoc));
178        } catch(IacSqlException) { return false; }
179        $gIAsql['selected_rows'] = $gSqlClass->num_rows;
180        return $ret;
181    }
182
183    /**
184     *  SELECT col1, col2 FROM da ['valor De Col1 Row#1', 'valor De Col1 Row#2', ]
185     *
186     * @param string $sql
187     * @return array|false
188     */
189    function ia_sqlVector($sql) {
190    global $gIAsql,$gSqlClass;
191        try {
192            $ret = $gSqlClass->selectVector($sql);
193        } catch(IacSqlException) { return false; }
194        $gIAsql['selected_rows'] = $gSqlClass->num_rows;
195        return $ret;
196    }
197
198    /**
199     * select key, value from da [key1 => val1, key2 => val2, ..]
200     * 
201     * @param string $sql el sql string a ejecutar
202     * @return array|boolean FALSE on error, el 2 dim array con key $by del query $sql. null array en not found
203     */
204    function ia_sqlKeyValue($sql) {
205    global $gIAsql,$gSqlClass;
206        try {
207            $ret = $gSqlClass->selectKeyValue($sql);
208        } catch(IacSqlException) { return false; }
209        $gIAsql['selected_rows'] = $gSqlClass->num_rows;
210        return $ret;
211    }
212
213    function ia_sqlSelectMultiKey($sql, $numKeys, $resultType = MYSQLI_ASSOC, $autoPrefix = false) {
214        global $gIAsql,$gSqlClass;
215        try {
216            $ret = $gSqlClass->selectArrayMultiKey($sql,$numKeys, $resultType, $autoPrefix);
217        } catch(Exception) { return []; }
218        $gIAsql['selected_rows'] = $gSqlClass->num_rows;
219        return $ret;
220    }
221
222// Transacciones
223    /**
224     * Ejecuta todos los comandos en $arr en una transacción
225     *
226     * @param array $arr
227     * @param string $cmnt
228     * @param bool $findID
229     * @return bool TRUE en error con rollback realiazado, FALSE all ok
230     * @noinspection PhpUnusedParameterInspection
231     */
232    function ia_transaction($arr,$cmnt='trsct',$findID=true) {
233        global $gIAsql,$gSqlClass;
234        try {
235            $ret = $gSqlClass->transaction($arr,$findID,'<<_','_>>','<_','_>','id');
236        } catch(IacSqlException) { ia_rollback(); return true; }
237        if($ret === false) ia_rollback();
238        $gIAsql['affected_rows'] = $gSqlClass->affected_rows;
239        return !$ret;
240    }
241
242    /**
243    * Inicia una transaccion.
244     *
245    * @return bool TRUE on error, FALSE on ok transaction started.
246     * @noinspection PhpUnusedParameterInspection
247     */
248    function ia_begin($cmnt='strt') { // ,$setAutoCommit=TRUE
249    global $gSqlClass;
250        try {
251            return !$gSqlClass->begin();
252        } catch(IacSqlException) { return true; }
253    }
254
255    /**
256     * ia_commit()
257    * Hace commit de una transaccion.
258    * - Decrementando $gIAsql['begins'] en 1.
259     * @param string $cmnt
260     * @return bool true on error, false all ok
261     * @noinspection PhpUnusedParameterInspection
262     */
263    function ia_commit($cmnt='cmit') { //,$autocommit=TRUE
264    global $gSqlClass;
265        try {
266            return !$gSqlClass->commit();
267        } catch(IacSqlException) {return true;}
268    }
269
270    /**
271     * ia_rollback()
272    * Hace rollback de una transaccion
273    * - Decrementando $gIAsql['begins'] en 1.
274     * @param string $cmnt
275     * @return bool TRUE on error, FALSE all ok rollback done.
276     * @noinspection PhpUnusedParameterInspection
277     */
278    function ia_rollback($cmnt='rllbck') { // ,$autocommit=TRUE
279    global $gSqlClass;
280        try {
281            return !$gSqlClass->rollback();
282        } catch(IacSqlException) { return true; }
283    }
284
285// queries cambian datos o db_schema
286
287    /**
288    * Ejecuta comando de sql, query (DML, DDL) que no regresa datos
289    * ie alter,delete,insert,update,replace,...
290    *
291    * @param string $sql el sql string a ejecutar
292    * @return bool TRUE on error, FALSE on ok.
293     * @noinspection PhpUnusedParameterInspection
294     */
295    function ia_query($sql, $doAffectedRows=TRUE, $doRetry=true) {
296        global $gIAsql,$gSqlClass;
297        try {
298             $ret = !$gSqlClass->query($sql);
299        } catch(IacSqlException) {return true;}
300            $gIAsql['affected_rows'] = $gSqlClass->affected_rows;
301        return $ret;
302    }
303/*
304function ia_queryOri($sql,$doAffectedRows=TRUE,$doRetry=true) {
305    global $gIAsql,$gSqlClass;
306    if(!$doRetry) {
307        $prev = $gSqlClass->retries;
308        $gSqlClass->retries = 0;
309    }
310    try { $ret = $gSqlClass->query($sql); }
311    catch(IacSqlException) {$ret = false;}
312    if($doAffectedRows) {
313        if($ret)
314            $gIAsql['affected_rows'] = $gSqlClass->affected_rows;
315        else
316            $gIAsql['affected_rows'] = 0;
317    }
318    if(!$doRetry) {
319        $gSqlClass->retries = $prev;
320    }
321    return !$ret;
322}
323*/
324    /**
325     * Ejecuta todos los comandos en $arr (sin transacción)
326     *
327     * @param array $arr
328     * @param bool $findID
329     * @return bool TRUE error, FALSE all ok
330     */
331    function ia_nontransaction($arr,$findID=true) {
332        global $gIAsql,$gSqlClass;
333        try {
334            $ret = $gSqlClass->queryArray($arr,$findID,'<_','_>','<_','_>','id');
335        } catch(IacSqlException) { $ret = true; }
336        $gIAsql['affected_rows'] = $gSqlClass->affected_rows;
337        return !$ret;
338    }
339
340    /**
341     * Ejecuta insert regresando el auto_increment id creado.
342     *
343     * @param string $sql el sql string a ejecutar
344     * @return int|string|false  false on error, auto_increment id on Active.
345     */
346    function ia_insertIded($sql) {
347        global $gSqlClass;
348        try {
349            return $gSqlClass->insertAndGetId($sql);
350        } catch(IacSqlException) { return false;}
351    }
352
353
354// Meta data e informativas
355
356    function trace_sql($bool) {
357        global $gSqlClass;
358        $gSqlClass->traceOn = $bool;
359    }
360
361    function sql_trace_get() {
362        global $gSqlClass;
363        return $gSqlClass->trace_get();
364    }
365
366    function last_inserted_id() {
367    global $gSqlClass;
368        return $gSqlClass->mysqli->insert_id;
369    }
370
371    function affected_rows() {
372    global  $gIAsql;
373        return $gIAsql['affected_rows'];
374    }
375
376    function getMetaData($sql) {
377        global $gSqlClass;
378        try {
379            $prev = $gSqlClass->metaDataOn;
380            $gSqlClass->metaDataOn = true;
381            $gSqlClass->singleton($sql);
382            $gSqlClass->metaDataOn = $prev;
383            return $gSqlClass->metaData_get();
384        } catch(IacSqlException) { return false; }
385    }
386
387    function metaDataOnSet($bool) {
388        global $gSqlClass;
389        $prev = $gSqlClass->metaDataOn;
390        $gSqlClass->metaDataOn = $bool;
391        return $prev;
392    }
393
394
395// utiles
396    function assoc_mysql2mysqli($assoc) {
397    return match ($assoc) {
398        MYSQLI_NUM, MYSQL_NUM => MYSQLI_NUM,
399        MYSQLI_BOTH,  MYSQL_BOTH =>  MYSQLI_BOTH,
400        default => MYSQLI_ASSOC,
401    };
402}
403
404/**
405 * ia_SqlOptions()
406 *
407 * @param string $sql
408 * @param string|array $selected
409 * @param mixed $extra
410 * @param string $optionTag
411 * @return string|false
412 */
413function ia_SqlOptions($sql,$selected='',$extra=array(),$optionTag='',$rn="\r\n") {
414
415    $ret='';
416    if($extra) foreach($extra as $k=>$v)
417        if(is_array($selected)) {
418            $ret.= "$rn<option value='$k'".(array_key_exists($k,$selected) ? " SELECTED='selected' " : "")."$optionTag>".ia_htmlentities($v)."</option>";
419        } else {
420            $ret.= "$rn<option value='$k'".(strcmp($selected,$k) ? "" : " SELECTED='selected' ")."$optionTag>".ia_htmlentities($v)."</option>";
421        }
422    $arr = ia_sqlArrayIndx($sql,MYSQLI_NUM);
423    if($arr === false) return false;
424    foreach($arr as $d) {
425        if(is_array($selected)) {
426            $ret.= "$rn<option value='$d[0]'".(array_key_exists($d[0],$selected) ? " SELECTED='selected' " : "")."$optionTag>".ia_htmlentities($d[1])."</option>";
427        } else {
428            $ret.= "$rn<option value='$d[0]'".(strcmp($selected,$d[0]) ? "" : " SELECTED='selected' ")."$optionTag>".ia_htmlentities($d[1])."</option>";
429        }
430    }
431    return $ret;
432}
433
434/**
435 * ia_echoSqlOptions()
436 * Hace un echo de options de un select donde col 1 es el value, col 2 el texto del sql, selected trae el value (col 1) se marca como selected
437 * 
438 * falta quote protect $d[0]
439 * @param string $sql el sql string a ejecutar col 1 es el value del option, col 2 se el texto entre options
440 * @param string|array $selected
441 * @param string $optionTag
442 * @return bool FALSE on error, TRUE ok
443 *
444 * @codeCoverageIgnore
445 */
446function ia_echoSqlOptions($sql,$selected='',$optionTag='') {
447    $arr = ia_sqlArrayIndx($sql,MYSQLI_NUM);
448    foreach($arr as $d) {
449        if(is_array($selected)) {
450            echo "\r\n<option value='$d[0]'".(array_key_exists($d[0],$selected) ? " SELECTED='selected' " : "")."$optionTag>".ia_htmlentities($d[1])."</option>";
451        } else {
452            echo "\r\n<option value='$d[0]'".(strcmp($selected,$d[0]) ? "" : " SELECTED='selected' ")."$optionTag>".ia_htmlentities($d[1])."</option>";
453        }
454    }
455    return TRUE;
456}
457
458
459/**
460 * ia_SqlOptionsSetDataData()
461 *
462 * @param string $sql
463 * @param string|array $selected
464 * @param mixed $extra
465 * @param string $optionTag
466 * @return
467
468function ia_SqlOptionsSetDataData($sql,$selected='',$extra=array(),$optionTag='') {
469global $gIAsql;
470    $ret = '';
471    if($extra) foreach($extra as $k=>$v)
472        if(is_array($selected)) {
473            $ret.= "\r\n<option value='$k'" . (array_key_exists($k,$selected) ? " SELECTED='selected' " : "")."$optionTag>".ia_htmlentities($v)."</option>";
474        } else {
475            $ret.= "\r\n<option value='$k'" . (strcmp($selected,$k) ? "" : " SELECTED='selected' ")."$optionTag>".ia_htmlentities($v)."</option>";
476        }
477    $arr = ia_sqlArrayIndx($sql,MYSQLI_NUM);
478    foreach($arr as $d) {
479        if(is_array($selected)) {
480            $ret.= "\r\n<option data-data='$d[2]' value='$d[0]'".(array_key_exists($d[0],$selected) ? " SELECTED='selected' " : "")."$optionTag>".ia_htmlentities($d[1])."</option>";
481        } else {
482            $ret.= "\r\n<option data-data='$d[2]' value='$d[0]'".(strcmp($selected,$d[0]) ? "" : " SELECTED='selected' ")."$optionTag>".ia_htmlentities($d[1])."</option>";
483        }
484    }
485    return true;
486}
487 */