"TYPO3 4.0.1: typo3_src-4.0.1/typo3/sysext/adodb/adodb/drivers/adodb-mysqli.inc.php Source File", "datetime" => "Sat Dec 2 19:22:26 2006", "date" => "2 Dec 2006", "doxygenversion" => "1.4.6", "projectname" => "TYPO3 4.0.1", "projectnumber" => "4.0.1" ); get_header($doxygen_vars); ?>

adodb-mysqli.inc.php

00001 <?php
00002 /*
00003 V4.90 8 June 2006  (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved.
00004   Released under both BSD license and Lesser GPL library license. 
00005   Whenever there is any discrepancy between the two licenses, 
00006   the BSD license will take precedence.
00007   Set tabs to 8.
00008   
00009   MySQL code that does not support transactions. Use mysqlt if you need transactions.
00010   Requires mysql client. Works on Windows and Unix.
00011  
00012 21 October 2003: MySQLi extension implementation by Arjen de Rijke (a.de.rijke@xs4all.nl)
00013 Based on adodb 3.40
00014 */ 
00015 
00016 // security - hide paths
00017 //if (!defined('ADODB_DIR')) die();
00018 
00019 if (! defined("_ADODB_MYSQLI_LAYER")) {
00020  define("_ADODB_MYSQLI_LAYER", 1 );
00021  
00022  // PHP5 compat...
00023  if (! defined("MYSQLI_BINARY_FLAG"))  define("MYSQLI_BINARY_FLAG", 128); 
00024  if (!defined('MYSQLI_READ_DEFAULT_GROUP')) define('MYSQLI_READ_DEFAULT_GROUP',1);
00025 
00026  // disable adodb extension - currently incompatible.
00027  global $ADODB_EXTENSION; $ADODB_EXTENSION = false;
00028 
00029 class ADODB_mysqli extends ADOConnection {
00030         var $databaseType = 'mysqli';
00031         var $dataProvider = 'native';
00032         var $hasInsertID = true;
00033         var $hasAffectedRows = true;    
00034         var $metaTablesSQL = "SHOW TABLES";     
00035         var $metaColumnsSQL = "SHOW COLUMNS FROM %s";
00036         var $fmtTimeStamp = "'Y-m-d H:i:s'";
00037         var $hasLimit = true;
00038         var $hasMoveFirst = true;
00039         var $hasGenID = true;
00040         var $isoDates = true; // accepts dates in ISO format
00041         var $sysDate = 'CURDATE()';
00042         var $sysTimeStamp = 'NOW()';
00043         var $hasTransactions = true;
00044         var $forceNewConnect = false;
00045         var $poorAffectedRows = true;
00046         var $clientFlags = 0;
00047         var $substr = "substring";
00048         var $port = false;
00049         var $socket = false;
00050         var $_bindInputArray = false;
00051         var $nameQuote = '`';           
00052         var $optionFlags = array(array(MYSQLI_READ_DEFAULT_GROUP,0));
00053         
00054         function ADODB_mysqli() 
00055         {                       
00056          // if(!extension_loaded("mysqli"))
00057               ;//trigger_error("You must have the mysqli extension installed.", E_USER_ERROR);
00058             
00059         }
00060         
00061         function SetTransactionMode( $transaction_mode ) 
00062         {
00063                 $this->_transmode  = $transaction_mode;
00064                 if (empty($transaction_mode)) {
00065                         $this->Execute('SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ');
00066                         return;
00067                 }
00068                 if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
00069                 $this->Execute("SET SESSION TRANSACTION ".$transaction_mode);
00070         }
00071 
00072         // returns true or false
00073         // To add: parameter int $port,
00074         //         parameter string $socket
00075         function _connect($argHostname = NULL, 
00076                           $argUsername = NULL, 
00077                           $argPassword = NULL, 
00078                           $argDatabasename = NULL, $persist=false)
00079           {
00080                  if(!extension_loaded("mysqli")) {
00081                         return null;
00082                  }
00083             $this->_connectionID = @mysqli_init();
00084             
00085             if (is_null($this->_connectionID)) {
00086               // mysqli_init only fails if insufficient memory
00087               if ($this->debug) 
00088                                 ADOConnection::outp("mysqli_init() failed : "  . $this->ErrorMsg());
00089               return false;
00090             }
00091                 /*
00092                 I suggest a simple fix which would enable adodb and mysqli driver to
00093                 read connection options from the standard mysql configuration file
00094                 /etc/my.cnf - "Bastien Duclaux" <bduclaux#yahoo.com>
00095                 */
00096                 foreach($this->optionFlags as $arr) {   
00097                         mysqli_options($this->_connectionID,$arr[0],$arr[1]);
00098                 }
00099 
00100                 #if (!empty($this->port)) $argHostname .= ":".$this->port;
00101                 $ok = mysqli_real_connect($this->_connectionID,
00102                                     $argHostname,
00103                                     $argUsername,
00104                                     $argPassword,
00105                                     $argDatabasename,
00106                                         $this->port,
00107                                         $this->socket,
00108                                         $this->clientFlags);
00109              
00110                 if ($ok) {
00111                         if ($argDatabasename)  return $this->SelectDB($argDatabasename);
00112                         return true;
00113            } else {
00114                         if ($this->debug) 
00115                                 ADOConnection::outp("Could't connect : "  . $this->ErrorMsg());
00116                         return false;
00117            }
00118         }
00119         
00120         // returns true or false
00121         // How to force a persistent connection
00122         function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
00123         {
00124                 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, true);
00125 
00126         }
00127         
00128         // When is this used? Close old connection first?
00129         // In _connect(), check $this->forceNewConnect? 
00130         function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
00131           {
00132             $this->forceNewConnect = true;
00133             return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
00134           }
00135         
00136         function IfNull( $field, $ifNull ) 
00137         {
00138                 return " IFNULL($field, $ifNull) "; // if MySQL
00139         }
00140         
00141         function ServerInfo()
00142         {
00143                 $arr['description'] = $this->GetOne("select version()");
00144                 $arr['version'] = ADOConnection::_findvers($arr['description']);
00145                 return $arr;
00146         }
00147         
00148         
00149         function BeginTrans()
00150         {         
00151                 if ($this->transOff) return true;
00152                 $this->transCnt += 1;
00153                 $this->Execute('SET AUTOCOMMIT=0');
00154                 $this->Execute('BEGIN');
00155                 return true;
00156         }
00157         
00158         function CommitTrans($ok=true) 
00159         {
00160                 if ($this->transOff) return true; 
00161                 if (!$ok) return $this->RollbackTrans();
00162                 
00163                 if ($this->transCnt) $this->transCnt -= 1;
00164                 $this->Execute('COMMIT');
00165                 $this->Execute('SET AUTOCOMMIT=1');
00166                 return true;
00167         }
00168         
00169         function RollbackTrans()
00170         {
00171                 if ($this->transOff) return true;
00172                 if ($this->transCnt) $this->transCnt -= 1;
00173                 $this->Execute('ROLLBACK');
00174                 $this->Execute('SET AUTOCOMMIT=1');
00175                 return true;
00176         }
00177         
00178         function RowLock($tables,$where='',$flds='1 as adodb_ignore') 
00179         {
00180                 if ($this->transCnt==0) $this->BeginTrans();
00181                 if ($where) $where = ' where '.$where;
00182                 $rs =& $this->Execute("select $flds from $tables $where for update");
00183                 return !empty($rs); 
00184         }
00185         
00186         // if magic quotes disabled, use mysql_real_escape_string()
00187         // From readme.htm:
00188         // Quotes a string to be sent to the database. The $magic_quotes_enabled
00189         // parameter may look funny, but the idea is if you are quoting a 
00190         // string extracted from a POST/GET variable, then 
00191         // pass get_magic_quotes_gpc() as the second parameter. This will 
00192         // ensure that the variable is not quoted twice, once by qstr and once 
00193         // by the magic_quotes_gpc.
00194         //
00195         //Eg. $s = $db->qstr(_GET['name'],get_magic_quotes_gpc());
00196         function qstr($s, $magic_quotes = false)
00197         {
00198                 if (!$magic_quotes) {
00199                 if (PHP_VERSION >= 5)
00200                         return "'" . mysqli_real_escape_string($this->_connectionID, $s) . "'";   
00201             
00202                 if ($this->replaceQuote[0] == '\\')
00203                         $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
00204             return  "'".str_replace("'",$this->replaceQuote,$s)."'"; 
00205           }
00206           // undo magic quotes for "
00207           $s = str_replace('\\"','"',$s);
00208           return "'$s'";
00209         }
00210         
00211         function _insertid()
00212         {
00213           $result = @mysqli_insert_id($this->_connectionID);
00214           if ($result == -1){
00215               if ($this->debug) ADOConnection::outp("mysqli_insert_id() failed : "  . $this->ErrorMsg());
00216           }
00217           return $result;
00218         }
00219         
00220         // Only works for INSERT, UPDATE and DELETE query's
00221         function _affectedrows()
00222         {
00223           $result =  @mysqli_affected_rows($this->_connectionID);
00224           if ($result == -1) {
00225               if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : "  . $this->ErrorMsg());
00226           }
00227           return $result;
00228         }
00229   
00230         // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
00231         // Reference on Last_Insert_ID on the recommended way to simulate sequences
00232         var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
00233         var $_genSeqSQL = "create table %s (id int not null)";
00234         var $_genSeq2SQL = "insert into %s values (%s)";
00235         var $_dropSeqSQL = "drop table %s";
00236         
00237         function CreateSequence($seqname='adodbseq',$startID=1)
00238         {
00239                 if (empty($this->_genSeqSQL)) return false;
00240                 $u = strtoupper($seqname);
00241                 
00242                 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
00243                 if (!$ok) return false;
00244                 return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
00245         }
00246         
00247         function GenID($seqname='adodbseq',$startID=1)
00248         {
00249                 // post-nuke sets hasGenID to false
00250                 if (!$this->hasGenID) return false;
00251                 
00252                 $getnext = sprintf($this->_genIDSQL,$seqname);
00253                 $holdtransOK = $this->_transOK; // save the current status
00254                 $rs = @$this->Execute($getnext);
00255                 if (!$rs) {
00256                         if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
00257                         $u = strtoupper($seqname);
00258                         $this->Execute(sprintf($this->_genSeqSQL,$seqname));
00259                         $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
00260                         $rs = $this->Execute($getnext);
00261                 }
00262                 $this->genID = mysqli_insert_id($this->_connectionID);
00263                 
00264                 if ($rs) $rs->Close();
00265                 
00266                 return $this->genID;
00267         }
00268         
00269         function &MetaDatabases()
00270         {
00271                 $query = "SHOW DATABASES";
00272                 $ret =& $this->Execute($query);
00273                 if ($ret && is_object($ret)){
00274                    $arr = array();
00275                         while (!$ret->EOF){
00276                                 $db = $ret->Fields('Database');
00277                                 if ($db != 'mysql') $arr[] = $db;
00278                                 $ret->MoveNext();
00279                         }
00280                    return $arr;
00281                 }
00282         return $ret;
00283         }
00284 
00285           
00286         function &MetaIndexes ($table, $primary = FALSE)
00287         {
00288                 // save old fetch mode
00289                 global $ADODB_FETCH_MODE;
00290                 
00291                 $false = false;
00292                 $save = $ADODB_FETCH_MODE;
00293                 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00294                 if ($this->fetchMode !== FALSE) {
00295                        $savem = $this->SetFetchMode(FALSE);
00296                 }
00297                 
00298                 // get index details
00299                 $rs = $this->Execute(sprintf('SHOW INDEXES FROM %s',$table));
00300                 
00301                 // restore fetchmode
00302                 if (isset($savem)) {
00303                         $this->SetFetchMode($savem);
00304                 }
00305                 $ADODB_FETCH_MODE = $save;
00306                 
00307                 if (!is_object($rs)) {
00308                         return $false;
00309                 }
00310                 
00311                 $indexes = array ();
00312                 
00313                 // parse index data into array
00314                 while ($row = $rs->FetchRow()) {
00315                         if ($primary == FALSE AND $row[2] == 'PRIMARY') {
00316                                 continue;
00317                         }
00318                         
00319                         if (!isset($indexes[$row[2]])) {
00320                                 $indexes[$row[2]] = array(
00321                                         'unique' => ($row[1] == 0),
00322                                         'columns' => array()
00323                                 );
00324                         }
00325                         
00326                         $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
00327                 }
00328                 
00329                 // sort columns by order in the index
00330                 foreach ( array_keys ($indexes) as $index )
00331                 {
00332                         ksort ($indexes[$index]['columns']);
00333                 }
00334                 
00335                 return $indexes;
00336         }
00337 
00338         
00339         // Format date column in sql string given an input format that understands Y M D
00340         function SQLDate($fmt, $col=false)
00341         {       
00342                 if (!$col) $col = $this->sysTimeStamp;
00343                 $s = 'DATE_FORMAT('.$col.",'";
00344                 $concat = false;
00345                 $len = strlen($fmt);
00346                 for ($i=0; $i < $len; $i++) {
00347                         $ch = $fmt[$i];
00348                         switch($ch) {
00349                         case 'Y':
00350                         case 'y':
00351                                 $s .= '%Y';
00352                                 break;
00353                         case 'Q':
00354                         case 'q':
00355                                 $s .= "'),Quarter($col)";
00356                                 
00357                                 if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
00358                                 else $s .= ",('";
00359                                 $concat = true;
00360                                 break;
00361                         case 'M':
00362                                 $s .= '%b';
00363                                 break;
00364                                 
00365                         case 'm':
00366                                 $s .= '%m';
00367                                 break;
00368                         case 'D':
00369                         case 'd':
00370                                 $s .= '%d';
00371                                 break;
00372                         
00373                         case 'H': 
00374                                 $s .= '%H';
00375                                 break;
00376                                 
00377                         case 'h':
00378                                 $s .= '%I';
00379                                 break;
00380                                 
00381                         case 'i':
00382                                 $s .= '%i';
00383                                 break;
00384                                 
00385                         case 's':
00386                                 $s .= '%s';
00387                                 break;
00388                                 
00389                         case 'a':
00390                         case 'A':
00391                                 $s .= '%p';
00392                                 break;
00393                         
00394                         case 'w':
00395                                 $s .= '%w';
00396                                 break;
00397                                 
00398                         case 'l':
00399                                 $s .= '%W';
00400                                 break;
00401                                 
00402                         default:
00403                                 
00404                                 if ($ch == '\\') {
00405                                         $i++;
00406                                         $ch = substr($fmt,$i,1);
00407                                 }
00408                                 $s .= $ch;
00409                                 break;
00410                         }
00411                 }
00412                 $s.="')";
00413                 if ($concat) $s = "CONCAT($s)";
00414                 return $s;
00415         }
00416         
00417         // returns concatenated string
00418         // much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
00419         function Concat()
00420         {
00421                 $s = "";
00422                 $arr = func_get_args();
00423                 
00424                 // suggestion by andrew005@mnogo.ru
00425                 $s = implode(',',$arr); 
00426                 if (strlen($s) > 0) return "CONCAT($s)";
00427                 else return '';
00428         }
00429         
00430         // dayFraction is a day in floating point
00431         function OffsetDate($dayFraction,$date=false)
00432         {               
00433                 if (!$date) 
00434                   $date = $this->sysDate;
00435                 return "from_unixtime(unix_timestamp($date)+($dayFraction)*24*3600)";
00436         }
00437         
00438         function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
00439         {       
00440                 $save = $this->metaTablesSQL;
00441                 if ($showSchema && is_string($showSchema)) {
00442                         $this->metaTablesSQL .= " from $showSchema";
00443                 }
00444                 
00445                 if ($mask) {
00446                         $mask = $this->qstr($mask);
00447                         $this->metaTablesSQL .= " like $mask";
00448                 }
00449                 $ret =& ADOConnection::MetaTables($ttype,$showSchema);
00450                 
00451                 $this->metaTablesSQL = $save;
00452                 return $ret;
00453         }
00454         
00455         // "Innox - Juan Carlos Gonzalez" <jgonzalez#innox.com.mx>
00456         function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
00457         {
00458          global $ADODB_FETCH_MODE;
00459                 
00460                 if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC) $associative = true;
00461                 
00462             if ( !empty($owner) ) {
00463                $table = "$owner.$table";
00464             }
00465             $a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table));
00466                 if ($associative) $create_sql = $a_create_table["Create Table"];
00467             else $create_sql  = $a_create_table[1];
00468         
00469             $matches = array();
00470         
00471             if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false;
00472                 $foreign_keys = array();                 
00473             $num_keys = count($matches[0]);
00474             for ( $i = 0;  $i < $num_keys;  $i ++ ) {
00475                 $my_field  = explode('`, `', $matches[1][$i]);
00476                 $ref_table = $matches[2][$i];
00477                 $ref_field = explode('`, `', $matches[3][$i]);
00478         
00479                 if ( $upper ) {
00480                     $ref_table = strtoupper($ref_table);
00481                 }
00482         
00483                 $foreign_keys[$ref_table] = array();
00484                 $num_fields               = count($my_field);
00485                 for ( $j = 0;  $j < $num_fields;  $j ++ ) {
00486                     if ( $associative ) {
00487                         $foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j];
00488                     } else {
00489                         $foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}";
00490                     }
00491                 }
00492             }
00493             
00494             return  $foreign_keys;
00495         }
00496         
00497         function &MetaColumns($table) 
00498         {
00499                 $false = false;
00500                 if (!$this->metaColumnsSQL)
00501                         return $false;
00502                 
00503                 global $ADODB_FETCH_MODE;
00504                 $save = $ADODB_FETCH_MODE;
00505                 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00506                 if ($this->fetchMode !== false)
00507                         $savem = $this->SetFetchMode(false);
00508                 $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
00509                 if (isset($savem)) $this->SetFetchMode($savem);
00510                 $ADODB_FETCH_MODE = $save;
00511                 if (!is_object($rs))
00512                         return $false;
00513                 
00514                 $retarr = array();
00515                 while (!$rs->EOF) {
00516                         $fld = new ADOFieldObject();
00517                         $fld->name = $rs->fields[0];
00518                         $type = $rs->fields[1];
00519                         
00520                         // split type into type(length):
00521                         $fld->scale = null;
00522                         if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
00523                                 $fld->type = $query_array[1];
00524                                 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
00525                                 $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
00526                         } elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
00527                                 $fld->type = $query_array[1];
00528                                 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
00529                         } elseif (preg_match("/^(enum)\((.*)\)$/i", $type, $query_array)) {
00530                                 $fld->type = $query_array[1];
00531                                 $fld->max_length = max(array_map("strlen",explode(",",$query_array[2]))) - 2; // PHP >= 4.0.6
00532                                 $fld->max_length = ($fld->max_length == 0 ? 1 : $fld->max_length);
00533                         } else {
00534                                 $fld->type = $type;
00535                                 $fld->max_length = -1;
00536                         }
00537                         $fld->not_null = ($rs->fields[2] != 'YES');
00538                         $fld->primary_key = ($rs->fields[3] == 'PRI');
00539                         $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
00540                         $fld->binary = (strpos($type,'blob') !== false);
00541                         $fld->unsigned = (strpos($type,'unsigned') !== false);
00542 
00543                         if (!$fld->binary) {
00544                                 $d = $rs->fields[4];
00545                                 if ($d != '' && $d != 'NULL') {
00546                                         $fld->has_default = true;
00547                                         $fld->default_value = $d;
00548                                 } else {
00549                                         $fld->has_default = false;
00550                                 }
00551                         }
00552                         
00553                         if ($save == ADODB_FETCH_NUM) {
00554                                 $retarr[] = $fld;
00555                         } else {
00556                                 $retarr[strtoupper($fld->name)] = $fld;
00557                         }
00558                         $rs->MoveNext();
00559                 }
00560                 
00561                 $rs->Close();
00562                 return $retarr;
00563         }
00564                 
00565         // returns true or false
00566         function SelectDB($dbName) 
00567         {
00568 //          $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
00569             $this->database = $dbName;
00570                 $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
00571                 
00572             if ($this->_connectionID) {
00573                 $result = @mysqli_select_db($this->_connectionID, $dbName);
00574                         if (!$result) {
00575                         ADOConnection::outp("Select of database " . $dbName . " failed. " . $this->ErrorMsg());
00576                         }
00577                         return $result;         
00578                 }
00579             return false;       
00580         }
00581         
00582         // parameters use PostgreSQL convention, not MySQL
00583         function &SelectLimit($sql,
00584                               $nrows = -1,
00585                               $offset = -1,
00586                               $inputarr = false, 
00587                               $arg3 = false,
00588                               $secs = 0)
00589         {
00590                 $offsetStr = ($offset >= 0) ? "$offset," : '';
00591                 if ($nrows < 0) $nrows = '18446744073709551615';
00592                 
00593                 if ($secs)
00594                         $rs =& $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr , $arg3);
00595                 else
00596                         $rs =& $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr , $arg3);
00597                         
00598                 return $rs;
00599         }
00600         
00601         
00602         function Prepare($sql)
00603         {
00604                 return $sql;
00605                 
00606                 $stmt = $this->_connectionID->prepare($sql);
00607                 if (!$stmt) {
00608                         echo $this->ErrorMsg();
00609                         return $sql;
00610                 }
00611                 return array($sql,$stmt);
00612         }
00613         
00614         
00615         // returns queryID or false
00616         function _query($sql, $inputarr)
00617         {
00618         global $ADODB_COUNTRECS;
00619                 
00620                 if (is_array($sql)) {
00621                         $stmt = $sql[1];
00622                         $a = '';
00623                         foreach($inputarr as $k => $v) {
00624                                 if (is_string($v)) $a .= 's';
00625                                 else if (is_integer($v)) $a .= 'i'; 
00626                                 else $a .= 'd';
00627                         }
00628                         
00629                         $fnarr = array_merge( array($stmt,$a) , $inputarr);
00630                         $ret = call_user_func_array('mysqli_stmt_bind_param',$fnarr);
00631 
00632                         $ret = mysqli_stmt_execute($stmt);
00633                         return $ret;
00634                 }
00635                 if (!$mysql_res =  mysqli_query($this->_connectionID, $sql, ($ADODB_COUNTRECS) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT)) {
00636                     if ($this->debug) ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg());
00637                     return false;
00638                 }
00639                 
00640                 return $mysql_res;
00641         }
00642 
00643         /*      Returns: the last error message from previous database operation        */      
00644         function ErrorMsg() 
00645           {
00646             if (empty($this->_connectionID)) 
00647               $this->_errorMsg = @mysqli_connect_error();
00648             else 
00649               $this->_errorMsg = @mysqli_error($this->_connectionID);
00650             return $this->_errorMsg;
00651           }
00652         
00653         /*      Returns: the last error number from previous database operation */      
00654         function ErrorNo() 
00655           {
00656             if (empty($this->_connectionID))  
00657               return @mysqli_connect_errno();
00658             else 
00659               return @mysqli_errno($this->_connectionID);
00660           }
00661         
00662         // returns true or false
00663         function _close()
00664           {
00665             @mysqli_close($this->_connectionID);
00666             $this->_connectionID = false;
00667           }
00668 
00669         /*
00670         * Maximum size of C field
00671         */
00672         function CharMax()
00673         {
00674                 return 255; 
00675         }
00676         
00677         /*
00678         * Maximum size of X field
00679         */
00680         function TextMax()
00681         {
00682           return 4294967295; 
00683         }
00684 
00685 
00686 
00687         // this is a set of functions for managing client encoding - very important if the encodings
00688         // of your database and your output target (i.e. HTML) don't match
00689         // for instance, you may have UTF8 database and server it on-site as latin1 etc.
00690         // GetCharSet - get the name of the character set the client is using now
00691         // Under Windows, the functions should work with MySQL 4.1.11 and above, the set of charsets supported
00692         // depends on compile flags of mysql distribution 
00693 
00694   function GetCharSet()
00695   {
00696     //we will use ADO's builtin property charSet
00697     if (!method_exists($this->_connectionID,'character_set_name'))
00698         return false;
00699         
00700     $this->charSet = @$this->_connectionID->character_set_name();
00701     if (!$this->charSet) {
00702       return false;
00703     } else {
00704       return $this->charSet;
00705     }
00706   }
00707 
00708   // SetCharSet - switch the client encoding
00709   function SetCharSet($charset_name)
00710   {
00711     if (!method_exists($this->_connectionID,'set_charset'))
00712         return false;
00713 
00714     if ($this->charSet !== $charset_name) {
00715       $if = @$this->_connectionID->set_charset($charset_name);
00716       if ($if == "0" & $this->GetCharSet() == $charset_name) {
00717         return true;
00718       } else return false;
00719     } else return true;
00720   }
00721 
00722 
00723 
00724 
00725 }
00726  
00727 /*--------------------------------------------------------------------------------------
00728          Class Name: Recordset
00729 --------------------------------------------------------------------------------------*/
00730 
00731 class ADORecordSet_mysqli extends ADORecordSet{ 
00732         
00733         var $databaseType = "mysqli";
00734         var $canSeek = true;
00735         
00736         function ADORecordSet_mysqli($queryID, $mode = false) 
00737         {
00738           if ($mode === false) 
00739            { 
00740               global $ADODB_FETCH_MODE;
00741               $mode = $ADODB_FETCH_MODE;
00742            }
00743            
00744           switch ($mode)
00745             {
00746             case ADODB_FETCH_NUM: 
00747               $this->fetchMode = MYSQLI_NUM; 
00748               break;
00749             case ADODB_FETCH_ASSOC:
00750               $this->fetchMode = MYSQLI_ASSOC; 
00751               break;
00752             case ADODB_FETCH_DEFAULT:
00753             case ADODB_FETCH_BOTH:
00754             default:
00755               $this->fetchMode = MYSQLI_BOTH; 
00756               break;
00757             }
00758           $this->adodbFetchMode = $mode;
00759           $this->ADORecordSet($queryID);        
00760         }
00761         
00762         function _initrs()
00763         {
00764         global $ADODB_COUNTRECS;
00765         
00766                 $this->_numOfRows = $ADODB_COUNTRECS ? @mysqli_num_rows($this->_queryID) : -1;
00767                 $this->_numOfFields = @mysqli_num_fields($this->_queryID);
00768         }
00769         
00770 /*
00771 1      = MYSQLI_NOT_NULL_FLAG
00772 2      = MYSQLI_PRI_KEY_FLAG
00773 4      = MYSQLI_UNIQUE_KEY_FLAG
00774 8      = MYSQLI_MULTIPLE_KEY_FLAG
00775 16     = MYSQLI_BLOB_FLAG
00776 32     = MYSQLI_UNSIGNED_FLAG
00777 64     = MYSQLI_ZEROFILL_FLAG
00778 128    = MYSQLI_BINARY_FLAG
00779 256    = MYSQLI_ENUM_FLAG
00780 512    = MYSQLI_AUTO_INCREMENT_FLAG
00781 1024   = MYSQLI_TIMESTAMP_FLAG
00782 2048   = MYSQLI_SET_FLAG
00783 32768  = MYSQLI_NUM_FLAG
00784 16384  = MYSQLI_PART_KEY_FLAG
00785 32768  = MYSQLI_GROUP_FLAG
00786 65536  = MYSQLI_UNIQUE_FLAG
00787 131072 = MYSQLI_BINCMP_FLAG
00788 */
00789 
00790         function &FetchField($fieldOffset = -1) 
00791         {       
00792                 $fieldnr = $fieldOffset;
00793                 if ($fieldOffset != -1) {
00794                   $fieldOffset = mysqli_field_seek($this->_queryID, $fieldnr);
00795                 }
00796                 $o = mysqli_fetch_field($this->_queryID);
00797                 /* Properties of an ADOFieldObject as set by MetaColumns */
00798                 $o->primary_key = $o->flags & MYSQLI_PRI_KEY_FLAG;
00799                 $o->not_null = $o->flags & MYSQLI_NOT_NULL_FLAG;
00800                 $o->auto_increment = $o->flags & MYSQLI_AUTO_INCREMENT_FLAG;
00801                 $o->binary = $o->flags & MYSQLI_BINARY_FLAG;
00802                 // $o->blob = $o->flags & MYSQLI_BLOB_FLAG; /* not returned by MetaColumns */
00803                 $o->unsigned = $o->flags & MYSQLI_UNSIGNED_FLAG;
00804 
00805                 return $o;
00806         }
00807 
00808         function &GetRowAssoc($upper = true)
00809         {
00810                 if ($this->fetchMode == MYSQLI_ASSOC && !$upper) 
00811                   return $this->fields;
00812                 $row =& ADORecordSet::GetRowAssoc($upper);
00813                 return $row;
00814         }
00815         
00816         /* Use associative array to get fields array */
00817         function Fields($colname)
00818         {       
00819           if ($this->fetchMode != MYSQLI_NUM) 
00820             return @$this->fields[$colname];
00821                 
00822           if (!$this->bind) {
00823             $this->bind = array();
00824             for ($i = 0; $i < $this->_numOfFields; $i++) {
00825               $o = $this->FetchField($i);
00826               $this->bind[strtoupper($o->name)] = $i;
00827             }
00828           }
00829           return $this->fields[$this->bind[strtoupper($colname)]];
00830         }
00831         
00832         function _seek($row)
00833         {
00834           if ($this->_numOfRows == 0) 
00835             return false;
00836 
00837           if ($row < 0)
00838             return false;
00839 
00840           mysqli_data_seek($this->_queryID, $row);
00841           $this->EOF = false;
00842           return true;
00843         }
00844                 
00845         // 10% speedup to move MoveNext to child class
00846         // This is the only implementation that works now (23-10-2003).
00847         // Other functions return no or the wrong results.
00848         function MoveNext() 
00849         {
00850                 if ($this->EOF) return false;
00851                 $this->_currentRow++;
00852                 $this->fields = @mysqli_fetch_array($this->_queryID,$this->fetchMode);
00853                 
00854                 if (is_array($this->fields)) return true;
00855                 $this->EOF = true;
00856                 return false;
00857         }       
00858         
00859         function _fetch()
00860         {
00861                 $this->fields = mysqli_fetch_array($this->_queryID,$this->fetchMode);  
00862                 return is_array($this->fields);
00863         }
00864         
00865         function _close() 
00866         {
00867                 mysqli_free_result($this->_queryID); 
00868                 $this->_queryID = false;        
00869         }
00870         
00871 /*
00872 
00873 0 = MYSQLI_TYPE_DECIMAL
00874 1 = MYSQLI_TYPE_CHAR
00875 1 = MYSQLI_TYPE_TINY
00876 2 = MYSQLI_TYPE_SHORT
00877 3 = MYSQLI_TYPE_LONG
00878 4 = MYSQLI_TYPE_FLOAT
00879 5 = MYSQLI_TYPE_DOUBLE
00880 6 = MYSQLI_TYPE_NULL
00881 7 = MYSQLI_TYPE_TIMESTAMP
00882 8 = MYSQLI_TYPE_LONGLONG
00883 9 = MYSQLI_TYPE_INT24
00884 10 = MYSQLI_TYPE_DATE
00885 11 = MYSQLI_TYPE_TIME
00886 12 = MYSQLI_TYPE_DATETIME
00887 13 = MYSQLI_TYPE_YEAR
00888 14 = MYSQLI_TYPE_NEWDATE
00889 247 = MYSQLI_TYPE_ENUM
00890 248 = MYSQLI_TYPE_SET
00891 249 = MYSQLI_TYPE_TINY_BLOB
00892 250 = MYSQLI_TYPE_MEDIUM_BLOB
00893 251 = MYSQLI_TYPE_LONG_BLOB
00894 252 = MYSQLI_TYPE_BLOB
00895 253 = MYSQLI_TYPE_VAR_STRING
00896 254 = MYSQLI_TYPE_STRING
00897 255 = MYSQLI_TYPE_GEOMETRY
00898 */
00899 
00900         function MetaType($t, $len = -1, $fieldobj = false)
00901         {
00902                 if (is_object($t)) {
00903                     $fieldobj = $t;
00904                     $t = $fieldobj->type;
00905                     $len = $fieldobj->max_length;
00906                 }
00907                 
00908                 
00909                  $len = -1; // mysql max_length is not accurate
00910                  switch (strtoupper($t)) {
00911                  case 'STRING': 
00912                  case 'CHAR':
00913                  case 'VARCHAR': 
00914                  case 'TINYBLOB': 
00915                  case 'TINYTEXT': 
00916                  case 'ENUM': 
00917                  case 'SET': 
00918                 
00919                 case MYSQLI_TYPE_TINY_BLOB :
00920                 case MYSQLI_TYPE_CHAR :
00921                 case MYSQLI_TYPE_STRING :
00922                 case MYSQLI_TYPE_ENUM :
00923                 case MYSQLI_TYPE_SET :
00924                 case 253 :
00925                    if ($len <= $this->blobSize) return 'C';
00926                    
00927                 case 'TEXT':
00928                 case 'LONGTEXT': 
00929                 case 'MEDIUMTEXT':
00930                    return 'X';
00931                 
00932                 
00933                    // php_mysql extension always returns 'blob' even if 'text'
00934                    // so we have to check whether binary...
00935                 case 'IMAGE':
00936                 case 'LONGBLOB': 
00937                 case 'BLOB':
00938                 case 'MEDIUMBLOB':
00939                 
00940                 case MYSQLI_TYPE_BLOB :
00941                 case MYSQLI_TYPE_LONG_BLOB :
00942                 case MYSQLI_TYPE_MEDIUM_BLOB :
00943                 
00944                    return !empty($fieldobj->binary) ? 'B' : 'X';
00945                 case 'YEAR':
00946                 case 'DATE': 
00947                 case MYSQLI_TYPE_DATE :
00948                 case MYSQLI_TYPE_YEAR :
00949                 
00950                    return 'D';
00951                 
00952                 case 'TIME':
00953                 case 'DATETIME':
00954                 case 'TIMESTAMP':
00955                 
00956                 case MYSQLI_TYPE_DATETIME :
00957                 case MYSQLI_TYPE_NEWDATE :
00958                 case MYSQLI_TYPE_TIME :
00959                 case MYSQLI_TYPE_TIMESTAMP :
00960                 
00961                         return 'T';
00962                 
00963                 case 'INT': 
00964                 case 'INTEGER':
00965                 case 'BIGINT':
00966                 case 'TINYINT':
00967                 case 'MEDIUMINT':
00968                 case 'SMALLINT': 
00969                 
00970                 case MYSQLI_TYPE_INT24 :
00971                 case MYSQLI_TYPE_LONG :
00972                 case MYSQLI_TYPE_LONGLONG :
00973                 case MYSQLI_TYPE_SHORT :
00974                 case MYSQLI_TYPE_TINY :
00975                 
00976                    if (!empty($fieldobj->primary_key)) return 'R';
00977                    
00978                    return 'I';
00979                 
00980                 
00981                    // Added floating-point types
00982                    // Maybe not necessery.
00983                  case 'FLOAT':
00984                  case 'DOUBLE':
00985                    //           case 'DOUBLE PRECISION':
00986                  case 'DECIMAL':
00987                  case 'DEC':
00988                  case 'FIXED':
00989                  default:
00990                         //if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>"; 
00991                         return 'N';
00992                 }
00993         } // function
00994         
00995 
00996 } // rs class
00997  
00998 }
00999 
01000 ?>