]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/adodb/drivers/adodb-mysql.inc.php
Upgrade adodb
[SourceForge/phpwiki.git] / lib / WikiDB / adodb / drivers / adodb-mysql.inc.php
1 <?php
2 /*
3 V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). 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  28 Feb 2001: MetaColumns bug fix - suggested by  Freek Dijkstra (phpeverywhere@macfreek.com)
13 */ 
14
15 // security - hide paths
16 if (!defined('ADODB_DIR')) die();
17
18 if (! defined("_ADODB_MYSQL_LAYER")) {
19  define("_ADODB_MYSQL_LAYER", 1 );
20
21 class ADODB_mysql extends ADOConnection {
22         var $databaseType = 'mysql';
23         var $dataProvider = 'mysql';
24         var $hasInsertID = true;
25         var $hasAffectedRows = true;    
26         var $metaTablesSQL = "SELECT TABLE_NAME, CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=SCHEMA()";
27         var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`";
28         var $fmtTimeStamp = "'Y-m-d H:i:s'";
29         var $hasLimit = true;
30         var $hasMoveFirst = true;
31         var $hasGenID = true;
32         var $isoDates = true; // accepts dates in ISO format
33         var $sysDate = 'CURDATE()';
34         var $sysTimeStamp = 'NOW()';
35         var $hasTransactions = false;
36         var $forceNewConnect = false;
37         var $poorAffectedRows = true;
38         var $clientFlags = 0;
39         var $charSet = '';
40         var $substr = "substring";
41         var $nameQuote = '`';           /// string to use to quote identifiers and names
42         var $compat323 = false;                 // true if compat with mysql 3.23
43         
44         function ADODB_mysql() 
45         {                       
46                 if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
47         }
48
49
50   // SetCharSet - switch the client encoding
51   function SetCharSet($charset_name)
52   {
53     if (!function_exists('mysql_set_charset'))
54         return false;
55
56         if ($this->charSet !== $charset_name) {
57       $ok = @mysql_set_charset($charset_name,$this->_connectionID);
58       if ($ok) {
59                 $this->charSet = $charset_name;
60         return true;
61       }
62           return false;
63     }
64         return true;
65   }
66   
67         function ServerInfo()
68         {
69                 $arr['description'] = ADOConnection::GetOne("select version()");
70                 $arr['version'] = ADOConnection::_findvers($arr['description']);
71                 return $arr;
72         }
73         
74         function IfNull( $field, $ifNull ) 
75         {
76                 return " IFNULL($field, $ifNull) "; // if MySQL
77         }
78         
79     function MetaProcedures($NamePattern = false, $catalog  = null, $schemaPattern  = null)
80     {
81         // save old fetch mode
82         global $ADODB_FETCH_MODE;
83
84         $false = false;
85         $save = $ADODB_FETCH_MODE;
86         $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
87
88         if ($this->fetchMode !== FALSE) {
89                $savem = $this->SetFetchMode(FALSE);
90         }
91
92         $procedures = array ();
93
94         // get index details
95
96         $likepattern = '';
97         if ($NamePattern) {
98            $likepattern = " LIKE '".$NamePattern."'";
99         }
100         $rs = $this->Execute('SHOW PROCEDURE STATUS'.$likepattern);
101         if (is_object($rs)) {
102
103             // parse index data into array
104             while ($row = $rs->FetchRow()) {
105                     $procedures[$row[1]] = array(
106                                     'type' => 'PROCEDURE',
107                                     'catalog' => '',
108
109                                     'schema' => '',
110                                     'remarks' => $row[7],
111                             );
112             }
113         }
114
115         $rs = $this->Execute('SHOW FUNCTION STATUS'.$likepattern);
116         if (is_object($rs)) {
117             // parse index data into array
118             while ($row = $rs->FetchRow()) {
119                 $procedures[$row[1]] = array(
120                         'type' => 'FUNCTION',
121                         'catalog' => '',
122                         'schema' => '',
123                         'remarks' => $row[7]
124                     );
125             }
126             }
127
128         // restore fetchmode
129         if (isset($savem)) {
130                 $this->SetFetchMode($savem);
131
132         }
133         $ADODB_FETCH_MODE = $save;
134
135
136         return $procedures;
137     }
138         
139         function MetaTables($ttype=false,$showSchema=false,$mask=false) 
140         {       
141                 $save = $this->metaTablesSQL;
142                 if ($showSchema && is_string($showSchema)) {
143                         $this->metaTablesSQL .= " from $showSchema";
144                 }
145                 
146                 if ($mask) {
147                         $mask = $this->qstr($mask);
148                         $this->metaTablesSQL .= " like $mask";
149                 }
150                 $ret = ADOConnection::MetaTables($ttype,$showSchema);
151                 
152                 $this->metaTablesSQL = $save;
153                 return $ret;
154         }
155         
156         
157         function MetaIndexes ($table, $primary = FALSE, $owner=false)
158         {
159         // save old fetch mode
160         global $ADODB_FETCH_MODE;
161         
162                 $false = false;
163         $save = $ADODB_FETCH_MODE;
164         $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
165         if ($this->fetchMode !== FALSE) {
166                $savem = $this->SetFetchMode(FALSE);
167         }
168         
169         // get index details
170         $rs = $this->Execute(sprintf('SHOW INDEX FROM %s',$table));
171         
172         // restore fetchmode
173         if (isset($savem)) {
174                 $this->SetFetchMode($savem);
175         }
176         $ADODB_FETCH_MODE = $save;
177         
178         if (!is_object($rs)) {
179                 return $false;
180         }
181         
182         $indexes = array ();
183         
184         // parse index data into array
185         while ($row = $rs->FetchRow()) {
186                 if ($primary == FALSE AND $row[2] == 'PRIMARY') {
187                         continue;
188                 }
189                 
190                 if (!isset($indexes[$row[2]])) {
191                         $indexes[$row[2]] = array(
192                                 'unique' => ($row[1] == 0),
193                                 'columns' => array()
194                         );
195                 }
196                 
197                 $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
198         }
199         
200         // sort columns by order in the index
201         foreach ( array_keys ($indexes) as $index )
202         {
203                 ksort ($indexes[$index]['columns']);
204         }
205         
206         return $indexes;
207         }
208
209         
210         // if magic quotes disabled, use mysql_real_escape_string()
211         function qstr($s,$magic_quotes=false)
212         {
213                 if (is_null($s)) return 'NULL';
214                 if (!$magic_quotes) {
215                 
216                         if (ADODB_PHPVER >= 0x4300) {
217                                 if (is_resource($this->_connectionID))
218                                         return "'".mysql_real_escape_string($s,$this->_connectionID)."'";
219                         }
220                         if ($this->replaceQuote[0] == '\\'){
221                                 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
222                         }
223                         return  "'".str_replace("'",$this->replaceQuote,$s)."'"; 
224                 }
225                 
226                 // undo magic quotes for "
227                 $s = str_replace('\\"','"',$s);
228                 return "'$s'";
229         }
230         
231         function _insertid()
232         {
233                 return ADOConnection::GetOne('SELECT LAST_INSERT_ID()');
234                 //return mysql_insert_id($this->_connectionID);
235         }
236         
237         function GetOne($sql,$inputarr=false)
238         {
239         global $ADODB_GETONE_EOF;
240                 if ($this->compat323 == false && strncasecmp($sql,'sele',4) == 0) {
241                         $rs = $this->SelectLimit($sql,1,-1,$inputarr);
242                         if ($rs) {
243                                 $rs->Close();
244                                 if ($rs->EOF) return $ADODB_GETONE_EOF;
245                                 return reset($rs->fields);
246                         }
247                 } else {
248                         return ADOConnection::GetOne($sql,$inputarr);
249                 }
250                 return false;
251         }
252         
253         function BeginTrans()
254         {
255                 if ($this->debug) ADOConnection::outp("Transactions not supported in 'mysql' driver. Use 'mysqlt' or 'mysqli' driver");
256         }
257         
258         function _affectedrows()
259         {
260                         return mysql_affected_rows($this->_connectionID);
261         }
262   
263          // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
264         // Reference on Last_Insert_ID on the recommended way to simulate sequences
265         var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
266         var $_genSeqSQL = "create table %s (id int not null)";
267         var $_genSeqCountSQL = "select count(*) from %s";
268         var $_genSeq2SQL = "insert into %s values (%s)";
269         var $_dropSeqSQL = "drop table %s";
270         
271         function CreateSequence($seqname='adodbseq',$startID=1)
272         {
273                 if (empty($this->_genSeqSQL)) return false;
274                 $u = strtoupper($seqname);
275                 
276                 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
277                 if (!$ok) return false;
278                 return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
279         }
280         
281
282         function GenID($seqname='adodbseq',$startID=1)
283         {
284                 // post-nuke sets hasGenID to false
285                 if (!$this->hasGenID) return false;
286                 
287                 $savelog = $this->_logsql;
288                 $this->_logsql = false;
289                 $getnext = sprintf($this->_genIDSQL,$seqname);
290                 $holdtransOK = $this->_transOK; // save the current status
291                 $rs = @$this->Execute($getnext);
292                 if (!$rs) {
293                         if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
294                         $u = strtoupper($seqname);
295                         $this->Execute(sprintf($this->_genSeqSQL,$seqname));
296                         $cnt = $this->GetOne(sprintf($this->_genSeqCountSQL,$seqname));
297                         if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
298                         $rs = $this->Execute($getnext);
299                 }
300                 
301                 if ($rs) {
302                         $this->genID = mysql_insert_id($this->_connectionID);
303                         $rs->Close();
304                 } else
305                         $this->genID = 0;
306                 
307                 $this->_logsql = $savelog;
308                 return $this->genID;
309         }
310         
311         function MetaDatabases()
312         {
313                 $qid = mysql_list_dbs($this->_connectionID);
314                 $arr = array();
315                 $i = 0;
316                 $max = mysql_num_rows($qid);
317                 while ($i < $max) {
318                         $db = mysql_tablename($qid,$i);
319                         if ($db != 'mysql') $arr[] = $db;
320                         $i += 1;
321                 }
322                 return $arr;
323         }
324         
325                 
326         // Format date column in sql string given an input format that understands Y M D
327         function SQLDate($fmt, $col=false)
328         {       
329                 if (!$col) $col = $this->sysTimeStamp;
330                 $s = 'DATE_FORMAT('.$col.",'";
331                 $concat = false;
332                 $len = strlen($fmt);
333                 for ($i=0; $i < $len; $i++) {
334                         $ch = $fmt[$i];
335                         switch($ch) {
336                                 
337                         default:
338                                 if ($ch == '\\') {
339                                         $i++;
340                                         $ch = substr($fmt,$i,1);
341                                 }
342                                 /** FALL THROUGH */
343                         case '-':
344                         case '/':
345                                 $s .= $ch;
346                                 break;
347                                 
348                         case 'Y':
349                         case 'y':
350                                 $s .= '%Y';
351                                 break;
352                         case 'M':
353                                 $s .= '%b';
354                                 break;
355                                 
356                         case 'm':
357                                 $s .= '%m';
358                                 break;
359                         case 'D':
360                         case 'd':
361                                 $s .= '%d';
362                                 break;
363                         
364                         case 'Q':
365                         case 'q':
366                                 $s .= "'),Quarter($col)";
367                                 
368                                 if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
369                                 else $s .= ",('";
370                                 $concat = true;
371                                 break;
372                         
373                         case 'H': 
374                                 $s .= '%H';
375                                 break;
376                                 
377                         case 'h':
378                                 $s .= '%I';
379                                 break;
380                                 
381                         case 'i':
382                                 $s .= '%i';
383                                 break;
384                                 
385                         case 's':
386                                 $s .= '%s';
387                                 break;
388                                 
389                         case 'a':
390                         case 'A':
391                                 $s .= '%p';
392                                 break;
393                                 
394                         case 'w':
395                                 $s .= '%w';
396                                 break;
397                                 
398                          case 'W':
399                                 $s .= '%U';
400                                 break;
401                                 
402                         case 'l':
403                                 $s .= '%W';
404                                 break;
405                         }
406                 }
407                 $s.="')";
408                 if ($concat) $s = "CONCAT($s)";
409                 return $s;
410         }
411         
412
413         // returns concatenated string
414         // much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
415         function Concat()
416         {
417                 $s = "";
418                 $arr = func_get_args();
419                 
420                 // suggestion by andrew005@mnogo.ru
421                 $s = implode(',',$arr); 
422                 if (strlen($s) > 0) return "CONCAT($s)";
423                 else return '';
424         }
425         
426         function OffsetDate($dayFraction,$date=false)
427         {               
428                 if (!$date) $date = $this->sysDate;
429                 
430                 $fraction = $dayFraction * 24 * 3600;
431                 return '('. $date . ' + INTERVAL ' .     $fraction.' SECOND)';
432                 
433 //              return "from_unixtime(unix_timestamp($date)+$fraction)";
434         }
435         
436         // returns true or false
437         function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
438         {
439                 if (!empty($this->port)) $argHostname .= ":".$this->port;
440                 
441                 if (ADODB_PHPVER >= 0x4300)
442                         $this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword,
443                                                                                                 $this->forceNewConnect,$this->clientFlags);
444                 else if (ADODB_PHPVER >= 0x4200)
445                         $this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword,
446                                                                                                 $this->forceNewConnect);
447                 else
448                         $this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword);
449         
450                 if ($this->_connectionID === false) return false;
451                 if ($argDatabasename) return $this->SelectDB($argDatabasename);
452                 return true;    
453         }
454         
455         // returns true or false
456         function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
457         {
458                 if (!empty($this->port)) $argHostname .= ":".$this->port;
459                 
460                 if (ADODB_PHPVER >= 0x4300)
461                         $this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword,$this->clientFlags);
462                 else
463                         $this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword);
464                 if ($this->_connectionID === false) return false;
465                 if ($this->autoRollback) $this->RollbackTrans();
466                 if ($argDatabasename) return $this->SelectDB($argDatabasename);
467                 return true;    
468         }
469         
470         function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
471         {
472                 $this->forceNewConnect = true;
473                 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
474         }
475         
476         function MetaColumns($table, $normalize=true) 
477         {
478                 $this->_findschema($table,$schema);
479                 if ($schema) {
480                         $dbName = $this->database;
481                         $this->SelectDB($schema);
482                 }
483                 global $ADODB_FETCH_MODE;
484                 $save = $ADODB_FETCH_MODE;
485                 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
486                 
487                 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
488                 $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
489                 
490                 if ($schema) {
491                         $this->SelectDB($dbName);
492                 }
493                 
494                 if (isset($savem)) $this->SetFetchMode($savem);
495                 $ADODB_FETCH_MODE = $save;
496                 if (!is_object($rs)) {
497                         $false = false;
498                         return $false;
499                 }
500                         
501                 $retarr = array();
502                 while (!$rs->EOF){
503                         $fld = new ADOFieldObject();
504                         $fld->name = $rs->fields[0];
505                         $type = $rs->fields[1];
506                         
507                         // split type into type(length):
508                         $fld->scale = null;
509                         if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
510                                 $fld->type = $query_array[1];
511                                 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
512                                 $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
513                         } elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
514                                 $fld->type = $query_array[1];
515                                 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
516                         } elseif (preg_match("/^(enum)\((.*)\)$/i", $type, $query_array)) {
517                                 $fld->type = $query_array[1];
518                                 $arr = explode(",",$query_array[2]);
519                                 $fld->enums = $arr;
520                                 $zlen = max(array_map("strlen",$arr)) - 2; // PHP >= 4.0.6
521                                 $fld->max_length = ($zlen > 0) ? $zlen : 1;
522                         } else {
523                                 $fld->type = $type;
524                                 $fld->max_length = -1;
525                         }
526                         $fld->not_null = ($rs->fields[2] != 'YES');
527                         $fld->primary_key = ($rs->fields[3] == 'PRI');
528                         $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
529                         $fld->binary = (strpos($type,'blob') !== false || strpos($type,'binary') !== false);
530                         $fld->unsigned = (strpos($type,'unsigned') !== false);
531                         $fld->zerofill = (strpos($type,'zerofill') !== false);
532
533                         if (!$fld->binary) {
534                                 $d = $rs->fields[4];
535                                 if ($d != '' && $d != 'NULL') {
536                                         $fld->has_default = true;
537                                         $fld->default_value = $d;
538                                 } else {
539                                         $fld->has_default = false;
540                                 }
541                         }
542                         
543                         if ($save == ADODB_FETCH_NUM) {
544                                 $retarr[] = $fld;
545                         } else {
546                                 $retarr[strtoupper($fld->name)] = $fld;
547                         }
548                                 $rs->MoveNext();
549                         }
550                 
551                         $rs->Close();
552                         return $retarr; 
553         }
554                 
555         // returns true or false
556         function SelectDB($dbName) 
557         {
558                 $this->database = $dbName;
559                 $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
560                 if ($this->_connectionID) {
561                         return @mysql_select_db($dbName,$this->_connectionID);          
562                 }
563                 else return false;      
564         }
565         
566         // parameters use PostgreSQL convention, not MySQL
567         function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
568         {
569                 $offsetStr =($offset>=0) ? ((integer)$offset)."," : '';
570                 // jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220
571                 if ($nrows < 0) $nrows = '18446744073709551615'; 
572                 
573                 if ($secs)
574                         $rs = $this->CacheExecute($secs,$sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
575                 else
576                         $rs = $this->Execute($sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
577                 return $rs;
578         }
579         
580         // returns queryID or false
581         function _query($sql,$inputarr=false)
582         {
583         //global $ADODB_COUNTRECS;
584                 //if($ADODB_COUNTRECS) 
585                 return mysql_query($sql,$this->_connectionID);
586                 //else return @mysql_unbuffered_query($sql,$this->_connectionID); // requires PHP >= 4.0.6
587         }
588
589         /*      Returns: the last error message from previous database operation        */      
590         function ErrorMsg() 
591         {
592         
593                 if ($this->_logsql) return $this->_errorMsg;
594                 if (empty($this->_connectionID)) $this->_errorMsg = @mysql_error();
595                 else $this->_errorMsg = @mysql_error($this->_connectionID);
596                 return $this->_errorMsg;
597         }
598         
599         /*      Returns: the last error number from previous database operation */      
600         function ErrorNo() 
601         {
602                 if ($this->_logsql) return $this->_errorCode;
603                 if (empty($this->_connectionID))  return @mysql_errno();
604                 else return @mysql_errno($this->_connectionID);
605         }
606         
607         // returns true or false
608         function _close()
609         {
610                 @mysql_close($this->_connectionID);
611                 
612                 $this->charSet = '';
613                 $this->_connectionID = false;
614         }
615
616         
617         /*
618         * Maximum size of C field
619         */
620         function CharMax()
621         {
622                 return 255; 
623         }
624         
625         /*
626         * Maximum size of X field
627         */
628         function TextMax()
629         {
630                 return 4294967295; 
631         }
632         
633         // "Innox - Juan Carlos Gonzalez" <jgonzalez#innox.com.mx>
634         function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
635      {
636          global $ADODB_FETCH_MODE;
637                 if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC) $associative = true;
638
639          if ( !empty($owner) ) {
640             $table = "$owner.$table";
641          }
642          $a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table));
643                  if ($associative) {
644                         $create_sql = isset($a_create_table["Create Table"]) ? $a_create_table["Create Table"] : $a_create_table["Create View"];
645          } else $create_sql  = $a_create_table[1];
646
647          $matches = array();
648
649          if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false;
650              $foreign_keys = array();            
651          $num_keys = count($matches[0]);
652          for ( $i = 0;  $i < $num_keys;  $i ++ ) {
653              $my_field  = explode('`, `', $matches[1][$i]);
654              $ref_table = $matches[2][$i];
655              $ref_field = explode('`, `', $matches[3][$i]);
656
657              if ( $upper ) {
658                  $ref_table = strtoupper($ref_table);
659              }
660
661                         // see https://sourceforge.net/tracker/index.php?func=detail&aid=2287278&group_id=42718&atid=433976
662                         if (!isset($foreign_keys[$ref_table])) {
663                                 $foreign_keys[$ref_table] = array();
664                         }
665             $num_fields = count($my_field);
666             for ( $j = 0;  $j < $num_fields;  $j ++ ) {
667                  if ( $associative ) {
668                      $foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j];
669                  } else {
670                      $foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}";
671                  }
672              }
673          }
674          
675          return  $foreign_keys;
676      }
677          
678         
679 }
680         
681 /*--------------------------------------------------------------------------------------
682          Class Name: Recordset
683 --------------------------------------------------------------------------------------*/
684
685
686 class ADORecordSet_mysql extends ADORecordSet{  
687         
688         var $databaseType = "mysql";
689         var $canSeek = true;
690         
691         function ADORecordSet_mysql($queryID,$mode=false) 
692         {
693                 if ($mode === false) { 
694                         global $ADODB_FETCH_MODE;
695                         $mode = $ADODB_FETCH_MODE;
696                 }
697                 switch ($mode)
698                 {
699                 case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
700                 case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
701                 case ADODB_FETCH_DEFAULT:
702                 case ADODB_FETCH_BOTH:
703                 default:
704                         $this->fetchMode = MYSQL_BOTH; break;
705                 }
706                 $this->adodbFetchMode = $mode;
707                 $this->ADORecordSet($queryID);  
708         }
709         
710         function _initrs()
711         {
712         //GLOBAL $ADODB_COUNTRECS;
713         //      $this->_numOfRows = ($ADODB_COUNTRECS) ? @mysql_num_rows($this->_queryID):-1;
714                 $this->_numOfRows = @mysql_num_rows($this->_queryID);
715                 $this->_numOfFields = @mysql_num_fields($this->_queryID);
716         }
717         
718         function FetchField($fieldOffset = -1) 
719         {       
720                 if ($fieldOffset != -1) {
721                         $o = @mysql_fetch_field($this->_queryID, $fieldOffset);
722                         $f = @mysql_field_flags($this->_queryID,$fieldOffset);
723                         if ($o) $o->max_length = @mysql_field_len($this->_queryID,$fieldOffset); // suggested by: Jim Nicholson (jnich#att.com)
724                         //$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
725                         if ($o) $o->binary = (strpos($f,'binary')!== false);
726                 }
727                 else  { /*      The $fieldOffset argument is not provided thus its -1   */
728                         $o = @mysql_fetch_field($this->_queryID);
729                         //if ($o) $o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich#att.com)
730                         $o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
731                 }
732                         
733                 return $o;
734         }
735
736         function GetRowAssoc($upper=true)
737         {
738                 if ($this->fetchMode == MYSQL_ASSOC && !$upper) $row = $this->fields;
739                 else $row = ADORecordSet::GetRowAssoc($upper);
740                 return $row;
741         }
742         
743         /* Use associative array to get fields array */
744         function Fields($colname)
745         {       
746                 // added @ by "Michael William Miller" <mille562@pilot.msu.edu>
747                 if ($this->fetchMode != MYSQL_NUM) return @$this->fields[$colname];
748                 
749                 if (!$this->bind) {
750                         $this->bind = array();
751                         for ($i=0; $i < $this->_numOfFields; $i++) {
752                                 $o = $this->FetchField($i);
753                                 $this->bind[strtoupper($o->name)] = $i;
754                         }
755                 }
756                  return $this->fields[$this->bind[strtoupper($colname)]];
757         }
758         
759         function _seek($row)
760         {
761                 if ($this->_numOfRows == 0) return false;
762                 return @mysql_data_seek($this->_queryID,$row);
763         }
764         
765         function MoveNext()
766         {
767                 //return adodb_movenext($this);
768                 //if (defined('ADODB_EXTENSION')) return adodb_movenext($this);
769                 if (@$this->fields = mysql_fetch_array($this->_queryID,$this->fetchMode)) {
770                         $this->_currentRow += 1;
771                         return true;
772                 }
773                 if (!$this->EOF) {
774                         $this->_currentRow += 1;
775                         $this->EOF = true;
776                 }
777                 return false;
778         }
779         
780         function _fetch()
781         {
782                 $this->fields =  @mysql_fetch_array($this->_queryID,$this->fetchMode);
783                 return is_array($this->fields);
784         }
785         
786         function _close() {
787                 @mysql_free_result($this->_queryID);    
788                 $this->_queryID = false;        
789         }
790         
791         function MetaType($t,$len=-1,$fieldobj=false)
792         {
793                 if (is_object($t)) {
794                         $fieldobj = $t;
795                         $t = $fieldobj->type;
796                         $len = $fieldobj->max_length;
797                 }
798                 
799                 $len = -1; // mysql max_length is not accurate
800                 switch (strtoupper($t)) {
801                 case 'STRING': 
802                 case 'CHAR':
803                 case 'VARCHAR': 
804                 case 'TINYBLOB': 
805                 case 'TINYTEXT': 
806                 case 'ENUM': 
807                 case 'SET': 
808                         if ($len <= $this->blobSize) return 'C';
809                         
810                 case 'TEXT':
811                 case 'LONGTEXT': 
812                 case 'MEDIUMTEXT':
813                         return 'X';
814                         
815                 // php_mysql extension always returns 'blob' even if 'text'
816                 // so we have to check whether binary...
817                 case 'IMAGE':
818                 case 'LONGBLOB': 
819                 case 'BLOB':
820                 case 'MEDIUMBLOB':
821                 case 'BINARY':
822                         return !empty($fieldobj->binary) ? 'B' : 'X';
823                         
824                 case 'YEAR':
825                 case 'DATE': return 'D';
826                 
827                 case 'TIME':
828                 case 'DATETIME':
829                 case 'TIMESTAMP': return 'T';
830                 
831                 case 'INT': 
832                 case 'INTEGER':
833                 case 'BIGINT':
834                 case 'TINYINT':
835                 case 'MEDIUMINT':
836                 case 'SMALLINT': 
837                         
838                         if (!empty($fieldobj->primary_key)) return 'R';
839                         else return 'I';
840                 
841                 default: return 'N';
842                 }
843         }
844
845 }
846
847 class ADORecordSet_ext_mysql extends ADORecordSet_mysql {       
848         function ADORecordSet_ext_mysql($queryID,$mode=false) 
849         {
850                 if ($mode === false) { 
851                         global $ADODB_FETCH_MODE;
852                         $mode = $ADODB_FETCH_MODE;
853                 }
854                 switch ($mode)
855                 {
856                 case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
857                 case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
858                 case ADODB_FETCH_DEFAULT:
859                 case ADODB_FETCH_BOTH:
860                 default:
861                 $this->fetchMode = MYSQL_BOTH; break;
862                 }
863                 $this->adodbFetchMode = $mode;
864                 $this->ADORecordSet($queryID);
865         }
866         
867         function MoveNext()
868         {
869                 return @adodb_movenext($this);
870         }
871 }
872
873
874 }
875 ?>