Merge commit 'catalyst/MOODLE_19_STABLE' into mdl19-linuxchix
[moodle-linuxchix.git] / lib / adodb / drivers / adodb-mysqli.inc.php
blob0070c917d105f8be760d7ffdaa6727fe71521afc
1 <?php
2 /*
3 V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
4 Released under both BSD license and Lesser GPL library license.
5 Whenever there is any discrepancy between the two licenses,
6 the BSD license will take precedence.
7 Set tabs to 8.
9 MySQL code that does not support transactions. Use mysqlt if you need transactions.
10 Requires mysql client. Works on Windows and Unix.
12 21 October 2003: MySQLi extension implementation by Arjen de Rijke (a.de.rijke@xs4all.nl)
13 Based on adodb 3.40
14 */
16 // security - hide paths
17 if (!defined('ADODB_DIR')) die();
19 if (! defined("_ADODB_MYSQLI_LAYER")) {
20 define("_ADODB_MYSQLI_LAYER", 1 );
22 // PHP5 compat...
23 if (! defined("MYSQLI_BINARY_FLAG")) define("MYSQLI_BINARY_FLAG", 128);
24 if (!defined('MYSQLI_READ_DEFAULT_GROUP')) define('MYSQLI_READ_DEFAULT_GROUP',1);
26 // disable adodb extension - currently incompatible.
27 global $ADODB_EXTENSION; $ADODB_EXTENSION = false;
29 class ADODB_mysqli extends ADOConnection {
30 var $databaseType = 'mysqli';
31 var $dataProvider = 'native';
32 var $hasInsertID = true;
33 var $hasAffectedRows = true;
34 var $metaTablesSQL = "SHOW TABLES";
35 var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`";
36 var $fmtTimeStamp = "'Y-m-d H:i:s'";
37 var $hasLimit = true;
38 var $hasMoveFirst = true;
39 var $hasGenID = true;
40 var $isoDates = true; // accepts dates in ISO format
41 var $sysDate = 'CURDATE()';
42 var $sysTimeStamp = 'NOW()';
43 var $hasTransactions = true;
44 var $forceNewConnect = false;
45 var $poorAffectedRows = true;
46 var $clientFlags = 0;
47 var $substr = "substring";
48 var $port = false;
49 var $socket = false;
50 var $_bindInputArray = false;
51 var $nameQuote = '`'; /// string to use to quote identifiers and names
52 var $optionFlags = array(array(MYSQLI_READ_DEFAULT_GROUP,0));
53 var $arrayClass = 'ADORecordSet_array_mysqli';
55 function ADODB_mysqli()
57 // if(!extension_loaded("mysqli"))
58 ;//trigger_error("You must have the mysqli extension installed.", E_USER_ERROR);
62 function SetTransactionMode( $transaction_mode )
64 $this->_transmode = $transaction_mode;
65 if (empty($transaction_mode)) {
66 $this->Execute('SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ');
67 return;
69 if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
70 $this->Execute("SET SESSION TRANSACTION ".$transaction_mode);
73 // returns true or false
74 // To add: parameter int $port,
75 // parameter string $socket
76 function _connect($argHostname = NULL,
77 $argUsername = NULL,
78 $argPassword = NULL,
79 $argDatabasename = NULL, $persist=false)
81 if(!extension_loaded("mysqli")) {
82 return null;
84 $this->_connectionID = @mysqli_init();
86 if (is_null($this->_connectionID)) {
87 // mysqli_init only fails if insufficient memory
88 if ($this->debug)
89 ADOConnection::outp("mysqli_init() failed : " . $this->ErrorMsg());
90 return false;
93 I suggest a simple fix which would enable adodb and mysqli driver to
94 read connection options from the standard mysql configuration file
95 /etc/my.cnf - "Bastien Duclaux" <bduclaux#yahoo.com>
97 foreach($this->optionFlags as $arr) {
98 mysqli_options($this->_connectionID,$arr[0],$arr[1]);
101 #if (!empty($this->port)) $argHostname .= ":".$this->port;
102 $ok = mysqli_real_connect($this->_connectionID,
103 $argHostname,
104 $argUsername,
105 $argPassword,
106 $argDatabasename,
107 $this->port,
108 $this->socket,
109 $this->clientFlags);
111 if ($ok) {
112 if ($argDatabasename) return $this->SelectDB($argDatabasename);
113 return true;
114 } else {
115 if ($this->debug)
116 ADOConnection::outp("Could't connect : " . $this->ErrorMsg());
117 $this->_connectionID = null;
118 return false;
122 // returns true or false
123 // How to force a persistent connection
124 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
126 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, true);
130 // When is this used? Close old connection first?
131 // In _connect(), check $this->forceNewConnect?
132 function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
134 $this->forceNewConnect = true;
135 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
138 function IfNull( $field, $ifNull )
140 return " IFNULL($field, $ifNull) "; // if MySQL
143 // do not use $ADODB_COUNTRECS
144 function GetOne($sql,$inputarr=false)
146 $ret = false;
147 $rs = &$this->Execute($sql,$inputarr);
148 if ($rs) {
149 if (!$rs->EOF) $ret = reset($rs->fields);
150 $rs->Close();
152 return $ret;
155 function ServerInfo()
157 $arr['description'] = $this->GetOne("select version()");
158 $arr['version'] = ADOConnection::_findvers($arr['description']);
159 return $arr;
163 function BeginTrans()
165 if ($this->transOff) return true;
166 $this->transCnt += 1;
168 //$this->Execute('SET AUTOCOMMIT=0');
169 mysqli_autocommit($this->_connectionID, false);
170 $this->Execute('BEGIN');
171 return true;
174 function CommitTrans($ok=true)
176 if ($this->transOff) return true;
177 if (!$ok) return $this->RollbackTrans();
179 if ($this->transCnt) $this->transCnt -= 1;
180 $this->Execute('COMMIT');
182 //$this->Execute('SET AUTOCOMMIT=1');
183 mysqli_autocommit($this->_connectionID, true);
184 return true;
187 function RollbackTrans()
189 if ($this->transOff) return true;
190 if ($this->transCnt) $this->transCnt -= 1;
191 $this->Execute('ROLLBACK');
192 //$this->Execute('SET AUTOCOMMIT=1');
193 mysqli_autocommit($this->_connectionID, true);
194 return true;
197 function RowLock($tables,$where='',$flds='1 as adodb_ignore')
199 if ($this->transCnt==0) $this->BeginTrans();
200 if ($where) $where = ' where '.$where;
201 $rs =& $this->Execute("select $flds from $tables $where for update");
202 return !empty($rs);
205 // if magic quotes disabled, use mysql_real_escape_string()
206 // From readme.htm:
207 // Quotes a string to be sent to the database. The $magic_quotes_enabled
208 // parameter may look funny, but the idea is if you are quoting a
209 // string extracted from a POST/GET variable, then
210 // pass get_magic_quotes_gpc() as the second parameter. This will
211 // ensure that the variable is not quoted twice, once by qstr and once
212 // by the magic_quotes_gpc.
214 //Eg. $s = $db->qstr(_GET['name'],get_magic_quotes_gpc());
215 function qstr($s, $magic_quotes = false)
217 if (is_null($s)) return 'NULL';
218 if (!$magic_quotes) {
219 if (PHP_VERSION >= 5)
220 return "'" . mysqli_real_escape_string($this->_connectionID, $s) . "'";
222 if ($this->replaceQuote[0] == '\\')
223 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
224 return "'".str_replace("'",$this->replaceQuote,$s)."'";
226 // undo magic quotes for "
227 $s = str_replace('\\"','"',$s);
228 return "'$s'";
231 function _insertid()
233 $result = @mysqli_insert_id($this->_connectionID);
234 if ($result == -1){
235 if ($this->debug) ADOConnection::outp("mysqli_insert_id() failed : " . $this->ErrorMsg());
237 return $result;
240 // Only works for INSERT, UPDATE and DELETE query's
241 function _affectedrows()
243 $result = @mysqli_affected_rows($this->_connectionID);
244 if ($result == -1) {
245 if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : " . $this->ErrorMsg());
247 return $result;
250 // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
251 // Reference on Last_Insert_ID on the recommended way to simulate sequences
252 var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
253 var $_genSeqSQL = "create table %s (id int not null)";
254 var $_genSeq2SQL = "insert into %s values (%s)";
255 var $_dropSeqSQL = "drop table %s";
257 function CreateSequence($seqname='adodbseq',$startID=1)
259 if (empty($this->_genSeqSQL)) return false;
260 $u = strtoupper($seqname);
262 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
263 if (!$ok) return false;
264 return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
267 function GenID($seqname='adodbseq',$startID=1)
269 // post-nuke sets hasGenID to false
270 if (!$this->hasGenID) return false;
272 $getnext = sprintf($this->_genIDSQL,$seqname);
273 $holdtransOK = $this->_transOK; // save the current status
274 $rs = @$this->Execute($getnext);
275 if (!$rs) {
276 if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
277 $u = strtoupper($seqname);
278 $this->Execute(sprintf($this->_genSeqSQL,$seqname));
279 $cnt = $this->GetOne(sprintf($this->_genSeqCountSQL,$seqname));
280 if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
281 $rs = $this->Execute($getnext);
284 if ($rs) {
285 $this->genID = mysqli_insert_id($this->_connectionID);
286 $rs->Close();
287 } else
288 $this->genID = 0;
290 return $this->genID;
293 function &MetaDatabases()
295 $query = "SHOW DATABASES";
296 $ret =& $this->Execute($query);
297 if ($ret && is_object($ret)){
298 $arr = array();
299 while (!$ret->EOF){
300 $db = $ret->Fields('Database');
301 if ($db != 'mysql') $arr[] = $db;
302 $ret->MoveNext();
304 return $arr;
306 return $ret;
310 function &MetaIndexes ($table, $primary = FALSE)
312 // save old fetch mode
313 global $ADODB_FETCH_MODE;
315 $false = false;
316 $save = $ADODB_FETCH_MODE;
317 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
318 if ($this->fetchMode !== FALSE) {
319 $savem = $this->SetFetchMode(FALSE);
322 // get index details
323 $rs = $this->Execute(sprintf('SHOW INDEXES FROM %s',$table));
325 // restore fetchmode
326 if (isset($savem)) {
327 $this->SetFetchMode($savem);
329 $ADODB_FETCH_MODE = $save;
331 if (!is_object($rs)) {
332 return $false;
335 $indexes = array ();
337 // parse index data into array
338 while ($row = $rs->FetchRow()) {
339 if ($primary == FALSE AND $row[2] == 'PRIMARY') {
340 continue;
343 if (!isset($indexes[$row[2]])) {
344 $indexes[$row[2]] = array(
345 'unique' => ($row[1] == 0),
346 'columns' => array()
350 $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
353 // sort columns by order in the index
354 foreach ( array_keys ($indexes) as $index )
356 ksort ($indexes[$index]['columns']);
359 return $indexes;
363 // Format date column in sql string given an input format that understands Y M D
364 function SQLDate($fmt, $col=false)
366 if (!$col) $col = $this->sysTimeStamp;
367 $s = 'DATE_FORMAT('.$col.",'";
368 $concat = false;
369 $len = strlen($fmt);
370 for ($i=0; $i < $len; $i++) {
371 $ch = $fmt[$i];
372 switch($ch) {
373 case 'Y':
374 case 'y':
375 $s .= '%Y';
376 break;
377 case 'Q':
378 case 'q':
379 $s .= "'),Quarter($col)";
381 if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
382 else $s .= ",('";
383 $concat = true;
384 break;
385 case 'M':
386 $s .= '%b';
387 break;
389 case 'm':
390 $s .= '%m';
391 break;
392 case 'D':
393 case 'd':
394 $s .= '%d';
395 break;
397 case 'H':
398 $s .= '%H';
399 break;
401 case 'h':
402 $s .= '%I';
403 break;
405 case 'i':
406 $s .= '%i';
407 break;
409 case 's':
410 $s .= '%s';
411 break;
413 case 'a':
414 case 'A':
415 $s .= '%p';
416 break;
418 case 'w':
419 $s .= '%w';
420 break;
422 case 'l':
423 $s .= '%W';
424 break;
426 default:
428 if ($ch == '\\') {
429 $i++;
430 $ch = substr($fmt,$i,1);
432 $s .= $ch;
433 break;
436 $s.="')";
437 if ($concat) $s = "CONCAT($s)";
438 return $s;
441 // returns concatenated string
442 // much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
443 function Concat()
445 $s = "";
446 $arr = func_get_args();
448 // suggestion by andrew005@mnogo.ru
449 $s = implode(',',$arr);
450 if (strlen($s) > 0) return "CONCAT($s)";
451 else return '';
454 // dayFraction is a day in floating point
455 function OffsetDate($dayFraction,$date=false)
457 if (!$date) $date = $this->sysDate;
459 $fraction = $dayFraction * 24 * 3600;
460 return $date . ' + INTERVAL ' . $fraction.' SECOND';
462 // return "from_unixtime(unix_timestamp($date)+$fraction)";
465 function &MetaTables($ttype=false,$showSchema=false,$mask=false)
467 $save = $this->metaTablesSQL;
468 if ($showSchema && is_string($showSchema)) {
469 $this->metaTablesSQL .= " from $showSchema";
472 if ($mask) {
473 $mask = $this->qstr($mask);
474 $this->metaTablesSQL .= " like $mask";
476 $ret =& ADOConnection::MetaTables($ttype,$showSchema);
478 $this->metaTablesSQL = $save;
479 return $ret;
482 // "Innox - Juan Carlos Gonzalez" <jgonzalez#innox.com.mx>
483 function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
485 global $ADODB_FETCH_MODE;
487 if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC) $associative = true;
489 if ( !empty($owner) ) {
490 $table = "$owner.$table";
492 $a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table));
493 if ($associative) $create_sql = $a_create_table["Create Table"];
494 else $create_sql = $a_create_table[1];
496 $matches = array();
498 if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false;
499 $foreign_keys = array();
500 $num_keys = count($matches[0]);
501 for ( $i = 0; $i < $num_keys; $i ++ ) {
502 $my_field = explode('`, `', $matches[1][$i]);
503 $ref_table = $matches[2][$i];
504 $ref_field = explode('`, `', $matches[3][$i]);
506 if ( $upper ) {
507 $ref_table = strtoupper($ref_table);
510 $foreign_keys[$ref_table] = array();
511 $num_fields = count($my_field);
512 for ( $j = 0; $j < $num_fields; $j ++ ) {
513 if ( $associative ) {
514 $foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j];
515 } else {
516 $foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}";
521 return $foreign_keys;
524 function &MetaColumns($table)
526 $false = false;
527 if (!$this->metaColumnsSQL)
528 return $false;
530 global $ADODB_FETCH_MODE;
531 $save = $ADODB_FETCH_MODE;
532 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
533 if ($this->fetchMode !== false)
534 $savem = $this->SetFetchMode(false);
535 $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
536 if (isset($savem)) $this->SetFetchMode($savem);
537 $ADODB_FETCH_MODE = $save;
538 if (!is_object($rs))
539 return $false;
541 $retarr = array();
542 while (!$rs->EOF) {
543 $fld = new ADOFieldObject();
544 $fld->name = $rs->fields[0];
545 $type = $rs->fields[1];
547 // split type into type(length):
548 $fld->scale = null;
549 if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
550 $fld->type = $query_array[1];
551 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
552 $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
553 } elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
554 $fld->type = $query_array[1];
555 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
556 } elseif (preg_match("/^(enum)\((.*)\)$/i", $type, $query_array)) {
557 $fld->type = $query_array[1];
558 $arr = explode(",",$query_array[2]);
559 $fld->enums = $arr;
560 $fld->max_length = max(array_map("strlen",explode(",",$query_array[2]))) - 2; // PHP >= 4.0.6
561 $fld->max_length = ($fld->max_length == 0 ? 1 : $fld->max_length);
562 } else {
563 $fld->type = $type;
564 $fld->max_length = -1;
566 $fld->not_null = ($rs->fields[2] != 'YES');
567 $fld->primary_key = ($rs->fields[3] == 'PRI');
568 $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
569 $fld->binary = (strpos($type,'blob') !== false);
570 $fld->unsigned = (strpos($type,'unsigned') !== false);
571 $fld->zerofill = (strpos($type,'zerofill') !== false);
573 if (!$fld->binary) {
574 $d = $rs->fields[4];
575 if ($d != '' && $d != 'NULL') {
576 $fld->has_default = true;
577 $fld->default_value = $d;
578 } else {
579 $fld->has_default = false;
583 if ($save == ADODB_FETCH_NUM) {
584 $retarr[] = $fld;
585 } else {
586 $retarr[strtoupper($fld->name)] = $fld;
588 $rs->MoveNext();
591 $rs->Close();
592 return $retarr;
595 // returns true or false
596 function SelectDB($dbName)
598 // $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
599 $this->database = $dbName;
600 $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
602 if ($this->_connectionID) {
603 $result = @mysqli_select_db($this->_connectionID, $dbName);
604 if (!$result) {
605 ADOConnection::outp("Select of database " . $dbName . " failed. " . $this->ErrorMsg());
607 return $result;
609 return false;
612 // parameters use PostgreSQL convention, not MySQL
613 function &SelectLimit($sql,
614 $nrows = -1,
615 $offset = -1,
616 $inputarr = false,
617 $secs = 0)
619 $offsetStr = ($offset >= 0) ? "$offset," : '';
620 if ($nrows < 0) $nrows = '18446744073709551615';
622 if ($secs)
623 $rs =& $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr);
624 else
625 $rs =& $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr);
627 return $rs;
631 function Prepare($sql)
633 return $sql;
635 $stmt = $this->_connectionID->prepare($sql);
636 if (!$stmt) {
637 echo $this->ErrorMsg();
638 return $sql;
640 return array($sql,$stmt);
644 // returns queryID or false
645 function _query($sql, $inputarr)
647 global $ADODB_COUNTRECS;
649 if (is_array($sql)) {
650 $stmt = $sql[1];
651 $a = '';
652 foreach($inputarr as $k => $v) {
653 if (is_string($v)) $a .= 's';
654 else if (is_integer($v)) $a .= 'i';
655 else $a .= 'd';
658 $fnarr = array_merge( array($stmt,$a) , $inputarr);
659 $ret = call_user_func_array('mysqli_stmt_bind_param',$fnarr);
661 $ret = mysqli_stmt_execute($stmt);
662 return $ret;
664 if (!$mysql_res = mysqli_query($this->_connectionID, $sql, ($ADODB_COUNTRECS) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT)) {
665 if ($this->debug) ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg());
666 return false;
669 return $mysql_res;
672 /* Returns: the last error message from previous database operation */
673 function ErrorMsg()
675 if (empty($this->_connectionID))
676 $this->_errorMsg = @mysqli_connect_error();
677 else
678 $this->_errorMsg = @mysqli_error($this->_connectionID);
679 return $this->_errorMsg;
682 /* Returns: the last error number from previous database operation */
683 function ErrorNo()
685 if (empty($this->_connectionID))
686 return @mysqli_connect_errno();
687 else
688 return @mysqli_errno($this->_connectionID);
691 // returns true or false
692 function _close()
694 @mysqli_close($this->_connectionID);
695 $this->_connectionID = false;
699 * Maximum size of C field
701 function CharMax()
703 return 255;
707 * Maximum size of X field
709 function TextMax()
711 return 4294967295;
716 // this is a set of functions for managing client encoding - very important if the encodings
717 // of your database and your output target (i.e. HTML) don't match
718 // for instance, you may have UTF8 database and server it on-site as latin1 etc.
719 // GetCharSet - get the name of the character set the client is using now
720 // Under Windows, the functions should work with MySQL 4.1.11 and above, the set of charsets supported
721 // depends on compile flags of mysql distribution
723 function GetCharSet()
725 //we will use ADO's builtin property charSet
726 if (!method_exists($this->_connectionID,'character_set_name'))
727 return false;
729 $this->charSet = @$this->_connectionID->character_set_name();
730 if (!$this->charSet) {
731 return false;
732 } else {
733 return $this->charSet;
737 // SetCharSet - switch the client encoding
738 function SetCharSet($charset_name)
740 if (!method_exists($this->_connectionID,'set_charset'))
741 return false;
743 if ($this->charSet !== $charset_name) {
744 $if = @$this->_connectionID->set_charset($charset_name);
745 if ($if == "0" & $this->GetCharSet() == $charset_name) {
746 return true;
747 } else return false;
748 } else return true;
756 /*--------------------------------------------------------------------------------------
757 Class Name: Recordset
758 --------------------------------------------------------------------------------------*/
760 class ADORecordSet_mysqli extends ADORecordSet{
762 var $databaseType = "mysqli";
763 var $canSeek = true;
765 function ADORecordSet_mysqli($queryID, $mode = false)
767 if ($mode === false)
769 global $ADODB_FETCH_MODE;
770 $mode = $ADODB_FETCH_MODE;
773 switch ($mode)
775 case ADODB_FETCH_NUM:
776 $this->fetchMode = MYSQLI_NUM;
777 break;
778 case ADODB_FETCH_ASSOC:
779 $this->fetchMode = MYSQLI_ASSOC;
780 break;
781 case ADODB_FETCH_DEFAULT:
782 case ADODB_FETCH_BOTH:
783 default:
784 $this->fetchMode = MYSQLI_BOTH;
785 break;
787 $this->adodbFetchMode = $mode;
788 $this->ADORecordSet($queryID);
791 function _initrs()
793 global $ADODB_COUNTRECS;
795 $this->_numOfRows = $ADODB_COUNTRECS ? @mysqli_num_rows($this->_queryID) : -1;
796 $this->_numOfFields = @mysqli_num_fields($this->_queryID);
800 1 = MYSQLI_NOT_NULL_FLAG
801 2 = MYSQLI_PRI_KEY_FLAG
802 4 = MYSQLI_UNIQUE_KEY_FLAG
803 8 = MYSQLI_MULTIPLE_KEY_FLAG
804 16 = MYSQLI_BLOB_FLAG
805 32 = MYSQLI_UNSIGNED_FLAG
806 64 = MYSQLI_ZEROFILL_FLAG
807 128 = MYSQLI_BINARY_FLAG
808 256 = MYSQLI_ENUM_FLAG
809 512 = MYSQLI_AUTO_INCREMENT_FLAG
810 1024 = MYSQLI_TIMESTAMP_FLAG
811 2048 = MYSQLI_SET_FLAG
812 32768 = MYSQLI_NUM_FLAG
813 16384 = MYSQLI_PART_KEY_FLAG
814 32768 = MYSQLI_GROUP_FLAG
815 65536 = MYSQLI_UNIQUE_FLAG
816 131072 = MYSQLI_BINCMP_FLAG
819 function &FetchField($fieldOffset = -1)
821 $fieldnr = $fieldOffset;
822 if ($fieldOffset != -1) {
823 $fieldOffset = mysqli_field_seek($this->_queryID, $fieldnr);
825 $o = mysqli_fetch_field($this->_queryID);
826 /* Properties of an ADOFieldObject as set by MetaColumns */
827 $o->primary_key = $o->flags & MYSQLI_PRI_KEY_FLAG;
828 $o->not_null = $o->flags & MYSQLI_NOT_NULL_FLAG;
829 $o->auto_increment = $o->flags & MYSQLI_AUTO_INCREMENT_FLAG;
830 $o->binary = $o->flags & MYSQLI_BINARY_FLAG;
831 // $o->blob = $o->flags & MYSQLI_BLOB_FLAG; /* not returned by MetaColumns */
832 $o->unsigned = $o->flags & MYSQLI_UNSIGNED_FLAG;
834 return $o;
837 function &GetRowAssoc($upper = true)
839 if ($this->fetchMode == MYSQLI_ASSOC && !$upper)
840 return $this->fields;
841 $row =& ADORecordSet::GetRowAssoc($upper);
842 return $row;
845 /* Use associative array to get fields array */
846 function Fields($colname)
848 if ($this->fetchMode != MYSQLI_NUM)
849 return @$this->fields[$colname];
851 if (!$this->bind) {
852 $this->bind = array();
853 for ($i = 0; $i < $this->_numOfFields; $i++) {
854 $o = $this->FetchField($i);
855 $this->bind[strtoupper($o->name)] = $i;
858 return $this->fields[$this->bind[strtoupper($colname)]];
861 function _seek($row)
863 if ($this->_numOfRows == 0)
864 return false;
866 if ($row < 0)
867 return false;
869 mysqli_data_seek($this->_queryID, $row);
870 $this->EOF = false;
871 return true;
874 // 10% speedup to move MoveNext to child class
875 // This is the only implementation that works now (23-10-2003).
876 // Other functions return no or the wrong results.
877 function MoveNext()
879 if ($this->EOF) return false;
880 $this->_currentRow++;
881 $this->fields = @mysqli_fetch_array($this->_queryID,$this->fetchMode);
883 if (is_array($this->fields)) return true;
884 $this->EOF = true;
885 return false;
888 function _fetch()
890 $this->fields = mysqli_fetch_array($this->_queryID,$this->fetchMode);
891 return is_array($this->fields);
894 function _close()
896 mysqli_free_result($this->_queryID);
897 $this->_queryID = false;
902 0 = MYSQLI_TYPE_DECIMAL
903 1 = MYSQLI_TYPE_CHAR
904 1 = MYSQLI_TYPE_TINY
905 2 = MYSQLI_TYPE_SHORT
906 3 = MYSQLI_TYPE_LONG
907 4 = MYSQLI_TYPE_FLOAT
908 5 = MYSQLI_TYPE_DOUBLE
909 6 = MYSQLI_TYPE_NULL
910 7 = MYSQLI_TYPE_TIMESTAMP
911 8 = MYSQLI_TYPE_LONGLONG
912 9 = MYSQLI_TYPE_INT24
913 10 = MYSQLI_TYPE_DATE
914 11 = MYSQLI_TYPE_TIME
915 12 = MYSQLI_TYPE_DATETIME
916 13 = MYSQLI_TYPE_YEAR
917 14 = MYSQLI_TYPE_NEWDATE
918 247 = MYSQLI_TYPE_ENUM
919 248 = MYSQLI_TYPE_SET
920 249 = MYSQLI_TYPE_TINY_BLOB
921 250 = MYSQLI_TYPE_MEDIUM_BLOB
922 251 = MYSQLI_TYPE_LONG_BLOB
923 252 = MYSQLI_TYPE_BLOB
924 253 = MYSQLI_TYPE_VAR_STRING
925 254 = MYSQLI_TYPE_STRING
926 255 = MYSQLI_TYPE_GEOMETRY
929 function MetaType($t, $len = -1, $fieldobj = false)
931 if (is_object($t)) {
932 $fieldobj = $t;
933 $t = $fieldobj->type;
934 $len = $fieldobj->max_length;
938 $len = -1; // mysql max_length is not accurate
939 switch (strtoupper($t)) {
940 case 'STRING':
941 case 'CHAR':
942 case 'VARCHAR':
943 case 'TINYBLOB':
944 case 'TINYTEXT':
945 case 'ENUM':
946 case 'SET':
948 case MYSQLI_TYPE_TINY_BLOB :
949 #case MYSQLI_TYPE_CHAR :
950 case MYSQLI_TYPE_STRING :
951 case MYSQLI_TYPE_ENUM :
952 case MYSQLI_TYPE_SET :
953 case 253 :
954 if ($len <= $this->blobSize) return 'C';
956 case 'TEXT':
957 case 'LONGTEXT':
958 case 'MEDIUMTEXT':
959 return 'X';
962 // php_mysql extension always returns 'blob' even if 'text'
963 // so we have to check whether binary...
964 case 'IMAGE':
965 case 'LONGBLOB':
966 case 'BLOB':
967 case 'MEDIUMBLOB':
969 case MYSQLI_TYPE_BLOB :
970 case MYSQLI_TYPE_LONG_BLOB :
971 case MYSQLI_TYPE_MEDIUM_BLOB :
973 return !empty($fieldobj->binary) ? 'B' : 'X';
974 case 'YEAR':
975 case 'DATE':
976 case MYSQLI_TYPE_DATE :
977 case MYSQLI_TYPE_YEAR :
979 return 'D';
981 case 'TIME':
982 case 'DATETIME':
983 case 'TIMESTAMP':
985 case MYSQLI_TYPE_DATETIME :
986 case MYSQLI_TYPE_NEWDATE :
987 case MYSQLI_TYPE_TIME :
988 case MYSQLI_TYPE_TIMESTAMP :
990 return 'T';
992 case 'INT':
993 case 'INTEGER':
994 case 'BIGINT':
995 case 'TINYINT':
996 case 'MEDIUMINT':
997 case 'SMALLINT':
999 case MYSQLI_TYPE_INT24 :
1000 case MYSQLI_TYPE_LONG :
1001 case MYSQLI_TYPE_LONGLONG :
1002 case MYSQLI_TYPE_SHORT :
1003 case MYSQLI_TYPE_TINY :
1005 if (!empty($fieldobj->primary_key)) return 'R';
1007 return 'I';
1010 // Added floating-point types
1011 // Maybe not necessery.
1012 case 'FLOAT':
1013 case 'DOUBLE':
1014 // case 'DOUBLE PRECISION':
1015 case 'DECIMAL':
1016 case 'DEC':
1017 case 'FIXED':
1018 default:
1019 //if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>";
1020 return 'N';
1022 } // function
1025 } // rs class
1029 class ADORecordSet_array_mysqli extends ADORecordSet_array {
1030 function ADORecordSet_array_mysqli($id=-1,$mode=false)
1032 $this->ADORecordSet_array($id,$mode);
1036 function MetaType($t, $len = -1, $fieldobj = false)
1038 if (is_object($t)) {
1039 $fieldobj = $t;
1040 $t = $fieldobj->type;
1041 $len = $fieldobj->max_length;
1045 $len = -1; // mysql max_length is not accurate
1046 switch (strtoupper($t)) {
1047 case 'STRING':
1048 case 'CHAR':
1049 case 'VARCHAR':
1050 case 'TINYBLOB':
1051 case 'TINYTEXT':
1052 case 'ENUM':
1053 case 'SET':
1055 case MYSQLI_TYPE_TINY_BLOB :
1056 #case MYSQLI_TYPE_CHAR :
1057 case MYSQLI_TYPE_STRING :
1058 case MYSQLI_TYPE_ENUM :
1059 case MYSQLI_TYPE_SET :
1060 case 253 :
1061 if ($len <= $this->blobSize) return 'C';
1063 case 'TEXT':
1064 case 'LONGTEXT':
1065 case 'MEDIUMTEXT':
1066 return 'X';
1069 // php_mysql extension always returns 'blob' even if 'text'
1070 // so we have to check whether binary...
1071 case 'IMAGE':
1072 case 'LONGBLOB':
1073 case 'BLOB':
1074 case 'MEDIUMBLOB':
1076 case MYSQLI_TYPE_BLOB :
1077 case MYSQLI_TYPE_LONG_BLOB :
1078 case MYSQLI_TYPE_MEDIUM_BLOB :
1080 return !empty($fieldobj->binary) ? 'B' : 'X';
1081 case 'YEAR':
1082 case 'DATE':
1083 case MYSQLI_TYPE_DATE :
1084 case MYSQLI_TYPE_YEAR :
1086 return 'D';
1088 case 'TIME':
1089 case 'DATETIME':
1090 case 'TIMESTAMP':
1092 case MYSQLI_TYPE_DATETIME :
1093 case MYSQLI_TYPE_NEWDATE :
1094 case MYSQLI_TYPE_TIME :
1095 case MYSQLI_TYPE_TIMESTAMP :
1097 return 'T';
1099 case 'INT':
1100 case 'INTEGER':
1101 case 'BIGINT':
1102 case 'TINYINT':
1103 case 'MEDIUMINT':
1104 case 'SMALLINT':
1106 case MYSQLI_TYPE_INT24 :
1107 case MYSQLI_TYPE_LONG :
1108 case MYSQLI_TYPE_LONGLONG :
1109 case MYSQLI_TYPE_SHORT :
1110 case MYSQLI_TYPE_TINY :
1112 if (!empty($fieldobj->primary_key)) return 'R';
1114 return 'I';
1117 // Added floating-point types
1118 // Maybe not necessery.
1119 case 'FLOAT':
1120 case 'DOUBLE':
1121 // case 'DOUBLE PRECISION':
1122 case 'DECIMAL':
1123 case 'DEC':
1124 case 'FIXED':
1125 default:
1126 //if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>";
1127 return 'N';
1129 } // function