[ Index ]

PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008]

title

Body

[close]

/lib/adodb/drivers/ -> adodb-mysqli.inc.php (source)

   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                  $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;
 565              }
 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);
 572  
 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;
 580                  }
 581              }
 582              
 583              if ($save == ADODB_FETCH_NUM) {
 584                  $retarr[] = $fld;
 585              } else {
 586                  $retarr[strtoupper($fld->name)] = $fld;
 587              }
 588              $rs->MoveNext();
 589          }
 590          
 591          $rs->Close();
 592          return $retarr;
 593      }
 594          
 595      // returns true or false
 596  	function SelectDB($dbName) 
 597      {
 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
 601          
 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());
 606              }
 607              return $result;        
 608          }
 609          return false;    
 610      }
 611      
 612      // parameters use PostgreSQL convention, not MySQL
 613      function &SelectLimit($sql,
 614                    $nrows = -1,
 615                    $offset = -1,
 616                    $inputarr = false, 
 617                    $secs = 0)
 618      {
 619          $offsetStr = ($offset >= 0) ? "$offset," : '';
 620          if ($nrows < 0) $nrows = '18446744073709551615';
 621          
 622          if ($secs)
 623              $rs =& $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr);
 624          else
 625              $rs =& $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr);
 626              
 627          return $rs;
 628      }
 629      
 630      
 631  	function Prepare($sql)
 632      {
 633          return $sql;
 634          
 635          $stmt = $this->_connectionID->prepare($sql);
 636          if (!$stmt) {
 637              echo $this->ErrorMsg();
 638              return $sql;
 639          }
 640          return array($sql,$stmt);
 641      }
 642      
 643      
 644      // returns queryID or false
 645  	function _query($sql, $inputarr)
 646      {
 647      global $ADODB_COUNTRECS;
 648          
 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';
 656              }
 657              
 658              $fnarr = array_merge( array($stmt,$a) , $inputarr);
 659              $ret = call_user_func_array('mysqli_stmt_bind_param',$fnarr);
 660  
 661              $ret = mysqli_stmt_execute($stmt);
 662              return $ret;
 663          }
 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;
 667          }
 668          
 669          return $mysql_res;
 670      }
 671  
 672      /*    Returns: the last error message from previous database operation    */    
 673  	function ErrorMsg() 
 674        {
 675          if (empty($this->_connectionID)) 
 676            $this->_errorMsg = @mysqli_connect_error();
 677          else 
 678            $this->_errorMsg = @mysqli_error($this->_connectionID);
 679          return $this->_errorMsg;
 680        }
 681      
 682      /*    Returns: the last error number from previous database operation    */    
 683  	function ErrorNo() 
 684        {
 685          if (empty($this->_connectionID))  
 686            return @mysqli_connect_errno();
 687          else 
 688            return @mysqli_errno($this->_connectionID);
 689        }
 690      
 691      // returns true or false
 692  	function _close()
 693        {
 694          @mysqli_close($this->_connectionID);
 695          $this->_connectionID = false;
 696        }
 697  
 698      /*
 699      * Maximum size of C field
 700      */
 701  	function CharMax()
 702      {
 703          return 255; 
 704      }
 705      
 706      /*
 707      * Maximum size of X field
 708      */
 709  	function TextMax()
 710      {
 711        return 4294967295; 
 712      }
 713  
 714  
 715  
 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 
 722  
 723    function GetCharSet()
 724    {
 725      //we will use ADO's builtin property charSet
 726      if (!method_exists($this->_connectionID,'character_set_name'))
 727          return false;
 728          
 729      $this->charSet = @$this->_connectionID->character_set_name();
 730      if (!$this->charSet) {
 731        return false;
 732      } else {
 733        return $this->charSet;
 734      }
 735    }
 736  
 737    // SetCharSet - switch the client encoding
 738    function SetCharSet($charset_name)
 739    {
 740      if (!method_exists($this->_connectionID,'set_charset'))
 741          return false;
 742  
 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;
 749    }
 750  
 751  
 752  
 753  
 754  }
 755   
 756  /*--------------------------------------------------------------------------------------
 757       Class Name: Recordset
 758  --------------------------------------------------------------------------------------*/
 759  
 760  class ADORecordSet_mysqli extends ADORecordSet{    
 761      
 762      var $databaseType = "mysqli";
 763      var $canSeek = true;
 764      
 765  	function ADORecordSet_mysqli($queryID, $mode = false) 
 766      {
 767        if ($mode === false) 
 768         { 
 769            global $ADODB_FETCH_MODE;
 770            $mode = $ADODB_FETCH_MODE;
 771         }
 772         
 773        switch ($mode)
 774          {
 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;
 786          }
 787        $this->adodbFetchMode = $mode;
 788        $this->ADORecordSet($queryID);    
 789      }
 790      
 791  	function _initrs()
 792      {
 793      global $ADODB_COUNTRECS;
 794      
 795          $this->_numOfRows = $ADODB_COUNTRECS ? @mysqli_num_rows($this->_queryID) : -1;
 796          $this->_numOfFields = @mysqli_num_fields($this->_queryID);
 797      }
 798      
 799  /*
 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
 817  */
 818  
 819      function &FetchField($fieldOffset = -1) 
 820      {    
 821          $fieldnr = $fieldOffset;
 822          if ($fieldOffset != -1) {
 823            $fieldOffset = mysqli_field_seek($this->_queryID, $fieldnr);
 824          }
 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;
 833  
 834          return $o;
 835      }
 836  
 837      function &GetRowAssoc($upper = true)
 838      {
 839          if ($this->fetchMode == MYSQLI_ASSOC && !$upper) 
 840            return $this->fields;
 841          $row =& ADORecordSet::GetRowAssoc($upper);
 842          return $row;
 843      }
 844      
 845      /* Use associative array to get fields array */
 846  	function Fields($colname)
 847      {    
 848        if ($this->fetchMode != MYSQLI_NUM) 
 849          return @$this->fields[$colname];
 850          
 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;
 856          }
 857        }
 858        return $this->fields[$this->bind[strtoupper($colname)]];
 859      }
 860      
 861  	function _seek($row)
 862      {
 863        if ($this->_numOfRows == 0) 
 864          return false;
 865  
 866        if ($row < 0)
 867          return false;
 868  
 869        mysqli_data_seek($this->_queryID, $row);
 870        $this->EOF = false;
 871        return true;
 872      }
 873          
 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() 
 878      {
 879          if ($this->EOF) return false;
 880          $this->_currentRow++;
 881          $this->fields = @mysqli_fetch_array($this->_queryID,$this->fetchMode);
 882          
 883          if (is_array($this->fields)) return true;
 884          $this->EOF = true;
 885          return false;
 886      }    
 887      
 888  	function _fetch()
 889      {
 890          $this->fields = mysqli_fetch_array($this->_queryID,$this->fetchMode);  
 891            return is_array($this->fields);
 892      }
 893      
 894  	function _close() 
 895      {
 896          mysqli_free_result($this->_queryID); 
 897            $this->_queryID = false;    
 898      }
 899      
 900  /*
 901  
 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
 927  */
 928  
 929  	function MetaType($t, $len = -1, $fieldobj = false)
 930      {
 931          if (is_object($t)) {
 932              $fieldobj = $t;
 933              $t = $fieldobj->type;
 934              $len = $fieldobj->max_length;
 935          }
 936          
 937          
 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': 
 947          
 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';
 955             
 956          case 'TEXT':
 957          case 'LONGTEXT': 
 958          case 'MEDIUMTEXT':
 959             return 'X';
 960          
 961          
 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':
 968          
 969          case MYSQLI_TYPE_BLOB :
 970          case MYSQLI_TYPE_LONG_BLOB :
 971          case MYSQLI_TYPE_MEDIUM_BLOB :
 972          
 973             return !empty($fieldobj->binary) ? 'B' : 'X';
 974          case 'YEAR':
 975          case 'DATE': 
 976          case MYSQLI_TYPE_DATE :
 977          case MYSQLI_TYPE_YEAR :
 978          
 979             return 'D';
 980          
 981          case 'TIME':
 982          case 'DATETIME':
 983          case 'TIMESTAMP':
 984          
 985          case MYSQLI_TYPE_DATETIME :
 986          case MYSQLI_TYPE_NEWDATE :
 987          case MYSQLI_TYPE_TIME :
 988          case MYSQLI_TYPE_TIMESTAMP :
 989          
 990              return 'T';
 991          
 992          case 'INT': 
 993          case 'INTEGER':
 994          case 'BIGINT':
 995          case 'TINYINT':
 996          case 'MEDIUMINT':
 997          case 'SMALLINT': 
 998          
 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 :
1004          
1005             if (!empty($fieldobj->primary_key)) return 'R';
1006             
1007             return 'I';
1008          
1009          
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';
1021          }
1022      } // function
1023      
1024  
1025  } // rs class
1026   
1027  }
1028  
1029  class ADORecordSet_array_mysqli extends ADORecordSet_array {
1030    function ADORecordSet_array_mysqli($id=-1,$mode=false) 
1031    {
1032      $this->ADORecordSet_array($id,$mode);
1033    }
1034    
1035  
1036  	function MetaType($t, $len = -1, $fieldobj = false)
1037      {
1038          if (is_object($t)) {
1039              $fieldobj = $t;
1040              $t = $fieldobj->type;
1041              $len = $fieldobj->max_length;
1042          }
1043          
1044          
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': 
1054          
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';
1062             
1063          case 'TEXT':
1064          case 'LONGTEXT': 
1065          case 'MEDIUMTEXT':
1066             return 'X';
1067          
1068          
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':
1075          
1076          case MYSQLI_TYPE_BLOB :
1077          case MYSQLI_TYPE_LONG_BLOB :
1078          case MYSQLI_TYPE_MEDIUM_BLOB :
1079          
1080             return !empty($fieldobj->binary) ? 'B' : 'X';
1081          case 'YEAR':
1082          case 'DATE': 
1083          case MYSQLI_TYPE_DATE :
1084          case MYSQLI_TYPE_YEAR :
1085          
1086             return 'D';
1087          
1088          case 'TIME':
1089          case 'DATETIME':
1090          case 'TIMESTAMP':
1091          
1092          case MYSQLI_TYPE_DATETIME :
1093          case MYSQLI_TYPE_NEWDATE :
1094          case MYSQLI_TYPE_TIME :
1095          case MYSQLI_TYPE_TIMESTAMP :
1096          
1097              return 'T';
1098          
1099          case 'INT': 
1100          case 'INTEGER':
1101          case 'BIGINT':
1102          case 'TINYINT':
1103          case 'MEDIUMINT':
1104          case 'SMALLINT': 
1105          
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 :
1111          
1112             if (!empty($fieldobj->primary_key)) return 'R';
1113             
1114             return 'I';
1115          
1116          
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';
1128          }
1129      } // function
1130    
1131  }
1132  
1133  ?>


Generated: Wed Jan 14 11:33:29 2009 Cross-referenced by PHPXref 0.7