"Fossies" - the Fresh Open Source Software Archive

Member "phpESP/admin/include/lib/adodb/drivers/adodb-mysqli.inc.php" (5 Apr 2008, 28727 Bytes) of package /linux/www/old/phpESP-2.1.4.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    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.
    8   
    9   MySQL code that does not support transactions. Use mysqlt if you need transactions.
   10   Requires mysql client. Works on Windows and Unix.
   11  
   12 21 October 2003: MySQLi extension implementation by Arjen de Rijke (a.de.rijke@xs4all.nl)
   13 Based on adodb 3.40
   14 */ 
   15 
   16 // security - hide paths
   17 if (!defined('ADODB_DIR')) die();
   18 
   19 if (! defined("_ADODB_MYSQLI_LAYER")) {
   20  define("_ADODB_MYSQLI_LAYER", 1 );
   21  
   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);
   25 
   26  // disable adodb extension - currently incompatible.
   27  global $ADODB_EXTENSION; $ADODB_EXTENSION = false;
   28 
   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';
   54     
   55     function ADODB_mysqli() 
   56     {           
   57      // if(!extension_loaded("mysqli"))
   58           ;//trigger_error("You must have the mysqli extension installed.", E_USER_ERROR);
   59         
   60     }
   61     
   62     function SetTransactionMode( $transaction_mode ) 
   63     {
   64         $this->_transmode  = $transaction_mode;
   65         if (empty($transaction_mode)) {
   66             $this->Execute('SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ');
   67             return;
   68         }
   69         if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
   70         $this->Execute("SET SESSION TRANSACTION ".$transaction_mode);
   71     }
   72 
   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)
   80       {
   81          if(!extension_loaded("mysqli")) {
   82             return null;
   83          }
   84         $this->_connectionID = @mysqli_init();
   85         
   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;
   91         }
   92         /*
   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>
   96         */
   97         foreach($this->optionFlags as $arr) {   
   98             mysqli_options($this->_connectionID,$arr[0],$arr[1]);
   99         }
  100 
  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);
  110          
  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;
  119        }
  120     }
  121     
  122     // returns true or false
  123     // How to force a persistent connection
  124     function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
  125     {
  126         return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, true);
  127 
  128     }
  129     
  130     // When is this used? Close old connection first?
  131     // In _connect(), check $this->forceNewConnect? 
  132     function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
  133       {
  134         $this->forceNewConnect = true;
  135         return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
  136       }
  137     
  138     function IfNull( $field, $ifNull ) 
  139     {
  140         return " IFNULL($field, $ifNull) "; // if MySQL
  141     }
  142     
  143     // do not use $ADODB_COUNTRECS
  144     function GetOne($sql,$inputarr=false)
  145     {
  146         $ret = false;
  147         $rs = &$this->Execute($sql,$inputarr);
  148         if ($rs) {  
  149             if (!$rs->EOF) $ret = reset($rs->fields);
  150             $rs->Close();
  151         }
  152         return $ret;
  153     }
  154     
  155     function ServerInfo()
  156     {
  157         $arr['description'] = $this->GetOne("select version()");
  158         $arr['version'] = ADOConnection::_findvers($arr['description']);
  159         return $arr;
  160     }
  161     
  162     
  163     function BeginTrans()
  164     {     
  165         if ($this->transOff) return true;
  166         $this->transCnt += 1;
  167         
  168         //$this->Execute('SET AUTOCOMMIT=0');
  169         mysqli_autocommit($this->_connectionID, false);
  170         $this->Execute('BEGIN');
  171         return true;
  172     }
  173     
  174     function CommitTrans($ok=true) 
  175     {
  176         if ($this->transOff) return true; 
  177         if (!$ok) return $this->RollbackTrans();
  178         
  179         if ($this->transCnt) $this->transCnt -= 1;
  180         $this->Execute('COMMIT');
  181         
  182         //$this->Execute('SET AUTOCOMMIT=1');
  183         mysqli_autocommit($this->_connectionID, true);
  184         return true;
  185     }
  186     
  187     function RollbackTrans()
  188     {
  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;
  195     }
  196     
  197     function RowLock($tables,$where='',$flds='1 as adodb_ignore') 
  198     {
  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); 
  203     }
  204     
  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.
  213     //
  214     //Eg. $s = $db->qstr(_GET['name'],get_magic_quotes_gpc());
  215     function qstr($s, $magic_quotes = false)
  216     {
  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) . "'";   
  221         
  222         if ($this->replaceQuote[0] == '\\')
  223             $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
  224         return  "'".str_replace("'",$this->replaceQuote,$s)."'"; 
  225       }
  226       // undo magic quotes for "
  227       $s = str_replace('\\"','"',$s);
  228       return "'$s'";
  229     }
  230     
  231     function _insertid()
  232     {
  233       $result = @mysqli_insert_id($this->_connectionID);
  234       if ($result == -1){
  235           if ($this->debug) ADOConnection::outp("mysqli_insert_id() failed : "  . $this->ErrorMsg());
  236       }
  237       return $result;
  238     }
  239     
  240     // Only works for INSERT, UPDATE and DELETE query's
  241     function _affectedrows()
  242     {
  243       $result =  @mysqli_affected_rows($this->_connectionID);
  244       if ($result == -1) {
  245           if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : "  . $this->ErrorMsg());
  246       }
  247       return $result;
  248     }
  249   
  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";
  256     
  257     function CreateSequence($seqname='adodbseq',$startID=1)
  258     {
  259         if (empty($this->_genSeqSQL)) return false;
  260         $u = strtoupper($seqname);
  261         
  262         $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
  263         if (!$ok) return false;
  264         return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
  265     }
  266     
  267     function GenID($seqname='adodbseq',$startID=1)
  268     {
  269         // post-nuke sets hasGenID to false
  270         if (!$this->hasGenID) return false;
  271         
  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);
  282         }
  283         
  284         if ($rs) {
  285             $this->genID = mysqli_insert_id($this->_connectionID);
  286             $rs->Close();
  287         } else
  288             $this->genID = 0;
  289             
  290         return $this->genID;
  291     }
  292     
  293     function &MetaDatabases()
  294     {
  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();
  303             }
  304            return $arr;
  305         }
  306         return $ret;
  307     }
  308 
  309       
  310     function &MetaIndexes ($table, $primary = FALSE)
  311     {
  312         // save old fetch mode
  313         global $ADODB_FETCH_MODE;
  314         
  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);
  320         }
  321         
  322         // get index details
  323         $rs = $this->Execute(sprintf('SHOW INDEXES FROM %s',$table));
  324         
  325         // restore fetchmode
  326         if (isset($savem)) {
  327                 $this->SetFetchMode($savem);
  328         }
  329         $ADODB_FETCH_MODE = $save;
  330         
  331         if (!is_object($rs)) {
  332                 return $false;
  333         }
  334         
  335         $indexes = array ();
  336         
  337         // parse index data into array
  338         while ($row = $rs->FetchRow()) {
  339                 if ($primary == FALSE AND $row[2] == 'PRIMARY') {
  340                         continue;
  341                 }
  342                 
  343                 if (!isset($indexes[$row[2]])) {
  344                         $indexes[$row[2]] = array(
  345                                 'unique' => ($row[1] == 0),
  346                                 'columns' => array()
  347                         );
  348                 }
  349                 
  350                 $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
  351         }
  352         
  353         // sort columns by order in the index
  354         foreach ( array_keys ($indexes) as $index )
  355         {
  356                 ksort ($indexes[$index]['columns']);
  357         }
  358         
  359         return $indexes;
  360     }
  361 
  362     
  363     // Format date column in sql string given an input format that understands Y M D
  364     function SQLDate($fmt, $col=false)
  365     {   
  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)";
  380                 
  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;
  388                 
  389             case 'm':
  390                 $s .= '%m';
  391                 break;
  392             case 'D':
  393             case 'd':
  394                 $s .= '%d';
  395                 break;
  396             
  397             case 'H': 
  398                 $s .= '%H';
  399                 break;
  400                 
  401             case 'h':
  402                 $s .= '%I';
  403                 break;
  404                 
  405             case 'i':
  406                 $s .= '%i';
  407                 break;
  408                 
  409             case 's':
  410                 $s .= '%s';
  411                 break;
  412                 
  413             case 'a':
  414             case 'A':
  415                 $s .= '%p';
  416                 break;
  417             
  418             case 'w':
  419                 $s .= '%w';
  420                 break;
  421                 
  422             case 'l':
  423                 $s .= '%W';
  424                 break;
  425                 
  426             default:
  427                 
  428                 if ($ch == '\\') {
  429                     $i++;
  430                     $ch = substr($fmt,$i,1);
  431                 }
  432                 $s .= $ch;
  433                 break;
  434             }
  435         }
  436         $s.="')";
  437         if ($concat) $s = "CONCAT($s)";
  438         return $s;
  439     }
  440     
  441     // returns concatenated string
  442     // much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
  443     function Concat()
  444     {
  445         $s = "";
  446         $arr = func_get_args();
  447         
  448         // suggestion by andrew005@mnogo.ru
  449         $s = implode(',',$arr); 
  450         if (strlen($s) > 0) return "CONCAT($s)";
  451         else return '';
  452     }
  453     
  454     // dayFraction is a day in floating point
  455     function OffsetDate($dayFraction,$date=false)
  456     {       
  457         if (!$date) $date = $this->sysDate;
  458         
  459         $fraction = $dayFraction * 24 * 3600;
  460         return $date . ' + INTERVAL ' .  $fraction.' SECOND';
  461         
  462 //      return "from_unixtime(unix_timestamp($date)+$fraction)";
  463     }
  464     
  465     function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
  466     {   
  467         $save = $this->metaTablesSQL;
  468         if ($showSchema && is_string($showSchema)) {
  469             $this->metaTablesSQL .= " from $showSchema";
  470         }
  471         
  472         if ($mask) {
  473             $mask = $this->qstr($mask);
  474             $this->metaTablesSQL .= " like $mask";
  475         }
  476         $ret =& ADOConnection::MetaTables($ttype,$showSchema);
  477         
  478         $this->metaTablesSQL = $save;
  479         return $ret;
  480     }
  481     
  482     // "Innox - Juan Carlos Gonzalez" <jgonzalez#innox.com.mx>
  483     function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
  484     {
  485      global $ADODB_FETCH_MODE;
  486         
  487         if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC) $associative = true;
  488         
  489         if ( !empty($owner) ) {
  490            $table = "$owner.$table";
  491         }
  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];
  495     
  496         $matches = array();
  497     
  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]);
  505     
  506             if ( $upper ) {
  507                 $ref_table = strtoupper($ref_table);
  508             }
  509     
  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]}";
  517                 }
  518             }
  519         }
  520         
  521         return  $foreign_keys;
  522     }
  523     
  524     function &MetaColumns($table) 
  525     {
  526         $false = false;
  527         if (!$this->metaColumnsSQL)
  528             return $false;
  529         
  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;
  540         
  541         $retarr = array();
  542         while (!$rs->EOF) {
  543             $fld = new ADOFieldObject();
  544             $fld->name = $rs->fields[0];
  545             $type = $rs->fields[1];
  546             
  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                 $fld->max_length = max(array_map("strlen",explode(",",$query_array[2]))) - 2; // PHP >= 4.0.6
  559                 $fld->max_length = ($fld->max_length == 0 ? 1 : $fld->max_length);
  560             } else {
  561                 $fld->type = $type;
  562                 $fld->max_length = -1;
  563             }
  564             $fld->not_null = ($rs->fields[2] != 'YES');
  565             $fld->primary_key = ($rs->fields[3] == 'PRI');
  566             $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
  567             $fld->binary = (strpos($type,'blob') !== false);
  568             $fld->unsigned = (strpos($type,'unsigned') !== false);
  569             $fld->zerofill = (strpos($type,'zerofill') !== false);
  570 
  571             if (!$fld->binary) {
  572                 $d = $rs->fields[4];
  573                 if ($d != '' && $d != 'NULL') {
  574                     $fld->has_default = true;
  575                     $fld->default_value = $d;
  576                 } else {
  577                     $fld->has_default = false;
  578                 }
  579             }
  580             
  581             if ($save == ADODB_FETCH_NUM) {
  582                 $retarr[] = $fld;
  583             } else {
  584                 $retarr[strtoupper($fld->name)] = $fld;
  585             }
  586             $rs->MoveNext();
  587         }
  588         
  589         $rs->Close();
  590         return $retarr;
  591     }
  592         
  593     // returns true or false
  594     function SelectDB($dbName) 
  595     {
  596 //      $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
  597         $this->database = $dbName;
  598         $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
  599         
  600         if ($this->_connectionID) {
  601             $result = @mysqli_select_db($this->_connectionID, $dbName);
  602             if (!$result) {
  603                 ADOConnection::outp("Select of database " . $dbName . " failed. " . $this->ErrorMsg());
  604             }
  605             return $result;     
  606         }
  607         return false;   
  608     }
  609     
  610     // parameters use PostgreSQL convention, not MySQL
  611     function &SelectLimit($sql,
  612                   $nrows = -1,
  613                   $offset = -1,
  614                   $inputarr = false, 
  615                   $secs = 0)
  616     {
  617         $offsetStr = ($offset >= 0) ? "$offset," : '';
  618         if ($nrows < 0) $nrows = '18446744073709551615';
  619         
  620         if ($secs)
  621             $rs =& $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr);
  622         else
  623             $rs =& $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr);
  624             
  625         return $rs;
  626     }
  627     
  628     
  629     function Prepare($sql)
  630     {
  631         return $sql;
  632         
  633         $stmt = $this->_connectionID->prepare($sql);
  634         if (!$stmt) {
  635             echo $this->ErrorMsg();
  636             return $sql;
  637         }
  638         return array($sql,$stmt);
  639     }
  640     
  641     
  642     // returns queryID or false
  643     function _query($sql, $inputarr)
  644     {
  645     global $ADODB_COUNTRECS;
  646         
  647         if (is_array($sql)) {
  648             $stmt = $sql[1];
  649             $a = '';
  650             foreach($inputarr as $k => $v) {
  651                 if (is_string($v)) $a .= 's';
  652                 else if (is_integer($v)) $a .= 'i'; 
  653                 else $a .= 'd';
  654             }
  655             
  656             $fnarr = array_merge( array($stmt,$a) , $inputarr);
  657             $ret = call_user_func_array('mysqli_stmt_bind_param',$fnarr);
  658 
  659             $ret = mysqli_stmt_execute($stmt);
  660             return $ret;
  661         }
  662         if (!$mysql_res =  mysqli_query($this->_connectionID, $sql, ($ADODB_COUNTRECS) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT)) {
  663             if ($this->debug) ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg());
  664             return false;
  665         }
  666         
  667         return $mysql_res;
  668     }
  669 
  670     /*  Returns: the last error message from previous database operation    */  
  671     function ErrorMsg() 
  672       {
  673         if (empty($this->_connectionID)) 
  674           $this->_errorMsg = @mysqli_connect_error();
  675         else 
  676           $this->_errorMsg = @mysqli_error($this->_connectionID);
  677         return $this->_errorMsg;
  678       }
  679     
  680     /*  Returns: the last error number from previous database operation */  
  681     function ErrorNo() 
  682       {
  683         if (empty($this->_connectionID))  
  684           return @mysqli_connect_errno();
  685         else 
  686           return @mysqli_errno($this->_connectionID);
  687       }
  688     
  689     // returns true or false
  690     function _close()
  691       {
  692         @mysqli_close($this->_connectionID);
  693         $this->_connectionID = false;
  694       }
  695 
  696     /*
  697     * Maximum size of C field
  698     */
  699     function CharMax()
  700     {
  701         return 255; 
  702     }
  703     
  704     /*
  705     * Maximum size of X field
  706     */
  707     function TextMax()
  708     {
  709       return 4294967295; 
  710     }
  711 
  712 
  713 
  714     // this is a set of functions for managing client encoding - very important if the encodings
  715     // of your database and your output target (i.e. HTML) don't match
  716     // for instance, you may have UTF8 database and server it on-site as latin1 etc.
  717     // GetCharSet - get the name of the character set the client is using now
  718     // Under Windows, the functions should work with MySQL 4.1.11 and above, the set of charsets supported
  719     // depends on compile flags of mysql distribution 
  720 
  721   function GetCharSet()
  722   {
  723     //we will use ADO's builtin property charSet
  724     if (!method_exists($this->_connectionID,'character_set_name'))
  725         return false;
  726         
  727     $this->charSet = @$this->_connectionID->character_set_name();
  728     if (!$this->charSet) {
  729       return false;
  730     } else {
  731       return $this->charSet;
  732     }
  733   }
  734 
  735   // SetCharSet - switch the client encoding
  736   function SetCharSet($charset_name)
  737   {
  738     if (!method_exists($this->_connectionID,'set_charset'))
  739         return false;
  740 
  741     if ($this->charSet !== $charset_name) {
  742       $if = @$this->_connectionID->set_charset($charset_name);
  743       if ($if == "0" & $this->GetCharSet() == $charset_name) {
  744         return true;
  745       } else return false;
  746     } else return true;
  747   }
  748 
  749 
  750 
  751 
  752 }
  753  
  754 /*--------------------------------------------------------------------------------------
  755      Class Name: Recordset
  756 --------------------------------------------------------------------------------------*/
  757 
  758 class ADORecordSet_mysqli extends ADORecordSet{ 
  759     
  760     var $databaseType = "mysqli";
  761     var $canSeek = true;
  762     
  763     function ADORecordSet_mysqli($queryID, $mode = false) 
  764     {
  765       if ($mode === false) 
  766        { 
  767           global $ADODB_FETCH_MODE;
  768           $mode = $ADODB_FETCH_MODE;
  769        }
  770        
  771       switch ($mode)
  772         {
  773         case ADODB_FETCH_NUM: 
  774           $this->fetchMode = MYSQLI_NUM; 
  775           break;
  776         case ADODB_FETCH_ASSOC:
  777           $this->fetchMode = MYSQLI_ASSOC; 
  778           break;
  779         case ADODB_FETCH_DEFAULT:
  780         case ADODB_FETCH_BOTH:
  781         default:
  782           $this->fetchMode = MYSQLI_BOTH; 
  783           break;
  784         }
  785       $this->adodbFetchMode = $mode;
  786       $this->ADORecordSet($queryID);    
  787     }
  788     
  789     function _initrs()
  790     {
  791     global $ADODB_COUNTRECS;
  792     
  793         $this->_numOfRows = $ADODB_COUNTRECS ? @mysqli_num_rows($this->_queryID) : -1;
  794         $this->_numOfFields = @mysqli_num_fields($this->_queryID);
  795     }
  796     
  797 /*
  798 1      = MYSQLI_NOT_NULL_FLAG
  799 2      = MYSQLI_PRI_KEY_FLAG
  800 4      = MYSQLI_UNIQUE_KEY_FLAG
  801 8      = MYSQLI_MULTIPLE_KEY_FLAG
  802 16     = MYSQLI_BLOB_FLAG
  803 32     = MYSQLI_UNSIGNED_FLAG
  804 64     = MYSQLI_ZEROFILL_FLAG
  805 128    = MYSQLI_BINARY_FLAG
  806 256    = MYSQLI_ENUM_FLAG
  807 512    = MYSQLI_AUTO_INCREMENT_FLAG
  808 1024   = MYSQLI_TIMESTAMP_FLAG
  809 2048   = MYSQLI_SET_FLAG
  810 32768  = MYSQLI_NUM_FLAG
  811 16384  = MYSQLI_PART_KEY_FLAG
  812 32768  = MYSQLI_GROUP_FLAG
  813 65536  = MYSQLI_UNIQUE_FLAG
  814 131072 = MYSQLI_BINCMP_FLAG
  815 */
  816 
  817     function &FetchField($fieldOffset = -1) 
  818     {   
  819         $fieldnr = $fieldOffset;
  820         if ($fieldOffset != -1) {
  821           $fieldOffset = mysqli_field_seek($this->_queryID, $fieldnr);
  822         }
  823         $o = mysqli_fetch_field($this->_queryID);
  824         /* Properties of an ADOFieldObject as set by MetaColumns */
  825         $o->primary_key = $o->flags & MYSQLI_PRI_KEY_FLAG;
  826         $o->not_null = $o->flags & MYSQLI_NOT_NULL_FLAG;
  827         $o->auto_increment = $o->flags & MYSQLI_AUTO_INCREMENT_FLAG;
  828         $o->binary = $o->flags & MYSQLI_BINARY_FLAG;
  829         // $o->blob = $o->flags & MYSQLI_BLOB_FLAG; /* not returned by MetaColumns */
  830         $o->unsigned = $o->flags & MYSQLI_UNSIGNED_FLAG;
  831 
  832         return $o;
  833     }
  834 
  835     function &GetRowAssoc($upper = true)
  836     {
  837         if ($this->fetchMode == MYSQLI_ASSOC && !$upper) 
  838           return $this->fields;
  839         $row =& ADORecordSet::GetRowAssoc($upper);
  840         return $row;
  841     }
  842     
  843     /* Use associative array to get fields array */
  844     function Fields($colname)
  845     {   
  846       if ($this->fetchMode != MYSQLI_NUM) 
  847         return @$this->fields[$colname];
  848         
  849       if (!$this->bind) {
  850         $this->bind = array();
  851         for ($i = 0; $i < $this->_numOfFields; $i++) {
  852           $o = $this->FetchField($i);
  853           $this->bind[strtoupper($o->name)] = $i;
  854         }
  855       }
  856       return $this->fields[$this->bind[strtoupper($colname)]];
  857     }
  858     
  859     function _seek($row)
  860     {
  861       if ($this->_numOfRows == 0) 
  862         return false;
  863 
  864       if ($row < 0)
  865         return false;
  866 
  867       mysqli_data_seek($this->_queryID, $row);
  868       $this->EOF = false;
  869       return true;
  870     }
  871         
  872     // 10% speedup to move MoveNext to child class
  873     // This is the only implementation that works now (23-10-2003).
  874     // Other functions return no or the wrong results.
  875     function MoveNext() 
  876     {
  877         if ($this->EOF) return false;
  878         $this->_currentRow++;
  879         $this->fields = @mysqli_fetch_array($this->_queryID,$this->fetchMode);
  880         
  881         if (is_array($this->fields)) return true;
  882         $this->EOF = true;
  883         return false;
  884     }   
  885     
  886     function _fetch()
  887     {
  888         $this->fields = mysqli_fetch_array($this->_queryID,$this->fetchMode);  
  889         return is_array($this->fields);
  890     }
  891     
  892     function _close() 
  893     {
  894         mysqli_free_result($this->_queryID); 
  895         $this->_queryID = false;    
  896     }
  897     
  898 /*
  899 
  900 0 = MYSQLI_TYPE_DECIMAL
  901 1 = MYSQLI_TYPE_CHAR
  902 1 = MYSQLI_TYPE_TINY
  903 2 = MYSQLI_TYPE_SHORT
  904 3 = MYSQLI_TYPE_LONG
  905 4 = MYSQLI_TYPE_FLOAT
  906 5 = MYSQLI_TYPE_DOUBLE
  907 6 = MYSQLI_TYPE_NULL
  908 7 = MYSQLI_TYPE_TIMESTAMP
  909 8 = MYSQLI_TYPE_LONGLONG
  910 9 = MYSQLI_TYPE_INT24
  911 10 = MYSQLI_TYPE_DATE
  912 11 = MYSQLI_TYPE_TIME
  913 12 = MYSQLI_TYPE_DATETIME
  914 13 = MYSQLI_TYPE_YEAR
  915 14 = MYSQLI_TYPE_NEWDATE
  916 247 = MYSQLI_TYPE_ENUM
  917 248 = MYSQLI_TYPE_SET
  918 249 = MYSQLI_TYPE_TINY_BLOB
  919 250 = MYSQLI_TYPE_MEDIUM_BLOB
  920 251 = MYSQLI_TYPE_LONG_BLOB
  921 252 = MYSQLI_TYPE_BLOB
  922 253 = MYSQLI_TYPE_VAR_STRING
  923 254 = MYSQLI_TYPE_STRING
  924 255 = MYSQLI_TYPE_GEOMETRY
  925 */
  926 
  927     function MetaType($t, $len = -1, $fieldobj = false)
  928     {
  929         if (is_object($t)) {
  930             $fieldobj = $t;
  931             $t = $fieldobj->type;
  932             $len = $fieldobj->max_length;
  933         }
  934         
  935         
  936          $len = -1; // mysql max_length is not accurate
  937          switch (strtoupper($t)) {
  938          case 'STRING': 
  939          case 'CHAR':
  940          case 'VARCHAR': 
  941          case 'TINYBLOB': 
  942          case 'TINYTEXT': 
  943          case 'ENUM': 
  944          case 'SET': 
  945         
  946         case MYSQLI_TYPE_TINY_BLOB :
  947         #case MYSQLI_TYPE_CHAR :
  948         case MYSQLI_TYPE_STRING :
  949         case MYSQLI_TYPE_ENUM :
  950         case MYSQLI_TYPE_SET :
  951         case 253 :
  952            if ($len <= $this->blobSize) return 'C';
  953            
  954         case 'TEXT':
  955         case 'LONGTEXT': 
  956         case 'MEDIUMTEXT':
  957            return 'X';
  958         
  959         
  960            // php_mysql extension always returns 'blob' even if 'text'
  961            // so we have to check whether binary...
  962         case 'IMAGE':
  963         case 'LONGBLOB': 
  964         case 'BLOB':
  965         case 'MEDIUMBLOB':
  966         
  967         case MYSQLI_TYPE_BLOB :
  968         case MYSQLI_TYPE_LONG_BLOB :
  969         case MYSQLI_TYPE_MEDIUM_BLOB :
  970         
  971            return !empty($fieldobj->binary) ? 'B' : 'X';
  972         case 'YEAR':
  973         case 'DATE': 
  974         case MYSQLI_TYPE_DATE :
  975         case MYSQLI_TYPE_YEAR :
  976         
  977            return 'D';
  978         
  979         case 'TIME':
  980         case 'DATETIME':
  981         case 'TIMESTAMP':
  982         
  983         case MYSQLI_TYPE_DATETIME :
  984         case MYSQLI_TYPE_NEWDATE :
  985         case MYSQLI_TYPE_TIME :
  986         case MYSQLI_TYPE_TIMESTAMP :
  987         
  988             return 'T';
  989         
  990         case 'INT': 
  991         case 'INTEGER':
  992         case 'BIGINT':
  993         case 'TINYINT':
  994         case 'MEDIUMINT':
  995         case 'SMALLINT': 
  996         
  997         case MYSQLI_TYPE_INT24 :
  998         case MYSQLI_TYPE_LONG :
  999         case MYSQLI_TYPE_LONGLONG :
 1000         case MYSQLI_TYPE_SHORT :
 1001         case MYSQLI_TYPE_TINY :
 1002         
 1003            if (!empty($fieldobj->primary_key)) return 'R';
 1004            
 1005            return 'I';
 1006         
 1007         
 1008            // Added floating-point types
 1009            // Maybe not necessery.
 1010          case 'FLOAT':
 1011          case 'DOUBLE':
 1012            //       case 'DOUBLE PRECISION':
 1013          case 'DECIMAL':
 1014          case 'DEC':
 1015          case 'FIXED':
 1016          default:
 1017             //if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>"; 
 1018             return 'N';
 1019         }
 1020     } // function
 1021     
 1022 
 1023 } // rs class
 1024  
 1025 }
 1026 
 1027 class ADORecordSet_array_mysqli extends ADORecordSet_array {
 1028   function ADORecordSet_array_mysqli($id=-1,$mode=false) 
 1029   {
 1030     $this->ADORecordSet_array($id,$mode);
 1031   }
 1032   
 1033 
 1034     function MetaType($t, $len = -1, $fieldobj = false)
 1035     {
 1036         if (is_object($t)) {
 1037             $fieldobj = $t;
 1038             $t = $fieldobj->type;
 1039             $len = $fieldobj->max_length;
 1040         }
 1041         
 1042         
 1043          $len = -1; // mysql max_length is not accurate
 1044          switch (strtoupper($t)) {
 1045          case 'STRING': 
 1046          case 'CHAR':
 1047          case 'VARCHAR': 
 1048          case 'TINYBLOB': 
 1049          case 'TINYTEXT': 
 1050          case 'ENUM': 
 1051          case 'SET': 
 1052         
 1053         case MYSQLI_TYPE_TINY_BLOB :
 1054         #case MYSQLI_TYPE_CHAR :
 1055         case MYSQLI_TYPE_STRING :
 1056         case MYSQLI_TYPE_ENUM :
 1057         case MYSQLI_TYPE_SET :
 1058         case 253 :
 1059            if ($len <= $this->blobSize) return 'C';
 1060            
 1061         case 'TEXT':
 1062         case 'LONGTEXT': 
 1063         case 'MEDIUMTEXT':
 1064            return 'X';
 1065         
 1066         
 1067            // php_mysql extension always returns 'blob' even if 'text'
 1068            // so we have to check whether binary...
 1069         case 'IMAGE':
 1070         case 'LONGBLOB': 
 1071         case 'BLOB':
 1072         case 'MEDIUMBLOB':
 1073         
 1074         case MYSQLI_TYPE_BLOB :
 1075         case MYSQLI_TYPE_LONG_BLOB :
 1076         case MYSQLI_TYPE_MEDIUM_BLOB :
 1077         
 1078            return !empty($fieldobj->binary) ? 'B' : 'X';
 1079         case 'YEAR':
 1080         case 'DATE': 
 1081         case MYSQLI_TYPE_DATE :
 1082         case MYSQLI_TYPE_YEAR :
 1083         
 1084            return 'D';
 1085         
 1086         case 'TIME':
 1087         case 'DATETIME':
 1088         case 'TIMESTAMP':
 1089         
 1090         case MYSQLI_TYPE_DATETIME :
 1091         case MYSQLI_TYPE_NEWDATE :
 1092         case MYSQLI_TYPE_TIME :
 1093         case MYSQLI_TYPE_TIMESTAMP :
 1094         
 1095             return 'T';
 1096         
 1097         case 'INT': 
 1098         case 'INTEGER':
 1099         case 'BIGINT':
 1100         case 'TINYINT':
 1101         case 'MEDIUMINT':
 1102         case 'SMALLINT': 
 1103         
 1104         case MYSQLI_TYPE_INT24 :
 1105         case MYSQLI_TYPE_LONG :
 1106         case MYSQLI_TYPE_LONGLONG :
 1107         case MYSQLI_TYPE_SHORT :
 1108         case MYSQLI_TYPE_TINY :
 1109         
 1110            if (!empty($fieldobj->primary_key)) return 'R';
 1111            
 1112            return 'I';
 1113         
 1114         
 1115            // Added floating-point types
 1116            // Maybe not necessery.
 1117          case 'FLOAT':
 1118          case 'DOUBLE':
 1119            //       case 'DOUBLE PRECISION':
 1120          case 'DECIMAL':
 1121          case 'DEC':
 1122          case 'FIXED':
 1123          default:
 1124             //if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>"; 
 1125             return 'N';
 1126         }
 1127     } // function
 1128   
 1129 }
 1130 
 1131 ?>