Zikula 1.0.1
[ class tree: Zikula 1.0.1 ] [ index: Zikula 1.0.1 ] [ all elements ]

Source for file adodb-mysqli.inc.php

Documentation is available at adodb-mysqli.inc.php

  1. <?php
  2. /*
  3. V4.97 22 Jan 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");
  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 = false;    // Fix for PostNuke Pablo Roca / larsneo / Neo
  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$argDatabasenametrue);
  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->transOffreturn true;
  166.         $this->transCnt += 1;
  167.         
  168.         //$this->Execute('SET AUTOCOMMIT=0');
  169.         mysqli_autocommit($this->_connectionIDfalse);
  170.         $this->Execute('BEGIN');
  171.         return true;
  172.     }
  173.     
  174.     function CommitTrans($ok=true
  175.     {
  176.         if ($this->transOffreturn true
  177.         if (!$okreturn $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->_connectionIDtrue);
  184.         return true;
  185.     }
  186.     
  187.     function RollbackTrans()
  188.     {
  189.         if ($this->transOffreturn true;
  190.         if ($this->transCnt$this->transCnt -= 1;
  191.         $this->Execute('ROLLBACK');
  192.         //$this->Execute('SET AUTOCOMMIT=1');
  193.         mysqli_autocommit($this->_connectionIDtrue);
  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->debugADOConnection::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->debugADOConnection::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 (!$okreturn false;
  264.         return $this->Execute(sprintf($this->_genSeqzikula.orgame,$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.         // temporal fix proca
  272.         if (!$this->hasGenIDreturn 0;
  273.         
  274.         $getnext sprintf($this->_genIDSQL,$seqname);
  275.         $holdtransOK $this->_transOK// save the current status
  276.         $rs @$this->Execute($getnext);
  277.         if (!$rs{
  278.             if ($holdtransOK$this->_transOK = true//if the status was ok before reset
  279.             $u strtoupper($seqname);
  280.             $this->Execute(sprintf($this->_genSeqSQL,$seqname));
  281.             $cnt $this->GetOne(sprintf($this->_genSeqCountSQL,$seqname));
  282.             if (!$cnt$this->Execute(sprintf($this->_genSeqzikula.orgame,$startID-1));
  283.             $rs $this->Execute($getnext);
  284.         }
  285.         
  286.         if ($rs{
  287.             $this->genID = mysqli_insert_id($this->_connectionID);
  288.             $rs->Close();
  289.         else
  290.             $this->genID = 0;
  291.             
  292.         return $this->genID;
  293.     }
  294.     
  295.       function &MetaDatabases()
  296.     {
  297.         $query "SHOW DATABASES";
  298.         $ret =$this->Execute($query);
  299.         if ($ret && is_object($ret)){
  300.            $arr array();
  301.             while (!$ret->EOF){
  302.                 $db $ret->Fields('Database');
  303.                 if ($db != 'mysql'$arr[$db;
  304.                 $ret->MoveNext();
  305.             }
  306.               return $arr;
  307.         }
  308.         return $ret;
  309.     }
  310.  
  311.       
  312.     function &MetaIndexes ($table$primary FALSE)
  313.     {
  314.         // save old fetch mode
  315.         global $ADODB_FETCH_MODE;
  316.         
  317.         $false false;
  318.         $save $ADODB_FETCH_MODE;
  319.         $ADODB_FETCH_MODE ADODB_FETCH_NUM;
  320.         if ($this->fetchMode !== FALSE{
  321.                $savem $this->SetFetchMode(FALSE);
  322.         }
  323.         
  324.         // get index details
  325.         $rs $this->Execute(sprintf('SHOW INDEXES FROM %s',$table));
  326.         
  327.         // restore fetchmode
  328.         if (isset($savem)) {
  329.                 $this->SetFetchMode($savem);
  330.         }
  331.         $ADODB_FETCH_MODE $save;
  332.         
  333.         if (!is_object($rs)) {
  334.                 return $false;
  335.         }
  336.         
  337.         $indexes array ();
  338.         
  339.         // parse index data into array
  340.         while ($row $rs->FetchRow()) {
  341.                 if ($primary == FALSE AND $row[2== 'PRIMARY'{
  342.                         continue;
  343.                 }
  344.                 
  345.                 if (!isset($indexes[$row[2]])) {
  346.                         $indexes[$row[2]] array(
  347.                                 'unique' => ($row[1== 0),
  348.                                 'columns' => array()
  349.                         );
  350.                 }
  351.                 
  352.                 $indexes[$row[2]]['columns'][$row[31$row[4];
  353.         }
  354.         
  355.         // sort columns by order in the index
  356.         foreach array_keys ($indexesas $index )
  357.         {
  358.                 ksort ($indexes[$index]['columns']);
  359.         }
  360.         
  361.         return $indexes;
  362.     }
  363.  
  364.     
  365.     // Format date column in sql string given an input format that understands Y M D
  366.     function SQLDate($fmt$col=false)
  367.     {    
  368.         if (!$col$col $this->sysTimeStamp;
  369.         $s 'DATE_FORMAT('.$col.",'";
  370.         $concat false;
  371.         $len strlen($fmt);
  372.         for ($i=0$i $len$i++{
  373.             $ch $fmt[$i];
  374.             switch($ch{
  375.             case 'Y':
  376.             case 'y':
  377.                 $s .= '%Y';
  378.                 break;
  379.             case 'Q':
  380.             case 'q':
  381.                 $s .= "'),Quarter($col)";
  382.                 
  383.                 if ($len $i+1$s .= ",DATE_FORMAT($col,'";
  384.                 else $s .= ",('";
  385.                 $concat true;
  386.                 break;
  387.             case 'M':
  388.                 $s .= '%b';
  389.                 break;
  390.                 
  391.             case 'm':
  392.                 $s .= '%m';
  393.                 break;
  394.             case 'D':
  395.             case 'd':
  396.                 $s .= '%d';
  397.                 break;
  398.             
  399.             case 'H'
  400.                 $s .= '%H';
  401.                 break;
  402.                 
  403.             case 'h':
  404.                 $s .= '%I';
  405.                 break;
  406.                 
  407.             case 'i':
  408.                 $s .= '%i';
  409.                 break;
  410.                 
  411.             case 's':
  412.                 $s .= '%s';
  413.                 break;
  414.                 
  415.             case 'a':
  416.             case 'A':
  417.                 $s .= '%p';
  418.                 break;
  419.             
  420.             case 'w':
  421.                 $s .= '%w';
  422.                 break;
  423.                 
  424.             case 'l':
  425.                 $s .= '%W';
  426.                 break;
  427.                 
  428.             default:
  429.                 
  430.                 if ($ch == '\\'{
  431.                     $i++;
  432.                     $ch substr($fmt,$i,1);
  433.                 }
  434.                 $s .= $ch;
  435.                 break;
  436.             }
  437.         }
  438.         $s.="')";
  439.         if ($concat$s "CONCAT($s)";
  440.         return $s;
  441.     }
  442.     
  443.     // returns concatenated string
  444.     // much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
  445.     function Concat()
  446.     {
  447.         $s "";
  448.         $arr func_get_args();
  449.         
  450.         // suggestion by andrew005@mnogo.ru
  451.         $s implode(',',$arr)
  452.         if (strlen($s0return "CONCAT($s)";
  453.         else return '';
  454.     }
  455.     
  456.     // dayFraction is a day in floating point
  457.     function OffsetDate($dayFraction,$date=false)
  458.     {        
  459.         if (!$date$date $this->sysDate;
  460.         
  461.         $fraction $dayFraction 24 3600;
  462.         return $date ' + INTERVAL ' .     $fraction.' SECOND';
  463.         
  464. //        return "from_unixtime(unix_timestamp($date)+$fraction)";
  465.     }
  466.     
  467.     function &MetaTables($ttype=false,$showSchema=false,$mask=false
  468.     {    
  469.         $save $this->metaTablesSQL;
  470.         if ($showSchema && is_string($showSchema)) {
  471.             $this->metaTablesSQL .= " from $showSchema";
  472.         }
  473.         
  474.         if ($mask{
  475.             $mask $this->qstr($mask);
  476.             $this->metaTablesSQL .= " like $mask";
  477.         }
  478.         $ret =ADOConnection::MetaTables($ttype,$showSchema);
  479.         
  480.         $this->metaTablesSQL = $save;
  481.         return $ret;
  482.     }
  483.     
  484.     // "Innox - Juan Carlos Gonzalez" <jgonzikula.orgnox.com.mx>
  485.     function MetaForeignKeys$table$owner FALSE$upper FALSE$associative FALSE )
  486.     {
  487.      global $ADODB_FETCH_MODE;
  488.         
  489.         if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC$associative true;
  490.         
  491.         if !empty($owner) ) {
  492.            $table "$owner.$table";
  493.         }
  494.         $a_create_table $this->getRow(sprintf('SHOW CREATE TABLE %s'$table));
  495.         if ($associative$create_sql $a_create_table["Create Table"];
  496.         else $create_sql  $a_create_table[1];
  497.     
  498.         $matches array();
  499.     
  500.         if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/"$create_sql$matches)) return false;
  501.          $foreign_keys array();          
  502.         $num_keys count($matches[0]);
  503.         for $i 0;  $i $num_keys;  $i ++ {
  504.             $my_field  explode('`, `'$matches[1][$i]);
  505.             $ref_table $matches[2][$i];
  506.             $ref_field explode('`, `'$matches[3][$i]);
  507.     
  508.             if $upper {
  509.                 $ref_table strtoupper($ref_table);
  510.             }
  511.     
  512.             $foreign_keys[$ref_tablearray();
  513.             $num_fields               count($my_field);
  514.             for $j 0;  $j $num_fields;  $j ++ {
  515.                 if $associative {
  516.                     $foreign_keys[$ref_table][$ref_field[$j]] $my_field[$j];
  517.                 else {
  518.                     $foreign_keys[$ref_table]["{$my_field[$j]}={$ref_field[$j]}";
  519.                 }
  520.             }
  521.         }
  522.         
  523.         return  $foreign_keys;
  524.     }
  525.     
  526.      function &MetaColumns($table
  527.     {
  528.         $false false;
  529.         if (!$this->metaColumnsSQL)
  530.             return $false;
  531.         
  532.         global $ADODB_FETCH_MODE;
  533.         $save $ADODB_FETCH_MODE;
  534.         $ADODB_FETCH_MODE ADODB_FETCH_NUM;
  535.         if ($this->fetchMode !== false)
  536.             $savem $this->SetFetchMode(false);
  537.         $rs $this->Execute(sprintf($this->metaColumnsSQL,$table));
  538.         if (isset($savem)) $this->SetFetchMode($savem);
  539.         $ADODB_FETCH_MODE $save;
  540.         if (!is_object($rs))
  541.             return $false;
  542.         
  543.         $retarr array();
  544.         while (!$rs->EOF{
  545.             $fld new ADOFieldObject();
  546.             $fld->name $rs->fields[0];
  547.             $type $rs->fields[1];
  548.             
  549.             // split type into type(length):
  550.             $fld->scale null;
  551.             if (preg_match("/^(.+)\((\d+),(\d+)/"$type$query_array)) {
  552.                 $fld->type $query_array[1];
  553.                 $fld->max_length is_numeric($query_array[2]$query_array[2: -1;
  554.                 $fld->scale is_numeric($query_array[3]$query_array[3: -1;
  555.             elseif (preg_match("/^(.+)\((\d+)/"$type$query_array)) {
  556.                 $fld->type $query_array[1];
  557.                 $fld->max_length is_numeric($query_array[2]$query_array[2: -1;
  558.             elseif (preg_match("/^(enum)\((.*)\)$/i"$type$query_array)) {
  559.                 $fld->type $query_array[1];
  560.                 $fld->max_length max(array_map("strlen",explode(",",$query_array[2]))) 2// PHP >= 4.0.6
  561.                 $fld->max_length ($fld->max_length == $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_mergearray($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_COUNTRECSMYSQLI_STORE_RESULT MYSQLI_USE_RESULT)) {
  665.             if ($this->debugADOConnection::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->EOFreturn 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->blobSizereturn '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.   function ADORecordSet_array_mysqli($id=-1,$mode=false
  1030.   {
  1031.     $this->ADORecordSet_array($id,$mode);
  1032.   }
  1033.   
  1034.  
  1035.     function MetaType($t$len = -1$fieldobj false)
  1036.     {
  1037.         if (is_object($t)) {
  1038.             $fieldobj $t;
  1039.             $t $fieldobj->type;
  1040.             $len $fieldobj->max_length;
  1041.         }
  1042.         
  1043.         
  1044.          $len = -1// mysql max_length is not accurate
  1045.          switch (strtoupper($t)) {
  1046.          case 'STRING'
  1047.          case 'CHAR':
  1048.          case 'VARCHAR'
  1049.          case 'TINYBLOB'
  1050.          case 'TINYTEXT'
  1051.          case 'ENUM'
  1052.          case 'SET'
  1053.         
  1054.         case MYSQLI_TYPE_TINY_BLOB :
  1055.         case MYSQLI_TYPE_CHAR :
  1056.         case MYSQLI_TYPE_STRING :
  1057.         case MYSQLI_TYPE_ENUM :
  1058.         case MYSQLI_TYPE_SET :
  1059.         case 253 :
  1060.            if ($len <= $this->blobSizereturn 'C';
  1061.            
  1062.         case 'TEXT':
  1063.         case 'LONGTEXT'
  1064.         case 'MEDIUMTEXT':
  1065.            return 'X';
  1066.         
  1067.         
  1068.            // php_mysql extension always returns 'blob' even if 'text'
  1069.            // so we have to check whether binary...
  1070.         case 'IMAGE':
  1071.         case 'LONGBLOB'
  1072.         case 'BLOB':
  1073.         case 'MEDIUMBLOB':
  1074.         
  1075.         case MYSQLI_TYPE_BLOB :
  1076.         case MYSQLI_TYPE_LONG_BLOB :
  1077.         case MYSQLI_TYPE_MEDIUM_BLOB :
  1078.         
  1079.            return !empty($fieldobj->binary'B' 'X';
  1080.         case 'YEAR':
  1081.         case 'DATE'
  1082.         case MYSQLI_TYPE_DATE :
  1083.         case MYSQLI_TYPE_YEAR :
  1084.         
  1085.            return 'D';
  1086.         
  1087.         case 'TIME':
  1088.         case 'DATETIME':
  1089.         case 'TIMESTAMP':
  1090.         
  1091.         case MYSQLI_TYPE_DATETIME :
  1092.         case MYSQLI_TYPE_NEWDATE :
  1093.         case MYSQLI_TYPE_TIME :
  1094.         case MYSQLI_TYPE_TIMESTAMP :
  1095.         
  1096.             return 'T';
  1097.         
  1098.         case 'INT'
  1099.         case 'INTEGER':
  1100.         case 'BIGINT':
  1101.         case 'TINYINT':
  1102.         case 'MEDIUMINT':
  1103.         case 'SMALLINT'
  1104.         
  1105.         case MYSQLI_TYPE_INT24 :
  1106.         case MYSQLI_TYPE_LONG :
  1107.         case MYSQLI_TYPE_LONGLONG :
  1108.         case MYSQLI_TYPE_SHORT :
  1109.         case MYSQLI_TYPE_TINY :
  1110.         
  1111.            if (!empty($fieldobj->primary_key)) return 'R';
  1112.            
  1113.            return 'I';
  1114.         
  1115.         
  1116.            // Added floating-point types
  1117.            // Maybe not necessery.
  1118.          case 'FLOAT':
  1119.          case 'DOUBLE':
  1120.            //        case 'DOUBLE PRECISION':
  1121.          case 'DECIMAL':
  1122.          case 'DEC':
  1123.          case 'FIXED':
  1124.          default:
  1125.              //if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>"; 
  1126.              return 'N';
  1127.         }
  1128.     // function
  1129.   
  1130. }
  1131.  
  1132. ?>

Documentation generated on Fri, 18 Jul 2008 21:40:18 +0200 by phpDocumentor 1.4.1