home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2005 June / PCpro_2005_06.ISO / files / opensource / xamp / xampp-win32.exe / xampp / adodb-mysqli.inc.php < prev    next >
Encoding:
PHP Script  |  2005-01-24  |  20.2 KB  |  818 lines

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