· 6 years ago · Jul 01, 2019, 04:10 PM
1class ADODB_mysqli extends ADOConnection {
2 var $databaseType = 'mysqli';
3 var $dataProvider = 'mysql';
4 var $hasInsertID = true;
5 var $hasAffectedRows = true;
6 var $metaTablesSQL = "SELECT
7 TABLE_NAME,
8 CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END
9 FROM INFORMATION_SCHEMA.TABLES
10 WHERE TABLE_SCHEMA=";
11 var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`";
12 var $fmtTimeStamp = "'Y-m-d H:i:s'";
13 var $hasLimit = true;
14 var $hasMoveFirst = true;
15 var $hasGenID = true;
16 var $isoDates = true; // accepts dates in ISO format
17 var $sysDate = 'CURDATE()';
18 var $sysTimeStamp = 'NOW()';
19 var $hasTransactions = true;
20 var $forceNewConnect = false;
21 var $poorAffectedRows = true;
22 var $clientFlags = 0;
23 var $substr = "substring";
24 var $port = 3306; //Default to 3306 to fix HHVM bug
25 var $socket = ''; //Default to empty string to fix HHVM bug
26 var $_bindInputArray = false;
27 var $nameQuote = '`'; /// string to use to quote identifiers and names
28 var $optionFlags = array(array(MYSQLI_READ_DEFAULT_GROUP,0));
29 var $arrayClass = 'ADORecordSet_array_mysqli';
30 var $multiQuery = false;
31
32 function __construct()
33 {
34 // if(!extension_loaded("mysqli"))
35 //trigger_error("You must have the mysqli extension installed.", E_USER_ERROR);
36 }
37
38 function SetTransactionMode( $transaction_mode )
39 {
40 $this->_transmode = $transaction_mode;
41 if (empty($transaction_mode)) {
42 $this->Execute('SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ');
43 return;
44 }
45 if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
46 $this->Execute("SET SESSION TRANSACTION ".$transaction_mode);
47 }
48
49 // returns true or false
50 // To add: parameter int $port,
51 // parameter string $socket
52 function _connect($argHostname = NULL,
53 $argUsername = NULL,
54 $argPassword = NULL,
55 $argDatabasename = NULL, $persist=false)
56 {
57 if(!extension_loaded("mysqli")) {
58 return null;
59 }
60 $this->_connectionID = @mysqli_init();
61
62 if (is_null($this->_connectionID)) {
63 // mysqli_init only fails if insufficient memory
64 if ($this->debug) {
65 ADOConnection::outp("mysqli_init() failed : " . $this->ErrorMsg());
66 }
67 return false;
68 }
69 /*
70 I suggest a simple fix which would enable adodb and mysqli driver to
71 read connection options from the standard mysql configuration file
72 /etc/my.cnf - "Bastien Duclaux" <bduclaux#yahoo.com>
73 */
74 foreach($this->optionFlags as $arr) {
75 mysqli_options($this->_connectionID,$arr[0],$arr[1]);
76 }
77
78 //http ://php.net/manual/en/mysqli.persistconns.php
79 if ($persist && PHP_VERSION > 5.2 && strncmp($argHostname,'p:',2) != 0) $argHostname = 'p:'.$argHostname;
80
81 #if (!empty($this->port)) $argHostname .= ":".$this->port;
82 $ok = mysqli_real_connect($this->_connectionID,
83 $argHostname,
84 $argUsername,
85 $argPassword,
86 $argDatabasename,
87 # PHP7 compat: port must be int. Use default port if cast yields zero
88 (int)$this->port != 0 ? (int)$this->port : 3306,
89 $this->socket,
90 $this->clientFlags);
91
92 if ($ok) {
93 if ($argDatabasename) return $this->SelectDB($argDatabasename);
94 return true;
95 } else {
96 if ($this->debug) {
97 ADOConnection::outp("Could't connect : " . $this->ErrorMsg());
98 }
99 $this->_connectionID = null;
100 return false;
101 }
102 }
103
104 // returns true or false
105 // How to force a persistent connection
106 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
107 {
108 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, true);
109 }
110
111 // When is this used? Close old connection first?
112 // In _connect(), check $this->forceNewConnect?
113 function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
114 {
115 $this->forceNewConnect = true;
116 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
117 }
118
119 function IfNull( $field, $ifNull )
120 {
121 return " IFNULL($field, $ifNull) "; // if MySQL
122 }
123
124 // do not use $ADODB_COUNTRECS
125 function GetOne($sql,$inputarr=false)
126 {
127 global $ADODB_GETONE_EOF;
128
129 $ret = false;
130 $rs = $this->Execute($sql,$inputarr);
131 if ($rs) {
132 if ($rs->EOF) $ret = $ADODB_GETONE_EOF;
133 else $ret = reset($rs->fields);
134 $rs->Close();
135 }
136 return $ret;
137 }
138
139 function ServerInfo()
140 {
141 $arr['description'] = $this->GetOne("select version()");
142 $arr['version'] = ADOConnection::_findvers($arr['description']);
143 return $arr;
144 }
145
146
147 function BeginTrans()
148 {
149 if ($this->transOff) return true;
150 $this->transCnt += 1;
151
152 //$this->Execute('SET AUTOCOMMIT=0');
153 mysqli_autocommit($this->_connectionID, false);
154 $this->Execute('BEGIN');
155 return true;
156 }
157
158 function CommitTrans($ok=true)
159 {
160 if ($this->transOff) return true;
161 if (!$ok) return $this->RollbackTrans();
162
163 if ($this->transCnt) $this->transCnt -= 1;
164 $this->Execute('COMMIT');
165
166 //$this->Execute('SET AUTOCOMMIT=1');
167 mysqli_autocommit($this->_connectionID, true);
168 return true;
169 }
170
171 function RollbackTrans()
172 {
173 if ($this->transOff) return true;
174 if ($this->transCnt) $this->transCnt -= 1;
175 $this->Execute('ROLLBACK');
176 //$this->Execute('SET AUTOCOMMIT=1');
177 mysqli_autocommit($this->_connectionID, true);
178 return true;
179 }
180
181 function RowLock($tables,$where='',$col='1 as adodbignore')
182 {
183 if ($this->transCnt==0) $this->BeginTrans();
184 if ($where) $where = ' where '.$where;
185 $rs = $this->Execute("select $col from $tables $where for update");
186 return !empty($rs);
187 }
188
189 /**
190 * Quotes a string to be sent to the database
191 * When there is no active connection,
192 * @param string $s The string to quote
193 * @param boolean $magic_quotes If false, use mysqli_real_escape_string()
194 * if you are quoting a string extracted from a POST/GET variable,
195 * then pass get_magic_quotes_gpc() as the second parameter. This will
196 * ensure that the variable is not quoted twice, once by qstr() and
197 * once by the magic_quotes_gpc.
198 * Eg. $s = $db->qstr(_GET['name'],get_magic_quotes_gpc());
199 * @return string Quoted string
200 */
201 function qstr($s, $magic_quotes = false)
202 {
203 if (is_null($s)) return 'NULL';
204 if (!$magic_quotes) {
205 // mysqli_real_escape_string() throws a warning when the given
206 // connection is invalid
207 if (PHP_VERSION >= 5 && $this->_connectionID) {
208 return "'" . mysqli_real_escape_string($this->_connectionID, $s) . "'";
209 }
210
211 if ($this->replaceQuote[0] == '\\') {
212 $s = adodb_str_replace(array('\\',"\0"), array('\\\\',"\\\0") ,$s);
213 }
214 return "'" . str_replace("'", $this->replaceQuote, $s) . "'";
215 }
216 // undo magic quotes for "
217 $s = str_replace('\\"','"',$s);
218 return "'$s'";
219 }
220
221 function _insertid()
222 {
223 $result = @mysqli_insert_id($this->_connectionID);
224 if ($result == -1) {
225 if ($this->debug) ADOConnection::outp("mysqli_insert_id() failed : " . $this->ErrorMsg());
226 }
227 return $result;
228 }
229
230 // Only works for INSERT, UPDATE and DELETE query's
231 function _affectedrows()
232 {
233 $result = @mysqli_affected_rows($this->_connectionID);
234 if ($result == -1) {
235 if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : " . $this->ErrorMsg());
236 }
237 return $result;
238 }
239
240 // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
241 // Reference on Last_Insert_ID on the recommended way to simulate sequences
242 var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
243 var $_genSeqSQL = "create table if not exists %s (id int not null)";
244 var $_genSeqCountSQL = "select count(*) from %s";
245 var $_genSeq2SQL = "insert into %s values (%s)";
246 var $_dropSeqSQL = "drop table if exists %s";
247
248 function CreateSequence($seqname='adodbseq',$startID=1)
249 {
250 if (empty($this->_genSeqSQL)) return false;
251 $u = strtoupper($seqname);
252
253 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
254 if (!$ok) return false;
255 return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
256 }
257
258 function GenID($seqname='adodbseq',$startID=1)
259 {
260 // post-nuke sets hasGenID to false
261 if (!$this->hasGenID) return false;
262
263 $getnext = sprintf($this->_genIDSQL,$seqname);
264 $holdtransOK = $this->_transOK; // save the current status
265 $rs = @$this->Execute($getnext);
266 if (!$rs) {
267 if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
268 $u = strtoupper($seqname);
269 $this->Execute(sprintf($this->_genSeqSQL,$seqname));
270 $cnt = $this->GetOne(sprintf($this->_genSeqCountSQL,$seqname));
271 if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
272 $rs = $this->Execute($getnext);
273 }
274
275 if ($rs) {
276 $this->genID = mysqli_insert_id($this->_connectionID);
277 $rs->Close();
278 } else
279 $this->genID = 0;
280
281 return $this->genID;
282 }
283
284 function MetaDatabases()
285 {
286 $query = "SHOW DATABASES";
287 $ret = $this->Execute($query);
288 if ($ret && is_object($ret)){
289 $arr = array();
290 while (!$ret->EOF){
291 $db = $ret->Fields('Database');
292 if ($db != 'mysql') $arr[] = $db;
293 $ret->MoveNext();
294 }
295 return $arr;
296 }
297 return $ret;
298 }
299
300
301 function MetaIndexes ($table, $primary = FALSE, $owner = false)
302 {
303 // save old fetch mode
304 global $ADODB_FETCH_MODE;
305
306 $false = false;
307 $save = $ADODB_FETCH_MODE;
308 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
309 if ($this->fetchMode !== FALSE) {
310 $savem = $this->SetFetchMode(FALSE);
311 }
312
313 // get index details
314 $rs = $this->Execute(sprintf('SHOW INDEXES FROM %s',$table));
315
316 // restore fetchmode
317 if (isset($savem)) {
318 $this->SetFetchMode($savem);
319 }
320 $ADODB_FETCH_MODE = $save;
321
322 if (!is_object($rs)) {
323 return $false;
324 }
325
326 $indexes = array ();
327
328 // parse index data into array
329 while ($row = $rs->FetchRow()) {
330 if ($primary == FALSE AND $row[2] == 'PRIMARY') {
331 continue;
332 }
333
334 if (!isset($indexes[$row[2]])) {
335 $indexes[$row[2]] = array(
336 'unique' => ($row[1] == 0),
337 'columns' => array()
338 );
339 }
340
341 $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
342 }
343
344 // sort columns by order in the index
345 foreach ( array_keys ($indexes) as $index )
346 {
347 ksort ($indexes[$index]['columns']);
348 }
349
350 return $indexes;
351 }
352
353
354 // Format date column in sql string given an input format that understands Y M D
355 function SQLDate($fmt, $col=false)
356 {
357 if (!$col) $col = $this->sysTimeStamp;
358 $s = 'DATE_FORMAT('.$col.",'";
359 $concat = false;
360 $len = strlen($fmt);
361 for ($i=0; $i < $len; $i++) {
362 $ch = $fmt[$i];
363 switch($ch) {
364 case 'Y':
365 case 'y':
366 $s .= '%Y';
367 break;
368 case 'Q':
369 case 'q':
370 $s .= "'),Quarter($col)";
371
372 if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
373 else $s .= ",('";
374 $concat = true;
375 break;
376 case 'M':
377 $s .= '%b';
378 break;
379
380 case 'm':
381 $s .= '%m';
382 break;
383 case 'D':
384 case 'd':
385 $s .= '%d';
386 break;
387
388 case 'H':
389 $s .= '%H';
390 break;
391
392 case 'h':
393 $s .= '%I';
394 break;
395
396 case 'i':
397 $s .= '%i';
398 break;
399
400 case 's':
401 $s .= '%s';
402 break;
403
404 case 'a':
405 case 'A':
406 $s .= '%p';
407 break;
408
409 case 'w':
410 $s .= '%w';
411 break;
412
413 case 'l':
414 $s .= '%W';
415 break;
416
417 default:
418
419 if ($ch == '\\') {
420 $i++;
421 $ch = substr($fmt,$i,1);
422 }
423 $s .= $ch;
424 break;
425 }
426 }
427 $s.="')";
428 if ($concat) $s = "CONCAT($s)";
429 return $s;
430 }
431
432 // returns concatenated string
433 // much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
434 function Concat()
435 {
436 $s = "";
437 $arr = func_get_args();
438
439 // suggestion by andrew005@mnogo.ru
440 $s = implode(',',$arr);
441 if (strlen($s) > 0) return "CONCAT($s)";
442 else return '';
443 }
444
445 // dayFraction is a day in floating point
446 function OffsetDate($dayFraction,$date=false)
447 {
448 if (!$date) $date = $this->sysDate;
449
450 $fraction = $dayFraction * 24 * 3600;
451 return $date . ' + INTERVAL ' . $fraction.' SECOND';
452
453// return "from_unixtime(unix_timestamp($date)+$fraction)";
454 }
455
456 function MetaProcedures($NamePattern = false, $catalog = null, $schemaPattern = null)
457 {
458 // save old fetch mode
459 global $ADODB_FETCH_MODE;
460
461 $false = false;
462 $save = $ADODB_FETCH_MODE;
463 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
464
465 if ($this->fetchMode !== FALSE) {
466 $savem = $this->SetFetchMode(FALSE);
467 }
468
469 $procedures = array ();
470
471 // get index details
472
473 $likepattern = '';
474 if ($NamePattern) {
475 $likepattern = " LIKE '".$NamePattern."'";
476 }
477 $rs = $this->Execute('SHOW PROCEDURE STATUS'.$likepattern);
478 if (is_object($rs)) {
479
480 // parse index data into array
481 while ($row = $rs->FetchRow()) {
482 $procedures[$row[1]] = array(
483 'type' => 'PROCEDURE',
484 'catalog' => '',
485 'schema' => '',
486 'remarks' => $row[7],
487 );
488 }
489 }
490
491 $rs = $this->Execute('SHOW FUNCTION STATUS'.$likepattern);
492 if (is_object($rs)) {
493 // parse index data into array
494 while ($row = $rs->FetchRow()) {
495 $procedures[$row[1]] = array(
496 'type' => 'FUNCTION',
497 'catalog' => '',
498 'schema' => '',
499 'remarks' => $row[7]
500 );
501 }
502 }
503
504 // restore fetchmode
505 if (isset($savem)) {
506 $this->SetFetchMode($savem);
507 }
508 $ADODB_FETCH_MODE = $save;
509
510 return $procedures;
511 }
512
513 /**
514 * Retrieves a list of tables based on given criteria
515 *
516 * @param string $ttype Table type = 'TABLE', 'VIEW' or false=both (default)
517 * @param string $showSchema schema name, false = current schema (default)
518 * @param string $mask filters the table by name
519 *
520 * @return array list of tables
521 */
522 function MetaTables($ttype=false,$showSchema=false,$mask=false)
523 {
524 $save = $this->metaTablesSQL;
525 if ($showSchema && is_string($showSchema)) {
526 $this->metaTablesSQL .= $this->qstr($showSchema);
527 } else {
528 $this->metaTablesSQL .= "schema()";
529 }
530
531 if ($mask) {
532 $mask = $this->qstr($mask);
533 $this->metaTablesSQL .= " AND table_name LIKE $mask";
534 }
535 $ret = ADOConnection::MetaTables($ttype,$showSchema);
536
537 $this->metaTablesSQL = $save;
538 return $ret;
539 }
540
541 // "Innox - Juan Carlos Gonzalez" <jgonzalez#innox.com.mx>
542 function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
543 {
544 global $ADODB_FETCH_MODE;
545
546 if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC) $associative = true;
547
548 if ( !empty($owner) ) {
549 $table = "$owner.$table";
550 }
551 $a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table));
552 if ($associative) {
553 $create_sql = isset($a_create_table["Create Table"]) ? $a_create_table["Create Table"] : $a_create_table["Create View"];
554 } else $create_sql = $a_create_table[1];
555
556 $matches = array();
557
558 if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false;
559 $foreign_keys = array();
560 $num_keys = count($matches[0]);
561 for ( $i = 0; $i < $num_keys; $i ++ ) {
562 $my_field = explode('`, `', $matches[1][$i]);
563 $ref_table = $matches[2][$i];
564 $ref_field = explode('`, `', $matches[3][$i]);
565
566 if ( $upper ) {
567 $ref_table = strtoupper($ref_table);
568 }
569
570 // see https://sourceforge.net/tracker/index.php?func=detail&aid=2287278&group_id=42718&atid=433976
571 if (!isset($foreign_keys[$ref_table])) {
572 $foreign_keys[$ref_table] = array();
573 }
574 $num_fields = count($my_field);
575 for ( $j = 0; $j < $num_fields; $j ++ ) {
576 if ( $associative ) {
577 $foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j];
578 } else {
579 $foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}";
580 }
581 }
582 }
583
584 return $foreign_keys;
585 }
586
587 function MetaColumns($table, $normalize=true)
588 {
589 $false = false;
590 if (!$this->metaColumnsSQL)
591 return $false;
592
593 global $ADODB_FETCH_MODE;
594 $save = $ADODB_FETCH_MODE;
595 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
596 if ($this->fetchMode !== false)
597 $savem = $this->SetFetchMode(false);
598 $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
599 if (isset($savem)) $this->SetFetchMode($savem);
600 $ADODB_FETCH_MODE = $save;
601 if (!is_object($rs))
602 return $false;
603
604 $retarr = array();
605 while (!$rs->EOF) {
606 $fld = new ADOFieldObject();
607 $fld->name = $rs->fields[0];
608 $type = $rs->fields[1];
609
610 // split type into type(length):
611 $fld->scale = null;
612 if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
613 $fld->type = $query_array[1];
614 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
615 $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
616 } elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
617 $fld->type = $query_array[1];
618 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
619 } elseif (preg_match("/^(enum)\((.*)\)$/i", $type, $query_array)) {
620 $fld->type = $query_array[1];
621 $arr = explode(",",$query_array[2]);
622 $fld->enums = $arr;
623 $zlen = max(array_map("strlen",$arr)) - 2; // PHP >= 4.0.6
624 $fld->max_length = ($zlen > 0) ? $zlen : 1;
625 } else {
626 $fld->type = $type;
627 $fld->max_length = -1;
628 }
629 $fld->not_null = ($rs->fields[2] != 'YES');
630 $fld->primary_key = ($rs->fields[3] == 'PRI');
631 $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
632 $fld->binary = (strpos($type,'blob') !== false);
633 $fld->unsigned = (strpos($type,'unsigned') !== false);
634 $fld->zerofill = (strpos($type,'zerofill') !== false);
635
636 if (!$fld->binary) {
637 $d = $rs->fields[4];
638 if ($d != '' && $d != 'NULL') {
639 $fld->has_default = true;
640 $fld->default_value = $d;
641 } else {
642 $fld->has_default = false;
643 }
644 }
645
646 if ($save == ADODB_FETCH_NUM) {
647 $retarr[] = $fld;
648 } else {
649 $retarr[strtoupper($fld->name)] = $fld;
650 }
651 $rs->MoveNext();
652 }
653
654 $rs->Close();
655 return $retarr;
656 }
657
658 // returns true or false
659 function SelectDB($dbName)
660 {
661// $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
662 $this->database = $dbName;
663 $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
664
665 if ($this->_connectionID) {
666 $result = @mysqli_select_db($this->_connectionID, $dbName);
667 if (!$result) {
668 ADOConnection::outp("Select of database " . $dbName . " failed. " . $this->ErrorMsg());
669 }
670 return $result;
671 }
672 return false;
673 }
674
675 // parameters use PostgreSQL convention, not MySQL
676 function SelectLimit($sql,
677 $nrows = -1,
678 $offset = -1,
679 $inputarr = false,
680 $secs = 0)
681 {
682 $offsetStr = ($offset >= 0) ? "$offset," : '';
683 if ($nrows < 0) $nrows = '18446744073709551615';
684
685 if ($secs)
686 $rs = $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr );
687 else
688 $rs = $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr );
689
690 return $rs;
691 }
692
693
694 function Prepare($sql)
695 {
696 return $sql;
697 $stmt = $this->_connectionID->prepare($sql);
698 if (!$stmt) {
699 echo $this->ErrorMsg();
700 return $sql;
701 }
702 return array($sql,$stmt);
703 }
704
705
706 // returns queryID or false
707 function _query($sql, $inputarr)
708 {
709 global $ADODB_COUNTRECS;
710 // Move to the next recordset, or return false if there is none. In a stored proc
711 // call, mysqli_next_result returns true for the last "recordset", but mysqli_store_result
712 // returns false. I think this is because the last "recordset" is actually just the
713 // return value of the stored proc (ie the number of rows affected).
714 // Commented out for reasons of performance. You should retrieve every recordset yourself.
715 // if (!mysqli_next_result($this->connection->_connectionID)) return false;
716
717 if (is_array($sql)) {
718
719 // Prepare() not supported because mysqli_stmt_execute does not return a recordset, but
720 // returns as bound variables.
721
722 $stmt = $sql[1];
723 $a = '';
724 foreach($inputarr as $k => $v) {
725 if (is_string($v)) $a .= 's';
726 else if (is_integer($v)) $a .= 'i';
727 else $a .= 'd';
728 }
729
730 $fnarr = array_merge( array($stmt,$a) , $inputarr);
731 $ret = call_user_func_array('mysqli_stmt_bind_param',$fnarr);
732 $ret = mysqli_stmt_execute($stmt);
733 return $ret;
734 }
735
736 /*
737 if (!$mysql_res = mysqli_query($this->_connectionID, $sql, ($ADODB_COUNTRECS) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT)) {
738 if ($this->debug) ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg());
739 return false;
740 }
741
742 return $mysql_res;
743 */
744
745 if ($this->multiQuery) {
746 $rs = mysqli_multi_query($this->_connectionID, $sql.';');
747 if ($rs) {
748 $rs = ($ADODB_COUNTRECS) ? @mysqli_store_result( $this->_connectionID ) : @mysqli_use_result( $this->_connectionID );
749 return $rs ? $rs : true; // mysqli_more_results( $this->_connectionID )
750 }
751 } else {
752 $rs = mysqli_query($this->_connectionID, $sql, $ADODB_COUNTRECS ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT);
753
754 if ($rs) return $rs;
755 }
756
757 if($this->debug)
758 ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg());
759
760 return false;
761
762 }
763
764 /* Returns: the last error message from previous database operation */
765 function ErrorMsg()
766 {
767 if (empty($this->_connectionID))
768 $this->_errorMsg = @mysqli_connect_error();
769 else
770 $this->_errorMsg = @mysqli_error($this->_connectionID);
771 return $this->_errorMsg;
772 }
773
774 /* Returns: the last error number from previous database operation */
775 function ErrorNo()
776 {
777 if (empty($this->_connectionID))
778 return @mysqli_connect_errno();
779 else
780 return @mysqli_errno($this->_connectionID);
781 }
782
783 // returns true or false
784 function _close()
785 {
786 @mysqli_close($this->_connectionID);
787 $this->_connectionID = false;
788 }
789
790 /*
791 * Maximum size of C field
792 */
793 function CharMax()
794 {
795 return 255;
796 }
797
798 /*
799 * Maximum size of X field
800 */
801 function TextMax()
802 {
803 return 4294967295;
804 }
805
806
807 // this is a set of functions for managing client encoding - very important if the encodings
808 // of your database and your output target (i.e. HTML) don't match
809 // for instance, you may have UTF8 database and server it on-site as latin1 etc.
810 // GetCharSet - get the name of the character set the client is using now
811 // Under Windows, the functions should work with MySQL 4.1.11 and above, the set of charsets supported
812 // depends on compile flags of mysql distribution
813
814 function GetCharSet()
815 {
816 //we will use ADO's builtin property charSet
817 if (!method_exists($this->_connectionID,'character_set_name'))
818 return false;
819
820 $this->charSet = @$this->_connectionID->character_set_name();
821 if (!$this->charSet) {
822 return false;
823 } else {
824 return $this->charSet;
825 }
826 }
827
828 // SetCharSet - switch the client encoding
829 function SetCharSet($charset_name)
830 {
831 if (!method_exists($this->_connectionID,'set_charset')) {
832 return false;
833 }
834
835 if ($this->charSet !== $charset_name) {
836 $if = @$this->_connectionID->set_charset($charset_name);
837 return ($if === true & $this->GetCharSet() == $charset_name);
838 } else {
839 return true;
840 }
841 }
842
843 }