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