diff options
author | Guillaume (ioguix) de Rorthais | 2009-10-30 15:16:34 +0000 |
---|---|---|
committer | Guillaume (ioguix) de Rorthais | 2009-10-30 15:16:34 +0000 |
commit | b7e71a73fd9b474c0689b7bcd3410bb584ad0299 (patch) | |
tree | 99eadc76da113134b0920cb2daa3f928bb7987ee | |
parent | ee55ec8f1616317fe4a407c483d4ea14a7f7ac68 (diff) |
Update adodb with the latest 5.09a which support php5 only and include deprecated bug fixes for php 5.3
23 files changed, 1142 insertions, 712 deletions
diff --git a/libraries/adodb/adodb-csvlib.inc.php b/libraries/adodb/adodb-csvlib.inc.php index 1e34d39e..1f7543f9 100644 --- a/libraries/adodb/adodb-csvlib.inc.php +++ b/libraries/adodb/adodb-csvlib.inc.php @@ -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"); diff --git a/libraries/adodb/adodb-datadict.inc.php b/libraries/adodb/adodb-datadict.inc.php index c31edd82..efcd453b 100644 --- a/libraries/adodb/adodb-datadict.inc.php +++ b/libraries/adodb/adodb-datadict.inc.php @@ -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 diff --git a/libraries/adodb/adodb-error.inc.php b/libraries/adodb/adodb-error.inc.php index e60976b0..ae0b9e35 100755 --- a/libraries/adodb/adodb-error.inc.php +++ b/libraries/adodb/adodb-error.inc.php @@ -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); diff --git a/libraries/adodb/adodb-iterator.inc.php b/libraries/adodb/adodb-iterator.inc.php index d291e78a..55d66a35 100755 --- a/libraries/adodb/adodb-iterator.inc.php +++ b/libraries/adodb/adodb-iterator.inc.php @@ -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. @@ -18,68 +18,13 @@ 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 diff --git a/libraries/adodb/adodb-lib.inc.php b/libraries/adodb/adodb-lib.inc.php index 2a67f28d..9b46dedc 100644 --- a/libraries/adodb/adodb-lib.inc.php +++ b/libraries/adodb/adodb-lib.inc.php @@ -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)." $ss\n<br />\n",false); - else - ADOConnection::outp( "<hr />\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<hr />\n",false); + ADOConnection::outp( "<br>\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<br>\n",false); + else if ($zthis->debug !== -99) + ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." $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)." $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)." $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 index 99fda176..00000000 --- a/libraries/adodb/adodb-php4.inc.php +++ /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 diff --git a/libraries/adodb/adodb-time.inc.php b/libraries/adodb/adodb-time.inc.php index 51f69f76..07638950 100644 --- a/libraries/adodb/adodb-time.inc.php +++ b/libraries/adodb/adodb-time.inc.php @@ -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) { diff --git a/libraries/adodb/adodb.inc.php b/libraries/adodb/adodb.inc.php index 5567f789..02b375ae 100755 --- a/libraries/adodb/adodb.inc.php +++ b/libraries/adodb/adodb.inc.php @@ -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. @@ -54,9 +54,12 @@ $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. //============================================================================================== @@ -115,17 +118,11 @@ 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); @@ -153,12 +150,16 @@ $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'; @@ -171,12 +172,12 @@ // 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. @@ -215,7 +216,7 @@ */ } - + // for transaction handling function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) { @@ -227,6 +228,95 @@ } } + //------------------ + // 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 //============================================================================================== @@ -287,6 +377,7 @@ 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 ' ' @@ -340,7 +431,7 @@ die('Virtual Class -- cannot instantiate'); } - function Version() + static function Version() { global $ADODB_vers; @@ -373,7 +464,7 @@ * 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; @@ -399,7 +490,7 @@ 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; @@ -424,6 +515,10 @@ 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 { @@ -479,6 +574,7 @@ */ function PConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") { + if (defined('ADODB_NEVER_PERSIST')) return $this->Connect($argHostname,$argUsername,$argPassword,$argDatabaseName); @@ -488,6 +584,10 @@ 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(); @@ -506,6 +606,30 @@ 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) { @@ -532,7 +656,7 @@ { return $sql; } - + /** * Some databases, eg. mssql require a different function for preparing * stored procedures. So we cannot use Prepare(). @@ -551,7 +675,7 @@ { return $this->Prepare($sql,$param); } - + /** * PEAR DB Compat */ @@ -570,6 +694,7 @@ function q(&$s) { + #if (!empty($this->qNull)) if ($s == 'null') return $s; $s = $this->qstr($s,false); } @@ -637,9 +762,9 @@ /** * 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; } @@ -648,9 +773,9 @@ /** * 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; } @@ -742,7 +867,7 @@ { if ($this->transOff > 0) { $this->transOff += 1; - return; + return true; } $this->_oldRaiseFn = $this->raiseErrorFn; @@ -750,8 +875,9 @@ $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; } @@ -818,11 +944,11 @@ * @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) { @@ -836,7 +962,7 @@ 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; @@ -861,14 +987,16 @@ 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 { @@ -879,22 +1007,22 @@ $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; @@ -919,14 +1047,16 @@ } 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; @@ -934,7 +1064,7 @@ 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; @@ -1079,7 +1209,7 @@ { // 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)) @@ -1128,7 +1258,7 @@ * @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 @@ -1137,7 +1267,7 @@ if ($ismssql) $isaccess = false; else $isaccess = (strpos($this->databaseType,'access') !== false); - if ($offset <= 0) { + if ($offset <= 0) { // access includes ties in result if ($isaccess) { @@ -1145,9 +1275,9 @@ '/(^\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){ @@ -1176,16 +1306,13 @@ $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; @@ -1196,11 +1323,11 @@ * * @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; } @@ -1223,12 +1350,12 @@ } $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(); @@ -1236,14 +1363,14 @@ $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); @@ -1254,35 +1381,35 @@ /* * 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; } @@ -1295,26 +1422,43 @@ */ 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(); } @@ -1323,8 +1467,8 @@ 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) { @@ -1339,15 +1483,16 @@ } } $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)); @@ -1360,13 +1505,15 @@ } } $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; @@ -1393,13 +1540,13 @@ * @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')) { @@ -1409,24 +1556,24 @@ $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) @@ -1437,12 +1584,17 @@ $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. @@ -1450,13 +1602,13 @@ * @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) { @@ -1470,12 +1622,13 @@ 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; } @@ -1530,16 +1683,16 @@ * @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; } @@ -1549,102 +1702,24 @@ * 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. @@ -1660,10 +1735,9 @@ * 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; @@ -1672,17 +1746,10 @@ $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'; } @@ -1696,10 +1763,10 @@ * @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; @@ -1712,29 +1779,19 @@ } 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) { @@ -1744,34 +1801,40 @@ 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; @@ -1781,9 +1844,9 @@ $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; @@ -1803,17 +1866,17 @@ $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; @@ -1827,7 +1890,7 @@ $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; @@ -1986,7 +2049,7 @@ 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); } @@ -2032,46 +2095,34 @@ } } - 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 [email protected] */ - 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 [email protected] */ - 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 diff --git a/libraries/adodb/drivers/adodb-postgres.inc.php b/libraries/adodb/drivers/adodb-postgres.inc.php index 5e8ce48e..491e4ccd 100644 --- a/libraries/adodb/drivers/adodb-postgres.inc.php +++ b/libraries/adodb/drivers/adodb-postgres.inc.php @@ -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. diff --git a/libraries/adodb/drivers/adodb-postgres64.inc.php b/libraries/adodb/drivers/adodb-postgres64.inc.php index 0135a20a..1444d02d 100644 --- a/libraries/adodb/drivers/adodb-postgres64.inc.php +++ b/libraries/adodb/drivers/adodb-postgres64.inc.php @@ -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 diff --git a/libraries/adodb/drivers/adodb-postgres7.inc.php b/libraries/adodb/drivers/adodb-postgres7.inc.php index 5c3d7bb6..191ee360 100644 --- a/libraries/adodb/drivers/adodb-postgres7.inc.php +++ b/libraries/adodb/drivers/adodb-postgres7.inc.php @@ -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,10 +56,59 @@ 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 pg_trigger t,pg_class c,pg_proc p @@ -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 diff --git a/libraries/adodb/drivers/adodb-postgres8.inc.php b/libraries/adodb/drivers/adodb-postgres8.inc.php index f3712a39..05a705eb 100755 --- a/libraries/adodb/drivers/adodb-postgres8.inc.php +++ b/libraries/adodb/drivers/adodb-postgres8.inc.php @@ -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. diff --git a/libraries/adodb/lang/adodb-ar.inc.php b/libraries/adodb/lang/adodb-ar.inc.php index dd0f830f..4b750952 100755 --- a/libraries/adodb/lang/adodb-ar.inc.php +++ b/libraries/adodb/lang/adodb-ar.inc.php @@ -30,5 +30,4 @@ $ADODB_LANG_ARRAY = array ( DB_ERROR_NOSUCHDB => '��� ����� ����� ������ ���� �����', DB_ERROR_ACCESS_VIOLATION => '������� ��� �����' ); -?> - +?>
\ No newline at end of file diff --git a/libraries/adodb/lang/adodb-bg.inc.php b/libraries/adodb/lang/adodb-bg.inc.php index 4fb1dc07..ee307c13 100755 --- a/libraries/adodb/lang/adodb-bg.inc.php +++ b/libraries/adodb/lang/adodb-bg.inc.php @@ -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 diff --git a/libraries/adodb/lang/adodb-bgutf8.inc.php b/libraries/adodb/lang/adodb-bgutf8.inc.php index 6f3a4173..5281ed53 100755 --- a/libraries/adodb/lang/adodb-bgutf8.inc.php +++ b/libraries/adodb/lang/adodb-bgutf8.inc.php @@ -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 diff --git a/libraries/adodb/lang/adodb-ca.inc.php b/libraries/adodb/lang/adodb-ca.inc.php index 3e6a4496..3640ebd0 100755 --- a/libraries/adodb/lang/adodb-ca.inc.php +++ b/libraries/adodb/lang/adodb-ca.inc.php @@ -1,35 +1,34 @@ -<?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 +<?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 diff --git a/libraries/adodb/lang/adodb-en.inc.php b/libraries/adodb/lang/adodb-en.inc.php index ed1b8f19..6895995e 100755 --- a/libraries/adodb/lang/adodb-en.inc.php +++ b/libraries/adodb/lang/adodb-en.inc.php @@ -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 diff --git a/libraries/adodb/lang/adodb-pl.inc.php b/libraries/adodb/lang/adodb-pl.inc.php index aee5bfdf..9d9e3906 100755 --- a/libraries/adodb/lang/adodb-pl.inc.php +++ b/libraries/adodb/lang/adodb-pl.inc.php @@ -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 diff --git a/libraries/adodb/lang/adodb-pt-br.inc.php b/libraries/adodb/lang/adodb-pt-br.inc.php index 3424099a..cd28f7e5 100755 --- a/libraries/adodb/lang/adodb-pt-br.inc.php +++ b/libraries/adodb/lang/adodb-pt-br.inc.php @@ -1,35 +1,35 @@ -<?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'
-);
-?>
+<?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 diff --git a/libraries/adodb/lang/adodb-ro.inc.php b/libraries/adodb/lang/adodb-ro.inc.php index 7c9aa522..bcd7d132 100755 --- a/libraries/adodb/lang/adodb-ro.inc.php +++ b/libraries/adodb/lang/adodb-ro.inc.php @@ -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 diff --git a/libraries/adodb/lang/adodb-uk1251.inc.php b/libraries/adodb/lang/adodb-uk1251.inc.php index 9fa32ed5..675016d1 100755 --- a/libraries/adodb/lang/adodb-uk1251.inc.php +++ b/libraries/adodb/lang/adodb-uk1251.inc.php @@ -32,4 +32,4 @@ $ADODB_LANG_ARRAY = array ( DB_ERROR_NOSUCHDB => '�� ���� ��', DB_ERROR_ACCESS_VIOLATION => '����������� ���� �������' ); -?> +?>
\ No newline at end of file diff --git a/libraries/adodb/toexport.inc.php b/libraries/adodb/toexport.inc.php index a7406a03..57b8bd1e 100644 --- a/libraries/adodb/toexport.inc.php +++ b/libraries/adodb/toexport.inc.php @@ -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; diff --git a/libraries/adodb/tohtml.inc.php b/libraries/adodb/tohtml.inc.php index 050e9556..6a4e3ba4 100755 --- a/libraries/adodb/tohtml.inc.php +++ b/libraries/adodb/tohtml.inc.php @@ -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 <[email protected]> */ - + // 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> </TD>\n"; - else if (!strpos($v,':')) { - $s .= " <TD>".$rs->UserDate($v,"D d, M Y") ." </TD>\n"; + if (strpos($v,':') !== false); + else { + if (empty($v)) { + $s .= "<TD> </TD>\n"; + } else { + $s .= " <TD>".$rs->UserDate($v,"D d, M Y") ."</TD>\n"; + } + break; } - break; case 'T': if (empty($v)) $s .= "<TD> </TD>\n"; - else $s .= " <TD>".$rs->UserTimeStamp($v,"D d, M Y, h:i:s") ." </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))) ." </TD>\n"; + $vv = stripslashes((trim($v))); + if (strlen($vv) == 0) $vv .= ' '; + $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]; |