source: trunk/phpgwapi/inc/adodb/drivers/adodb-mysql.inc.php @ 2

Revision 2, 17.8 KB checked in by niltonneto, 17 years ago (diff)

Removida todas as tags usadas pelo CVS ($Id, $Source).
Primeira versão no CVS externo.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1<?php
2/*
3V4.51 29 July 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 28 Feb 2001: MetaColumns bug fix - suggested by  Freek Dijkstra (phpeverywhere@macfreek.com)
13*/
14
15// security - hide paths
16if (!defined('ADODB_DIR')) die();
17
18if (! defined("_ADODB_MYSQL_LAYER")) {
19 define("_ADODB_MYSQL_LAYER", 1 );
20
21class ADODB_mysql extends ADOConnection {
22        var $databaseType = 'mysql';
23        var $dataProvider = 'mysql';
24        var $hasInsertID = true;
25        var $hasAffectedRows = true;   
26        var $metaTablesSQL = "SHOW TABLES";     
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 $substr = "substring";
40        var $nameQuote = '`';           /// string to use to quote identifiers and names
41       
42        function ADODB_mysql()
43        {                       
44                if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
45        }
46       
47        function ServerInfo()
48        {
49                $arr['description'] = ADOConnection::GetOne("select version()");
50                $arr['version'] = ADOConnection::_findvers($arr['description']);
51                return $arr;
52        }
53       
54        function IfNull( $field, $ifNull )
55        {
56                return " IFNULL($field, $ifNull) "; // if MySQL
57        }
58       
59        function &MetaTables($ttype=false,$showSchema=false,$mask=false)
60        {       
61                $save = $this->metaTablesSQL;
62                if ($showSchema && is_string($showSchema)) {
63                        $this->metaTablesSQL .= " from $showSchema";
64                }
65               
66                if ($mask) {
67                        $mask = $this->qstr($mask);
68                        $this->metaTablesSQL .= " like $mask";
69                }
70                $ret =& ADOConnection::MetaTables($ttype,$showSchema);
71               
72                $this->metaTablesSQL = $save;
73                return $ret;
74        }
75       
76       
77        function &MetaIndexes ($table, $primary = FALSE, $owner=false)
78        {
79        // save old fetch mode
80        global $ADODB_FETCH_MODE;
81       
82        $save = $ADODB_FETCH_MODE;
83        $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
84        if ($this->fetchMode !== FALSE) {
85               $savem = $this->SetFetchMode(FALSE);
86        }
87       
88        // get index details
89        $rs = $this->Execute(sprintf('SHOW INDEX FROM %s',$table));
90       
91        // restore fetchmode
92        if (isset($savem)) {
93                $this->SetFetchMode($savem);
94        }
95        $ADODB_FETCH_MODE = $save;
96       
97        if (!is_object($rs)) {
98                return FALSE;
99        }
100       
101        $indexes = array ();
102       
103        // parse index data into array
104        while ($row = $rs->FetchRow()) {
105                if ($primary == FALSE AND $row[2] == 'PRIMARY') {
106                        continue;
107                }
108               
109                if (!isset($indexes[$row[2]])) {
110                        $indexes[$row[2]] = array(
111                                'unique' => ($row[1] == 0),
112                                'columns' => array()
113                        );
114                }
115               
116                $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
117        }
118       
119        // sort columns by order in the index
120        foreach ( array_keys ($indexes) as $index )
121        {
122                ksort ($indexes[$index]['columns']);
123        }
124       
125        return $indexes;
126        }
127
128       
129        // if magic quotes disabled, use mysql_real_escape_string()
130        function qstr($s,$magic_quotes=false)
131        {
132                if (!$magic_quotes) {
133               
134                        if (ADODB_PHPVER >= 0x4300) {
135                                if (is_resource($this->_connectionID))
136                                        return "'".mysql_real_escape_string($s,$this->_connectionID)."'";
137                        }
138                        if ($this->replaceQuote[0] == '\\'){
139                                $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
140                        }
141                        return  "'".str_replace("'",$this->replaceQuote,$s)."'";
142                }
143               
144                // undo magic quotes for "
145                $s = str_replace('\\"','"',$s);
146                return "'$s'";
147        }
148       
149        function _insertid()
150        {
151                return mysql_insert_id($this->_connectionID);
152        }
153       
154        function GetOne($sql,$inputarr=false)
155        {
156                if (strncasecmp($sql,'sele',4) == 0) {
157                        $rs =& $this->SelectLimit($sql,1,-1,$inputarr);
158                        if ($rs) {
159                                $rs->Close();
160                                if ($rs->EOF) return false;
161                                return reset($rs->fields);
162                        }
163                } else {
164                        return ADOConnection::GetOne($sql,$inputarr);
165                }
166                return false;
167        }
168       
169        function BeginTrans()
170        {
171                if ($this->debug) ADOConnection::outp("Transactions not supported in 'mysql' driver. Use 'mysqlt' or 'mysqli' driver");
172        }
173       
174        function _affectedrows()
175        {
176                        return mysql_affected_rows($this->_connectionID);
177        }
178 
179        // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
180        // Reference on Last_Insert_ID on the recommended way to simulate sequences
181        var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
182        var $_genSeqSQL = "create table %s (id int not null)";
183        var $_genSeq2SQL = "insert into %s values (%s)";
184        var $_dropSeqSQL = "drop table %s";
185       
186        function CreateSequence($seqname='adodbseq',$startID=1)
187        {
188                if (empty($this->_genSeqSQL)) return false;
189                $u = strtoupper($seqname);
190               
191                $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
192                if (!$ok) return false;
193                return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
194        }
195       
196
197        function GenID($seqname='adodbseq',$startID=1)
198        {
199                // post-nuke sets hasGenID to false
200                if (!$this->hasGenID) return false;
201               
202                $savelog = $this->_logsql;
203                $this->_logsql = false;
204                $getnext = sprintf($this->_genIDSQL,$seqname);
205                $holdtransOK = $this->_transOK; // save the current status
206                $rs = @$this->Execute($getnext);
207                if (!$rs) {
208                        if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
209                        $u = strtoupper($seqname);
210                        $this->Execute(sprintf($this->_genSeqSQL,$seqname));
211                        $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
212                        $rs = $this->Execute($getnext);
213                }
214                $this->genID = mysql_insert_id($this->_connectionID);
215               
216                if ($rs) $rs->Close();
217               
218                $this->_logsql = $savelog;
219                return $this->genID;
220        }
221       
222        function &MetaDatabases()
223        {
224                $qid = mysql_list_dbs($this->_connectionID);
225                $arr = array();
226                $i = 0;
227                $max = mysql_num_rows($qid);
228                while ($i < $max) {
229                        $db = mysql_tablename($qid,$i);
230                        if ($db != 'mysql') $arr[] = $db;
231                        $i += 1;
232                }
233                return $arr;
234        }
235       
236               
237        // Format date column in sql string given an input format that understands Y M D
238        function SQLDate($fmt, $col=false)
239        {       
240                if (!$col) $col = $this->sysTimeStamp;
241                $s = 'DATE_FORMAT('.$col.",'";
242                $concat = false;
243                $len = strlen($fmt);
244                for ($i=0; $i < $len; $i++) {
245                        $ch = $fmt[$i];
246                        switch($ch) {
247                               
248                        default:
249                                if ($ch == '\\') {
250                                        $i++;
251                                        $ch = substr($fmt,$i,1);
252                                }
253                                /** FALL THROUGH */
254                        case '-':
255                        case '/':
256                                $s .= $ch;
257                                break;
258                               
259                        case 'Y':
260                        case 'y':
261                                $s .= '%Y';
262                                break;
263                        case 'M':
264                                $s .= '%b';
265                                break;
266                               
267                        case 'm':
268                                $s .= '%m';
269                                break;
270                        case 'D':
271                        case 'd':
272                                $s .= '%d';
273                                break;
274                       
275                        case 'Q':
276                        case 'q':
277                                $s .= "'),Quarter($col)";
278                               
279                                if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
280                                else $s .= ",('";
281                                $concat = true;
282                                break;
283                       
284                        case 'H':
285                                $s .= '%H';
286                                break;
287                               
288                        case 'h':
289                                $s .= '%I';
290                                break;
291                               
292                        case 'i':
293                                $s .= '%i';
294                                break;
295                               
296                        case 's':
297                                $s .= '%s';
298                                break;
299                               
300                        case 'a':
301                        case 'A':
302                                $s .= '%p';
303                                break;
304                               
305
306                        }
307                }
308                $s.="')";
309                if ($concat) $s = "CONCAT($s)";
310                return $s;
311        }
312       
313
314        // returns concatenated string
315        // much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
316        function Concat()
317        {
318                $s = "";
319                $arr = func_get_args();
320               
321                // suggestion by andrew005@mnogo.ru
322                $s = implode(',',$arr);
323                if (strlen($s) > 0) return "CONCAT($s)";
324                else return '';
325        }
326       
327        function OffsetDate($dayFraction,$date=false)
328        {               
329                if (!$date) $date = $this->sysDate;
330                return "from_unixtime(unix_timestamp($date)+($dayFraction)*24*3600)";
331        }
332       
333        // returns true or false
334        function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
335        {
336                if (ADODB_PHPVER >= 0x4300)
337                        $this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword,
338                                                                                                $this->forceNewConnect,$this->clientFlags);
339                else if (ADODB_PHPVER >= 0x4200)
340                        $this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword,
341                                                                                                $this->forceNewConnect);
342                else
343                        $this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword);
344       
345                if ($this->_connectionID === false) return false;
346                if ($argDatabasename) return $this->SelectDB($argDatabasename);
347                return true;   
348        }
349       
350        // returns true or false
351        function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
352        {
353                if (ADODB_PHPVER >= 0x4300)
354                        $this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword,$this->clientFlags);
355                else
356                        $this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword);
357                if ($this->_connectionID === false) return false;
358                if ($this->autoRollback) $this->RollbackTrans();
359                if ($argDatabasename) return $this->SelectDB($argDatabasename);
360                return true;   
361        }
362       
363        function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
364        {
365                $this->forceNewConnect = true;
366                return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
367        }
368       
369        function &MetaColumns($table)
370        {
371       
372                if ($this->metaColumnsSQL) {
373                global $ADODB_FETCH_MODE;
374               
375                        $save = $ADODB_FETCH_MODE;
376                        $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
377                        if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
378                       
379                        $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
380                       
381                        if (isset($savem)) $this->SetFetchMode($savem);
382                        $ADODB_FETCH_MODE = $save;
383                       
384                        if ($rs === false) return false;
385                       
386                        $retarr = array();
387                        while (!$rs->EOF){
388                                $fld = new ADOFieldObject();
389                                $fld->name = $rs->fields[0];
390                                $type = $rs->fields[1];
391                               
392                               
393                                // split type into type(length):
394                                $fld->scale = null;
395                                if (strpos($type,',') && preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
396                                        $fld->type = $query_array[1];
397                                        $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
398                                        $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
399                                } elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
400                                        $fld->type = $query_array[1];
401                                        $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
402                                } else {
403                                        $fld->max_length = -1;
404                                        $fld->type = $type;
405                                }
406                                /*
407                                // split type into type(length):
408                                if (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
409                                        $fld->type = $query_array[1];
410                                        $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
411                                } else {
412                                        $fld->max_length = -1;
413                                        $fld->type = $type;
414                                }*/
415                                $fld->not_null = ($rs->fields[2] != 'YES');
416                                $fld->primary_key = ($rs->fields[3] == 'PRI');
417                                $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
418                                $fld->binary = (strpos($fld->type,'blob') !== false);
419                               
420                                if (!$fld->binary) {
421                                        $d = $rs->fields[4];
422                                        if ($d != "" && $d != "NULL") {
423                                                $fld->has_default = true;
424                                                $fld->default_value = $d;
425                                        } else {
426                                                $fld->has_default = false;
427                                        }
428                                }
429                                if ($save == ADODB_FETCH_NUM) $retarr[] = $fld;
430                                else $retarr[strtoupper($fld->name)] = $fld;
431                                $rs->MoveNext();
432                        }
433                        $rs->Close();
434                        return $retarr;
435                }
436                return false;
437        }
438               
439        // returns true or false
440        function SelectDB($dbName)
441        {
442                $this->databaseName = $dbName;
443                if ($this->_connectionID) {
444                        return @mysql_select_db($dbName,$this->_connectionID);         
445                }
446                else return false;     
447        }
448       
449        // parameters use PostgreSQL convention, not MySQL
450        function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
451        {
452                $offsetStr =($offset>=0) ? "$offset," : '';
453                // jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220
454                if ($nrows < 0) $nrows = '18446744073709551615';
455               
456                if ($secs)
457                        $rs =& $this->CacheExecute($secs,$sql." LIMIT $offsetStr$nrows",$inputarr);
458                else
459                        $rs =& $this->Execute($sql." LIMIT $offsetStr$nrows",$inputarr);
460                return $rs;
461        }
462       
463        // returns queryID or false
464        function _query($sql,$inputarr)
465        {
466        //global $ADODB_COUNTRECS;
467                //if($ADODB_COUNTRECS)
468                return mysql_query($sql,$this->_connectionID);
469                //else return @mysql_unbuffered_query($sql,$this->_connectionID); // requires PHP >= 4.0.6
470        }
471
472        /*      Returns: the last error message from previous database operation        */     
473        function ErrorMsg()
474        {
475       
476                if ($this->_logsql) return $this->_errorMsg;
477                if (empty($this->_connectionID)) $this->_errorMsg = @mysql_error();
478                else $this->_errorMsg = @mysql_error($this->_connectionID);
479                return $this->_errorMsg;
480        }
481       
482        /*      Returns: the last error number from previous database operation */     
483        function ErrorNo()
484        {
485                if ($this->_logsql) return $this->_errorCode;
486                if (empty($this->_connectionID))  return @mysql_errno();
487                else return @mysql_errno($this->_connectionID);
488        }
489       
490        // returns true or false
491        function _close()
492        {
493                @mysql_close($this->_connectionID);
494                $this->_connectionID = false;
495        }
496
497       
498        /*
499        * Maximum size of C field
500        */
501        function CharMax()
502        {
503                return 255;
504        }
505       
506        /*
507        * Maximum size of X field
508        */
509        function TextMax()
510        {
511                return 4294967295;
512        }
513       
514}
515       
516/*--------------------------------------------------------------------------------------
517         Class Name: Recordset
518--------------------------------------------------------------------------------------*/
519
520
521class ADORecordSet_mysql extends ADORecordSet{ 
522       
523        var $databaseType = "mysql";
524        var $canSeek = true;
525       
526        function ADORecordSet_mysql($queryID,$mode=false)
527        {
528                if ($mode === false) {
529                        global $ADODB_FETCH_MODE;
530                        $mode = $ADODB_FETCH_MODE;
531                }
532                switch ($mode)
533                {
534                case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
535                case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
536                default:
537                case ADODB_FETCH_DEFAULT:
538                case ADODB_FETCH_BOTH:$this->fetchMode = MYSQL_BOTH; break;
539                }
540       
541                $this->ADORecordSet($queryID); 
542        }
543       
544        function _initrs()
545        {
546        //GLOBAL $ADODB_COUNTRECS;
547        //      $this->_numOfRows = ($ADODB_COUNTRECS) ? @mysql_num_rows($this->_queryID):-1;
548                $this->_numOfRows = @mysql_num_rows($this->_queryID);
549                $this->_numOfFields = @mysql_num_fields($this->_queryID);
550        }
551       
552        function &FetchField($fieldOffset = -1)
553        {       
554                if ($fieldOffset != -1) {
555                        $o = @mysql_fetch_field($this->_queryID, $fieldOffset);
556                        $f = @mysql_field_flags($this->_queryID,$fieldOffset);
557                        $o->max_length = @mysql_field_len($this->_queryID,$fieldOffset); // suggested by: Jim Nicholson (jnich@att.com)
558                        //$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
559                        $o->binary = (strpos($f,'binary')!== false);
560                }
561                else if ($fieldOffset == -1) {  /*      The $fieldOffset argument is not provided thus its -1   */
562                        $o = @mysql_fetch_field($this->_queryID);
563                        $o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich@att.com)
564                        //$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
565                }
566                       
567                return $o;
568        }
569
570        function &GetRowAssoc($upper=true)
571        {
572                if ($this->fetchMode == MYSQL_ASSOC && !$upper) return $this->fields;
573                $row =& ADORecordSet::GetRowAssoc($upper);
574                return $row;
575        }
576       
577        /* Use associative array to get fields array */
578        function Fields($colname)
579        {       
580                // added @ by "Michael William Miller" <mille562@pilot.msu.edu>
581                if ($this->fetchMode != MYSQL_NUM) return @$this->fields[$colname];
582               
583                if (!$this->bind) {
584                        $this->bind = array();
585                        for ($i=0; $i < $this->_numOfFields; $i++) {
586                                $o = $this->FetchField($i);
587                                $this->bind[strtoupper($o->name)] = $i;
588                        }
589                }
590                 return $this->fields[$this->bind[strtoupper($colname)]];
591        }
592       
593        function _seek($row)
594        {
595                if ($this->_numOfRows == 0) return false;
596                return @mysql_data_seek($this->_queryID,$row);
597        }
598       
599        function MoveNext()
600        {
601                //return adodb_movenext($this);
602                //if (defined('ADODB_EXTENSION')) return adodb_movenext($this);
603                if (@$this->fields =& mysql_fetch_array($this->_queryID,$this->fetchMode)) {
604                        $this->_currentRow += 1;
605                        return true;
606                }
607                if (!$this->EOF) {
608                        $this->_currentRow += 1;
609                        $this->EOF = true;
610                }
611                return false;
612        }
613       
614        function _fetch()
615        {
616                $this->fields =  @mysql_fetch_array($this->_queryID,$this->fetchMode);
617                return is_array($this->fields);
618        }
619       
620        function _close() {
621                @mysql_free_result($this->_queryID);   
622                $this->_queryID = false;       
623        }
624       
625        function MetaType($t,$len=-1,$fieldobj=false)
626        {
627                if (is_object($t)) {
628                        $fieldobj = $t;
629                        $t = $fieldobj->type;
630                        $len = $fieldobj->max_length;
631                }
632               
633                $len = -1; // mysql max_length is not accurate
634                switch (strtoupper($t)) {
635                case 'STRING':
636                case 'CHAR':
637                case 'VARCHAR':
638                case 'TINYBLOB':
639                case 'TINYTEXT':
640                case 'ENUM':
641                case 'SET':
642                        if ($len <= $this->blobSize) return 'C';
643                       
644                case 'TEXT':
645                case 'LONGTEXT':
646                case 'MEDIUMTEXT':
647                        return 'X';
648                       
649                // php_mysql extension always returns 'blob' even if 'text'
650                // so we have to check whether binary...
651                case 'IMAGE':
652                case 'LONGBLOB':
653                case 'BLOB':
654                case 'MEDIUMBLOB':
655                        return !empty($fieldobj->binary) ? 'B' : 'X';
656                       
657                case 'YEAR':
658                case 'DATE': return 'D';
659               
660                case 'TIME':
661                case 'DATETIME':
662                case 'TIMESTAMP': return 'T';
663               
664                case 'INT':
665                case 'INTEGER':
666                case 'BIGINT':
667                case 'TINYINT':
668                case 'MEDIUMINT':
669                case 'SMALLINT':
670                       
671                        if (!empty($fieldobj->primary_key)) return 'R';
672                        else return 'I';
673               
674                default: return 'N';
675                }
676        }
677
678}
679
680class ADORecordSet_ext_mysql extends ADORecordSet_mysql {       
681        function ADORecordSet_ext_mysql($queryID,$mode=false)
682        {
683                if ($mode === false) {
684                        global $ADODB_FETCH_MODE;
685                        $mode = $ADODB_FETCH_MODE;
686                }
687                switch ($mode)
688                {
689                case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
690                case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
691                default:
692                case ADODB_FETCH_DEFAULT:
693                case ADODB_FETCH_BOTH:$this->fetchMode = MYSQL_BOTH; break;
694                }
695       
696                $this->ADORecordSet($queryID); 
697        }
698       
699        function MoveNext()
700        {
701                return adodb_movenext($this);
702        }
703}
704
705
706}
707?>
Note: See TracBrowser for help on using the repository browser.