Update adodb with the latest 5.09a which support php5 only and include deprecated...
authorGuillaume (ioguix) de Rorthais <ioguix@free.fr>
Fri, 30 Oct 2009 15:16:34 +0000 (16:16 +0100)
committerGuillaume (ioguix) de Rorthais <ioguix@free.fr>
Fri, 30 Oct 2009 15:16:34 +0000 (16:16 +0100)
23 files changed:
libraries/adodb/adodb-csvlib.inc.php
libraries/adodb/adodb-datadict.inc.php
libraries/adodb/adodb-error.inc.php
libraries/adodb/adodb-iterator.inc.php
libraries/adodb/adodb-lib.inc.php
libraries/adodb/adodb-php4.inc.php [deleted file]
libraries/adodb/adodb-time.inc.php
libraries/adodb/adodb.inc.php
libraries/adodb/drivers/adodb-postgres.inc.php
libraries/adodb/drivers/adodb-postgres64.inc.php
libraries/adodb/drivers/adodb-postgres7.inc.php
libraries/adodb/drivers/adodb-postgres8.inc.php
libraries/adodb/lang/adodb-ar.inc.php
libraries/adodb/lang/adodb-bg.inc.php
libraries/adodb/lang/adodb-bgutf8.inc.php
libraries/adodb/lang/adodb-ca.inc.php
libraries/adodb/lang/adodb-en.inc.php
libraries/adodb/lang/adodb-pl.inc.php
libraries/adodb/lang/adodb-pt-br.inc.php
libraries/adodb/lang/adodb-ro.inc.php
libraries/adodb/lang/adodb-uk1251.inc.php
libraries/adodb/toexport.inc.php
libraries/adodb/tohtml.inc.php

index 1e34d39eef0d83991f002c68dc9fa65af235fa2f..1f7543f9f3b93a5b965ab40b29d7547baa036902 100644 (file)
@@ -8,7 +8,7 @@ $ADODB_INCLUDED_CSV = 1;
 
 /* 
 
-  V4.94 23 Jan 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.09 25 June 2009   (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. See License.txt. 
@@ -54,7 +54,7 @@ $ADODB_INCLUDED_CSV = 1;
                $line = "====1,$tt,$sql\n";
                
                if ($rs->databaseType == 'array') {
-                       $rows =& $rs->_array;
+                       $rows = $rs->_array;
                } else {
                        $rows = array();
                        while (!$rs->EOF) {     
@@ -64,7 +64,7 @@ $ADODB_INCLUDED_CSV = 1;
                }
                
                for($i=0; $i < $max; $i++) {
-                       $o =& $rs->FetchField($i);
+                       $o = $rs->FetchField($i);
                        $flds[] = $o;
                }
        
@@ -90,7 +90,7 @@ $ADODB_INCLUDED_CSV = 1;
 *                      error occurred in sql INSERT/UPDATE/DELETE, 
 *                      empty recordset is returned
 */
-       function &csv2rs($url,&$err,$timeout=0, $rsclass='ADORecordSet_array')
+       function csv2rs($url,&$err,$timeout=0, $rsclass='ADORecordSet_array')
        {
                $false = false;
                $err = false;
@@ -261,6 +261,7 @@ $ADODB_INCLUDED_CSV = 1;
 
        /**
        * Save a file $filename and its $contents (normally for caching) with file locking
+       * Returns true if ok, false if fopen/fwrite error, 0 if rename error (eg. file is locked)
        */
        function adodb_write_file($filename, $contents,$debug=false)
        { 
@@ -280,27 +281,31 @@ $ADODB_INCLUDED_CSV = 1;
                        $mtime = substr(str_replace(' ','_',microtime()),2); 
                        // getmypid() actually returns 0 on Win98 - never mind!
                        $tmpname = $filename.uniqid($mtime).getmypid();
-                       if (!($fd = @fopen($tmpname,'a'))) return false;
-                       $ok = ftruncate($fd,0);                 
-                       if (!fwrite($fd,$contents)) $ok = false;
+                       if (!($fd = @fopen($tmpname,'w'))) return false;
+                       if (fwrite($fd,$contents)) $ok = true;
+                       else $ok = false;
                        fclose($fd);
-                       chmod($tmpname,0644);
-                       // the tricky moment
-                       @unlink($filename);
-                       if (!@rename($tmpname,$filename)) {
-                               unlink($tmpname);
-                               $ok = false;
-                       }
-                       if (!$ok) {
-                               if ($debug) ADOConnection::outp( " Rename $tmpname ".($ok? 'ok' : 'failed'));
+                       
+                       if ($ok) {
+                               @chmod($tmpname,0644);
+                               // the tricky moment
+                               @unlink($filename);
+                               if (!@rename($tmpname,$filename)) {
+                                       unlink($tmpname);
+                                       $ok = 0;
+                               }
+                               if (!$ok) {
+                                       if ($debug) ADOConnection::outp( " Rename $tmpname ".($ok? 'ok' : 'failed'));
+                               }
                        }
                        return $ok;
                }
                if (!($fd = @fopen($filename, 'a'))) return false;
                if (flock($fd, LOCK_EX) && ftruncate($fd, 0)) {
-                       $ok = fwrite( $fd, $contents );
+                       if (fwrite( $fd, $contents )) $ok = true;
+                       else $ok = false;
                        fclose($fd);
-                       chmod($filename,0644);
+                       @chmod($filename,0644);
                }else {
                        fclose($fd);
                        if ($debug)ADOConnection::outp( " Failed acquiring lock for $filename<br>\n");
index c31edd82237ada2f960b169822df3ef2f0d9a912..efcd453bb9781e6027d86486be596b857e988d79 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.94 23 Jan 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.09 25 June 2009   (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
@@ -216,8 +216,117 @@ class ADODB_DataDict {
        }
        
        function MetaType($t,$len=-1,$fieldobj=false)
-       {
-               return ADORecordSet::MetaType($t,$len,$fieldobj);
+       {               
+               static $typeMap = array(
+               'VARCHAR' => 'C',
+               'VARCHAR2' => 'C',
+               'CHAR' => 'C',
+               'C' => 'C',
+               'STRING' => 'C',
+               'NCHAR' => 'C',
+               'NVARCHAR' => 'C',
+               'VARYING' => 'C',
+               'BPCHAR' => 'C',
+               'CHARACTER' => 'C',
+               'INTERVAL' => 'C',  # Postgres
+               'MACADDR' => 'C', # postgres
+               'VAR_STRING' => 'C', # mysql
+               ##
+               'LONGCHAR' => 'X',
+               'TEXT' => 'X',
+               'NTEXT' => 'X',
+               'M' => 'X',
+               'X' => 'X',
+               'CLOB' => 'X',
+               'NCLOB' => 'X',
+               'LVARCHAR' => 'X',
+               ##
+               'BLOB' => 'B',
+               'IMAGE' => 'B',
+               'BINARY' => 'B',
+               'VARBINARY' => 'B',
+               'LONGBINARY' => 'B',
+               'B' => 'B',
+               ##
+               'YEAR' => 'D', // mysql
+               'DATE' => 'D',
+               'D' => 'D',
+               ##
+               'UNIQUEIDENTIFIER' => 'C', # MS SQL Server
+               ##
+               'TIME' => 'T',
+               'TIMESTAMP' => 'T',
+               'DATETIME' => 'T',
+               'TIMESTAMPTZ' => 'T',
+               'SMALLDATETIME' => 'T',
+               'T' => 'T',
+               'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql
+               ##
+               'BOOL' => 'L',
+               'BOOLEAN' => 'L', 
+               'BIT' => 'L',
+               'L' => 'L',
+               ##
+               'COUNTER' => 'R',
+               'R' => 'R',
+               'SERIAL' => 'R', // ifx
+               'INT IDENTITY' => 'R',
+               ##
+               'INT' => 'I',
+               'INT2' => 'I',
+               'INT4' => 'I',
+               'INT8' => 'I',
+               'INTEGER' => 'I',
+               'INTEGER UNSIGNED' => 'I',
+               'SHORT' => 'I',
+               'TINYINT' => 'I',
+               'SMALLINT' => 'I',
+               'I' => 'I',
+               ##
+               'LONG' => 'N', // interbase is numeric, oci8 is blob
+               'BIGINT' => 'N', // this is bigger than PHP 32-bit integers
+               'DECIMAL' => 'N',
+               'DEC' => 'N',
+               'REAL' => 'N',
+               'DOUBLE' => 'N',
+               'DOUBLE PRECISION' => 'N',
+               'SMALLFLOAT' => 'N',
+               'FLOAT' => 'N',
+               'NUMBER' => 'N',
+               'NUM' => 'N',
+               'NUMERIC' => 'N',
+               'MONEY' => 'N',
+               
+               ## informix 9.2
+               'SQLINT' => 'I', 
+               'SQLSERIAL' => 'I', 
+               'SQLSMINT' => 'I', 
+               'SQLSMFLOAT' => 'N', 
+               'SQLFLOAT' => 'N', 
+               'SQLMONEY' => 'N', 
+               'SQLDECIMAL' => 'N', 
+               'SQLDATE' => 'D', 
+               'SQLVCHAR' => 'C', 
+               'SQLCHAR' => 'C', 
+               'SQLDTIME' => 'T', 
+               'SQLINTERVAL' => 'N', 
+               'SQLBYTES' => 'B', 
+               'SQLTEXT' => 'X',
+                ## informix 10
+               "SQLINT8" => 'I8',
+               "SQLSERIAL8" => 'I8',
+               "SQLNCHAR" => 'C',
+               "SQLNVCHAR" => 'C',
+               "SQLLVARCHAR" => 'X',
+               "SQLBOOL" => 'L'
+               );
+               
+               if (!$this->connection->IsConnected()) {
+                       $t = strtoupper($t);
+                       if (isset($typeMap[$t])) return $typeMap[$t];
+                       return 'N';
+               }
+               return $this->connection->MetaType($t,$len,$fieldobj);
        }
        
        function NameQuote($name = NULL,$allowBrackets=false)
@@ -261,7 +370,7 @@ class ADODB_DataDict {
        function ExecuteSQLArray($sql, $continueOnError = true)
        {
                $rez = 2;
-               $conn = &$this->connection;
+               $conn = $this->connection;
                $saved = $conn->debug;
                foreach($sql as $line) {
                        
@@ -705,7 +814,7 @@ class ADODB_DataDict {
        
        
        // return string must begin with space
-       function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint)
+       function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
        {       
                $suffix = '';
                if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
@@ -810,7 +919,7 @@ class ADODB_DataDict {
        This function changes/adds new fields to your table. You don't
        have to know if the col is new or not. It will check on its own.
        */
-       function ChangeTableSQL($tablename, $flds, $tableoptions = false)
+       function ChangeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=false)
        {
        global $ADODB_FETCH_MODE;
        
@@ -843,13 +952,15 @@ class ADODB_DataDict {
                                        $obj = $cols[$k];
                                        if (isset($obj->not_null) && $obj->not_null)
                                                $v = str_replace('NOT NULL','',$v);
-
+                                       if (isset($obj->auto_increment) && $obj->auto_increment && empty($v['AUTOINCREMENT'])) 
+                                           $v = str_replace('AUTOINCREMENT','',$v);
+                                       
                                        $c = $cols[$k];
                                        $ml = $c->max_length;
                                        $mt = $this->MetaType($c->type,$ml);
                                        if ($ml == -1) $ml = '';
                                        if ($mt == 'X') $ml = $v['SIZE'];
-                                       if (($mt != $v['TYPE']) ||  $ml != $v['SIZE']) {
+                                       if (($mt != $v['TYPE']) ||  $ml != $v['SIZE'] || (isset($v['AUTOINCREMENT']) && $v['AUTOINCREMENT'] != $obj->auto_increment)) {
                                                $holdflds[$k] = $v;
                                        }
                                } else {
@@ -873,8 +984,11 @@ class ADODB_DataDict {
                                $flds = Lens_ParseArgs($v,',');
                                
                                //  We are trying to change the size of the field, if not allowed, simply ignore the request.
-                               if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)) {
-                                       echo "<h3>$this->alterCol cannot be changed to $flds currently</h3>";
+                               // $flds[1] holds the type, $flds[2] holds the size -postnuke addition
+                               if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)
+                                && (isset($flds[0][2]) && is_numeric($flds[0][2]))) {
+                                       if ($this->debug) ADOConnection::outp(sprintf("<h3>%s cannot be changed to %s currently</h3>", $flds[0][0], $flds[0][1]));
+                                       #echo "<h3>$this->alterCol cannot be changed to $flds currently</h3>";
                                        continue;        
                                }
                                $sql[] = $alter . $this->alterCol . ' ' . $v;
@@ -883,6 +997,11 @@ class ADODB_DataDict {
                        }
                }
                
+               if ($dropOldFlds) {
+                       foreach ( $cols as $id => $v )
+                           if ( !isset($lines[$id]) ) 
+                                       $sql[] = $alter . $this->dropCol . ' ' . $v->name;
+               }
                return $sql;
        }
 } // class
index e60976b0d8e59421e8e446521bbc168541bab251..ae0b9e3543da50d0f082d02bd0b15848362c3f34 100755 (executable)
@@ -1,6 +1,6 @@
 <?php
 /** 
- * @version V4.94 23 Jan 2007 (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.06 16 Oct 2008  (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license. 
  * Whenever there is any discrepancy between the two licenses, 
  * the BSD license will take precedence. 
@@ -92,14 +92,14 @@ function adodb_error_pg($errormsg)
 {
        if (is_numeric($errormsg)) return (integer) $errormsg;
     static $error_regexps = array(
-            '/(Table does not exist\.|Relation [\"\'].*[\"\'] does not exist|sequence does not exist|class ".+" not found)$/' => DB_ERROR_NOSUCHTABLE,
-            '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/'      => DB_ERROR_ALREADY_EXISTS,
-            '/divide by zero$/'                     => DB_ERROR_DIVZERO,
-            '/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER,
-            '/ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD,
-            '/parser: parse error at or near \"/'   => DB_ERROR_SYNTAX,
-            '/referential integrity violation/'     => DB_ERROR_CONSTRAINT,
-                       '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*|duplicate key violates unique constraint/'     
+            '/(Table does not exist\.|Relation [\"\'].*[\"\'] does not exist|sequence does not exist|class ".+" not found)$/i' => DB_ERROR_NOSUCHTABLE,
+            '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/i'      => DB_ERROR_ALREADY_EXISTS,
+            '/divide by zero$/i'                     => DB_ERROR_DIVZERO,
+            '/pg_atoi: error in .*: can\'t parse /i' => DB_ERROR_INVALID_NUMBER,
+            '/ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/i' => DB_ERROR_NOSUCHFIELD,
+            '/parser: parse error at or near \"/i'   => DB_ERROR_SYNTAX,
+            '/referential integrity violation/i'     => DB_ERROR_CONSTRAINT,
+                       '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*|duplicate key violates unique constraint/i'     
                                 => DB_ERROR_ALREADY_EXISTS
         );
        reset($error_regexps);
index d291e78a13638308acccae4560ecc1551fd06dd1..55d66a35ba7fedd0355159b200b8767847d86c08 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-  V4.94 23 Jan 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.09 25 June 2009   (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
                
                
        Iterator code based on http://cvs.php.net/cvs.php/php-src/ext/spl/examples/cachingiterator.inc?login=2
- */
-
- class ADODB_Iterator implements Iterator {
-
-    private $rs;
-
-    function __construct($rs) 
-       {
-        $this->rs = $rs;
-    }
-    function rewind() 
-       {
-        $this->rs->MoveFirst();
-    }
-
-       function valid() 
-       {
-        return !$this->rs->EOF;
-    }
-       
-    function key() 
-       {
-        return $this->rs->_currentRow;
-    }
        
-    function current() 
-       {
-        return $this->rs->fields;
-    }
        
-    function next() 
-       {
-        $this->rs->MoveNext();
-    }
-       
-       function __call($func, $params)
-       {
-               return call_user_func_array(array($this->rs, $func), $params);
-       }
-
-       
-       function hasMore()
-       {
-               return !$this->rs->EOF;
-       }
-
-}
+       Moved to adodb.inc.php to improve performance.
+ */
 
 
-class ADODB_BASE_RS implements IteratorAggregate {
-    function getIterator() {
-        return new ADODB_Iterator($this);
-    }
-       
-       /* this is experimental - i don't really know what to return... */
-       function __toString()
-       {
-               include_once(ADODB_DIR.'/toexport.inc.php');
-               return _adodb_export($this,',',',',false,true);
-       }
-} 
 
 
 ?>
\ No newline at end of file
index 2a67f28d4f12c39028f59c447eb263e8eaa1e2d5..9b46dedc8f1a886654fc11127cbbb7495e9ab9f6 100644 (file)
@@ -1,5 +1,8 @@
 <?php
 
+
+
+
 // security - hide paths
 if (!defined('ADODB_DIR')) die();
 
@@ -7,7 +10,7 @@ global $ADODB_INCLUDED_LIB;
 $ADODB_INCLUDED_LIB = 1;
 
 /* 
- @version V4.94 23 Jan 2007 (c) 2000-2007 John Lim (jlim\@natsoft.com.my). All rights reserved.
+ @version V5.06 16 Oct 2008  (c) 2000-2009 John Lim (jlim\@natsoft.com.my). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. See License.txt. 
@@ -16,6 +19,36 @@ $ADODB_INCLUDED_LIB = 1;
   Less commonly used functions are placed here to reduce size of adodb.inc.php. 
 */ 
 
+function adodb_strip_order_by($sql)
+{
+       $rez = preg_match('/(\sORDER\s+BY\s[^)]*)/is',$sql,$arr);
+       if ($arr)
+               if (strpos($arr[0],'(') !== false) {
+                       $at = strpos($sql,$arr[0]);
+                       $cntin = 0;
+                       for ($i=$at, $max=strlen($sql); $i < $max; $i++) {
+                               $ch = $sql[$i];
+                               if ($ch == '(') {
+                                       $cntin += 1;
+                               } elseif($ch == ')') {
+                                       $cntin -= 1;
+                                       if ($cntin < 0) {
+                                               break;
+                                       }
+                               }
+                       }
+                       $sql = substr($sql,0,$at).substr($sql,$i);
+               } else
+                       $sql = str_replace($arr[0], '', $sql); 
+       return $sql;
+ }
+
+if (false) {
+       $sql = 'select * from (select a from b order by a(b),b(c) desc)';
+       $sql = '(select * from abc order by 1)';
+       die(adodb_strip_order_by($sql));
+}
+
 function adodb_probetypes(&$array,&$types,$probe=8)
 {
 // probe and guess the type
@@ -25,7 +58,7 @@ function adodb_probetypes(&$array,&$types,$probe=8)
        
        
        for ($j=0;$j < $max; $j++) {
-               $row =& $array[$j];
+               $row = $array[$j];
                if (!$row) break;
                $i = -1;
                foreach($row as $v) {
@@ -111,7 +144,10 @@ function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_
                        $keyCol = array($keyCol);
                }
                foreach($fieldArray as $k => $v) {
-                       if ($autoQuote && !is_numeric($v) and strncmp($v,"'",1) !== 0 and strcasecmp($v,$zthis->null2null)!=0) {
+                       if ($v === null) {
+                               $v = 'NULL';
+                               $fieldArray[$k] = $v;
+                       } else if ($autoQuote && /*!is_numeric($v) /*and strncmp($v,"'",1) !== 0 -- sql injection risk*/ strcasecmp($v,$zthis->null2null)!=0) {
                                $v = $zthis->qstr($v);
                                $fieldArray[$k] = $v;
                        }
@@ -123,7 +159,7 @@ function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_
                        } else
                                $uSet .= ",$k=$v";
                }
-                
+               
                $where = false;
                foreach ($keyCol as $v) {
                        if (isset($fieldArray[$v])) {
@@ -369,42 +405,35 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
         if (!empty($zthis->_nestedSQL) || preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) || 
                preg_match('/\s+GROUP\s+BY\s+/is',$sql) || 
                preg_match('/\s+UNION\s+/is',$sql)) {
+               
+               $rewritesql = adodb_strip_order_by($sql);
+               
                // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias
                // but this is only supported by oracle and postgresql...
                if ($zthis->dataProvider == 'oci8') {
-                       
-                       $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$sql);
-                       
                        // Allow Oracle hints to be used for query optimization, Chris Wrye
                        if (preg_match('#/\\*+.*?\\*\\/#', $sql, $hint)) {
                                $rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")"; 
                        } else
                                $rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")"; 
                        
-               } else if (strncmp($zthis->databaseType,'postgres',8) == 0)  {
-                       $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$sql);
+               } else if (strncmp($zthis->databaseType,'postgres',8) == 0 || strncmp($zthis->databaseType,'mysql',5) == 0)  {
                        $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
+               } else {
+                       $rewritesql = "SELECT COUNT(*) FROM ($rewritesql)";
                }
        } else {
                // now replace SELECT ... FROM with SELECT COUNT(*) FROM
                $rewritesql = preg_replace(
                                        '/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
-
-               
-               
                // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails 
                // with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
                // also see http://phplens.com/lens/lensforum/msgs.php?id=12752
-               if (preg_match('/\sORDER\s+BY\s*\(/i',$rewritesql))
-                       $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$rewritesql);
-               else
-                       $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$rewritesql);
+               $rewritesql = adodb_strip_order_by($rewritesql);
        }
        
-       
-       
        if (isset($rewritesql) && $rewritesql != $sql) {
-               if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[1];
+               if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
                 
                if ($secs2cache) {
                        // we only use half the time of secs2cache because the count can quickly
@@ -422,11 +451,11 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
        
        // strip off unneeded ORDER BY if no UNION
        if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
-       else $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql); 
+       else $rewritesql = $rewritesql = adodb_strip_order_by($sql); 
        
        if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
                
-       $rstest = &$zthis->Execute($rewritesql,$inputarr);
+       $rstest = $zthis->Execute($rewritesql,$inputarr);
        if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr);
        
        if ($rstest) {
@@ -460,7 +489,7 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
        data will get out of synch. use CachePageExecute() only with tables that
        rarely change.
 */
-function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page, 
+function _adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page, 
                                                $inputarr=false, $secs2cache=0) 
 {
        $atfirstpage = false;
@@ -496,9 +525,9 @@ function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
        // We get the data we want
        $offset = $nrows * ($page-1);
        if ($secs2cache > 0) 
-               $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
+               $rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
        else 
-               $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
+               $rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
 
        
        // Before returning the RecordSet, we set the pagination properties we need
@@ -514,7 +543,7 @@ function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
 }
 
 // Iván Oliva version
-function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0) 
+function _adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0) 
 {
 
        $atfirstpage = false;
@@ -530,16 +559,16 @@ function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputar
        // the last page number.
        $pagecounter = $page + 1;
        $pagecounteroffset = ($pagecounter * $nrows) - $nrows;
-       if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
-       else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
+       if ($secs2cache>0) $rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
+       else $rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
        if ($rstest) {
                while ($rstest && $rstest->EOF && $pagecounter>0) {
                        $atlastpage = true;
                        $pagecounter--;
                        $pagecounteroffset = $nrows * ($pagecounter - 1);
                        $rstest->Close();
-                       if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
-                       else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
+                       if ($secs2cache>0) $rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
+                       else $rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
                }
                if ($rstest) $rstest->Close();
        }
@@ -551,8 +580,8 @@ function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputar
        
        // We get the data we want
        $offset = $nrows * ($page-1);
-       if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
-       else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
+       if ($secs2cache > 0) $rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
+       else $rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
        
        // Before returning the RecordSet, we set the pagination properties we need
        if ($rsreturn) {
@@ -747,10 +776,10 @@ static $cacheCols;
                //php can't do a $rsclass::MetaType()
                $rsclass = $zthis->rsPrefix.$zthis->databaseType;
                $recordSet = new $rsclass(-1,$zthis->fetchMode);
-               $recordSet->connection = &$zthis;
+               $recordSet->connection = $zthis;
                
                if (is_string($cacheRS) && $cacheRS == $rs) {
-                       $columns =& $cacheCols;
+                       $columns = $cacheCols;
                } else {
                        $columns = $zthis->MetaColumns( $tableName );
                        $cacheRS = $tableName;
@@ -758,7 +787,7 @@ static $cacheCols;
                }
        } else if (is_subclass_of($rs, 'adorecordset')) {
                if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) {
-                       $columns =& $cacheCols;
+                       $columns = $cacheCols;
                } else {
                        for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) 
                                $columns[] = $rs->FetchField($i);
@@ -766,7 +795,7 @@ static $cacheCols;
                        $cacheCols = $columns;
                        $rs->insertSig = $cacheSig++;
                }
-               $recordSet =& $rs;
+               $recordSet = $rs;
        
        } else {
                printf(ADODB_BAD_RS,'GetInsertSQL');
@@ -971,9 +1000,20 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields,
                case "T":
                        $val = $zthis->DBTimeStamp($arrFields[$fname]);
                        break;
+                       
+               case "N":
+                   $val = $arrFields[$fname];
+                       if (!is_numeric($val)) $val = str_replace(',', '.', (float)$val);
+                   break;
+
+               case "I":
+               case "R":
+                   $val = $arrFields[$fname];
+                       if (!is_numeric($val)) $val = (integer) $val;
+                   break;
 
                default:
-                       $val = $arrFields[$fname];
+                       $val = str_replace(array("'"," ","("),"",$arrFields[$fname]); // basic sql injection defence
                        if (empty($val)) $val = '0';
                        break;
        }
@@ -993,7 +1033,8 @@ function _adodb_debug_execute(&$zthis, $sql, $inputarr)
        if ($inputarr) {
                foreach($inputarr as $kk=>$vv) {
                        if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
-                       $ss .= "($kk=>'$vv') ";
+                       if (is_null($vv)) $ss .= "($kk=>null) ";
+                       else $ss .= "($kk=>'$vv') ";
                }
                $ss = "[ $ss ]";
        }
@@ -1012,11 +1053,13 @@ function _adodb_debug_execute(&$zthis, $sql, $inputarr)
                        $ss = '<code>'.htmlspecialchars($ss).'</code>';
                }
                if ($zthis->debug === -1)
-                       ADOConnection::outp( "<br />\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<br />\n",false);
-               else 
-                       ADOConnection::outp( "<hr />\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr />\n",false);
+                       ADOConnection::outp( "<br>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<br>\n",false);
+               else if ($zthis->debug !== -99)
+                       ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr>\n",false);
        } else {
-               ADOConnection::outp("-----\n($dbt): ".$sqlTxt."\n-----\n",false);
+               $ss = "\n   ".$ss;
+               if ($zthis->debug !== -99)
+                       ADOConnection::outp("-----<hr>\n($dbt): ".$sqlTxt." $ss\n-----<hr>\n",false);
        }
 
        $qID = $zthis->_query($sql,$inputarr);
@@ -1027,10 +1070,21 @@ function _adodb_debug_execute(&$zthis, $sql, $inputarr)
        */
        if ($zthis->databaseType == 'mssql') { 
        // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
+       
                if($emsg = $zthis->ErrorMsg()) {
-                       if ($err = $zthis->ErrorNo()) ADOConnection::outp($err.': '.$emsg);
+                       if ($err = $zthis->ErrorNo()) {
+                               if ($zthis->debug === -99) 
+                                       ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr>\n",false);
+               
+                               ADOConnection::outp($err.': '.$emsg);
+                       }
                }
        } else if (!$qID) {
+       
+               if ($zthis->debug === -99) 
+                               if ($inBrowser) ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." &nbsp; $ss\n<hr>\n",false);
+                               else ADOConnection::outp("-----<hr>\n($dbt): ".$sqlTxt."$ss\n-----<hr>\n",false);
+                               
                ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
        }
        
@@ -1039,11 +1093,13 @@ function _adodb_debug_execute(&$zthis, $sql, $inputarr)
 }
 
 # pretty print the debug_backtrace function
-function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0)
+function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0,$ishtml=null)
 {
        if (!function_exists('debug_backtrace')) return '';
         
-       $html =  (isset($_SERVER['HTTP_USER_AGENT']));
+       if ($ishtml === null) $html =  (isset($_SERVER['HTTP_USER_AGENT']));
+       else $html = $ishtml;
+       
        $fmt =  ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
 
        $MAXSTRLEN = 128;
@@ -1074,7 +1130,7 @@ function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0)
                        else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
                        else {
                                $v = (string) @$v;
-                               $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
+                               $str = htmlspecialchars(str_replace(array("\r","\n"),' ',substr($v,0,$MAXSTRLEN)));
                                if (strlen($v) > $MAXSTRLEN) $str .= '...';
                                $args[] = $str;
                        }
diff --git a/libraries/adodb/adodb-php4.inc.php b/libraries/adodb/adodb-php4.inc.php
deleted file mode 100755 (executable)
index 99fda17..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-/*
-  V4.94 23 Jan 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
-  Released under both BSD license and Lesser GPL library license. 
-  Whenever there is any discrepancy between the two licenses, 
-  the BSD license will take precedence.
-  
-  Set tabs to 4.
-*/
-
-
-class ADODB_BASE_RS {
-}
-
-?>
\ No newline at end of file
index 51f69f76c673eda7a431003ab66856025d972611..076389507d2f5f717683a330f2267e6ec5893024 100644 (file)
@@ -241,6 +241,24 @@ b. Implement daylight savings, which looks awfully complicated, see
 
 
 CHANGELOG
+
+- 11 Feb 2008 0.33
+* Bug in 0.32 fix for hour handling. Fixed.
+
+- 1 Feb 2008 0.32
+* Now adodb_mktime(0,0,0,12+$m,20,2040) works properly. 
+
+- 10 Jan 2008 0.31
+* Now adodb_mktime(0,0,0,24,1,2037) works correctly.
+
+- 15 July 2007 0.30
+Added PHP 5.2.0 compatability fixes. 
+ * gmtime behaviour for 1970 has changed. We use the actual date if it is between 1970 to 2038 to get the
+ * timezone, otherwise we use the current year as the baseline to retrieve the timezone.
+ * Also the timezone's in php 5.2.* support historical data better, eg. if timezone today was +8, but 
+   in 1970 it was +7:30, then php 5.2 return +7:30, while this library will use +8.
+ * 
 - 19 March 2006 0.24
 Changed strftime() locale detection, because some locales prepend the day of week to the date when %c is used.
 
@@ -368,7 +386,9 @@ First implementation.
 /*
        Version Number
 */
-define('ADODB_DATE_VERSION',0.24);
+define('ADODB_DATE_VERSION',0.33);
+
+$ADODB_DATETIME_CLASS = (PHP_VERSION >= 5.2);
 
 /*
        This code was originally for windows. But apparently this problem happens 
@@ -387,10 +407,13 @@ if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1);
 
 function adodb_date_test_date($y1,$m,$d=13)
 {
-       $t = adodb_mktime(0,0,0,$m,$d,$y1);
+       $h = round(rand()% 24);
+       $t = adodb_mktime($h,0,0,$m,$d,$y1);
        $rez = adodb_date('Y-n-j H:i:s',$t);
-       if ("$y1-$m-$d 00:00:00" != $rez) {
-               print "<b>$y1 error, expected=$y1-$m-$d 00:00:00, adodb=$rez</b><br>";
+       if ($h == 0) $h = '00';
+       else if ($h < 10) $h = '0'.$h;
+       if ("$y1-$m-$d $h:00:00" != $rez) {
+               print "<b>$y1 error, expected=$y1-$m-$d $h:00:00, adodb=$rez</b><br>";
                return false;
        }
        return true;
@@ -403,16 +426,19 @@ function adodb_date_test_strftime($fmt)
        
        if ($s1 == $s2) return true;
        
-       echo "error for $fmt,  strftime=$s1, $adodb=$s2<br>";
+       echo "error for $fmt,  strftime=$s1, adodb=$s2<br>";
        return false;
 }
 
 /**
         Test Suite
-*/
+*/     
 function adodb_date_test()
 {
        
+       for ($m=-24; $m<=24; $m++)
+               echo "$m :",adodb_date('d-m-Y',adodb_mktime(0,0,0,1+$m,20,2040)),"<br>";
+       
        error_reporting(E_ALL);
        print "<h4>Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION.' PHP='.PHP_VERSION."</h4>";
        @set_time_limit(0);
@@ -421,6 +447,15 @@ function adodb_date_test()
        // This flag disables calling of PHP native functions, so we can properly test the code
        if (!defined('ADODB_TEST_DATES')) define('ADODB_TEST_DATES',1);
        
+       $t = time();
+       
+       
+       $fmt = 'Y-m-d H:i:s';
+       echo '<pre>';
+       echo 'adodb: ',adodb_date($fmt,$t),'<br>';
+       echo 'php  : ',date($fmt,$t),'<br>';
+       echo '</pre>';
+       
        adodb_date_test_strftime('%Y %m %x %X');
        adodb_date_test_strftime("%A %d %B %Y");
        adodb_date_test_strftime("%H %M S");
@@ -480,6 +515,7 @@ function adodb_date_test()
        
        // Test string formating
        print "<p>Testing date formating</p>";
+       
        $fmt = '\d\a\t\e T Y-m-d H:i:s a A d D F g G h H i j l L m M n O \R\F\C2822 r s t U w y Y z Z 2003';
        $s1 = date($fmt,0);
        $s2 = adodb_date($fmt,0);
@@ -657,15 +693,45 @@ function adodb_year_digit_check($y)
        return $y;
 }
 
+function adodb_get_gmt_diff_ts($ts) 
+{
+       if (0 <= $ts && $ts <= 0x7FFFFFFF) { // check if number in 32-bit signed range) {
+               $arr = getdate($ts);
+               $y = $arr['year'];
+               $m = $arr['mon'];
+               $d = $arr['mday'];
+               return adodb_get_gmt_diff($y,$m,$d);    
+       } else {
+               return adodb_get_gmt_diff(false,false,false);
+       }
+       
+}
+
 /**
- get local time zone offset from GMT
+ get local time zone offset from GMT. Does not handle historical timezones before 1970.
 */
-function adodb_get_gmt_diff() 
+function adodb_get_gmt_diff($y,$m,$d
 {
-static $TZ;
-       if (isset($TZ)) return $TZ;
+static $TZ,$tzo;
+global $ADODB_DATETIME_CLASS;
+
+       if (!defined('ADODB_TEST_DATES')) $y = false;
+       else if ($y < 1970 || $y >= 2038) $y = false;
+
+       if ($ADODB_DATETIME_CLASS && $y !== false) {
+               $dt = new DateTime();
+               $dt->setISODate($y,$m,$d);
+               if (empty($tzo)) {
+                       $tzo = new DateTimeZone(date_default_timezone_get());
+               #       $tzt = timezone_transitions_get( $tzo );
+               }
+               return -$tzo->getOffset($dt);
+       } else {
+               if (isset($TZ)) return $TZ;
+               $y = date('Y');
+               $TZ = mktime(0,0,0,12,2,$y,0) - gmmktime(0,0,0,12,2,$y,0);
+       }
        
-       $TZ = mktime(0,0,0,1,2,1970,0) - gmmktime(0,0,0,1,2,1970,0);
        return $TZ;
 }
 
@@ -712,8 +778,8 @@ function adodb_validdate($y,$m,$d)
 {
 global $_month_table_normal,$_month_table_leaf;
 
-       if (_adodb_is_leap_year($y)) $marr =& $_month_table_leaf;
-       else $marr =& $_month_table_normal;
+       if (_adodb_is_leap_year($y)) $marr = $_month_table_leaf;
+       else $marr = $_month_table_normal;
        
        if ($m > 12 || $m < 1) return false;
        
@@ -736,8 +802,7 @@ function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
 static $YRS;
 global $_month_table_normal,$_month_table_leaf;
 
-       $d =  $origd - ($is_gmt ? 0 : adodb_get_gmt_diff());
-       
+       $d =  $origd - ($is_gmt ? 0 : adodb_get_gmt_diff_ts($origd));
        $_day_power = 86400;
        $_hour_power = 3600;
        $_min_power = 60;
@@ -927,6 +992,22 @@ global $_month_table_normal,$_month_table_leaf;
                0 => $origd
        );
 }
+/*
+               if ($isphp5)
+                               $dates .= sprintf('%s%04d',($gmt<=0)?'+':'-',abs($gmt)/36); 
+                       else
+                               $dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36); 
+                       break;*/
+function adodb_tz_offset($gmt,$isphp5)
+{
+       $zhrs = abs($gmt)/3600;
+       $hrs = floor($zhrs);
+       if ($isphp5) 
+               return sprintf('%s%02d%02d',($gmt<=0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60); 
+       else
+               return sprintf('%s%02d%02d',($gmt<0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60); 
+}
+
 
 function adodb_gmdate($fmt,$d=false)
 {
@@ -958,6 +1039,7 @@ function adodb_date2($fmt, $d=false, $is_gmt=false)
 function adodb_date($fmt,$d=false,$is_gmt=false)
 {
 static $daylight;
+global $ADODB_DATETIME_CLASS;
 
        if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
        if (!defined('ADODB_TEST_DATES')) {
@@ -992,7 +1074,14 @@ static $daylight;
        */
        for ($i=0; $i < $max; $i++) {
                switch($fmt[$i]) {
-               case 'T': $dates .= date('T');break;
+               case 'T': 
+                       if ($ADODB_DATETIME_CLASS) {
+                               $dt = new DateTime();
+                               $dt->SetDate($year,$month,$day);
+                               $dates .= $dt->Format('T');
+                       } else
+                               $dates .= date('T');
+                       break;
                // YEAR
                case 'L': $dates .= $arr['leap'] ? '1' : '0'; break;
                case 'r': // Thu, 21 Dec 2000 16:01:07 +0200
@@ -1008,13 +1097,11 @@ static $daylight;
                        
                        if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs;
                        
-                       $gmt = adodb_get_gmt_diff();
-                       if ($isphp5) 
-                               $dates .= sprintf(' %s%04d',($gmt<=0)?'+':'-',abs($gmt)/36); 
-                       else
-                               $dates .= sprintf(' %s%04d',($gmt<0)?'+':'-',abs($gmt)/36); 
+                       $gmt = adodb_get_gmt_diff($year,$month,$day);
+                       
+                       $dates .= ' '.adodb_tz_offset($gmt,$isphp5);
                        break;
-                               
+                       
                case 'Y': $dates .= $year; break;
                case 'y': $dates .= substr($year,strlen($year)-2,2); break;
                // MONTH
@@ -1041,14 +1128,11 @@ static $daylight;
                        
                // HOUR
                case 'Z':
-                       $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff(); break;
+                       $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff($year,$month,$day); break;
                case 'O': 
-                       $gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff();
+                       $gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$month,$day);
                        
-                       if ($isphp5)
-                               $dates .= sprintf('%s%04d',($gmt<=0)?'+':'-',abs($gmt)/36); 
-                       else
-                               $dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36); 
+                       $dates .= adodb_tz_offset($gmt,$isphp5);
                        break;
                        
                case 'H': 
@@ -1130,16 +1214,21 @@ function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=fa
                
                // for windows, we don't check 1970 because with timezone differences, 
                // 1 Jan 1970 could generate negative timestamp, which is illegal
-               if (1971 < $year && $year < 2038
+               $usephpfns = (1970 < $year && $year < 2038
                        || !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038)
-                       ) {
+                       ); 
+                       
+               
+               if ($usephpfns && ($year + $mon/12+$day/365.25+$hr/(24*365.25) >= 2038)) $usephpfns = false;
+                       
+               if ($usephpfns) {
                                return $is_gmt ?
                                        @gmmktime($hr,$min,$sec,$mon,$day,$year):
                                        @mktime($hr,$min,$sec,$mon,$day,$year);
-                       }
+               }
        }
        
-       $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff();
+       $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$mon,$day);
 
        /*
        # disabled because some people place large values in $sec.
@@ -1156,7 +1245,7 @@ function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=fa
        $year = adodb_year_digit_check($year);
 
        if ($mon > 12) {
-               $y = floor($mon / 12);
+               $y = floor(($mon-1)/ 12);
                $year += $y;
                $mon -= $y*12;
        } else if ($mon < 1) {
index 5567f7898ffa4517d8db719e2db045e9cbedd188..02b375aeb695a17136d5f7eab61d559a680a6402 100755 (executable)
@@ -12,9 +12,9 @@
  */
 
 /**
-       \mainpage       
+       \mainpage
        
-        @version V4.94 23 Jan 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+        @version V5.09 25 June 2009   (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
 
        Released under both BSD license and Lesser GPL library license. You can choose which license
        you prefer.
                $ADODB_vers,            // database version
                $ADODB_COUNTRECS,       // count number of records returned - slows down query
                $ADODB_CACHE_DIR,       // directory to cache recordsets
+               $ADODB_CACHE,
+               $ADODB_CACHE_CLASS,
                $ADODB_EXTENSION,   // ADODB extension installed
                $ADODB_COMPAT_FETCH, // If $ADODB_COUNTRECS and this is true, $rs->fields is available on EOF
                $ADODB_FETCH_MODE,      // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default...
+               $ADODB_GETONE_EOF,
                $ADODB_QUOTE_FIELDNAMES; // Allows you to force quotes (backticks) around field names in queries generated by getinsertsql and getupdatesql.    
        
        //==============================================================================================        
                        define('ADODB_PHPVER',0x5200);
                } else if ($_adodb_ver >= 5.0) {
                        define('ADODB_PHPVER',0x5000);
-               } else if ($_adodb_ver > 4.299999) { # 4.3
-                       define('ADODB_PHPVER',0x4300);
-               } else if ($_adodb_ver > 4.199999) { # 4.2
-                       define('ADODB_PHPVER',0x4200);
-               } else if (strnatcmp(PHP_VERSION,'4.0.5')>=0) {
-                       define('ADODB_PHPVER',0x4050);
-               } else {
-                       define('ADODB_PHPVER',0x4000);
-               }
+               } else 
+                       die("PHP5 or later required. You are running ".PHP_VERSION);
        }
        
+       
        //if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
 
        
                $ADODB_COUNTRECS,       // count number of records returned - slows down query
                $ADODB_CACHE_DIR,       // directory to cache recordsets
                $ADODB_FETCH_MODE,
+               $ADODB_CACHE,
+               $ADODB_CACHE_CLASS,
                $ADODB_FORCE_TYPE,
+               $ADODB_GETONE_EOF,
                $ADODB_QUOTE_FIELDNAMES;
                
+               if (empty($ADODB_CACHE_CLASS)) $ADODB_CACHE_CLASS =  'ADODB_Cache_File' ;
                $ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT;
                $ADODB_FORCE_TYPE = ADODB_FORCE_VALUE;
-
+               $ADODB_GETONE_EOF = null;
 
                if (!isset($ADODB_CACHE_DIR)) {
                        $ADODB_CACHE_DIR = '/tmp'; //(isset($_ENV['TMP'])) ? $_ENV['TMP'] : '/tmp';
                        
                // Initialize random number generator for randomizing cache flushes
                // -- note Since PHP 4.2.0, the seed  becomes optional and defaults to a random value if omitted.
-               srand(((double)microtime())*1000000);
+                srand(((double)microtime())*1000000);
                
                /**
                 * ADODB version as a string.
                 */
-               $ADODB_vers = 'V4.94 23 Jan 2007 (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.';
+               $ADODB_vers = 'V5.09 25 June 2009  (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved. Released BSD & LGPL.';
        
                /**
                 * Determines whether recordset->RecordCount() is used. 
 */
        }
        
-
+       // for transaction handling
        
        function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection)
        {
                }
        }
        
+       //------------------
+       // class for caching
+       class ADODB_Cache_File {
+       
+               var $createdir = true; // requires creation of temp dirs
+               
+               function ADODB_Cache_File()
+               {
+               global $ADODB_INCLUDED_CSV;
+                       if (empty($ADODB_INCLUDED_CSV)) include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
+               }
+               
+               // write serialised recordset to cache item/file
+               function writecache($filename, $contents,  $debug, $secs2cache)
+               {
+                       return adodb_write_file($filename, $contents,$debug);
+               }
+               
+               // load serialised recordset and unserialise it
+               function &readcache($filename, &$err, $secs2cache, $rsClass)
+               {
+                       $rs = csv2rs($filename,$err,$secs2cache,$rsClass);
+                       return $rs;
+               }
+               
+               // flush all items in cache
+               function flushall($debug=false)
+               {
+               global $ADODB_CACHE_DIR;
+
+               $rez = false;
+               
+                       if (strlen($ADODB_CACHE_DIR) > 1) {
+                               $rez = $this->_dirFlush($ADODB_CACHE_DIR);
+                       if ($debug) ADOConnection::outp( "flushall: $dir<br><pre>\n". $rez."</pre>");
+                       }
+                       return $rez;
+               }
+               
+               // flush one file in cache
+               function flushcache($f, $debug=false)
+               {
+                       if (!@unlink($f)) {
+                               if ($debug) ADOConnection::outp( "flushcache: failed for $f");
+                       }
+               }
+               
+               function getdirname($hash)
+               {
+               global $ADODB_CACHE_DIR;
+                       if (!isset($this->notSafeMode)) $this->notSafeMode = !ini_get('safe_mode');
+                       return ($this->notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($hash,0,2) : $ADODB_CACHE_DIR;
+               }
+               
+               // create temp directories
+               function createdir($hash, $debug)
+               {
+                       $dir = $this->getdirname($hash);
+                       if ($this->notSafeMode && !file_exists($dir)) {
+                               $oldu = umask(0);
+                               if (!@mkdir($dir,0771)) if(!is_dir($dir) && $debug) ADOConnection::outp("Cannot create $dir");
+                               umask($oldu);
+                       }
+               
+                       return $dir;
+               }
+               
+               /**
+               * Private function to erase all of the files and subdirectories in a directory.
+               *
+               * Just specify the directory, and tell it if you want to delete the directory or just clear it out.
+               * Note: $kill_top_level is used internally in the function to flush subdirectories.
+               */
+               function _dirFlush($dir, $kill_top_level = false) 
+               {
+                  if(!$dh = @opendir($dir)) return;
+                  
+                  while (($obj = readdir($dh))) {
+                               if($obj=='.' || $obj=='..') continue;
+                               $f = $dir.'/'.$obj;
+               
+                               if (strpos($obj,'.cache')) @unlink($f);
+                               if (is_dir($f)) $this->_dirFlush($f, true);
+                  }
+                  if ($kill_top_level === true) @rmdir($dir);
+                  return true;
+               }
+       }
+       
        //==============================================================================================        
        // CLASS ADOConnection
        //==============================================================================================        
 
        var $sysDate = false; /// name of function that returns the current date
        var $sysTimeStamp = false; /// name of function that returns the current timestamp
+       var $sysUTimeStamp = false; // name of function that returns the current timestamp accurate to the microsecond or nearest fraction
        var $arrayClass = 'ADORecordSet_array'; /// name of class used to generate array recordsets, which are pre-downloaded recordsets
        
        var $noNullStrings = false; /// oracle specific stuff - if true ensures that '' is converted to ' '
                die('Virtual Class -- cannot instantiate');
        }
        
-       function Version()
+       static function Version()
        {
        global $ADODB_vers;
        
        * All error messages go through this bottleneck function.
        * You can define your own handler by defining the function name in ADODB_OUTP.
        */
-       function outp($msg,$newline=true)
+       static function outp($msg,$newline=true)
        {
        global $ADODB_FLUSH,$ADODB_OUTP;
        
        
        function Time()
        {
-               $rs =& $this->_Execute("select $this->sysTimeStamp");
+               $rs = $this->_Execute("select $this->sysTimeStamp");
                if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
                
                return false;
                if ($argDatabaseName != "") $this->database = $argDatabaseName;         
                
                $this->_isPersistentConnection = false; 
+                       
+               global $ADODB_CACHE;
+               if (empty($ADODB_CACHE)) $this->_CreateCache();
+               
                if ($forceNew) {
                        if ($rez=$this->_nconnect($this->host, $this->user, $this->password, $this->database)) return true;
                } else {
         */     
        function PConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "")
        {
+               
                if (defined('ADODB_NEVER_PERSIST')) 
                        return $this->Connect($argHostname,$argUsername,$argPassword,$argDatabaseName);
                
                if ($argDatabaseName != "") $this->database = $argDatabaseName;         
                        
                $this->_isPersistentConnection = true;  
+               
+               global $ADODB_CACHE;
+               if (empty($ADODB_CACHE)) $this->_CreateCache();
+               
                if ($rez = $this->_pconnect($this->host, $this->user, $this->password, $this->database)) return true;
                if (isset($rez)) {
                        $err = $this->ErrorMsg();
                return $ret;
        }
 
+       function outp_throw($msg,$src='WARN',$sql='')
+       {
+               if (defined('ADODB_ERROR_HANDLER') &&  ADODB_ERROR_HANDLER == 'adodb_throw') {
+                       adodb_throw($this->databaseType,$src,-9999,$msg,$sql,false,$this);
+                       return;
+               } 
+               ADOConnection::outp($msg);
+       }
+       
+       // create cache class. Code is backward compat with old memcache implementation
+       function _CreateCache()
+       {
+       global $ADODB_CACHE, $ADODB_CACHE_CLASS;
+       
+               if ($this->memCache) {
+               global $ADODB_INCLUDED_MEMCACHE;
+               
+                       if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php');
+                               $ADODB_CACHE = new ADODB_Cache_MemCache($this);
+               } else
+                               $ADODB_CACHE = new $ADODB_CACHE_CLASS($this);
+               
+       }
+       
        // Format date column in sql string given an input format that understands Y M D
        function SQLDate($fmt, $col=false)
        {       
        {
                return $sql;
        }
-       
+
        /**
         * Some databases, eg. mssql require a different function for preparing
         * stored procedures. So we cannot use Prepare().
        {
                return $this->Prepare($sql,$param);
        }
-       
+
        /**
        * PEAR DB Compat
        */
 
        function q(&$s)
        {
+               #if (!empty($this->qNull)) if ($s == 'null') return $s;
                $s = $this->qstr($s,false);
        }
        
        /**
        * PEAR DB Compat - do not use internally. 
        */
-       function &Query($sql, $inputarr=false)
+       function Query($sql, $inputarr=false)
        {
-               $rs = &$this->Execute($sql, $inputarr);
+               $rs = $this->Execute($sql, $inputarr);
                if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error();
                return $rs;
        }
        /**
        * PEAR DB Compat - do not use internally
        */
-       function &LimitQuery($sql, $offset, $count, $params=false)
+       function LimitQuery($sql, $offset, $count, $params=false)
        {
-               $rs = &$this->SelectLimit($sql, $count, $offset, $params); 
+               $rs = $this->SelectLimit($sql, $count, $offset, $params); 
                if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error();
                return $rs;
        }
        {
                if ($this->transOff > 0) {
                        $this->transOff += 1;
-                       return;
+                       return true;
                }
                
                $this->_oldRaiseFn = $this->raiseErrorFn;
                $this->_transOK = true;
                
                if ($this->debug && $this->transCnt > 0) ADOConnection::outp("Bad Transaction: StartTrans called within BeginTrans");
-               $this->BeginTrans();
+               $ok = $this->BeginTrans();
                $this->transOff = 1;
+               return $ok;
        }
        
        
         * @param [inputarr]    holds the input data to bind to. Null elements will be set to null.
         * @return              RecordSet or false
         */
-       function &Execute($sql,$inputarr=false) 
+       function Execute($sql,$inputarr=false) 
        {
                if ($this->fnExecute) {
                        $fn = $this->fnExecute;
-                       $ret =& $fn($this,$sql,$inputarr);
+                       $ret = $fn($this,$sql,$inputarr);
                        if (isset($ret)) return $ret;
                }
                if ($inputarr) {
                        
                        if (!is_array($sql) && !$this->_bindInputArray) {
                                $sqlarr = explode('?',$sql);
-                                       
+                               $nparams = sizeof($sqlarr)-1;
                                if (!$array_2d) $inputarr = array($inputarr);
                                foreach($inputarr as $arr) {
                                        $sql = ''; $i = 0;
                                                else
                                                        $sql .= $v;
                                                $i += 1;
-                                       }
+                                               
+                                               if ($i == $nparams) break;
+                                       } // while
                                        if (isset($sqlarr[$i])) {
                                                $sql .= $sqlarr[$i];
-                                               if ($i+1 != sizeof($sqlarr)) ADOConnection::outp( "Input Array does not match ?: ".htmlspecialchars($sql));
+                                               if ($i+1 != sizeof($sqlarr)) $this->outp_throw( "Input Array does not match ?: ".htmlspecialchars($sql),'Execute');
                                        } else if ($i != sizeof($sqlarr))       
-                                               ADOConnection::outp( "Input array does not match ?: ".htmlspecialchars($sql));
+                                               $this->outp_throw( "Input array does not match ?: ".htmlspecialchars($sql),'Execute');
                
-                                       $ret =& $this->_Execute($sql);
+                                       $ret = $this->_Execute($sql);
                                        if (!$ret) return $ret;
                                }       
                        } else {
                                                $stmt = $sql;
                                                
                                        foreach($inputarr as $arr) {
-                                               $ret =& $this->_Execute($stmt,$arr);
+                                               $ret = $this->_Execute($stmt,$arr);
                                                if (!$ret) return $ret;
                                        }
                                } else {
-                                       $ret =& $this->_Execute($sql,$inputarr);
+                                       $ret = $this->_Execute($sql,$inputarr);
                                }
                        }
                } else {
-                       $ret =& $this->_Execute($sql,false);
+                       $ret = $this->_Execute($sql,false);
                }
 
                return $ret;
        }
        
        
-       function &_Execute($sql,$inputarr=false)
+       function _Execute($sql,$inputarr=false)
        {
                if ($this->debug) {
                        global $ADODB_INCLUDED_LIB;
                } 
                
                if ($this->_queryID === true) { // return simplified recordset for inserts/updates/deletes with lower overhead
-                       $rs = new ADORecordSet_empty();
+                       $rsclass = $this->rsPrefix.'empty';
+                       $rs = (class_exists($rsclass)) ? new $rsclass():  new ADORecordSet_empty();
+                       
                        return $rs;
                }
                
                // return real recordset from select statement
                $rsclass = $this->rsPrefix.$this->databaseType;
                $rs = new $rsclass($this->_queryID,$this->fetchMode);
-               $rs->connection = &$this; // Pablo suggestion
+               $rs->connection = $this; // Pablo suggestion
                $rs->Init();
                if (is_array($sql)) $rs->sql = $sql[0];
                else $rs->sql = $sql;
                global $ADODB_COUNTRECS;
                        if ($ADODB_COUNTRECS) {
                                if (!$rs->EOF) { 
-                                       $rs = &$this->_rs2rs($rs,-1,-1,!is_array($sql));
+                                       $rs = $this->_rs2rs($rs,-1,-1,!is_array($sql));
                                        $rs->_queryID = $this->_queryID;
                                } else
                                        $rs->_numOfRows = 0;
        {
        // owner not used in base class - see oci8
                $p = array();
-               $objs =& $this->MetaColumns($table);
+               $objs = $this->MetaColumns($table);
                if ($objs) {
                        foreach($objs as $v) {
                                if (!empty($v->primary_key))
        * @param [secs2cache]           is a private parameter only used by jlim
        * @return               the recordset ($rs->databaseType == 'array')
        */
-       function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+       function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
        {
                if ($this->hasTop && $nrows > 0) {
                // suggested by Reinhard Balling. Access requires top after distinct 
                        if ($ismssql) $isaccess = false;
                        else $isaccess = (strpos($this->databaseType,'access') !== false);
                        
-                       if ($offset <= 0) {
+                       if ($offset <=  0) {
                                
                                        // access includes ties in result
                                        if ($isaccess) {
                                                '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql);
 
                                                if ($secs2cache != 0) {
-                                                       $ret =& $this->CacheExecute($secs2cache, $sql,$inputarr);
+                                                       $ret = $this->CacheExecute($secs2cache, $sql,$inputarr);
                                                } else {
-                                                       $ret =& $this->Execute($sql,$inputarr);
+                                                       $ret = $this->Execute($sql,$inputarr);
                                                }
                                                return $ret; // PHP5 fix
                                        } else if ($ismssql){
                $savec = $ADODB_COUNTRECS;
                $ADODB_COUNTRECS = false;
                        
-               if ($offset>0){
-                       if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
-                       else $rs = &$this->Execute($sql,$inputarr);
-               } else {
-                       if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
-                       else $rs = &$this->Execute($sql,$inputarr);
-               }
+
+               if ($secs2cache != 0) $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
+               else $rs = $this->Execute($sql,$inputarr);
+               
                $ADODB_COUNTRECS = $savec;
                if ($rs && !$rs->EOF) {
-                       $rs =& $this->_rs2rs($rs,$nrows,$offset);
+                       $rs = $this->_rs2rs($rs,$nrows,$offset);
                }
                //print_r($rs);
                return $rs;
        *
        * @param rs                     the recordset to serialize
        */
-       function &SerializableRS(&$rs)
+       function SerializableRS(&$rs)
        {
-               $rs2 =& $this->_rs2rs($rs);
+               $rs2 = $this->_rs2rs($rs);
                $ignore = false;
-               $rs2->connection =& $ignore;
+               $rs2->connection = $ignore;
                
                return $rs2;
        }
                }
                $dbtype = $rs->databaseType;
                if (!$dbtype) {
-                       $rs = &$rs;  // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ?
+                       $rs = $rs;  // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ?
                        return $rs;
                }
                if (($dbtype == 'array' || $dbtype == 'csv') && $nrows == -1 && $offset == -1) {
                        $rs->MoveFirst();
-                       $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ?
+                       $rs = $rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ?
                        return $rs;
                }
                $flds = array();
                        $flds[] = $rs->FetchField($i);
                }
 
-               $arr =& $rs->GetArrayLimit($nrows,$offset);
+               $arr = $rs->GetArrayLimit($nrows,$offset);
                //print_r($arr);
                if ($close) $rs->Close();
                
                $arrayClass = $this->arrayClass;
                
                $rs2 = new $arrayClass();
-               $rs2->connection = &$this;
+               $rs2->connection = $this;
                $rs2->sql = $rs->sql;
                $rs2->dataProvider = $this->dataProvider;
                $rs2->InitArrayFields($arr,$flds);
        /*
        * Return all rows. Compat with PEAR DB
        */
-       function &GetAll($sql, $inputarr=false)
+       function GetAll($sql, $inputarr=false)
        {
-               $arr =& $this->GetArray($sql,$inputarr);
+               $arr = $this->GetArray($sql,$inputarr);
                return $arr;
        }
        
-       function &GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false)
+       function GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false)
        {
-               $rs =& $this->Execute($sql, $inputarr);
+               $rs = $this->Execute($sql, $inputarr);
                if (!$rs) {
                        $false = false;
                        return $false;
                }
-               $arr =& $rs->GetAssoc($force_array,$first2cols);
+               $arr = $rs->GetAssoc($force_array,$first2cols);
                return $arr;
        }
        
-       function &CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false)
+       function CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false)
        {
                if (!is_numeric($secs2cache)) {
                        $first2cols = $force_array;
                        $force_array = $inputarr;
                }
-               $rs =& $this->CacheExecute($secs2cache, $sql, $inputarr);
+               $rs = $this->CacheExecute($secs2cache, $sql, $inputarr);
                if (!$rs) {
                        $false = false;
                        return $false;
                }
-               $arr =& $rs->GetAssoc($force_array,$first2cols);
+               $arr = $rs->GetAssoc($force_array,$first2cols);
                return $arr;
        }
        
        */
        function GetOne($sql,$inputarr=false)
        {
-       global $ADODB_COUNTRECS;
+       global $ADODB_COUNTRECS,$ADODB_GETONE_EOF;
                $crecs = $ADODB_COUNTRECS;
                $ADODB_COUNTRECS = false;
                
                $ret = false;
-               $rs = &$this->Execute($sql,$inputarr);
+               $rs = $this->Execute($sql,$inputarr);
                if ($rs) {      
-                       if (!$rs->EOF) $ret = reset($rs->fields);
+                       if ($rs->EOF) $ret = $ADODB_GETONE_EOF;
+                       else $ret = reset($rs->fields);
+                       
                        $rs->Close();
                }
                $ADODB_COUNTRECS = $crecs;
                return $ret;
        }
        
+       // $where should include 'WHERE fld=value'
+       function GetMedian($table, $field,$where = '')
+       {
+               $total = $this->GetOne("select count(*) from $table $where");
+               if (!$total) return false;
+       
+               $midrow = (integer) ($total/2);
+               $rs = $this->SelectLimit("select $field from $table $where order by 1",1,$midrow);
+               if ($rs && !$rs->EOF) return reset($rs->fields);
+               return false;
+       }
+       
+       
        function CacheGetOne($secs2cache,$sql=false,$inputarr=false)
        {
+       global $ADODB_GETONE_EOF;
                $ret = false;
-               $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
-               if ($rs) {              
-                       if (!$rs->EOF) $ret = reset($rs->fields);
+               $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
+               if ($rs) {
+                       if ($rs->EOF) $ret = $ADODB_GETONE_EOF;
+                       else $ret = reset($rs->fields);
                        $rs->Close();
                } 
                
        
        function GetCol($sql, $inputarr = false, $trim = false)
        {
-               $rv = false;
-               $rs = &$this->Execute($sql, $inputarr);
+               
+               $rs = $this->Execute($sql, $inputarr);
                if ($rs) {
                        $rv = array();
                        if ($trim) {
                                }
                        }
                        $rs->Close();
-               }
+               } else
+                       $rv = false;
                return $rv;
        }
        
        function CacheGetCol($secs, $sql = false, $inputarr = false,$trim=false)
        {
-               $rv = false;
-               $rs = &$this->CacheExecute($secs, $sql, $inputarr);
+               $rs = $this->CacheExecute($secs, $sql, $inputarr);
                if ($rs) {
+                       $rv = array();
                        if ($trim) {
                                while (!$rs->EOF) {
                                        $rv[] = trim(reset($rs->fields));
                                }
                        }
                        $rs->Close();
-               }
+               } else
+                       $rv = false;
+                       
                return $rv;
        }
        
-       function &Transpose(&$rs,$addfieldnames=true)
+       function Transpose(&$rs,$addfieldnames=true)
        {
-               $rs2 =& $this->_rs2rs($rs);
+               $rs2 = $this->_rs2rs($rs);
                $false = false;
                if (!$rs2) return $false;
                
        * @param sql                    SQL statement
        * @param [inputarr]             input bind array
        */
-       function &GetArray($sql,$inputarr=false)
+       function GetArray($sql,$inputarr=false)
        {
        global $ADODB_COUNTRECS;
                
                $savec = $ADODB_COUNTRECS;
                $ADODB_COUNTRECS = false;
-               $rs =& $this->Execute($sql,$inputarr);
+               $rs = $this->Execute($sql,$inputarr);
                $ADODB_COUNTRECS = $savec;
                if (!$rs) 
                        if (defined('ADODB_PEAR')) {
                                $false = false;
                                return $false;
                        }
-               $arr =& $rs->GetArray();
+               $arr = $rs->GetArray();
                $rs->Close();
                return $arr;
        }
        
-       function &CacheGetAll($secs2cache,$sql=false,$inputarr=false)
+       function CacheGetAll($secs2cache,$sql=false,$inputarr=false)
        {
-               $arr =& $this->CacheGetArray($secs2cache,$sql,$inputarr);
+               $arr = $this->CacheGetArray($secs2cache,$sql,$inputarr);
                return $arr;
        }
        
-       function &CacheGetArray($secs2cache,$sql=false,$inputarr=false)
+       function CacheGetArray($secs2cache,$sql=false,$inputarr=false)
        {
        global $ADODB_COUNTRECS;
                
                $savec = $ADODB_COUNTRECS;
                $ADODB_COUNTRECS = false;
-               $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr);
+               $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
                $ADODB_COUNTRECS = $savec;
                
                if (!$rs) 
                                $false = false;
                                return $false;
                        }
-               $arr =& $rs->GetArray();
+               $arr = $rs->GetArray();
                $rs->Close();
                return $arr;
        }
        
-       
+       function GetRandRow($sql, $arr= false)
+       {
+               $rezarr = $this->GetAll($sql, $arr);
+               $sz = sizeof($rezarr);
+               return $rezarr[abs(rand()) % $sz];
+       }
        
        /**
        * Return one row of sql statement. Recordset is disposed for you.
        * @param sql                    SQL statement
        * @param [inputarr]             input bind array
        */
-       function &GetRow($sql,$inputarr=false)
+       function GetRow($sql,$inputarr=false)
        {
        global $ADODB_COUNTRECS;
                $crecs = $ADODB_COUNTRECS;
                $ADODB_COUNTRECS = false;
                
-               $rs =& $this->Execute($sql,$inputarr);
+               $rs = $this->Execute($sql,$inputarr);
                
                $ADODB_COUNTRECS = $crecs;
                if ($rs) {
                return $false;
        }
        
-       function &CacheGetRow($secs2cache,$sql=false,$inputarr=false)
+       function CacheGetRow($secs2cache,$sql=false,$inputarr=false)
        {
-               $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr);
+               $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
                if ($rs) {
-                       $arr = false;
                        if (!$rs->EOF) $arr = $rs->fields;
+                       else $arr = array();
+                       
                        $rs->Close();
                        return $arr;
                }
        * @param [inputarr]     array of bind variables
        * @return               the recordset ($rs->databaseType == 'array')
        */
-       function &CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false)
+       function CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false)
        {       
                if (!is_numeric($secs2cache)) {
                        if ($sql === false) $sql = -1;
                        if ($offset == -1) $offset = false;
                                                                          // sql,       nrows, offset,inputarr
-                       $rs =& $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs);
+                       $rs = $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs);
                } else {
-                       if ($sql === false) ADOConnection::outp( "Warning: \$sql missing from CacheSelectLimit()");
-                       $rs =& $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+                       if ($sql === false) $this->outp_throw("Warning: \$sql missing from CacheSelectLimit()",'CacheSelectLimit');
+                       $rs = $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
                }
                return $rs;
        }
        * Flush cached recordsets that match a particular $sql statement. 
        * If $sql == false, then we purge all files in the cache.
        */
-       function CacheFlush($sql=false,$inputarr=false)
-       {
-       global $ADODB_CACHE_DIR;
-       
-               if ($this->memCache) {
-               global $ADODB_INCLUDED_MEMCACHE;
-               
-                       $key = false;
-                       if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php');
-                       if ($sql) $key = $this->_gencachename($sql.serialize($inputarr),false,true);
-                       FlushMemCache($key, $this->memCacheHost, $this->memCachePort, $this->debug);
-                       return;
-               }
-       
-               if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) {
-                       /*if (strncmp(PHP_OS,'WIN',3) === 0)
-                       $dir = str_replace('/', '\\', $ADODB_CACHE_DIR);
-                       else */
-                       $dir = $ADODB_CACHE_DIR;
-                       
-                       if ($this->debug)
-                               ADOConnection::outp( "CacheFlush: $dir<br><pre>\n", $this->_dirFlush($dir),"</pre>");
-                       else
-                               $this->_dirFlush($dir);
-                       return;
-               }
-               
-               global $ADODB_INCLUDED_CSV;
-               if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php');
-               
-               $f = $this->_gencachename($sql.serialize($inputarr),false);
-               adodb_write_file($f,''); // is adodb_write_file needed?
-               if (!@unlink($f))
-                       if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f");
-       }
        
        /**
-       * Private function to erase all of the files and subdirectories in a directory.
-       *
-       * Just specify the directory, and tell it if you want to delete the directory or just clear it out.
-       * Note: $kill_top_level is used internally in the function to flush subdirectories.
-       */
-       function _dirFlush($dir, $kill_top_level = false) {
-               if(!$dh = @opendir($dir)) return;
-               
-               while (($obj = readdir($dh))) {
-                       if($obj=='.' || $obj=='..')
-                               continue;
-
-                       if (!@unlink($dir.'/'.$obj))
-                               $this->_dirFlush($dir.'/'.$obj, true);
-               }
-               if ($kill_top_level === true)
-                       @rmdir($dir);
-               return true;
-       }
-       
-       
-       function xCacheFlush($sql=false,$inputarr=false)
+   * Flush cached recordsets that match a particular $sql statement. 
+   * If $sql == false, then we purge all files in the cache.
+    */
+       function CacheFlush($sql=false,$inputarr=false)
        {
-       global $ADODB_CACHE_DIR;
-       
-               if ($this->memCache) {
-                       global $ADODB_INCLUDED_MEMCACHE;
-                       $key = false;
-                       if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php');
-                       if ($sql) $key = $this->_gencachename($sql.serialize($inputarr),false,true);
-                       flushmemCache($key, $this->memCacheHost, $this->memCachePort, $this->debug);
-                       return;
-               }
-
-               if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) {
-                       if (strncmp(PHP_OS,'WIN',3) === 0) {
-                               $cmd = 'del /s '.str_replace('/','\\',$ADODB_CACHE_DIR).'\adodb_*.cache';
-                       } else {
-                               //$cmd = 'find "'.$ADODB_CACHE_DIR.'" -type f -maxdepth 1 -print0 | xargs -0 rm -f';
-                               $cmd = 'rm -rf '.$ADODB_CACHE_DIR.'/[0-9a-f][0-9a-f]/'; 
-                               // old version 'rm -f `find '.$ADODB_CACHE_DIR.' -name adodb_*.cache`';
-                       }
-                       if ($this->debug) {
-                               ADOConnection::outp( "CacheFlush: $cmd<br><pre>\n", system($cmd),"</pre>");
-                       } else {
-                               exec($cmd);
-                       }
-                       return;
-               } 
+       global $ADODB_CACHE_DIR, $ADODB_CACHE;
                
-               global $ADODB_INCLUDED_CSV;
-               if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php');
+               if (!$sql) {
+                        $ADODB_CACHE->flushall($this->debug);
+                return;
+           }
                
                $f = $this->_gencachename($sql.serialize($inputarr),false);
-               adodb_write_file($f,''); // is adodb_write_file needed?
-               if (!@unlink($f)) {
-                       if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f");
-               }
+               return $ADODB_CACHE->flushcache($f, $this->debug);
        }
+   
        
        /**
        * Private function to generate filename for caching.
        * Assuming that we can have 50,000 files per directory with good performance, 
        * then we can scale to 12.8 million unique cached recordsets. Wow!
        */
-       function _gencachename($sql,$createdir,$memcache=false)
+       function _gencachename($sql,$createdir)
        {
-       global $ADODB_CACHE_DIR;
-       static $notSafeMode;
+       global $ADODB_CACHE, $ADODB_CACHE_DIR;
                
                if ($this->fetchMode === false) { 
                global $ADODB_FETCH_MODE;
                        $mode = $this->fetchMode;
                }
                $m = md5($sql.$this->databaseType.$this->database.$this->user.$mode);
-               if ($memcache) return $m;
+               if (!$ADODB_CACHE->createdir) return $m;
+               if (!$createdir) $dir = $ADODB_CACHE->getdirname($m);
+               else $dir = $ADODB_CACHE->createdir($m, $this->debug);
                
-               if (!isset($notSafeMode)) $notSafeMode = !ini_get('safe_mode');
-               $dir = ($notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($m,0,2) : $ADODB_CACHE_DIR;
-                       
-               if ($createdir && $notSafeMode && !file_exists($dir)) {
-                       $oldu = umask(0);
-                       if (!mkdir($dir,0771)) 
-                               if ($this->debug) ADOConnection::outp( "Unable to mkdir $dir for $sql");
-                       umask($oldu);
-               }
                return $dir.'/adodb_'.$m.'.cache';
        }
        
         * @param [inputarr]    holds the input data  to bind to
         * @return              RecordSet or false
         */
-       function &CacheExecute($secs2cache,$sql=false,$inputarr=false)
+       function CacheExecute($secs2cache,$sql=false,$inputarr=false)
        {
-
-                       
+       global $ADODB_CACHE;
+       
                if (!is_numeric($secs2cache)) {
                        $inputarr = $sql;
                        $sql = $secs2cache;
                } else
                        $sqlparam = $sql;
                        
-               if ($this->memCache) {
-                       global $ADODB_INCLUDED_MEMCACHE;
-                       if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php');
-                       $md5file = $this->_gencachename($sql.serialize($inputarr),false,true);
-               } else {
-               global $ADODB_INCLUDED_CSV;
-                       if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php');
-                       $md5file = $this->_gencachename($sql.serialize($inputarr),true);
-               }
-
+               
+               $md5file = $this->_gencachename($sql.serialize($inputarr),true);
                $err = '';
                
                if ($secs2cache > 0){
-                       if ($this->memCache)
-                               $rs = &getmemCache($md5file,$err,$secs2cache, $this->memCacheHost, $this->memCachePort);
-                       else
-                               $rs = &csv2rs($md5file,$err,$secs2cache,$this->arrayClass);
+                       $rs = $ADODB_CACHE->readcache($md5file,$err,$secs2cache,$this->arrayClass);
                        $this->numCacheHits += 1;
                } else {
                        $err='Timeout 1';
                        $rs = false;
                        $this->numCacheMisses += 1;
                }
+               
                if (!$rs) {
                // no cached rs found
                        if ($this->debug) {
                                if ($this->debug !== -1) ADOConnection::outp( " $md5file cache failure: $err (see sql below)");
                        }
                        
-                       $rs = &$this->Execute($sqlparam,$inputarr);
+                       $rs = $this->Execute($sqlparam,$inputarr);
+
+                       if ($rs) {
 
-                       if ($rs && $this->memCache) {
-                               $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately
-                               if(!putmemCache($md5file, $rs, $this->memCacheHost, $this->memCachePort, $this->memCacheCompress, $this->debug)) {
-                                       if ($fn = $this->raiseErrorFn)
-                                               $fn($this->databaseType,'CacheExecute',-32000,"Cache write error",$md5file,$sql,$this);
-                                       if ($this->debug) ADOConnection::outp( " Cache write error");
-                               }
-                       } else if ($rs) {
                                $eof = $rs->EOF;
-                               $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately
+                               $rs = $this->_rs2rs($rs); // read entire recordset into memory immediately
+                               $rs->timeCreated = time(); // used by caching
                                $txt = _rs2serialize($rs,false,$sql); // serialize
-               
-                               if (!adodb_write_file($md5file,$txt,$this->debug)) {
-                                       if ($fn = $this->raiseErrorFn) {
-                                               $fn($this->databaseType,'CacheExecute',-32000,"Cache write error",$md5file,$sql,$this);
+       
+                               $ok = $ADODB_CACHE->writecache($md5file,$txt,$this->debug, $secs2cache);
+                               if (!$ok) {
+                                       if ($ok === false) {
+                                               $em = 'Cache write error';
+                                               $en = -32000;
+                                               
+                                               if ($fn = $this->raiseErrorFn) {
+                                                       $fn($this->databaseType,'CacheExecute', $en, $em, $md5file,$sql,$this);
+                                               }
+                                       } else {
+                                               $em = 'Cache file locked warning';
+                                               $en = -32001;
+                                               // do not call error handling for just a warning
                                        }
-                                       if ($this->debug) ADOConnection::outp( " Cache write error");
+                                       
+                                       if ($this->debug) ADOConnection::outp( " ".$em);
                                }
                                if ($rs->EOF && !$eof) {
                                        $rs->MoveFirst();
-                                       //$rs = &csv2rs($md5file,$err);         
-                                       $rs->connection = &$this; // Pablo suggestion
+                                       //$rs = csv2rs($md5file,$err);          
+                                       $rs->connection = $this; // Pablo suggestion
                                }  
                                
                        } else if (!$this->memCache)
-                               @unlink($md5file);
+                               $ADODB_CACHE->flushcache($md5file);
                } else {
                        $this->_errorMsg = '';
                        $this->_errorCode = 0;
                                $fn($this, $secs2cache, $sql, $inputarr);
                        }
                // ok, set cached object found
-                       $rs->connection = &$this; // Pablo suggestion
-                       if ($this->debug){ 
-                                       
+                       $rs->connection = $this; // Pablo suggestion
+                       if ($this->debug){                      
+                               if ($this->debug == 99) adodb_backtrace();
                                $inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
                                $ttl = $rs->timeCreated + $secs2cache - time();
                                $s = is_array($sql) ? $sql[0] : $sql;
                
                $forceUpdate means that even if the data has not changed, perform update.
         */
-       function& AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false) 
+       function AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false) 
        {
                $false = false;
                $sql = 'SELECT * FROM '.$table;  
                if ($where!==FALSE) $sql .= ' WHERE '.$where;
                else if ($mode == 'UPDATE' || $mode == 2 /* DB_AUTOQUERY_UPDATE */) {
-                       ADOConnection::outp('AutoExecute: Illegal mode=UPDATE with empty WHERE clause');
+                       $this->outp_throw('AutoExecute: Illegal mode=UPDATE with empty WHERE clause','AutoExecute');
                        return $false;
                }
 
-               $rs =& $this->SelectLimit($sql,1);
+               $rs = $this->SelectLimit($sql,1);
                if (!$rs) return $false; // table does not exist
                $rs->tableName = $table;
                
                        $sql = $this->GetInsertSQL($rs, $fields_values, $magicq);
                        break;
                default:
-                       ADOConnection::outp("AutoExecute: Unknown mode=$mode");
+                       $this->outp_throw("AutoExecute: Unknown mode=$mode",'AutoExecute');
                        return $false;
                }
                $ret = false;
                if (empty($this->_metars)) {
                        $rsclass = $this->rsPrefix.$this->databaseType;
                        $this->_metars = new $rsclass(false,$this->fetchMode); 
-                       $this->_metars->connection =& $this;
+                       $this->_metars->connection = $this;
                }
                return $this->_metars->MetaType($t,$len,$fieldobj);
        }
                }
        }
 
-       function &GetActiveRecordsClass($class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false)
+       /**
+        * GetActiveRecordsClass Performs an 'ALL' query 
+        * 
+        * @param mixed $class This string represents the class of the current active record
+        * @param mixed $table Table used by the active record object
+        * @param mixed $whereOrderBy Where, order, by clauses
+        * @param mixed $bindarr 
+        * @param mixed $primkeyArr 
+        * @param array $extra Query extras: limit, offset...
+        * @param mixed $relations Associative array: table's foreign name, "hasMany", "belongsTo"
+        * @access public
+        * @return void
+        */
+       function GetActiveRecordsClass(
+                       $class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false,
+                       $extra=array(),
+                       $relations=array())
        {
        global $_ADODB_ACTIVE_DBS;
-       
-               $save = $this->SetFetchMode(ADODB_FETCH_NUM);
-               if (empty($whereOrderBy)) $whereOrderBy = '1=1';
-               $rows = $this->GetAll("select * from ".$table.' WHERE '.$whereOrderBy,$bindarr);
-               $this->SetFetchMode($save);
-               
-               $false = false;
-               
-               if ($rows === false) {  
-                       return $false;
-               }
-               
-               
-               if (!isset($_ADODB_ACTIVE_DBS)) {
-                       include(ADODB_DIR.'/adodb-active-record.inc.php');
-               }       
-               if (!class_exists($class)) {
-                       ADOConnection::outp("Unknown class $class in GetActiveRcordsClass()");
-                       return $false;
-               }
-               $arr = array();
-               foreach($rows as $row) {
-               
-                       $obj = new $class($table,$primkeyArr,$this);
-                       if ($obj->ErrorMsg()){
-                               $this->_errorMsg = $obj->ErrorMsg();
-                               return $false;
-                       }
-                       $obj->Set($row);
-                       $arr[] = $obj;
-               }
-               return $arr;
+               ## reduce overhead of adodb.inc.php -- moved to adodb-active-record.inc.php
+               ## if adodb-active-recordx is loaded -- should be no issue as they will probably use Find()
+               if (!isset($_ADODB_ACTIVE_DBS))include_once(ADODB_DIR.'/adodb-active-record.inc.php');
+               return adodb_GetActiveRecordsClass($this, $class, $table, $whereOrderBy, $bindarr, $primkeyArr, $extra, $relations);
        }
        
-       function &GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false)
+       function GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false)
        {
-               $arr =& $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr);
+               $arr = $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr);
                return $arr;
        }
        
@@ -2174,27 +2225,27 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return an array of database names.
         */
-       function MetaDatabases() 
-       {
-       global $ADODB_FETCH_MODE;
+               function MetaDatabases() 
+               {
+               global $ADODB_FETCH_MODE;
                
-               if ($this->metaDatabasesSQL) {
-                       $save = $ADODB_FETCH_MODE;
-                       $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-                       
-                       if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
+                       if ($this->metaDatabasesSQL) {
+                               $save = $ADODB_FETCH_MODE; 
+                               $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 
+                               
+                               if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
+                               
+                               $arr = $this->GetCol($this->metaDatabasesSQL);
+                               if (isset($savem)) $this->SetFetchMode($savem);
+                               $ADODB_FETCH_MODE = $save; 
                        
-                       $arr = $this->GetCol($this->metaDatabasesSQL);
-                       if (isset($savem)) $this->SetFetchMode($savem);
-                       $ADODB_FETCH_MODE = $save;
+                               return $arr;
+                       }
                        
-                       return $arr;
+                       return false;
                }
-               
-               return false;
-       }
-       
        
+               
        /**
         * @param ttype can either be 'VIEW' or 'TABLE' or false. 
         *              If false, both views and tables are returned.
@@ -2205,7 +2256,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return  array of tables for current database.
         */ 
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+       function MetaTables($ttype=false,$showSchema=false,$mask=false) 
        {
        global $ADODB_FETCH_MODE;
        
@@ -2225,7 +2276,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        $ADODB_FETCH_MODE = $save; 
                        
                        if ($rs === false) return $false;
-                       $arr =& $rs->GetArray();
+                       $arr = $rs->GetArray();
                        $arr2 = array();
                        
                        if ($hast = ($ttype && isset($arr[0][1]))) { 
@@ -2267,7 +2318,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return  array of ADOFieldObjects for current table.
         */
-       function &MetaColumns($table,$normalize=true) 
+       function MetaColumns($table,$normalize=true) 
        {
        global $ADODB_FETCH_MODE;
                
@@ -2326,7 +2377,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                  )
                )               
       */
-     function &MetaIndexes($table, $primary = false, $owner = false)
+     function MetaIndexes($table, $primary = false, $owner = false)
      {
                        $false = false;
             return $false;
@@ -2338,9 +2389,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return  array of column names for current table.
         */ 
-       function &MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */) 
+       function MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */) 
        {
-               $objarr =& $this->MetaColumns($table);
+               $objarr = $this->MetaColumns($table);
                if (!is_array($objarr)) {
                        $false = false;
                        return $false;
@@ -2384,10 +2435,14 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return  date string in database date format
         */
-       function DBDate($d)
+       function DBDate($d, $isfld=false)
        {
                if (empty($d) && $d !== 0) return 'null';
-
+               if ($isfld) return $d;
+               
+               if (is_object($d)) return $d->format($this->fmtDate);
+               
+               
                if (is_string($d) && !is_numeric($d)) {
                        if ($d === 'null' || strncmp($d,"'",1) === 0) return $d;
                        if ($this->isoDates) return "'$d'";
@@ -2421,10 +2476,12 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return  timestamp string in database timestamp format
         */
-       function DBTimeStamp($ts)
+       function DBTimeStamp($ts,$isfld=false)
        {
                if (empty($ts) && $ts !== 0) return 'null';
-
+               if ($isfld) return $ts;
+               if (is_object($ts)) return $ts->format($this->fmtTimeStamp);
+               
                # strlen(14) allows YYYYMMDDHHMMSS format
                if (!is_string($ts) || (is_numeric($ts) && strlen($ts)<14)) 
                        return adodb_date($this->fmtTimeStamp,$ts);
@@ -2442,7 +2499,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
         */
-       function UnixDate($v)
+       static function UnixDate($v)
        {
                if (is_object($v)) {
                // odbtp support
@@ -2466,7 +2523,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
         */
-       function UnixTimeStamp($v)
+       static function UnixTimeStamp($v)
        {
                if (is_object($v)) {
                // odbtp support
@@ -2552,7 +2609,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                // undo magic quotes for "
                $s = str_replace('\\"','"',$s);
                
-               if ($this->replaceQuote == "\\'")  // ' already quoted, no need to change anything
+               if ($this->replaceQuote == "\\'" || ini_get('magic_quotes_sybase'))  // ' already quoted, no need to change anything
                        return $s;
                else {// change \' to '' for sybase/mssql
                        $s = str_replace('\\\\','\\',$s);
@@ -2586,7 +2643,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                // undo magic quotes for "
                $s = str_replace('\\"','"',$s);
                
-               if ($this->replaceQuote == "\\'")  // ' already quoted, no need to change anything
+               if ($this->replaceQuote == "\\'" || ini_get('magic_quotes_sybase'))  // ' already quoted, no need to change anything
                        return "'$s'";
                else {// change \' to '' for sybase/mssql
                        $s = str_replace('\\\\','\\',$s);
@@ -2612,12 +2669,12 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        * NOTE: phpLens uses a different algorithm and does not use PageExecute().
        *
        */
-       function &PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) 
+       function PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) 
        {
                global $ADODB_INCLUDED_LIB;
                if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
-               if ($this->pageExecuteCountRows) $rs =& _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache);
-               else $rs =& _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache);
+               if ($this->pageExecuteCountRows) $rs = _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache);
+               else $rs = _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache);
                return $rs;
        }
        
@@ -2634,7 +2691,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        * @param [inputarr]     array of bind variables
        * @return               the recordset ($rs->databaseType == 'array')
        */
-       function &CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) 
+       function CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) 
        {
                /*switch($this->dataProvider) {
                case 'postgres':
@@ -2642,7 +2699,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        break;
                default: $secs2cache = 0; break;
                }*/
-               $rs =& $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache);
+               $rs = $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache);
                return $rs;
        }
 
@@ -2664,10 +2721,54 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        // CLASS ADORecordSet_empty
        //==============================================================================================        
        
+       class ADODB_Iterator_empty implements Iterator {
+       
+           private $rs;
+       
+           function __construct($rs) 
+               {
+               $this->rs = $rs;
+           }
+           function rewind() 
+               {
+           }
+       
+               function valid() 
+               {
+               return !$this->rs->EOF;
+           }
+               
+           function key() 
+               {
+               return false;
+           }
+               
+           function current() 
+               {
+               return false;
+           }
+               
+           function next() 
+               {
+           }
+               
+               function __call($func, $params)
+               {
+                       return call_user_func_array(array($this->rs, $func), $params);
+               }
+               
+               function hasMore()
+               {
+                       return false;
+               }
+       
+       }
+
+       
        /**
        * Lightweight recordset when there are no records to be returned
        */
-       class ADORecordSet_empty
+       class ADORecordSet_empty implements IteratorAggregate
        {
                var $dataProvider = 'empty';
                var $databaseType = false;
@@ -2682,6 +2783,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                function FetchRow() {return false;}
                function FieldCount(){ return 0;}
                function Init() {}
+               function getIterator() {return new ADODB_Iterator_empty($this);}
        }
        
        //==============================================================================================        
@@ -2693,15 +2795,61 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        // CLASS ADORecordSet
        //==============================================================================================        
 
-       if (PHP_VERSION < 5) include_once(ADODB_DIR.'/adodb-php4.inc.php');
-       else include_once(ADODB_DIR.'/adodb-iterator.inc.php');
+       class ADODB_Iterator implements Iterator {
+       
+           private $rs;
+       
+           function __construct($rs) 
+               {
+               $this->rs = $rs;
+           }
+           function rewind() 
+               {
+               $this->rs->MoveFirst();
+           }
+       
+               function valid() 
+               {
+               return !$this->rs->EOF;
+           }
+               
+           function key() 
+               {
+               return $this->rs->_currentRow;
+           }
+               
+           function current() 
+               {
+               return $this->rs->fields;
+           }
+               
+           function next() 
+               {
+               $this->rs->MoveNext();
+           }
+               
+               function __call($func, $params)
+               {
+                       return call_user_func_array(array($this->rs, $func), $params);
+               }
+       
+               
+               function hasMore()
+               {
+                       return !$this->rs->EOF;
+               }
+       
+       }
+
+
+
    /**
         * RecordSet class that represents the dataset returned by the database.
         * To keep memory overhead low, this class holds only the current row in memory.
         * No prefetching of data is done, so the RecordCount() can return -1 ( which
         * means recordcount not known).
         */
-       class ADORecordSet extends ADODB_BASE_RS {
+       class ADORecordSet implements IteratorAggregate {
        /*
         * public variables     
         */
@@ -2751,6 +2899,17 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                $this->_queryID = $queryID;
        }
        
+       function getIterator() 
+       {
+        return new ADODB_Iterator($this);
+    }
+       
+       /* this is experimental - i don't really know what to return... */
+       function __toString()
+       {
+               include_once(ADODB_DIR.'/toexport.inc.php');
+               return _adodb_export($this,',',',',false,true);
+       }
        
        
        function Init()
@@ -2837,13 +2996,12 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return an array indexed by the rows (0-based) from the recordset
         */
-       function &GetArray($nRows = -1) 
+       function GetArray($nRows = -1) 
        {
-       global $ADODB_EXTENSION;
-               if ($ADODB_EXTENSION) {
-                       $results = adodb_getall($this,$nRows);
-                       return $results;
-               }
+       global $ADODB_EXTENSION; if ($ADODB_EXTENSION) {
+               $results = adodb_getall($this,$nRows);
+               return $results;
+       }
                $results = array();
                $cnt = 0;
                while (!$this->EOF && $nRows != $cnt) {
@@ -2854,9 +3012,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                return $results;
        }
        
-       function &GetAll($nRows = -1)
+       function GetAll($nRows = -1)
        {
-               $arr =& $this->GetArray($nRows);
+               $arr = $this->GetArray($nRows);
                return $arr;
        }
        
@@ -2878,10 +3036,10 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return an array indexed by the rows (0-based) from the recordset
         */
-       function &GetArrayLimit($nrows,$offset=-1) 
+       function GetArrayLimit($nrows,$offset=-1) 
        {       
                if ($offset <= 0) {
-                       $arr =& $this->GetArray($nrows);
+                       $arr = $this->GetArray($nrows);
                        return $arr;
                } 
                
@@ -2905,9 +3063,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return an array indexed by the rows (0-based) from the recordset
         */
-       function &GetRows($nRows = -1) 
+       function GetRows($nRows = -1) 
        {
-               $arr =& $this->GetArray($nRows);
+               $arr = $this->GetArray($nRows);
                return $arr;
        }
        
@@ -2927,7 +3085,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         * @return an associative array indexed by the first column of the array, 
         *      or false if the  data has less than 2 cols.
         */
-       function &GetAssoc($force_array = false, $first2cols = false) 
+       function GetAssoc($force_array = false, $first2cols = false) 
        {
        global $ADODB_EXTENSION;
        
@@ -3018,7 +3176,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        }
                }
                
-               $ref =& $results; # workaround accelerator incompat with PHP 4.4 :(
+               $ref = $results; # workaround accelerator incompat with PHP 4.4 :(
                return $ref; 
        }
        
@@ -3064,7 +3222,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
         */
-       function UnixDate($v)
+       static function UnixDate($v)
        {
                return ADOConnection::UnixDate($v);
        }
@@ -3075,7 +3233,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
         */
-       function UnixTimeStamp($v)
+       static function UnixTimeStamp($v)
        {
                return ADOConnection::UnixTimeStamp($v);
        }
@@ -3113,7 +3271,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        *
        * @return false or array containing the current record
        */
-       function &FetchRow()
+       function FetchRow()
        {
                if ($this->EOF) {
                        $false = false;
@@ -3277,7 +3435,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
    *
    * $upper  0 = lowercase, 1 = uppercase, 2 = whatever is returned by FetchField
    */
-       function &GetRowAssoc($upper=1)
+       function GetRowAssoc($upper=1)
        {
                $record = array();
         //     if (!$this->fields) return $record;
@@ -3351,7 +3509,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                if ($lnumrows == -1 && $this->connection) {
                        IF ($table) {
                                if ($condition) $condition = " WHERE " . $condition; 
-                               $resultrows = &$this->connection->Execute("SELECT COUNT(*) FROM $table $condition");
+                               $resultrows = $this->connection->Execute("SELECT COUNT(*) FROM $table $condition");
                                if ($resultrows) $lnumrows = reset($resultrows->fields);
                        }
                }
@@ -3385,7 +3543,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return the ADOFieldObject for that column, or false.
         */
-       function &FetchField($fieldoffset = -1) 
+       function FetchField($fieldoffset = -1) 
        {
                // must be defined by child class
                
@@ -3397,7 +3555,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         * Get the ADOFieldObjects of all columns in an array.
         *
         */
-       function& FieldTypesArray()
+       function FieldTypesArray()
        {
                $arr = array();
                for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) 
@@ -3411,9 +3569,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        *
        * @return the object with the properties set to the fields of the current row
        */
-       function &FetchObj()
+       function FetchObj()
        {
-               $o =& $this->FetchObject(false);
+               $o = $this->FetchObject(false);
                return $o;
        }
        
@@ -3425,7 +3583,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        *
        * @return the object with the properties set to the fields of the current row
        */
-       function &FetchObject($isupper=true)
+       function FetchObject($isupper=true)
        {
                if (empty($this->_obj)) {
                        $this->_obj = new ADOFetchObj();
@@ -3458,9 +3616,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        *
        * Fixed bug reported by tim@orotech.net
        */
-       function &FetchNextObj()
+       function FetchNextObj()
        {
-               $o =& $this->FetchNextObject(false);
+               $o = $this->FetchNextObject(false);
                return $o;
        }
        
@@ -3476,7 +3634,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        *
        * Fixed bug reported by tim@orotech.net
        */
-       function &FetchNextObject($isupper=true)
+       function FetchNextObject($isupper=true)
        {
                $o = false;
                if ($this->_numOfRows != 0 && !$this->EOF) {
@@ -3533,6 +3691,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                'CHARACTER' => 'C',
                'INTERVAL' => 'C',  # Postgres
                'MACADDR' => 'C', # postgres
+               'VAR_STRING' => 'C', # mysql
                ##
                'LONGCHAR' => 'X',
                'TEXT' => 'X',
@@ -3556,6 +3715,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                ##
                'UNIQUEIDENTIFIER' => 'C', # MS SQL Server
                ##
+               'SMALLDATETIME' => 'T',
                'TIME' => 'T',
                'TIMESTAMP' => 'T',
                'DATETIME' => 'T',
@@ -3747,7 +3907,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        //adodb_pr($newarr);
                        
                        $this->_skiprow1 = false;
-                       $this->_array =& $newarr;
+                       $this->_array = $newarr;
                        $this->_colnames = $hdr;
                        
                        adodb_probetypes($newarr,$this->_types);
@@ -3801,20 +3961,20 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                 */
                function InitArrayFields(&$array,&$fieldarr)
                {
-                       $this->_array =& $array;
+                       $this->_array = $array;
                        $this->_skiprow1= false;
                        if ($fieldarr) {
-                               $this->_fieldobjects =& $fieldarr;
+                               $this->_fieldobjects = $fieldarr;
                        } 
                        $this->Init();
                }
                
-               function &GetArray($nRows=-1)
+               function GetArray($nRows=-1)
                {
                        if ($nRows == -1 && $this->_currentRow <= 0 && !$this->_skiprow1) {
                                return $this->_array;
                        } else {
-                               $arr =& ADORecordSet::GetArray($nRows);
+                               $arr = ADORecordSet::GetArray($nRows);
                                return $arr;
                        }
                }
@@ -3834,7 +3994,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        $mode = isset($this->adodbFetchMode) ? $this->adodbFetchMode : $this->fetchMode;
                        
                        if ($mode & ADODB_FETCH_ASSOC) {
-                               if (!isset($this->fields[$colname])) $colname = strtolower($colname);
+                               if (!isset($this->fields[$colname]) && !is_null($this->fields[$colname])) $colname = strtolower($colname);
                                return $this->fields[$colname];
                        }
                        if (!$this->bind) {
@@ -3847,7 +4007,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        return $this->fields[$this->bind[strtoupper($colname)]];
                }
                
-               function &FetchField($fieldOffset = -1) 
+               function FetchField($fieldOffset = -1) 
                {
                        if (isset($this->_fieldobjects)) {
                                return $this->_fieldobjects[$fieldOffset];
@@ -3962,9 +4122,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        /**
         * synonym for ADONewConnection for people like me who cannot remember the correct name
         */
-       function &NewADOConnection($db='')
+       function NewADOConnection($db='')
        {
-               $tmp =& ADONewConnection($db);
+               $tmp = ADONewConnection($db);
                return $tmp;
        }
        
@@ -3976,38 +4136,42 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return the freshly created instance of the Connection class.
         */
-       function &ADONewConnection($db='')
+       function ADONewConnection($db='')
        {
        GLOBAL $ADODB_NEWCONNECTION, $ADODB_LASTDB;
                
                if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
                $errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false;
                $false = false;
-               if ($at = strpos($db,'://')) {
+               if (($at = strpos($db,'://')) !== FALSE) {
                        $origdsn = $db;
-                       if (PHP_VERSION < 5) $dsna = @parse_url($db);
-                       else {
-                               $fakedsn = 'fake'.substr($db,$at);
+                       $fakedsn = 'fake'.substr($origdsn,$at);
+                       if (($at2 = strpos($origdsn,'@/')) !== FALSE) {
+                               // special handling of oracle, which might not have host
+                               $fakedsn = str_replace('@/','@adodb-fakehost/',$fakedsn);
+                       }
                                $dsna = @parse_url($fakedsn);
-                               $dsna['scheme'] = substr($db,0,$at);
+                       if (!$dsna) {
+                               return $false;
+                       }
+                               $dsna['scheme'] = substr($origdsn,0,$at);
+                       if ($at2 !== FALSE) {
+                               $dsna['host'] = '';
+                       }
                        
-                               if (strncmp($db,'pdo',3) == 0) {
-                                       $sch = explode('_',$dsna['scheme']);
-                                       if (sizeof($sch)>1) {
-                                               $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
+                       if (strncmp($origdsn,'pdo',3) == 0) {
+                               $sch = explode('_',$dsna['scheme']);
+                               if (sizeof($sch)>1) {
+                               
+                                       $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
+                                       if ($sch[1] == 'sqlite')
+                                               $dsna['host'] = rawurlencode($sch[1].':'.rawurldecode($dsna['host']));
+                                       else
                                                $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host']));
-                                               $dsna['scheme'] = 'pdo';
-                                       }
+                                       $dsna['scheme'] = 'pdo';
                                }
                        }
                        
-                       if (!$dsna) {
-                               // special handling of oracle, which might not have host
-                               $db = str_replace('@/','@adodb-fakehost/',$db);
-                               $dsna = parse_url($db);
-                               if (!$dsna) return $false;
-                               $dsna['host'] = '';
-                       }
                        $db = @$dsna['scheme'];
                        if (!$db) return $false;
                        $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
@@ -4035,7 +4199,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                if (!empty($ADODB_NEWCONNECTION)) {
                        $obj = $ADODB_NEWCONNECTION($db);
 
-               } else {
+               } 
+               
+               if(empty($obj)) {
                
                        if (!isset($ADODB_LASTDB)) $ADODB_LASTDB = '';
                        if (empty($db)) $db = $ADODB_LASTDB;
@@ -4072,7 +4238,8 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                                if (isset($dsna['port'])) $obj->port = $dsna['port'];
                                foreach($opt as $k => $v) {
                                        switch(strtolower($k)) {
-                                       case 'new':             $nconnect = true; $persist = true; break;
+                                       case 'new':
+                                                                               $nconnect = true; $persist = true; break;
                                        case 'persist':
                                        case 'persistent':      $persist = $v; break;
                                        case 'debug':           $obj->debug = (integer) $v; break;
@@ -4092,6 +4259,18 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                                        case 'socket': $obj->socket = $v; break;
                                        #oci8
                                        case 'nls_date_format': $obj->NLS_DATE_FORMAT = $v; break;
+                                       case 'cachesecs': $obj->cacheSecs = $v; break;
+                                       case 'memcache': 
+                                               $varr = explode(':',$v);
+                                               $vlen = sizeof($varr);
+                                               if ($vlen == 0) break;  
+                                               $obj->memCache = true;
+                                               $obj->memCacheHost = explode(',',$varr[0]);
+                                               if ($vlen == 1) break;  
+                                               $obj->memCachePort = $varr[1];
+                                               if ($vlen == 2) break;  
+                                               $obj->memCacheCompress = $varr[2] ?  true : false;
+                                               break;
                                        }
                                }
                                if (empty($persist))
@@ -4142,7 +4321,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                return $drivername;
        }
        
-       function &NewPerfMonitor(&$conn)
+       function NewPerfMonitor(&$conn)
        {
                $false = false;
                $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType,true);
@@ -4156,7 +4335,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                return $perf;
        }
        
-       function &NewDataDictionary(&$conn,$drivername=false)
+       function NewDataDictionary(&$conn,$drivername=false)
        {
                $false = false;
                if (!$drivername) $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType);
@@ -4173,7 +4352,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                $class = "ADODB2_$drivername";
                $dict = new $class();
                $dict->dataProvider = $conn->dataProvider;
-               $dict->connection = &$conn;
+               $dict->connection = $conn;
                $dict->upperName = strtoupper($drivername);
                $dict->quote = $conn->nameQuote;
                if (!empty($conn->_connectionID))
@@ -4209,13 +4388,13 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                @param printOrArr  Pass in a boolean to indicate print, or an $exception->trace array (assumes that print is true then).
                @param levels Number of levels to display
        */
-       function adodb_backtrace($printOrArr=true,$levels=9999)
+       function adodb_backtrace($printOrArr=true,$levels=9999,$ishtml=null)
        {
                global $ADODB_INCLUDED_LIB;
                if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
-               return _adodb_backtrace($printOrArr,$levels);
+               return _adodb_backtrace($printOrArr,$levels,0,$ishtml);
        }
 
 
 }
-?>
+?>
\ No newline at end of file
index 5e8ce48e05b40f1c4b686e8fafabb997ff83cf00..491e4ccdb87bd9c6a65c19f3838b5cc66edadfae 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
- V4.94 23 Jan 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.09 25 June 2009   (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
index 0135a20a5579f2f6de0c9b4b28a5418c932cddab..1444d02dc73d0078a3cc9fa0d5225a963f63695c 100644 (file)
@@ -1,8 +1,6 @@
 <?php
 /*
- Modified by phpPgAdmin team: functions _connect and _decode
-
- V4.94 23 Jan 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.09 25 June 2009   (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
@@ -106,7 +104,8 @@ WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
        var $random = 'random()';               /// random function
        var $autoRollback = true; // apparently pgsql does not autorollback properly before php 4.3.4
                                                        // http://bugs.php.net/bug.php?id=25404
-                                                       
+       
+       var $uniqueIisR = true;
        var $_bindInputArray = false; // requires postgresql 7.3+ and ability to modify database
        var $disableBlobs = false; // set to true to disable blob checking, resulting in 2-5% improvement in performance.
        
@@ -203,7 +202,7 @@ a different OID if a database must be reloaded. */
                return @pg_Exec($this->_connectionID, "rollback");
        }
        
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+       function MetaTables($ttype=false,$showSchema=false,$mask=false) 
        {
                $info = $this->ServerInfo();
                if ($info['version'] >= 7.3) {
@@ -226,7 +225,7 @@ select tablename,'T' from pg_tables where tablename like $mask
  union 
 select viewname,'V' from pg_views where viewname like $mask";
                }
-               $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+               $ret = ADOConnection::MetaTables($ttype,$showSchema);
                
                if ($mask) {
                        $this->metaTablesSQL = $save;
@@ -238,10 +237,12 @@ select viewname,'V' from pg_views where viewname like $mask";
        // if magic quotes disabled, use pg_escape_string()
        function qstr($s,$magic_quotes=false)
        {
+               if (is_bool($s)) return $s ? 'true' : 'false';
+                
                if (!$magic_quotes) {
                        if (ADODB_PHPVER >= 0x5200) {
                                return  "'".pg_escape_string($this->_connectionID,$s)."'";
-                       }
+                       } 
                        if (ADODB_PHPVER >= 0x4200) {
                                return  "'".pg_escape_string($s)."'";
                        }
@@ -318,7 +319,7 @@ select viewname,'V' from pg_views where viewname like $mask";
                                $s .= 'DAY';
                                break;
                        
-                       case 'W':
+                        case 'W':
                                $s .= 'WW';
                                break;
 
@@ -459,14 +460,17 @@ select viewname,'V' from pg_views where viewname like $mask";
                        if (10 <= $len && $len <= 12) $date = 'date '.$date;
                        else $date = 'timestamp '.$date;
                }
-               return "($date+interval'$dayFraction days')";
+               
+               
+               return "($date+interval'".($dayFraction * 1440)." minutes')";
+               #return "($date+interval'$dayFraction days')";
        }
        
 
        // for schema support, pass in the $table param "$schema.$tabname".
        // converts field names to lowercase, $upper is ignored
        // see http://phplens.com/lens/lensforum/msgs.php?id=14018 for more info
-       function &MetaColumns($table,$normalize=true) 
+       function MetaColumns($table,$normalize=true) 
        {
        global $ADODB_FETCH_MODE;
        
@@ -480,8 +484,8 @@ select viewname,'V' from pg_views where viewname like $mask";
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
                if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
                
-               if ($schema) $rs =& $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
-               else $rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
+               if ($schema) $rs = $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
+               else $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
                if (isset($savem)) $this->SetFetchMode($savem);
                $ADODB_FETCH_MODE = $save;
                
@@ -498,7 +502,7 @@ select viewname,'V' from pg_views where viewname like $mask";
                        
                        $rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
                        // fetch all result in once for performance.
-                       $keys =& $rskey->GetArray();
+                       $keys = $rskey->GetArray();
                        if (isset($savem)) $this->SetFetchMode($savem);
                        $ADODB_FETCH_MODE = $save;
                        
@@ -556,6 +560,7 @@ select viewname,'V' from pg_views where viewname like $mask";
                        //Freek
                        $fld->not_null = $rs->fields[4] == 't';
                        
+                       
                        // Freek
                        if (is_array($keys)) {
                                foreach($keys as $key) {
@@ -573,13 +578,13 @@ select viewname,'V' from pg_views where viewname like $mask";
                }
                $rs->Close();
                if (empty($retarr))
-                       return $false;
+                       return  $false;
                else
                        return $retarr; 
                
        }
 
-         function &MetaIndexes ($table, $primary = FALSE)
+         function MetaIndexes ($table, $primary = FALSE)
       {
          global $ADODB_FETCH_MODE;
                 
@@ -621,7 +626,7 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
 
                 if (!is_object($rs)) {
                        $false = false;
-                       return $false;
+                                       return $false;
                 }
                                
                 $col_names = $this->MetaColumnNames($table,true,true); 
@@ -665,18 +670,16 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
                                else $str = '';
                                if (isset($host[1])) $str .= " port=$host[1]";
                                else if (!empty($this->port)) $str .= " port=".$this->port;
-                               if (isset($host[2])) $str .= " sslmode=".adodb_addslashes($host[2]);
-                               else if (!empty($this->sslmode)) $str .= " sslmode=".$this->sslmode;
                        }
-                       if ($user) $str .= " user=".$user;
-                       if ($pwd)  $str .= " password=".$pwd;
-                       if ($db)   $str .= " dbname=".$db;
+                               if ($user) $str .= " user=".$user;
+                               if ($pwd)  $str .= " password=".$pwd;
+                               if ($db)   $str .= " dbname=".$db;
                }
 
                //if ($user) $linea = "user=$user host=$linea password=$pwd dbname=$db port=5432";
                
                if ($ctype === 1) { // persistent
-                       $this->_connectionID = @pg_pconnect($str);
+                       $this->_connectionID = pg_pconnect($str);
                } else {
                        if ($ctype === -1) { // nconnect, we trick pgsql ext by changing the connection str
                        static $ncnt;
@@ -686,7 +689,7 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
                                
                                $str .= str_repeat(' ',$ncnt);
                        }
-                       $this->_connectionID = @pg_connect($str);
+                       $this->_connectionID = pg_connect($str);
                }
                if ($this->_connectionID === false) return false;
                $this->Execute("set datestyle='ISO'");
@@ -716,7 +719,7 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
        
 
        // returns queryID or false
-       function _query($sql,$inputarr)
+       function _query($sql,$inputarr=false)
        {
                $this->_errorMsg = false;
                if ($inputarr) {
@@ -748,6 +751,7 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
                        if ($execp) $exsql = "EXECUTE $plan ($execp)";
                        else $exsql = "EXECUTE $plan";
                        
+                       
                        $rez = @pg_exec($this->_connectionID,$exsql);
                        if (!$rez) {
                        # Perhaps plan does not exist? Prepare/compile plan.
@@ -824,8 +828,8 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
                $e = $this->ErrorMsg();
                if (strlen($e)) {
                        return ADOConnection::MetaError($e);
-               }
-               return 0;
+                }
+                return 0;
        }
 
        // returns true or false
@@ -888,10 +892,10 @@ class ADORecordSet_postgres64 extends ADORecordSet{
                $this->ADORecordSet($queryID);
        }
        
-       function &GetRowAssoc($upper=true)
+       function GetRowAssoc($upper=true)
        {
                if ($this->fetchMode == PGSQL_ASSOC && !$upper) return $this->fields;
-               $row =& ADORecordSet::GetRowAssoc($upper);
+               $row = ADORecordSet::GetRowAssoc($upper);
                return $row;
        }
 
@@ -927,7 +931,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
                 return $this->fields[$this->bind[strtoupper($colname)]];
        }
 
-       function &FetchField($off = 0) 
+       function FetchField($off = 0) 
        {
                // offsets begin at 0
                
@@ -945,8 +949,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
        
        function _decode($blob)
        {
-               if (is_null($blob))
-                       return NULL;
+               if ($blob === NULL) return NULL;
                eval('$realblob="'.adodb_str_replace(array('"','$'),array('\"','\$'),$blob).'";');
                return $realblob;       
        }
@@ -987,7 +990,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
        {
                                
                if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0)
-                       return false;
+               return false;
 
                $this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
                
@@ -1038,6 +1041,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
                                case 'DATE':
                                        return 'D';
                                
+                               
                                case 'TIMESTAMP WITHOUT TIME ZONE':
                                case 'TIME':
                                case 'DATETIME':
@@ -1052,7 +1056,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
                                case 'INT4':
                                case 'INT2':
                                        if (isset($fieldobj) &&
-                               empty($fieldobj->primary_key) && empty($fieldobj->unique)) return 'I';
+                               empty($fieldobj->primary_key) && (!$this->uniqueIisR || empty($fieldobj->unique))) return 'I';
                                
                                case 'OID':
                                case 'SERIAL':
@@ -1064,4 +1068,4 @@ class ADORecordSet_postgres64 extends ADORecordSet{
        }
 
 }
-?>
+?>
\ No newline at end of file
index 5c3d7bb63ba7457b7a1dab70bc3452da0336305a..191ee360881510a46ff63395ab76ee830bede08a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
- V4.94 23 Jan 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.09 25 June 2009   (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
@@ -34,14 +34,14 @@ class ADODB_postgres7 extends ADODB_postgres64 {
        
        // the following should be compat with postgresql 7.2, 
        // which makes obsolete the LIMIT limit,offset syntax
-        function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 
+        function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 
         {
                 $offsetStr = ($offset >= 0) ? " OFFSET ".((integer)$offset) : '';
                 $limitStr  = ($nrows >= 0)  ? " LIMIT ".((integer)$nrows) : '';
                 if ($secs2cache)
-                       $rs =& $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
+                       $rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
                 else
-                       $rs =& $this->Execute($sql."$limitStr$offsetStr",$inputarr);
+                       $rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr);
                
                return $rs;
         }
@@ -56,9 +56,58 @@ class ADODB_postgres7 extends ADODB_postgres64 {
        }
        */
 
-
-       // from  Edward Jaramilla, improved version - works on pg 7.4
+       /*
+               I discovered that the MetaForeignKeys method no longer worked for Postgres 8.3.
+               I went ahead and modified it to work for both 8.2 and 8.3. 
+               Please feel free to include this change in your next release of adodb.
+                William Kolodny [William.Kolodny#gt-t.net]
+       */
        function MetaForeignKeys($table, $owner=false, $upper=false)
+       {
+         $sql="
+         SELECT fum.ftblname AS lookup_table, split_part(fum.rf, ')'::text, 1) AS lookup_field,
+            fum.ltable AS dep_table, split_part(fum.lf, ')'::text, 1) AS dep_field
+         FROM (
+         SELECT fee.ltable, fee.ftblname, fee.consrc, split_part(fee.consrc,'('::text, 2) AS lf, 
+           split_part(fee.consrc, '('::text, 3) AS rf
+         FROM (
+             SELECT foo.relname AS ltable, foo.ftblname,
+                 pg_get_constraintdef(foo.oid) AS consrc
+             FROM (
+                 SELECT c.oid, c.conname AS name, t.relname, ft.relname AS ftblname
+                 FROM pg_constraint c 
+                 JOIN pg_class t ON (t.oid = c.conrelid) 
+                 JOIN pg_class ft ON (ft.oid = c.confrelid)
+                 JOIN pg_namespace nft ON (nft.oid = ft.relnamespace)
+                 LEFT JOIN pg_description ds ON (ds.objoid = c.oid)
+                 JOIN pg_namespace n ON (n.oid = t.relnamespace)
+                 WHERE c.contype = 'f'::\"char\"
+                 ORDER BY t.relname, n.nspname, c.conname, c.oid
+                 ) foo
+             ) fee) fum
+         WHERE fum.ltable='".strtolower($table)."'
+         ORDER BY fum.ftblname, fum.ltable, split_part(fum.lf, ')'::text, 1)
+         ";
+         $rs = $this->Execute($sql);
+       
+         if (!$rs || $rs->EOF) return false;
+       
+         $a = array();
+         while (!$rs->EOF) {
+           if ($upper) {
+             $a[strtoupper($rs->Fields('lookup_table'))][] = strtoupper(str_replace('"','',$rs->Fields('dep_field').'='.$rs->Fields('lookup_field')));
+           } else {
+             $a[$rs->Fields('lookup_table')][] = str_replace('"','',$rs->Fields('dep_field').'='.$rs->Fields('lookup_field'));
+           }
+               $rs->MoveNext();
+         }
+       
+         return $a;
+       
+       }
+       
+       // from  Edward Jaramilla, improved version - works on pg 7.4
+       function _old_MetaForeignKeys($table, $owner=false, $upper=false)
        {
                $sql = 'SELECT t.tgargs as args
                FROM
@@ -72,11 +121,11 @@ class ADODB_postgres7 extends ADODB_postgres64 {
                ORDER BY
                        t.tgrelid';
                
-               $rs =& $this->Execute($sql);
+               $rs = $this->Execute($sql);
                
                if (!$rs || $rs->EOF) return false;
                
-               $arr =& $rs->GetArray();
+               $arr = $rs->GetArray();
                $a = array();
                foreach($arr as $v) {
                        $data = explode(chr(0), $v['args']);
@@ -91,7 +140,7 @@ class ADODB_postgres7 extends ADODB_postgres64 {
                return $a;
        }
 
-       function _query($sql,$inputarr)
+       function _query($sql,$inputarr=false)
        {
                if (! $this->_bindInputArray) {
                        // We don't have native support for parameterized queries, so let's emulate it at the parent
index f3712a3947a45954bd4e2befd8663c71cdfb5eee..05a705eb8b252383af8aaf4578d1de500cd3124d 100755 (executable)
@@ -1,6 +1,6 @@
 <?php
 /*
- V4.94 23 Jan 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.09 25 June 2009   (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
index dd0f830f17796d505d176322bdf6c7e634bbcc87..4b7509527c2fc22d7111b33cafe2074699f712c3 100755 (executable)
@@ -30,5 +30,4 @@ $ADODB_LANG_ARRAY = array (
            DB_ERROR_NOSUCHDB           => 'áíÓ åäÇáß ÞÇÚÏÉ ÈíÇäÇÊ ÈåÐÇ ÇáÇÓã',
            DB_ERROR_ACCESS_VIOLATION   => 'ÓãÇÍíÇÊ ÛíÑ ßÇÝíÉ'
 );
-?>
-               
+?>
\ No newline at end of file
index 4fb1dc070ac6864f29a77bab62f6a0f8989899da..ee307c13fed9ca14443cb56f762d92cd1c0ab70c 100755 (executable)
@@ -34,5 +34,4 @@ $ADODB_LANG_ARRAY = array (
             DB_ERROR_NOSUCHDB           => 'íåñúùåñòâóâàùà áàçà äàííè',
             DB_ERROR_ACCESS_VIOLATION   => 'íÿìàòå äîñòàòú÷íî ïðàâà'
 );
-?>
-               
\ No newline at end of file
+?>
\ No newline at end of file
index 6f3a4173353df265235c88ca04cd933df8f63ce5..5281ed53b6513bd16e4bdb91bf73fcaa72e270ef 100755 (executable)
@@ -34,5 +34,4 @@ $ADODB_LANG_ARRAY = array (
             DB_ERROR_NOSUCHDB           => 'несъществуваща база данни',
             DB_ERROR_ACCESS_VIOLATION   => 'нямате достатъчно права'
 );
-?>
-               
\ No newline at end of file
+?>
\ No newline at end of file
index 3e6a4496bd30eb5570d60ada02fa2ed143cab2ff..3640ebd0bbb956f6e7bc657c75c40ace97457484 100755 (executable)
@@ -1,35 +1,34 @@
-<?php\r
-// Catalan language\r
-// contributed by "Josep Lladonosa" jlladono#pie.xtec.es\r
-$ADODB_LANG_ARRAY = array (\r
-                       'LANG'                      => 'ca',\r
-            DB_ERROR                    => 'error desconegut',\r
-            DB_ERROR_ALREADY_EXISTS     => 'ja existeix',\r
-            DB_ERROR_CANNOT_CREATE      => 'no es pot crear',\r
-            DB_ERROR_CANNOT_DELETE      => 'no es pot esborrar',\r
-            DB_ERROR_CANNOT_DROP        => 'no es pot eliminar',\r
-            DB_ERROR_CONSTRAINT         => 'violació de constraint',\r
-            DB_ERROR_DIVZERO            => 'divisió per zero',\r
-            DB_ERROR_INVALID            => 'no és vàlid',\r
-            DB_ERROR_INVALID_DATE       => 'la data o l\'hora no són vàlides',\r
-            DB_ERROR_INVALID_NUMBER     => 'el nombre no és vàlid',\r
-            DB_ERROR_MISMATCH           => 'no hi ha coincidència',\r
-            DB_ERROR_NODBSELECTED       => 'cap base de dades seleccionada',\r
-            DB_ERROR_NOSUCHFIELD        => 'camp inexistent',\r
-            DB_ERROR_NOSUCHTABLE        => 'taula inexistent',\r
-            DB_ERROR_NOT_CAPABLE        => 'l\'execució secundària de DB no pot',\r
-            DB_ERROR_NOT_FOUND          => 'no trobat',\r
-            DB_ERROR_NOT_LOCKED         => 'no blocat',\r
-            DB_ERROR_SYNTAX             => 'error de sintaxi',\r
-            DB_ERROR_UNSUPPORTED        => 'no suportat',\r
-            DB_ERROR_VALUE_COUNT_ON_ROW => 'el nombre de columnes no coincideix amb el nombre de valors en la fila',\r
-            DB_ERROR_INVALID_DSN        => 'el DSN no és vàlid',\r
-            DB_ERROR_CONNECT_FAILED     => 'connexió fallida',\r
-            0                         => 'cap error', // DB_OK\r
-            DB_ERROR_NEED_MORE_DATA     => 'les dades subministrades són insuficients',\r
-            DB_ERROR_EXTENSION_NOT_FOUND=> 'extensió no trobada',\r
-            DB_ERROR_NOSUCHDB           => 'base de dades inexistent',\r
-            DB_ERROR_ACCESS_VIOLATION   => 'permisos insuficients'\r
-);\r
-?>\r
-               
\ No newline at end of file
+<?php
+// Catalan language
+// contributed by "Josep Lladonosa" jlladono#pie.xtec.es
+$ADODB_LANG_ARRAY = array (
+                       'LANG'                      => 'ca',
+            DB_ERROR                    => 'error desconegut',
+            DB_ERROR_ALREADY_EXISTS     => 'ja existeix',
+            DB_ERROR_CANNOT_CREATE      => 'no es pot crear',
+            DB_ERROR_CANNOT_DELETE      => 'no es pot esborrar',
+            DB_ERROR_CANNOT_DROP        => 'no es pot eliminar',
+            DB_ERROR_CONSTRAINT         => 'violació de constraint',
+            DB_ERROR_DIVZERO            => 'divisió per zero',
+            DB_ERROR_INVALID            => 'no és vàlid',
+            DB_ERROR_INVALID_DATE       => 'la data o l\'hora no són vàlides',
+            DB_ERROR_INVALID_NUMBER     => 'el nombre no és vàlid',
+            DB_ERROR_MISMATCH           => 'no hi ha coincidència',
+            DB_ERROR_NODBSELECTED       => 'cap base de dades seleccionada',
+            DB_ERROR_NOSUCHFIELD        => 'camp inexistent',
+            DB_ERROR_NOSUCHTABLE        => 'taula inexistent',
+            DB_ERROR_NOT_CAPABLE        => 'l\'execució secundària de DB no pot',
+            DB_ERROR_NOT_FOUND          => 'no trobat',
+            DB_ERROR_NOT_LOCKED         => 'no blocat',
+            DB_ERROR_SYNTAX             => 'error de sintaxi',
+            DB_ERROR_UNSUPPORTED        => 'no suportat',
+            DB_ERROR_VALUE_COUNT_ON_ROW => 'el nombre de columnes no coincideix amb el nombre de valors en la fila',
+            DB_ERROR_INVALID_DSN        => 'el DSN no és vàlid',
+            DB_ERROR_CONNECT_FAILED     => 'connexió fallida',
+            0                         => 'cap error', // DB_OK
+            DB_ERROR_NEED_MORE_DATA     => 'les dades subministrades són insuficients',
+            DB_ERROR_EXTENSION_NOT_FOUND=> 'extensió no trobada',
+            DB_ERROR_NOSUCHDB           => 'base de dades inexistent',
+            DB_ERROR_ACCESS_VIOLATION   => 'permisos insuficients'
+);
+?>
\ No newline at end of file
index ed1b8f19a869c998b9e43f0c0690865e26505935..6895995effd494b70d7025dc91f3c856c19c25b8 100755 (executable)
@@ -30,5 +30,4 @@ $ADODB_LANG_ARRAY = array (
             DB_ERROR_NOSUCHDB           => 'no such database',
             DB_ERROR_ACCESS_VIOLATION   => 'insufficient permissions'
 );
-?>
-               
\ No newline at end of file
+?>
\ No newline at end of file
index aee5bfdfdc00c26c6cb95bd532132620618c3361..9d9e390676234410849276fbff74b190f9733684 100755 (executable)
@@ -32,5 +32,4 @@ $ADODB_LANG_ARRAY = array (
             DB_ERROR_NOSUCHDB           => 'nie znaleziono bazy',
             DB_ERROR_ACCESS_VIOLATION   => 'niedostateczne uprawnienia'
 );
-?>
-               
\ No newline at end of file
+?>
\ No newline at end of file
index 3424099a5c8e3f6c330fdf9bcbce850d2320fc24..cd28f7e55cab5b8216511559af12a893f93ea5e4 100755 (executable)
@@ -1,35 +1,35 @@
-<?php\r
-// contributed by "Levi Fukumori" levi _AT_ fukumori _DOT_ com _DOT_ br\r
-// portugese (brazilian)\r
-$ADODB_LANG_ARRAY = array (\r
-                       'LANG'                      => 'pt-br',\r
-            DB_ERROR                    => 'erro desconhecido',\r
-            DB_ERROR_ALREADY_EXISTS     => 'já existe',\r
-            DB_ERROR_CANNOT_CREATE      => 'impossível criar',\r
-            DB_ERROR_CANNOT_DELETE      => 'impossível excluír',\r
-            DB_ERROR_CANNOT_DROP        => 'impossível remover',\r
-            DB_ERROR_CONSTRAINT         => 'violação do confinamente',\r
-            DB_ERROR_DIVZERO            => 'divisão por zero',\r
-            DB_ERROR_INVALID            => 'inválido',\r
-            DB_ERROR_INVALID_DATE       => 'data ou hora inválida',\r
-            DB_ERROR_INVALID_NUMBER     => 'número inválido',\r
-            DB_ERROR_MISMATCH           => 'erro',\r
-            DB_ERROR_NODBSELECTED       => 'nenhum banco de dados selecionado',\r
-            DB_ERROR_NOSUCHFIELD        => 'campo inválido',\r
-            DB_ERROR_NOSUCHTABLE        => 'tabela inexistente',\r
-            DB_ERROR_NOT_CAPABLE        => 'capacidade inválida para este BD',\r
-            DB_ERROR_NOT_FOUND          => 'não encontrado',\r
-            DB_ERROR_NOT_LOCKED         => 'não bloqueado',\r
-            DB_ERROR_SYNTAX             => 'erro de sintaxe',\r
-            DB_ERROR_UNSUPPORTED        => \r
-'não suportado',\r
-            DB_ERROR_VALUE_COUNT_ON_ROW => 'a quantidade de colunas não corresponde ao de valores',\r
-            DB_ERROR_INVALID_DSN        => 'DSN inválido',\r
-            DB_ERROR_CONNECT_FAILED     => 'falha na conexão',\r
-            0                          => 'sem erro', // DB_OK\r
-            DB_ERROR_NEED_MORE_DATA     => 'dados insuficientes',\r
-            DB_ERROR_EXTENSION_NOT_FOUND=> 'extensão não encontrada',\r
-            DB_ERROR_NOSUCHDB           => 'banco de dados não encontrado',\r
-            DB_ERROR_ACCESS_VIOLATION   => 'permissão insuficiente'\r
-);\r
-?>\r
+<?php
+// contributed by "Levi Fukumori" levi _AT_ fukumori _DOT_ com _DOT_ br
+// portugese (brazilian)
+$ADODB_LANG_ARRAY = array (
+                       'LANG'                      => 'pt-br',
+            DB_ERROR                    => 'erro desconhecido',
+            DB_ERROR_ALREADY_EXISTS     => 'já existe',
+            DB_ERROR_CANNOT_CREATE      => 'impossível criar',
+            DB_ERROR_CANNOT_DELETE      => 'impossível excluír',
+            DB_ERROR_CANNOT_DROP        => 'impossível remover',
+            DB_ERROR_CONSTRAINT         => 'violação do confinamente',
+            DB_ERROR_DIVZERO            => 'divisão por zero',
+            DB_ERROR_INVALID            => 'inválido',
+            DB_ERROR_INVALID_DATE       => 'data ou hora inválida',
+            DB_ERROR_INVALID_NUMBER     => 'número inválido',
+            DB_ERROR_MISMATCH           => 'erro',
+            DB_ERROR_NODBSELECTED       => 'nenhum banco de dados selecionado',
+            DB_ERROR_NOSUCHFIELD        => 'campo inválido',
+            DB_ERROR_NOSUCHTABLE        => 'tabela inexistente',
+            DB_ERROR_NOT_CAPABLE        => 'capacidade inválida para este BD',
+            DB_ERROR_NOT_FOUND          => 'não encontrado',
+            DB_ERROR_NOT_LOCKED         => 'não bloqueado',
+            DB_ERROR_SYNTAX             => 'erro de sintaxe',
+            DB_ERROR_UNSUPPORTED        => 
+'não suportado',
+            DB_ERROR_VALUE_COUNT_ON_ROW => 'a quantidade de colunas não corresponde ao de valores',
+            DB_ERROR_INVALID_DSN        => 'DSN inválido',
+            DB_ERROR_CONNECT_FAILED     => 'falha na conexão',
+            0                          => 'sem erro', // DB_OK
+            DB_ERROR_NEED_MORE_DATA     => 'dados insuficientes',
+            DB_ERROR_EXTENSION_NOT_FOUND=> 'extensão não encontrada',
+            DB_ERROR_NOSUCHDB           => 'banco de dados não encontrado',
+            DB_ERROR_ACCESS_VIOLATION   => 'permissão insuficiente'
+);
+?>
\ No newline at end of file
index 7c9aa522b7e89d4e2042ef4da93b43ee17a85e8f..bcd7d13228cf25988075b8e2fcd55e92becff5b2 100755 (executable)
@@ -32,5 +32,4 @@ $ADODB_LANG_ARRAY = array (
             DB_ERROR_NOSUCHDB           => 'nu exista baza de date',
             DB_ERROR_ACCESS_VIOLATION   => 'permisiuni insuficiente'
 );
-?>
-
+?>
\ No newline at end of file
index 9fa32ed5b46186828a90a31821bf17b695324935..675016d125e404cf604df8f7dc4753b2baa5fe47 100755 (executable)
@@ -32,4 +32,4 @@ $ADODB_LANG_ARRAY = array (
             DB_ERROR_NOSUCHDB           => 'íå ³ñíóº ÁÄ',
             DB_ERROR_ACCESS_VIOLATION   => 'íåäîñòàòíüî ïðàâ äîñòóïà'
 );
-?>
+?>
\ No newline at end of file
index a7406a03c23424f2cdf6830f9a3f5035e8d38046..57b8bd1eb8e549af4d7d298175de65462b95ceea 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /** 
- * @version V4.93 10 Oct 2006 (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V4.93 10 Oct 2006 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license. 
  * Whenever there is any discrepancy between the two licenses, 
  * the BSD license will take precedence. 
@@ -73,9 +73,10 @@ function _adodb_export(&$rs,$sep,$sepreplace,$fp=false,$addtitles=true,$quote =
        if ($addtitles) {
                $fieldTypes = $rs->FieldTypesArray();
                reset($fieldTypes);
+               $i = 0;
                while(list(,$o) = each($fieldTypes)) {
-                       
-                       $v = $o->name;
+               
+                       $v = ($o) ? $o->name : 'Field'.($i++);
                        if ($escquote) $v = str_replace($quote,$escquotequote,$v);
                        $v = strip_tags(str_replace("\n", $replaceNewLine, str_replace("\r\n",$replaceNewLine,str_replace($sep,$sepreplace,$v))));
                        $elements[] = $v;
index 050e9556905ff41c5810722a88c09146d13a099f..6a4e3ba471ca4af061290c88321d7c9ea4697264 100755 (executable)
@@ -1,13 +1,13 @@
 <?php 
 /*
-  V4.93 10 Oct 2006  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V4.93 10 Oct 2006  (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
   
   Some pretty-printing by Chris Oxenreider <oxenreid@state.net>
 */ 
-  
+
 // specific code for tohtml
 GLOBAL $gSQLMaxRows,$gSQLBlockRows,$ADODB_ROUND;
 
@@ -84,14 +84,18 @@ GLOBAL $gSQLMaxRows,$gSQLBlockRows,$ADODB_ROUND;
                        $type = $typearr[$i];
                        switch($type) {
                        case 'D':
-                               if (empty($v)) $s .= "<TD> &nbsp; </TD>\n";
-                               else if (!strpos($v,':')) {
-                                       $s .= " <TD>".$rs->UserDate($v,"D d, M Y") ."&nbsp;</TD>\n";
+                               if (strpos($v,':') !== false);
+                               else {
+                                       if (empty($v)) {
+                                       $s .= "<TD> &nbsp; </TD>\n";
+                                       } else {
+                                               $s .= " <TD>".$rs->UserDate($v,"D d, M Y") ."</TD>\n";                          
+                                       }
+                                       break;
                                }
-                               break;
                        case 'T':
                                if (empty($v)) $s .= "<TD> &nbsp; </TD>\n";
-                               else $s .= "    <TD>".$rs->UserTimeStamp($v,"D d, M Y, h:i:s") ."&nbsp;</TD>\n";
+                               else $s .= "    <TD>".$rs->UserTimeStamp($v,"D d, M Y, H:i:s") ."</TD>\n";
                        break;
                        
                        case 'N':
@@ -100,7 +104,9 @@ GLOBAL $gSQLMaxRows,$gSQLBlockRows,$ADODB_ROUND;
                                else
                                        $v = round($v,$ADODB_ROUND);
                        case 'I':
-                               $s .= " <TD align=right>".stripslashes((trim($v))) ."&nbsp;</TD>\n";
+                               $vv = stripslashes((trim($v)));
+                               if (strlen($vv) == 0) $vv .= '&nbsp;';
+                               $s .= " <TD align=right>".$vv ."</TD>\n";
                                
                        break;
                        /*
@@ -176,7 +182,7 @@ function arr2html(&$arr,$ztabhtml='',$zheaderarray='')
        
        for ($i=0; $i<sizeof($arr); $i++) {
                $s .= '<TR>';
-               $a = &$arr[$i];
+               $a = $arr[$i];
                if (is_array($a)) 
                        for ($j=0; $j<sizeof($a); $j++) {
                                $val = $a[$j];