home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / ENTER.ISO / files / xampp-win32-1.4.5-installer.exe / xampp / adodb-mysqli.inc.php < prev    next >
Encoding:
PHP Script  |  2004-03-20  |  21.4 KB  |  828 lines

  1. <?php
  2. /*
  3. V4.21 20 Mar 2004  (c) 2000-2004 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. if (! defined("_ADODB_MYSQL_LAYER")) {
  16.  define("_ADODB_MYSQL_LAYER", 1 );
  17.  
  18. class ADODB_mysqli extends ADOConnection {
  19.     var $databaseType = 'mysqli';
  20.     var $dataProvider = 'native';
  21.     var $hasInsertID = true;
  22.     var $hasAffectedRows = true;    
  23.     var $metaTablesSQL = "SHOW TABLES";    
  24.     var $metaColumnsSQL = "SHOW COLUMNS FROM %s";
  25.     var $fmtTimeStamp = "'Y-m-d H:i:s'";
  26.     var $hasLimit = true;
  27.     var $hasMoveFirst = true;
  28.     var $hasGenID = true;
  29.     var $upperCase = 'upper';
  30.     var $isoDates = true; // accepts dates in ISO format
  31.     var $sysDate = 'CURDATE()';
  32.     var $sysTimeStamp = 'NOW()';
  33.     var $hasTransactions = false;
  34.     var $forceNewConnect = false;
  35.     var $poorAffectedRows = true;
  36.     var $clientFlags = 0;
  37.     var $executeOnly = true;
  38.     var $substr = "substring";
  39.     var $nameQuote = '`';        /// string to use to quote identifiers and names
  40.     //var $_bindInputArray = true;
  41.     
  42.     function ADODB_mysqli() 
  43.     {            
  44.       if(!extension_loaded("mysqli"))
  45.         {
  46.           trigger_error("You must have the MySQLi extension.", E_USER_ERROR);
  47.         }
  48.     }
  49.     
  50.     function IfNull( $field, $ifNull ) 
  51.     {
  52.         return " IFNULL($field, $ifNull) "; // if MySQL
  53.     }
  54.     
  55.     function ServerInfo()
  56.     {
  57.         $arr['description'] = $this->GetOne("select version()");
  58.         $arr['version'] = ADOConnection::_findvers($arr['description']);
  59.         return $arr;
  60.     }
  61.     
  62.     
  63.     function BeginTrans()
  64.     {      
  65.         if ($this->transOff) return true;
  66.         $this->transCnt += 1;
  67.         $this->Execute('SET AUTOCOMMIT=0');
  68.         $this->Execute('BEGIN');
  69.         return true;
  70.     }
  71.     
  72.     function CommitTrans($ok=true) 
  73.     {
  74.         if ($this->transOff) return true; 
  75.         if (!$ok) return $this->RollbackTrans();
  76.         
  77.         if ($this->transCnt) $this->transCnt -= 1;
  78.         $this->Execute('COMMIT');
  79.         $this->Execute('SET AUTOCOMMIT=1');
  80.         return true;
  81.     }
  82.     
  83.     function RollbackTrans()
  84.     {
  85.         if ($this->transOff) return true;
  86.         if ($this->transCnt) $this->transCnt -= 1;
  87.         $this->Execute('ROLLBACK');
  88.         $this->Execute('SET AUTOCOMMIT=1');
  89.         return true;
  90.     }
  91.     
  92.     // if magic quotes disabled, use mysql_real_escape_string()
  93.     // From readme.htm:
  94.     // Quotes a string to be sent to the database. The $magic_quotes_enabled
  95.     // parameter may look funny, but the idea is if you are quoting a 
  96.     // string extracted from a POST/GET variable, then 
  97.     // pass get_magic_quotes_gpc() as the second parameter. This will 
  98.     // ensure that the variable is not quoted twice, once by qstr and once 
  99.     // by the magic_quotes_gpc.
  100.     //
  101.     //Eg. $s = $db->qstr(HTTP_GET_VARS['name'],get_magic_quotes_gpc());
  102.     function qstr($s, $magic_quotes = false)
  103.     {
  104.       if (!$magic_quotes) {
  105.         if (ADODB_PHPVER >= 0x5000) {
  106.         //  $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
  107.           return "'" . mysqli_real_escape_string($this->_connectionID, $s) . "'";
  108.         }
  109.         else
  110.           {
  111.         trigger_error("phpver < 5 not implemented", E_USER_ERROR);
  112.           }
  113.         
  114.         if ($this->replaceQuote[0] == '\\')
  115.           {
  116.         $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
  117.           }
  118.         return  "'".str_replace("'",$this->replaceQuote,$s)."'"; 
  119.       }
  120.       // undo magic quotes for "
  121.       $s = str_replace('\\"','"',$s);
  122.       return "'$s'";
  123.     }
  124.     
  125.     function _insertid()
  126.     {
  127. //      $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
  128.       $result = @mysqli_insert_id($this->_connectionID);
  129.       if ($result == -1){
  130.           if ($this->debug) ADOConnection::outp("mysqli_insert_id() failed : "  . $this->ErrorMsg());
  131.       }
  132.       return $result;
  133.     }
  134.     
  135.     // Only works for INSERT, UPDATE and DELETE query's
  136.     function _affectedrows()
  137.     {
  138.     //  $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
  139.       $result =  @mysqli_affected_rows($this->_connectionID);
  140.       if ($result == -1) {
  141.           if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : "  . $this->ErrorMsg());
  142.       }
  143.       return $result;
  144.     }
  145.   
  146.      // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
  147.     // Reference on Last_Insert_ID on the recommended way to simulate sequences
  148.      var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
  149.     var $_genSeqSQL = "create table %s (id int not null)";
  150.     var $_genSeq2SQL = "insert into %s values (%s)";
  151.     var $_dropSeqSQL = "drop table %s";
  152.     
  153.     function CreateSequence($seqname='adodbseq',$startID=1)
  154.     {
  155.         if (empty($this->_genSeqSQL)) return false;
  156.         $u = strtoupper($seqname);
  157.         
  158.         $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
  159.         if (!$ok) return false;
  160.         return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
  161.     }
  162.     
  163.     function GenID($seqname='adodbseq',$startID=1)
  164.     {
  165.         // post-nuke sets hasGenID to false
  166.         if (!$this->hasGenID) return false;
  167.         
  168.         $getnext = sprintf($this->_genIDSQL,$seqname);
  169.         $holdtransOK = $this->_transOK; // save the current status
  170.         $rs = @$this->Execute($getnext);
  171.         if (!$rs) {
  172.             if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
  173.             $u = strtoupper($seqname);
  174.             $this->Execute(sprintf($this->_genSeqSQL,$seqname));
  175.             $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
  176.             $rs = $this->Execute($getnext);
  177.         }
  178.         $this->genID = mysqli_insert_id($this->_connectionID);
  179.         
  180.         if ($rs) $rs->Close();
  181.         
  182.         return $this->genID;
  183.     }
  184.     
  185.       function &MetaDatabases()
  186.       {
  187.         $query = "SHOW DATABASES";
  188.         $ret =& $this->Execute($query);
  189.         return $ret;
  190.       }
  191.  
  192.       
  193.     function &MetaIndexes ($table, $primary = FALSE)
  194.     {
  195.             // save old fetch mode
  196.             global $ADODB_FETCH_MODE;
  197.             
  198.             $save = $ADODB_FETCH_MODE;
  199.             $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
  200.             if ($this->fetchMode !== FALSE) {
  201.                    $savem = $this->SetFetchMode(FALSE);
  202.             }
  203.             
  204.             // get index details
  205.             $rs = $this->Execute(sprintf('SHOW INDEXES FROM %s',$table));
  206.             
  207.             // restore fetchmode
  208.             if (isset($savem)) {
  209.                     $this->SetFetchMode($savem);
  210.             }
  211.             $ADODB_FETCH_MODE = $save;
  212.             
  213.             if (!is_object($rs)) {
  214.                     return FALSE;
  215.             }
  216.             
  217.             $indexes = array ();
  218.             
  219.             // parse index data into array
  220.             while ($row = $rs->FetchRow()) {
  221.                     if ($primary == FALSE AND $row[2] == 'PRIMARY') {
  222.                             continue;
  223.                     }
  224.                     
  225.                     if (!isset($indexes[$row[2]])) {
  226.                             $indexes[$row[2]] = array(
  227.                                     'unique' => ($row[1] == 0),
  228.                                     'columns' => array()
  229.                             );
  230.                     }
  231.                     
  232.                     $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
  233.             }
  234.             
  235.             // sort columns by order in the index
  236.             foreach ( array_keys ($indexes) as $index )
  237.             {
  238.                     ksort ($indexes[$index]['columns']);
  239.             }
  240.             
  241.             return $indexes;
  242.     }
  243.  
  244.     
  245.     // Format date column in sql string given an input format that understands Y M D
  246.     function SQLDate($fmt, $col=false)
  247.     {    
  248.         if (!$col) $col = $this->sysTimeStamp;
  249.         $s = 'DATE_FORMAT('.$col.",'";
  250.         $concat = false;
  251.         $len = strlen($fmt);
  252.         for ($i=0; $i < $len; $i++) {
  253.             $ch = $fmt[$i];
  254.             switch($ch) {
  255.             case 'Y':
  256.             case 'y':
  257.                 $s .= '%Y';
  258.                 break;
  259.             case 'Q':
  260.             case 'q':
  261.                 $s .= "'),Quarter($col)";
  262.                 
  263.                 if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
  264.                 else $s .= ",('";
  265.                 $concat = true;
  266.                 break;
  267.             case 'M':
  268.                 $s .= '%b';
  269.                 break;
  270.                 
  271.             case 'm':
  272.                 $s .= '%m';
  273.                 break;
  274.             case 'D':
  275.             case 'd':
  276.                 $s .= '%d';
  277.                 break;
  278.             
  279.             case 'H': 
  280.                 $s .= '%H';
  281.                 break;
  282.                 
  283.             case 'h':
  284.                 $s .= '%I';
  285.                 break;
  286.                 
  287.             case 'i':
  288.                 $s .= '%i';
  289.                 break;
  290.                 
  291.             case 's':
  292.                 $s .= '%s';
  293.                 break;
  294.                 
  295.             case 'a':
  296.             case 'A':
  297.                 $s .= '%p';
  298.                 break;
  299.                 
  300.             default:
  301.                 
  302.                 if ($ch == '\\') {
  303.                     $i++;
  304.                     $ch = substr($fmt,$i,1);
  305.                 }
  306.                 $s .= $ch;
  307.                 break;
  308.             }
  309.         }
  310.         $s.="')";
  311.         if ($concat) $s = "CONCAT($s)";
  312.         return $s;
  313.     }
  314.     
  315.     // returns concatenated string
  316.     // much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
  317.     function Concat()
  318.     {
  319.         $s = "";
  320.         $arr = func_get_args();
  321.         
  322.         // suggestion by andrew005@mnogo.ru
  323.         $s = implode(',',$arr); 
  324.         if (strlen($s) > 0) return "CONCAT($s)";
  325.         else return '';
  326.     }
  327.     
  328.     // dayFraction is a day in floating point
  329.     function OffsetDate($dayFraction,$date=false)
  330.     {        
  331.         if (!$date) 
  332.           $date = $this->sysDate;
  333.         return "from_unixtime(unix_timestamp($date)+($dayFraction)*24*3600)";
  334.     }
  335.     
  336.     // returns true or false
  337.     // To add: parameter int $port,
  338.     //         parameter string $socket
  339.     function _connect($argHostname = NULL, 
  340.               $argUsername = NULL, 
  341.               $argPassword = NULL, 
  342.               $argDatabasename = NULL)
  343.       {
  344.         // @ means: error surpression on
  345.         $this->_connectionID = @mysqli_init();
  346.         
  347.         if (is_null($this->_connectionID))
  348.         {
  349.           // mysqli_init only fails if insufficient memory
  350.           if ($this->debug) 
  351.         ADOConnection::outp("mysqli_init() failed : "  . $this->ErrorMsg());
  352.           return false;
  353.         }
  354.         // Set connection options
  355.         // Not implemented now
  356.         // mysqli_options($this->_connection,,);
  357.          if (mysqli_real_connect($this->_connectionID,
  358.                      $argHostname,
  359.                      $argUsername,
  360.                      $argPassword,
  361.                      $argDatabasename))
  362.            {
  363.          if ($argDatabasename) 
  364.           {
  365.             return $this->SelectDB($argDatabasename);
  366.           }
  367.         
  368.          return true;
  369.            }
  370.          else
  371.           {
  372.         if ($this->debug) 
  373.           ADOConnection::outp("Could't connect : "  . $this->ErrorMsg());
  374.         return false;
  375.           }
  376.       }
  377.     
  378.     // returns true or false
  379.     // How to force a persistent connection
  380.     function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
  381.       {
  382.         // not implemented in mysqli (yet)?
  383.         $this->_connectionID = mysqli_connect($argHostname,
  384.                           $argUsername,
  385.                           $argPassword,
  386.                           $argDatabasename);
  387.         if ($this->_connectionID === false) return false;
  388.         //        if ($this->autoRollback) $this->RollbackTrans();
  389.         if ($argDatabasename) return $this->SelectDB($argDatabasename);
  390.         return true;    
  391.       }
  392.     
  393.     // When is this used? Close old connection first?
  394.     // In _connect(), check $this->forceNewConnect? 
  395.     function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
  396.       {
  397.         $this->forceNewConnect = true;
  398.         $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
  399.       }
  400.     
  401.      function &MetaColumns($table) 
  402.     {
  403.       if ($this->metaColumnsSQL) {
  404.         global $ADODB_FETCH_MODE;
  405.         $save = $ADODB_FETCH_MODE;
  406.         $rs = false;
  407.         switch($ADODB_FETCH_MODE)
  408.           {
  409.           case ADODB_FETCH_NUM:
  410.         $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
  411.         $rs = $this->Execute(sprintf($this->metaColumnsSQL,
  412.                          $table));
  413.         
  414.         $ADODB_FETCH_MODE = $save;
  415.         if ($rs === false) break;
  416.         $retarr = array();
  417.         while (!$rs->EOF){
  418.           $fld = new ADOFieldObject();
  419.           $fld->name = $rs->fields[0];
  420.           $fld->type = $rs->fields[1];
  421.           // split type into type(length):
  422.           if (preg_match("/^(.+)\((\d+)\)$/", $fld->type, $query_array))
  423.             {
  424.               $fld->type = $query_array[1];
  425.               $fld->max_length = $query_array[2];
  426.             }
  427.           else
  428.             {
  429.               $fld->max_length = -1;
  430.             }
  431.           $fld->not_null = ($rs->fields[2] != 'YES');
  432.           $fld->primary_key = ($rs->fields[3] == 'PRI');
  433.           $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
  434.           $fld->binary = (strpos($fld->type,'blob') !== false);
  435.           if (!$fld->binary) 
  436.             {
  437.               $d = $rs->fields[4];
  438.               $d = $rs->fields['Default'];
  439.               if ($d != "" && $d != "NULL")
  440.             {
  441.               $fld->has_default = true;
  442.               $fld->default_value = $d;
  443.             } 
  444.               else 
  445.             {
  446.               $fld->has_default = false;
  447.             }
  448.             }
  449.           $retarr[strtoupper($fld->name)] = $fld;    
  450.           $rs->MoveNext();
  451.         }
  452.         break;
  453.           case ADODB_FETCH_ASSOC:
  454.           case ADODB_FETCH_DEFAULT:
  455.           case ADODB_FETCH_BOTH:
  456.         $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
  457.         $rs = $this->Execute(sprintf($this->metaColumnsSQL,
  458.                          $table));
  459.         $ADODB_FETCH_MODE = $save;
  460.         if ($rs === false) break;
  461.         $retarr = array();
  462.         while (!$rs->EOF){
  463.           $fld = new ADOFieldObject();
  464.           $fld->name = $rs->fields['Field'];
  465.           $fld->type = $rs->fields['Type'];
  466.                 
  467.           // split type into type(length):
  468.           if (preg_match("/^(.+)\((\d+)\)$/", $fld->type, $query_array))
  469.             {
  470.               $fld->type = $query_array[1];
  471.               $fld->max_length = $query_array[2];
  472.             }
  473.           else
  474.             {
  475.               $fld->max_length = -1;
  476.             }
  477.           $fld->not_null = ($rs->fields['Null'] != 'YES');
  478.           $fld->primary_key = ($rs->fields['Key'] == 'PRI');
  479.           $fld->auto_increment = (strpos($rs->fields['Extra'], 'auto_increment') !== false);
  480.           $fld->binary = (strpos($fld->type,'blob') !== false);
  481.           if (!$fld->binary) 
  482.             {
  483.               $d = $rs->fields['Default'];
  484.               if ($d != "" && $d != "NULL")
  485.             {
  486.               $fld->has_default = true;
  487.               $fld->default_value = $d;
  488.             } 
  489.               else 
  490.             {
  491.               $fld->has_default = false;
  492.             }
  493.             }
  494.           $retarr[strtoupper($fld->name)] = $fld;    
  495.           $rs->MoveNext();
  496.         }
  497.         break;
  498.           default:
  499.           }
  500.         
  501.         if ($rs === false) return false;
  502.         $rs->Close();
  503.         return $retarr;    
  504.       }
  505.       return false;
  506.     }
  507.         
  508.     // returns true or false
  509.     function SelectDB($dbName) 
  510.     {
  511. //        $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
  512.         $this->databaseName = $dbName;
  513.         if ($this->_connectionID) {
  514.             $result = @mysqli_select_db($this->_connectionID, $dbName);
  515.             if (!$result) {
  516.                 ADOConnection::outp("Select of database " . $dbName . " failed. " . $this->ErrorMsg());
  517.             }
  518.             return $result;        
  519.         }
  520.         return false;    
  521.     }
  522.     
  523.     // parameters use PostgreSQL convention, not MySQL
  524.     function &SelectLimit($sql,
  525.                   $nrows = -1,
  526.                   $offset = -1,
  527.                   $inputarr = false, 
  528.                   $arg3 = false,
  529.                   $secs = 0)
  530.     {
  531.         $offsetStr = ($offset >= 0) ? "$offset," : '';
  532.         
  533.         if ($secs)
  534.             $rs =& $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr , $arg3);
  535.         else
  536.             $rs =& $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr , $arg3);
  537.             
  538.         return $rs;
  539.     }
  540.     
  541.     
  542.     function Prepare($sql)
  543.     {
  544.         return $sql;
  545.         
  546.         $stmt = mysqli_prepare($this->_connectionID,$sql);
  547.         if (!$stmt) return false;
  548.         return array($sql,$stmt);
  549.     }
  550.     
  551.     
  552.     // returns queryID or false
  553.     function _query($sql, $inputarr)
  554.     {
  555.     global $ADODB_COUNTRECS;
  556.     
  557.         if (is_array($sql)) {
  558.             $stmt = $sql[1];
  559.             foreach($inputarr as $k => $v) {
  560.                 if (is_string($v)) $a[] = MYSQLI_BIND_STRING;
  561.                 else if (is_integer($v)) $a[] = MYSQLI_BIND_INT; 
  562.                 else $a[] = MYSQLI_BIND_DOUBLE;
  563.                 
  564.                 $fnarr =& array_merge( array($stmt,$a) , $inputarr);
  565.                 $ret = call_user_func_array('mysqli_bind_param',$fnarr);
  566.             }
  567.             $ret = mysqli_execute($stmt);
  568.             return $ret;
  569.         }
  570.         if (!$mysql_res =  mysqli_query($this->_connectionID, $sql, ($ADODB_COUNTRECS) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT)) {
  571.             if ($this->debug) ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg());
  572.             return false;
  573.         }
  574.         
  575.         return $mysql_res;
  576.     }
  577.  
  578.     /*    Returns: the last error message from previous database operation    */    
  579.     function ErrorMsg() 
  580.       {
  581.         if (empty($this->_connectionID)) 
  582.           $this->_errorMsg = @mysqli_error();
  583.         else 
  584.           $this->_errorMsg = @mysqli_error($this->_connectionID);
  585.         return $this->_errorMsg;
  586.       }
  587.     
  588.     /*    Returns: the last error number from previous database operation    */    
  589.     function ErrorNo() 
  590.       {
  591.         if (empty($this->_connectionID))  
  592.           return @mysqli_errno();
  593.         else 
  594.           return @mysqli_errno($this->_connectionID);
  595.       }
  596.     
  597.     // returns true or false
  598.     function _close()
  599.       {
  600.         @mysqli_close($this->_connectionID);
  601.         $this->_connectionID = false;
  602.       }
  603.  
  604.     /*
  605.     * Maximum size of C field
  606.     */
  607.     function CharMax()
  608.     {
  609.         return 255; 
  610.     }
  611.     
  612.     /*
  613.     * Maximum size of X field
  614.     */
  615.     function TextMax()
  616.     {
  617.       return 4294967295; 
  618.     }
  619.  
  620.  
  621. }
  622.  
  623. /*--------------------------------------------------------------------------------------
  624.      Class Name: Recordset
  625. --------------------------------------------------------------------------------------*/
  626.  
  627. class ADORecordSet_mysqli extends ADORecordSet{    
  628.     
  629.     var $databaseType = "mysqli";
  630.     var $canSeek = true;
  631.     
  632.     function ADORecordSet_mysqli($queryID, $mode = false) 
  633.     {
  634.       if ($mode === false) 
  635.         { 
  636.           global $ADODB_FETCH_MODE;
  637.           $mode = $ADODB_FETCH_MODE;
  638.         }
  639.       switch ($mode)
  640.         {
  641.         case ADODB_FETCH_NUM: 
  642.           $this->fetchMode = MYSQLI_NUM; 
  643.           break;
  644.         case ADODB_FETCH_ASSOC:
  645.           $this->fetchMode = MYSQLI_ASSOC; 
  646.           break;
  647.         case ADODB_FETCH_DEFAULT:
  648.         case ADODB_FETCH_BOTH:
  649.         default:
  650.           $this->fetchMode = MYSQLI_ASSOC; 
  651.           break;
  652.         }
  653.       $this->ADORecordSet($queryID);    
  654.     }
  655.     
  656.     function _initrs()
  657.     {
  658.         // mysqli_num_rows only return correct number, depens
  659.         // on the use of mysql_store_result and mysql_use_result
  660.         if (!$this->Connection->executeOnly) {
  661.             $this->_numOfRows = @mysqli_num_rows($this->_queryID);
  662.             $this->_numOfFields = @mysqli_num_fields($this->_queryID);
  663.         }
  664.         else {
  665.             $this->_numOfRows = 0;
  666.             $this->_numOfFields = 0;
  667.         }
  668.     }
  669.     
  670.     function &FetchField($fieldOffset = -1) 
  671.     {    
  672.       $fieldnr = $fieldOffset;
  673.       if ($fieldOffset != -1) {
  674.         $fieldOffset = mysqi_field_seek($this->_queryID, $fieldnr);
  675.       }
  676.       $o = mysqli_fetch_field($this->_queryID);
  677.       return $o;
  678.     }
  679.  
  680.     function &GetRowAssoc($upper = true)
  681.     {
  682.       if ($this->fetchMode == MYSQLI_ASSOC && !$upper) 
  683.         return $this->fields;
  684.       $row =& ADORecordSet::GetRowAssoc($upper);
  685.       return $row;
  686.     }
  687.     
  688.     /* Use associative array to get fields array */
  689.     function Fields($colname)
  690.     {    
  691.       if ($this->fetchMode != MYSQLI_NUM) 
  692.         return @$this->fields[$colname];
  693.         
  694.       if (!$this->bind) {
  695.         $this->bind = array();
  696.         for ($i = 0; $i < $this->_numOfFields; $i++) {
  697.           $o = $this->FetchField($i);
  698.           $this->bind[strtoupper($o->name)] = $i;
  699.         }
  700.       }
  701.       return $this->fields[$this->bind[strtoupper($colname)]];
  702.     }
  703.     
  704.     function _seek($row)
  705.     {
  706.       if ($this->_numOfRows == 0) 
  707.         return false;
  708.  
  709.       if ($row < 0)
  710.         return false;
  711.  
  712.       mysqli_data_seek($this->_queryID, $row);
  713.       $this->EOF = false;
  714.       return true;
  715.     }
  716.         
  717.     // 10% speedup to move MoveNext to child class
  718.     // This is the only implementation that works now (23-10-2003).
  719.     // Other functions return no or the wrong results.
  720.     function MoveNext() 
  721.     {
  722.       if ($this->EOF) 
  723.         return false;
  724.       $this->_currentRow++;
  725.       switch($this->fetchMode)
  726.         {
  727.         case MYSQLI_NUM:
  728.           $this->fields = mysqli_fetch_array($this->_queryID);
  729.           break;
  730.         case MYSQLI_ASSOC:
  731.         case MYSQLI_BOTH:
  732.           $this->fields = mysqli_fetch_assoc($this->_queryID);
  733.           break;
  734.         default:
  735.         }
  736.       if (is_array($this->fields)) 
  737.         return true;
  738.       $this->EOF = true;
  739.       return false;
  740.     }    
  741.     
  742.     function _fetch()
  743.     {
  744.       // mysqli_fetch_array($this->_queryID, MYSQLI_NUM) does not
  745.       // work (22-10-2003). But mysqli_fetch_array($this->_queryID) gives
  746.       // int resulttype should default to MYSQLI_BOTH,but give MYSQLI_NUM.
  747.  
  748.       //      $this->fields =  mysqli_fetch_fields($this->_queryID);
  749.       //      $this->fields =  mysqli_fetch_array($this->_queryID); //, $this->fetchMode);
  750.           
  751.       $this->fields =  mysqli_fetch_assoc($this->_queryID); // $this->fetchMode);
  752.       return is_array($this->fields);
  753.     }
  754.     
  755.     function _close() 
  756.     {
  757.       mysqli_free_result($this->_queryID); 
  758.       $this->_queryID = false;    
  759.     }
  760.     
  761.     function MetaType($t, $len = -1, $fieldobj = false)
  762.     {
  763.       if (is_object($t)) 
  764.         {
  765.           $fieldobj = $t;
  766.           $t = $fieldobj->type;
  767.           $len = $fieldobj->max_length;
  768.         }
  769.         
  770.       $len = -1; // mysql max_length is not accurate
  771.       switch (strtoupper($t)) {
  772.       case 'STRING': 
  773.       case 'CHAR':
  774.       case 'VARCHAR': 
  775.       case 'TINYBLOB': 
  776.       case 'TINYTEXT': 
  777.       case 'ENUM': 
  778.       case 'SET': 
  779.         if ($len <= $this->blobSize) return 'C';
  780.         
  781.       case 'TEXT':
  782.       case 'LONGTEXT': 
  783.       case 'MEDIUMTEXT':
  784.         return 'X';
  785.             
  786.         // php_mysql extension always returns 'blob' even if 'text'
  787.         // so we have to check whether binary...
  788.       case 'IMAGE':
  789.       case 'LONGBLOB': 
  790.       case 'BLOB':
  791.       case 'MEDIUMBLOB':
  792.         return !empty($fieldobj->binary) ? 'B' : 'X';
  793.       case 'YEAR':
  794.       case 'DATE': 
  795.         return 'D';
  796.         
  797.       case 'TIME':
  798.       case 'DATETIME':
  799.       case 'TIMESTAMP': return 'T';
  800.         
  801.       case 'INT': 
  802.       case 'INTEGER':
  803.       case 'BIGINT':
  804.       case 'TINYINT':
  805.       case 'MEDIUMINT':
  806.       case 'SMALLINT': 
  807.             
  808.         if (!empty($fieldobj->primary_key)) return 'R';
  809.         else return 'I';
  810.         // Added floating-point types
  811.         // Maybe not necessery.
  812.       case 'FLOAT':
  813.       case 'DOUBLE':
  814.         //        case 'DOUBLE PRECISION':
  815.       case 'DECIMAL':
  816.       case 'DEC':
  817.       case 'FIXED':
  818.       default: 
  819.         return 'N';
  820.       }
  821.     }
  822.     
  823.  
  824. }
  825.  
  826. }
  827.  
  828. ?>