From d6392dfd4464104856b71e7fe78b8fbb1e81f3c3 Mon Sep 17 00:00:00 2001 From: Shish Date: Mon, 19 Jul 2010 13:09:32 +0100 Subject: [PATCH] adodb updates --- lib/adodb/adodb-csvlib.inc.php | 42 +- lib/adodb/adodb-error.inc.php | 18 +- lib/adodb/adodb-exceptions.inc.php | 2 +- lib/adodb/adodb-iterator.inc.php | 63 +- lib/adodb/adodb-lib.inc.php | 173 ++-- lib/adodb/adodb-php4.inc.php | 2 +- lib/adodb/adodb-time.inc.php | 162 +++- lib/adodb/adodb.inc.php | 953 +++++++++++++-------- lib/adodb/drivers/adodb-mysql.inc.php | 73 +- lib/adodb/drivers/adodb-postgres.inc.php | 14 + lib/adodb/drivers/adodb-postgres64.inc.php | 43 +- lib/adodb/drivers/adodb-postgres7.inc.php | 67 +- lib/adodb/drivers/adodb-postgres8.inc.php | 12 + lib/adodb/drivers/adodb-sqlite.inc.php | 19 +- lib/adodb/drivers/adodb-sqlitepo.inc.php | 62 ++ 15 files changed, 1085 insertions(+), 620 deletions(-) create mode 100644 lib/adodb/drivers/adodb-postgres.inc.php create mode 100644 lib/adodb/drivers/adodb-postgres8.inc.php create mode 100644 lib/adodb/drivers/adodb-sqlitepo.inc.php diff --git a/lib/adodb/adodb-csvlib.inc.php b/lib/adodb/adodb-csvlib.inc.php index 1e34d39e..1c0d0818 100644 --- a/lib/adodb/adodb-csvlib.inc.php +++ b/lib/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.11 5 May 2010 (c) 2000-2010 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,13 +64,14 @@ $ADODB_INCLUDED_CSV = 1; } for($i=0; $i < $max; $i++) { - $o =& $rs->FetchField($i); + $o = $rs->FetchField($i); $flds[] = $o; } $savefetch = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode; $class = $rs->connection->arrayClass; $rs2 = new $class(); + $rs2->timeCreated = $rs->timeCreated; # memcache fix $rs2->sql = $rs->sql; $rs2->oldProvider = $rs->dataProvider; $rs2->InitArrayFields($rows,$flds); @@ -90,7 +91,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 +262,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 +282,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
\n"); diff --git a/lib/adodb/adodb-error.inc.php b/lib/adodb/adodb-error.inc.php index e60976b0..6ec614d2 100644 --- a/lib/adodb/adodb-error.inc.php +++ b/lib/adodb/adodb-error.inc.php @@ -1,6 +1,6 @@ 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/lib/adodb/adodb-exceptions.inc.php b/lib/adodb/adodb-exceptions.inc.php index 3eebc4e0..65f89432 100644 --- a/lib/adodb/adodb-exceptions.inc.php +++ b/lib/adodb/adodb-exceptions.inc.php @@ -1,7 +1,7 @@ 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; - } - -} - - -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/lib/adodb/adodb-lib.inc.php b/lib/adodb/adodb-lib.inc.php index bdda6498..6b2e8910 100644 --- a/lib/adodb/adodb-lib.inc.php +++ b/lib/adodb/adodb-lib.inc.php @@ -1,5 +1,8 @@ name); + } else + $newarr[] = array(); + for ($y = 0; $y < $oldY; $y++) { $newarr[$x-$startx][] = $arr[$y][$x]; } @@ -105,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; } @@ -117,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])) { @@ -363,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 @@ -416,13 +451,17 @@ 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); - if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr); - + if ($secs2cache) { + $rstest = $zthis->CacheExecute($secs2cache,$rewritesql,$inputarr); + if (!$rstest) $rstest = $zthis->CacheExecute($secs2cache,$sql,$inputarr); + } else { + $rstest = $zthis->Execute($rewritesql,$inputarr); + if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr); + } if ($rstest) { $qryRecs = $rstest->RecordCount(); if ($qryRecs == -1) { @@ -454,7 +493,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; @@ -490,9 +529,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 @@ -508,7 +547,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; @@ -524,16 +563,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(); } @@ -545,8 +584,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) { @@ -560,6 +599,8 @@ function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputar function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2) { + global $ADODB_QUOTE_FIELDNAMES; + if (!$rs) { printf(ADODB_BAD_RS,'GetUpdateSQL'); return false; @@ -606,7 +647,7 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq $type = 'C'; } - if (strpos($upperfname,' ') !== false) + if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote; else $fnameq = $upperfname; @@ -720,6 +761,7 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2) static $cacheRS = false; static $cacheSig = 0; static $cacheCols; + global $ADODB_QUOTE_FIELDNAMES; $tableName = ''; $values = ''; @@ -738,10 +780,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; @@ -749,7 +791,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); @@ -757,7 +799,7 @@ static $cacheCols; $cacheCols = $columns; $rs->insertSig = $cacheSig++; } - $recordSet =& $rs; + $recordSet = $rs; } else { printf(ADODB_BAD_RS,'GetInsertSQL'); @@ -769,7 +811,7 @@ static $cacheCols; $upperfname = strtoupper($field->name); if (adodb_key_exists($upperfname,$arrFields,$force)) { $bad = false; - if (strpos($upperfname,' ') !== false) + if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote; else $fnameq = $upperfname; @@ -962,9 +1004,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; } @@ -984,7 +1037,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 ]"; } @@ -1003,11 +1057,13 @@ function _adodb_debug_execute(&$zthis, $sql, $inputarr) $ss = ''.htmlspecialchars($ss).''; } if ($zthis->debug === -1) - ADOConnection::outp( "
\n($dbt): ".htmlspecialchars($sqlTxt)."   $ss\n
\n",false); - else - ADOConnection::outp( "
\n($dbt): ".htmlspecialchars($sqlTxt)."   $ss\n
\n",false); + ADOConnection::outp( "
\n($dbt): ".htmlspecialchars($sqlTxt)."   $ss\n
\n",false); + else if ($zthis->debug !== -99) + ADOConnection::outp( "
\n($dbt): ".htmlspecialchars($sqlTxt)."   $ss\n
\n",false); } else { - ADOConnection::outp("-----\n($dbt): ".$sqlTxt."\n-----\n",false); + $ss = "\n ".$ss; + if ($zthis->debug !== -99) + ADOConnection::outp("-----
\n($dbt): ".$sqlTxt." $ss\n-----
\n",false); } $qID = $zthis->_query($sql,$inputarr); @@ -1018,10 +1074,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( "
\n($dbt): ".htmlspecialchars($sqlTxt)."   $ss\n
\n",false); + + ADOConnection::outp($err.': '.$emsg); + } } } else if (!$qID) { + + if ($zthis->debug === -99) + if ($inBrowser) ADOConnection::outp( "
\n($dbt): ".htmlspecialchars($sqlTxt)."   $ss\n
\n",false); + else ADOConnection::outp("-----
\n($dbt): ".$sqlTxt."$ss\n-----
\n",false); + ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg()); } @@ -1030,11 +1097,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) ? " %% line %4d, file: %s" : "%% line %4d, file: %s"; $MAXSTRLEN = 128; @@ -1065,7 +1134,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/lib/adodb/adodb-php4.inc.php b/lib/adodb/adodb-php4.inc.php index a23dc170..e46a74d8 100644 --- a/lib/adodb/adodb-php4.inc.php +++ b/lib/adodb/adodb-php4.inc.php @@ -1,7 +1,7 @@ = 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 "$y1 error, expected=$y1-$m-$d 00:00:00, adodb=$rez
"; + if ($h == 0) $h = '00'; + else if ($h < 10) $h = '0'.$h; + if ("$y1-$m-$d $h:00:00" != $rez) { + print "$y1 error, expected=$y1-$m-$d $h:00:00, adodb=$rez
"; 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
"; + echo "error for $fmt, strftime=$s1, adodb=$s2
"; 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)),"
"; + error_reporting(E_ALL); print "

Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION.' PHP='.PHP_VERSION."

"; @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 '
';
+	echo 'adodb: ',adodb_date($fmt,$t),'
'; + echo 'php : ',date($fmt,$t),'
'; + echo '
'; + 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 "

Testing date formating

"; + $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; } -/** - get local time zone offset from GMT -*/ -function adodb_get_gmt_diff() +function adodb_get_gmt_diff_ts($ts) { -static $TZ; - if (isset($TZ)) return $TZ; + 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. Does not handle historical timezones before 1970. +*/ +function adodb_get_gmt_diff($y,$m,$d) +{ +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,17 @@ static $daylight; */ for ($i=0; $i < $max; $i++) { switch($fmt[$i]) { - case 'T': $dates .= date('T');break; + case 'e': + $dates .= date('e'); + 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 +1100,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 +1131,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 +1217,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 +1248,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/lib/adodb/adodb.inc.php b/lib/adodb/adodb.inc.php index d8c1b590..2da3777d 100644 --- a/lib/adodb/adodb.inc.php +++ b/lib/adodb/adodb.inc.php @@ -12,9 +12,9 @@ */ /** - \mainpage + \mainpage - @version V4.93 10 Oct 2006 (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved. + @version V5.11 5 May 2010 (c) 2000-2010 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,13 @@ $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_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. //============================================================================================== // GLOBAL SETUP @@ -114,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); @@ -152,11 +150,16 @@ $ADODB_COUNTRECS, // count number of records returned - slows down query $ADODB_CACHE_DIR, // directory to cache recordsets $ADODB_FETCH_MODE, - $ADODB_FORCE_TYPE; + $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'; @@ -174,7 +177,7 @@ /** * ADODB version as a string. */ - $ADODB_vers = 'V4.93 10 Oct 2006 (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.'; + $ADODB_vers = 'V5.11 5 May 2010 (c) 2000-2010 John Lim (jlim#natsoft.com). All rights reserved. Released BSD & LGPL.'; /** * Determines whether recordset->RecordCount() is used. @@ -213,7 +216,7 @@ */ } - + // for transaction handling function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) { @@ -225,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
\n". $rez."
"); + } + 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 //============================================================================================== @@ -285,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 ' ' @@ -310,6 +403,7 @@ var $fetchMode=false; var $null2null = 'null'; // in autoexecute/getinsertsql/getupdatesql, this value will be converted to a null + var $bulkBind = false; // enable 2D Execute array // // PRIVATE VARS // @@ -338,11 +432,13 @@ die('Virtual Class -- cannot instantiate'); } - function Version() + static function Version() { global $ADODB_vers; - return (float) substr($ADODB_vers,1); + $ok = preg_match( '/^[Vv]([0-9\.]+)/', $ADODB_vers, $matches ); + if (!$ok) return (float) substr($ADODB_vers,1); + else return $matches[1]; } /** @@ -371,7 +467,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; @@ -397,7 +493,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; @@ -418,14 +514,15 @@ { if ($argHostname != "") $this->host = $argHostname; if ($argUsername != "") $this->user = $argUsername; - if ($argPassword != "") $this->password = $argPassword; // not stored for security reasons + if ($argPassword != "") $this->password = 'not stored'; // not stored for security reasons if ($argDatabaseName != "") $this->database = $argDatabaseName; $this->_isPersistentConnection = false; + if ($forceNew) { - if ($rez=$this->_nconnect($this->host, $this->user, $this->password, $this->database)) return true; + if ($rez=$this->_nconnect($this->host, $this->user, $argPassword, $this->database)) return true; } else { - if ($rez=$this->_connect($this->host, $this->user, $this->password, $this->database)) return true; + if ($rez=$this->_connect($this->host, $this->user, $argPassword, $this->database)) return true; } if (isset($rez)) { $err = $this->ErrorMsg(); @@ -477,16 +574,18 @@ */ function PConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") { + if (defined('ADODB_NEVER_PERSIST')) return $this->Connect($argHostname,$argUsername,$argPassword,$argDatabaseName); if ($argHostname != "") $this->host = $argHostname; if ($argUsername != "") $this->user = $argUsername; - if ($argPassword != "") $this->password = $argPassword; + if ($argPassword != "") $this->password = 'not stored'; if ($argDatabaseName != "") $this->database = $argDatabaseName; $this->_isPersistentConnection = true; - if ($rez = $this->_pconnect($this->host, $this->user, $this->password, $this->database)) return true; + + if ($rez = $this->_pconnect($this->host, $this->user, $argPassword, $this->database)) return true; if (isset($rez)) { $err = $this->ErrorMsg(); if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'"; @@ -504,6 +603,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) { @@ -530,7 +653,7 @@ { return $sql; } - + /** * Some databases, eg. mssql require a different function for preparing * stored procedures. So we cannot use Prepare(). @@ -549,7 +672,7 @@ { return $this->Prepare($sql,$param); } - + /** * PEAR DB Compat */ @@ -596,7 +719,7 @@ * @param $table name of table to lock * @param $where where clause to use, eg: "WHERE row=12". If left empty, will escalate to table lock */ - function RowLock($table,$where) + function RowLock($table,$where,$col='1 as adodbignore') { return false; } @@ -636,9 +759,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; } @@ -647,9 +770,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; } @@ -741,7 +864,7 @@ { if ($this->transOff > 0) { $this->transOff += 1; - return; + return true; } $this->_oldRaiseFn = $this->raiseErrorFn; @@ -749,8 +872,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; } @@ -817,11 +941,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) { @@ -829,13 +953,13 @@ $element0 = reset($inputarr); # is_object check because oci8 descriptors can be passed in - $array_2d = is_array($element0) && !is_object(reset($element0)); + $array_2d = $this->bulkBind && is_array($element0) && !is_object(reset($element0)); //remove extra memory copy of input -mikefedyk unset($element0); 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; @@ -860,14 +984,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 { @@ -878,22 +1004,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; @@ -918,14 +1044,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; @@ -933,7 +1061,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; @@ -1078,7 +1206,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)) @@ -1127,7 +1255,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 @@ -1144,9 +1272,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){ @@ -1175,16 +1303,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; @@ -1195,11 +1320,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; } @@ -1222,12 +1347,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(); @@ -1235,14 +1360,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); @@ -1253,35 +1378,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; } @@ -1294,26 +1419,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(); } @@ -1322,8 +1464,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) { @@ -1338,15 +1480,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)); @@ -1359,17 +1502,19 @@ } } $rs->Close(); - } + } else + $rv = false; + return $rv; } - function &Transpose(&$rs) + function Transpose(&$rs,$addfieldnames=true) { - $rs2 =& $this->_rs2rs($rs); + $rs2 = $this->_rs2rs($rs); $false = false; if (!$rs2) return $false; - $rs2->_transpose(); + $rs2->_transpose($addfieldnames); return $rs2; } @@ -1392,13 +1537,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')) { @@ -1408,24 +1553,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) @@ -1436,12 +1581,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. @@ -1449,13 +1599,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) { @@ -1469,12 +1619,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; } @@ -1529,16 +1680,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; } @@ -1555,102 +1706,19 @@ */ function CacheFlush($sql=false,$inputarr=false) { - global $ADODB_CACHE_DIR; - - if ($this->memCache) { - global $ADODB_INCLUDED_MEMCACHE; + global $ADODB_CACHE_DIR, $ADODB_CACHE; - $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
\n", $this->_dirFlush($dir),"
"); - } 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) - { - 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
\n", system($cmd),"
"); - } else { - exec($cmd); - } - return; - } + if (empty($ADODB_CACHE)) return false; - 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. @@ -1666,10 +1734,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; @@ -1678,17 +1745,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'; } @@ -1702,10 +1762,12 @@ * @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 (empty($ADODB_CACHE)) $this->_CreateCache(); + if (!is_numeric($secs2cache)) { $inputarr = $sql; $sql = $secs2cache; @@ -1718,29 +1780,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) { @@ -1750,36 +1802,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 && $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); + } else if (!$this->memCache) + $ADODB_CACHE->flushcache($md5file); } else { $this->_errorMsg = ''; $this->_errorCode = 0; @@ -1789,9 +1845,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; @@ -1811,19 +1867,20 @@ $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; + $rs->sql = $sql; switch((string) $mode) { case 'UPDATE': @@ -1835,7 +1892,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; @@ -1993,8 +2050,8 @@ if (empty($this->_metars)) { $rsclass = $this->rsPrefix.$this->databaseType; - $this->_metars =& new $rsclass(false,$this->fetchMode); - $this->_metars->connection =& $this; + $this->_metars = new $rsclass(false,$this->fetchMode); + $this->_metars->connection = $this; } return $this->_metars->MetaType($t,$len,$fieldobj); } @@ -2019,6 +2076,7 @@ $this->fmtTimeStamp = "'m-d-Y H:i:s'"; break; + case 'PT_BR': case 'NL': case 'FR': case 'RO': @@ -2039,46 +2097,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; } @@ -2097,7 +2143,11 @@ * * @return true if succeeded or false if database does not support transactions */ - function BeginTrans() {return false;} + function BeginTrans() + { + if ($this->debug) ADOConnection::outp("BeginTrans: Transactions not supported for this driver"); + return false; + } /* set transaction mode */ function SetTransactionMode( $transaction_mode ) @@ -2208,7 +2258,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; @@ -2228,7 +2278,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]))) { @@ -2270,7 +2320,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; @@ -2329,7 +2379,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; @@ -2341,9 +2391,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; @@ -2387,10 +2437,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'"; @@ -2424,10 +2478,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); @@ -2445,7 +2501,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 @@ -2469,7 +2525,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 @@ -2555,7 +2611,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); @@ -2589,7 +2645,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); @@ -2615,12 +2671,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; } @@ -2637,7 +2693,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': @@ -2645,7 +2701,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; } @@ -2667,10 +2723,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; @@ -2685,6 +2785,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);} } //============================================================================================== @@ -2696,15 +2797,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 */ @@ -2754,6 +2901,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() @@ -2840,7 +2998,7 @@ 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); @@ -2856,9 +3014,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; } @@ -2880,10 +3038,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; } @@ -2907,9 +3065,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; } @@ -2929,7 +3087,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; @@ -3020,7 +3178,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; } @@ -3066,7 +3224,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); } @@ -3077,7 +3235,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); } @@ -3115,7 +3273,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; @@ -3279,7 +3437,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; @@ -3353,7 +3511,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); } } @@ -3387,16 +3545,19 @@ 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) + function FetchField($fieldoffset = -1) { // must be defined by child class + + $false = false; + return $false; } /** * Get the ADOFieldObjects of all columns in an array. * */ - function& FieldTypesArray() + function FieldTypesArray() { $arr = array(); for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) @@ -3410,9 +3571,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; } @@ -3424,7 +3585,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(); @@ -3457,9 +3618,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * Fixed bug reported by tim@orotech.net */ - function &FetchNextObj() + function FetchNextObj() { - $o =& $this->FetchNextObject(false); + $o = $this->FetchNextObject(false); return $o; } @@ -3475,7 +3636,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * Fixed bug reported by tim@orotech.net */ - function &FetchNextObject($isupper=true) + function FetchNextObject($isupper=true) { $o = false; if ($this->_numOfRows != 0 && !$this->EOF) { @@ -3532,6 +3693,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', @@ -3555,6 +3717,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', @@ -3734,18 +3897,19 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 $this->fetchMode = $ADODB_FETCH_MODE; } - function _transpose() + function _transpose($addfieldnames=true) { global $ADODB_INCLUDED_LIB; if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); $hdr = true; - adodb_transpose($this->_array, $newarr, $hdr); + $fobjs = $addfieldnames ? $this->_fieldobjects : false; + adodb_transpose($this->_array, $newarr, $hdr, $fobjs); //adodb_pr($newarr); $this->_skiprow1 = false; - $this->_array =& $newarr; + $this->_array = $newarr; $this->_colnames = $hdr; adodb_probetypes($newarr,$this->_types); @@ -3758,7 +3922,6 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 $f->type = $this->_types[$k]; $f->max_length = -1; $this->_fieldobjects[] = $f; - } $this->fields = reset($this->_array); @@ -3800,20 +3963,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; } } @@ -3833,7 +3996,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) { @@ -3846,7 +4009,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]; @@ -3961,9 +4124,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; } @@ -3975,38 +4138,56 @@ 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); - $dsna = @parse_url($fakedsn); - $dsna['scheme'] = substr($db,0,$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); + } - if (strncmp($db,'pdo',3) == 0) { - $sch = explode('_',$dsna['scheme']); - if (sizeof($sch)>1) { - $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; + if ((strpos($origdsn, 'sqlite')) !== FALSE) { + // special handling for SQLite, it only might have the path to the database file. + // If you try to connect to a SQLite database using a dsn like 'sqlite:///path/to/database', the 'parse_url' php function + // will throw you an exception with a message such as "unable to parse url" + list($scheme, $path) = explode('://', $origdsn); + $dsna['scheme'] = $scheme; + if ($qmark = strpos($path,'?')) { + $dsn['query'] = substr($path,$qmark+1); + $path = substr($path,0,$qmark); + } + $dsna['path'] = '/' . urlencode($path); + } else + $dsna = @parse_url($fakedsn); + + if (!$dsna) { + return $false; + } + $dsna['scheme'] = substr($origdsn,0,$at); + if ($at2 !== FALSE) { + $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']) : ''; @@ -4034,7 +4215,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; @@ -4092,6 +4275,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 +4337,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 +4351,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 +4368,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 +4404,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/lib/adodb/drivers/adodb-mysql.inc.php b/lib/adodb/drivers/adodb-mysql.inc.php index 8e79d4a7..4b215e54 100644 --- a/lib/adodb/drivers/adodb-mysql.inc.php +++ b/lib/adodb/drivers/adodb-mysql.inc.php @@ -1,6 +1,6 @@ metaTablesSQL; if ($showSchema && is_string($showSchema)) { @@ -69,14 +69,14 @@ class ADODB_mysql extends ADOConnection { $mask = $this->qstr($mask); $this->metaTablesSQL .= " like $mask"; } - $ret =& ADOConnection::MetaTables($ttype,$showSchema); + $ret = ADOConnection::MetaTables($ttype,$showSchema); $this->metaTablesSQL = $save; return $ret; } - function &MetaIndexes ($table, $primary = FALSE, $owner=false) + function MetaIndexes ($table, $primary = FALSE, $owner=false) { // save old fetch mode global $ADODB_FETCH_MODE; @@ -132,6 +132,7 @@ class ADODB_mysql extends ADOConnection { // if magic quotes disabled, use mysql_real_escape_string() function qstr($s,$magic_quotes=false) { + if (is_null($s)) return 'NULL'; if (!$magic_quotes) { if (ADODB_PHPVER >= 0x4300) { @@ -157,11 +158,12 @@ class ADODB_mysql extends ADOConnection { function GetOne($sql,$inputarr=false) { + global $ADODB_GETONE_EOF; if ($this->compat323 == false && strncasecmp($sql,'sele',4) == 0) { - $rs =& $this->SelectLimit($sql,1,-1,$inputarr); + $rs = $this->SelectLimit($sql,1,-1,$inputarr); if ($rs) { $rs->Close(); - if ($rs->EOF) return false; + if ($rs->EOF) return $ADODB_GETONE_EOF; return reset($rs->fields); } } else { @@ -180,10 +182,11 @@ class ADODB_mysql extends ADOConnection { return mysql_affected_rows($this->_connectionID); } - // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html + // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html // Reference on Last_Insert_ID on the recommended way to simulate sequences var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);"; var $_genSeqSQL = "create table %s (id int not null)"; + var $_genSeqCountSQL = "select count(*) from %s"; var $_genSeq2SQL = "insert into %s values (%s)"; var $_dropSeqSQL = "drop table %s"; @@ -212,18 +215,22 @@ class ADODB_mysql extends ADOConnection { if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset $u = strtoupper($seqname); $this->Execute(sprintf($this->_genSeqSQL,$seqname)); - $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1)); + $cnt = $this->GetOne(sprintf($this->_genSeqCountSQL,$seqname)); + if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1)); $rs = $this->Execute($getnext); } - $this->genID = mysql_insert_id($this->_connectionID); - if ($rs) $rs->Close(); + if ($rs) { + $this->genID = mysql_insert_id($this->_connectionID); + $rs->Close(); + } else + $this->genID = 0; $this->_logsql = $savelog; return $this->genID; } - function &MetaDatabases() + function MetaDatabases() { $qid = mysql_list_dbs($this->_connectionID); $arr = array(); @@ -343,7 +350,7 @@ class ADODB_mysql extends ADOConnection { if (!$date) $date = $this->sysDate; $fraction = $dayFraction * 24 * 3600; - return $date . ' + INTERVAL ' . $fraction.' SECOND'; + return '('. $date . ' + INTERVAL ' . $fraction.' SECOND)'; // return "from_unixtime(unix_timestamp($date)+$fraction)"; } @@ -388,7 +395,7 @@ class ADODB_mysql extends ADOConnection { return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename); } - function &MetaColumns($table) + function MetaColumns($table, $normalize=true) { $this->_findschema($table,$schema); if ($schema) { @@ -441,9 +448,10 @@ class ADODB_mysql extends ADOConnection { $fld->not_null = ($rs->fields[2] != 'YES'); $fld->primary_key = ($rs->fields[3] == 'PRI'); $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false); - $fld->binary = (strpos($type,'blob') !== false); + $fld->binary = (strpos($type,'blob') !== false || strpos($type,'binary') !== false); $fld->unsigned = (strpos($type,'unsigned') !== false); - + $fld->zerofill = (strpos($type,'zerofill') !== false); + if (!$fld->binary) { $d = $rs->fields[4]; if ($d != '' && $d != 'NULL') { @@ -478,21 +486,21 @@ class ADODB_mysql extends ADOConnection { } // parameters use PostgreSQL convention, not MySQL - function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0) + function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0) { $offsetStr =($offset>=0) ? ((integer)$offset)."," : ''; // jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220 if ($nrows < 0) $nrows = '18446744073709551615'; if ($secs) - $rs =& $this->CacheExecute($secs,$sql." LIMIT $offsetStr".((integer)$nrows),$inputarr); + $rs = $this->CacheExecute($secs,$sql." LIMIT $offsetStr".((integer)$nrows),$inputarr); else - $rs =& $this->Execute($sql." LIMIT $offsetStr".((integer)$nrows),$inputarr); + $rs = $this->Execute($sql." LIMIT $offsetStr".((integer)$nrows),$inputarr); return $rs; } // returns queryID or false - function _query($sql,$inputarr) + function _query($sql,$inputarr=false) { //global $ADODB_COUNTRECS; //if($ADODB_COUNTRECS) @@ -552,8 +560,9 @@ class ADODB_mysql extends ADOConnection { $table = "$owner.$table"; } $a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table)); - if ($associative) $create_sql = $a_create_table["Create Table"]; - else $create_sql = $a_create_table[1]; + if ($associative) { + $create_sql = isset($a_create_table["Create Table"]) ? $a_create_table["Create Table"] : $a_create_table["Create View"]; + } else $create_sql = $a_create_table[1]; $matches = array(); @@ -569,9 +578,12 @@ class ADODB_mysql extends ADOConnection { $ref_table = strtoupper($ref_table); } - $foreign_keys[$ref_table] = array(); - $num_fields = count($my_field); - for ( $j = 0; $j < $num_fields; $j ++ ) { + // see https://sourceforge.net/tracker/index.php?func=detail&aid=2287278&group_id=42718&atid=433976 + if (!isset($foreign_keys[$ref_table])) { + $foreign_keys[$ref_table] = array(); + } + $num_fields = count($my_field); + for ( $j = 0; $j < $num_fields; $j ++ ) { if ( $associative ) { $foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j]; } else { @@ -623,28 +635,28 @@ class ADORecordSet_mysql extends ADORecordSet{ $this->_numOfFields = @mysql_num_fields($this->_queryID); } - function &FetchField($fieldOffset = -1) + function FetchField($fieldOffset = -1) { if ($fieldOffset != -1) { $o = @mysql_fetch_field($this->_queryID, $fieldOffset); $f = @mysql_field_flags($this->_queryID,$fieldOffset); - $o->max_length = @mysql_field_len($this->_queryID,$fieldOffset); // suggested by: Jim Nicholson (jnich@att.com) + if ($o) $o->max_length = @mysql_field_len($this->_queryID,$fieldOffset); // suggested by: Jim Nicholson (jnich#att.com) //$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable - $o->binary = (strpos($f,'binary')!== false); + if ($o) $o->binary = (strpos($f,'binary')!== false); } else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */ $o = @mysql_fetch_field($this->_queryID); - $o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich@att.com) + if ($o) $o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich#att.com) //$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable } return $o; } - function &GetRowAssoc($upper=true) + function GetRowAssoc($upper=true) { if ($this->fetchMode == MYSQL_ASSOC && !$upper) $row = $this->fields; - else $row =& ADORecordSet::GetRowAssoc($upper); + else $row = ADORecordSet::GetRowAssoc($upper); return $row; } @@ -726,6 +738,7 @@ class ADORecordSet_mysql extends ADORecordSet{ case 'LONGBLOB': case 'BLOB': case 'MEDIUMBLOB': + case 'BINARY': return !empty($fieldobj->binary) ? 'B' : 'X'; case 'YEAR': diff --git a/lib/adodb/drivers/adodb-postgres.inc.php b/lib/adodb/drivers/adodb-postgres.inc.php new file mode 100644 index 00000000..6f580ff6 --- /dev/null +++ b/lib/adodb/drivers/adodb-postgres.inc.php @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/lib/adodb/drivers/adodb-postgres64.inc.php b/lib/adodb/drivers/adodb-postgres64.inc.php index 69d44fc7..8258149c 100644 --- a/lib/adodb/drivers/adodb-postgres64.inc.php +++ b/lib/adodb/drivers/adodb-postgres64.inc.php @@ -1,6 +1,6 @@ _connectionID, "begin ".$this->_transmode); } - function RowLock($tables,$where,$flds='1 as ignore') + function RowLock($tables,$where,$col='1 as adodbignore') { if (!$this->transCnt) $this->BeginTrans(); - return $this->GetOne("select $flds from $tables where $where for update"); + return $this->GetOne("select $col from $tables where $where for update"); } // returns true/false. @@ -201,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) { @@ -224,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; @@ -236,6 +237,8 @@ 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)."'"; @@ -457,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; @@ -478,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; @@ -496,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; @@ -578,7 +584,7 @@ select viewname,'V' from pg_views where viewname like $mask"; } - function &MetaIndexes ($table, $primary = FALSE) + function MetaIndexes ($table, $primary = FALSE, $owner = false) { global $ADODB_FETCH_MODE; @@ -659,7 +665,7 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))'; if (strlen($db) == 0) $db = 'template1'; $db = adodb_addslashes($db); if ($str) { - $host = split(":", $str); + $host = explode(":", $str); if ($host[0]) $str = "host=".adodb_addslashes($host[0]); else $str = ''; if (isset($host[1])) $str .= " port=$host[1]"; @@ -713,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) { @@ -886,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; } @@ -925,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 @@ -943,6 +949,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{ function _decode($blob) { + if ($blob === NULL) return NULL; eval('$realblob="'.adodb_str_replace(array('"','$'),array('\"','\$'),$blob).'";'); return $realblob; } @@ -1049,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->connection->uniqueIisR || empty($fieldobj->unique))) return 'I'; case 'OID': case 'SERIAL': diff --git a/lib/adodb/drivers/adodb-postgres7.inc.php b/lib/adodb/drivers/adodb-postgres7.inc.php index 5c3d7bb6..eecfdc37 100644 --- a/lib/adodb/drivers/adodb-postgres7.inc.php +++ b/lib/adodb/drivers/adodb-postgres7.inc.php @@ -1,6 +1,6 @@ = 0) ? " OFFSET ".((integer)$offset) : ''; $limitStr = ($nrows >= 0) ? " LIMIT ".((integer)$nrows) : ''; if ($secs2cache) - $rs =& $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr); + $rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr); else - $rs =& $this->Execute($sql."$limitStr$offsetStr",$inputarr); + $rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr); return $rs; } @@ -56,9 +56,58 @@ class ADODB_postgres7 extends ADODB_postgres64 { } */ - - // from Edward Jaramilla, improved version - works on pg 7.4 + /* + I discovered that the MetaForeignKeys method no longer worked for Postgres 8.3. + I went ahead and modified it to work for both 8.2 and 8.3. + Please feel free to include this change in your next release of adodb. + William Kolodny [William.Kolodny#gt-t.net] + */ function MetaForeignKeys($table, $owner=false, $upper=false) + { + $sql=" + SELECT fum.ftblname AS lookup_table, split_part(fum.rf, ')'::text, 1) AS lookup_field, + fum.ltable AS dep_table, split_part(fum.lf, ')'::text, 1) AS dep_field + FROM ( + SELECT fee.ltable, fee.ftblname, fee.consrc, split_part(fee.consrc,'('::text, 2) AS lf, + split_part(fee.consrc, '('::text, 3) AS rf + FROM ( + SELECT foo.relname AS ltable, foo.ftblname, + pg_get_constraintdef(foo.oid) AS consrc + FROM ( + SELECT c.oid, c.conname AS name, t.relname, ft.relname AS ftblname + FROM pg_constraint c + JOIN pg_class t ON (t.oid = c.conrelid) + JOIN pg_class ft ON (ft.oid = c.confrelid) + JOIN pg_namespace nft ON (nft.oid = ft.relnamespace) + LEFT JOIN pg_description ds ON (ds.objoid = c.oid) + JOIN pg_namespace n ON (n.oid = t.relnamespace) + WHERE c.contype = 'f'::\"char\" + ORDER BY t.relname, n.nspname, c.conname, c.oid + ) foo + ) fee) fum + WHERE fum.ltable='".strtolower($table)."' + ORDER BY fum.ftblname, fum.ltable, split_part(fum.lf, ')'::text, 1) + "; + $rs = $this->Execute($sql); + + if (!$rs || $rs->EOF) return false; + + $a = array(); + while (!$rs->EOF) { + if ($upper) { + $a[strtoupper($rs->Fields('lookup_table'))][] = strtoupper(str_replace('"','',$rs->Fields('dep_field').'='.$rs->Fields('lookup_field'))); + } else { + $a[$rs->Fields('lookup_table')][] = str_replace('"','',$rs->Fields('dep_field').'='.$rs->Fields('lookup_field')); + } + $rs->MoveNext(); + } + + return $a; + + } + + // from Edward Jaramilla, improved version - works on pg 7.4 + function _old_MetaForeignKeys($table, $owner=false, $upper=false) { $sql = 'SELECT t.tgargs as args FROM @@ -72,11 +121,11 @@ class ADODB_postgres7 extends ADODB_postgres64 { ORDER BY t.tgrelid'; - $rs =& $this->Execute($sql); + $rs = $this->Execute($sql); if (!$rs || $rs->EOF) return false; - $arr =& $rs->GetArray(); + $arr = $rs->GetArray(); $a = array(); foreach($arr as $v) { $data = explode(chr(0), $v['args']); @@ -91,7 +140,7 @@ class ADODB_postgres7 extends ADODB_postgres64 { return $a; } - function _query($sql,$inputarr) + function _query($sql,$inputarr=false) { if (! $this->_bindInputArray) { // We don't have native support for parameterized queries, so let's emulate it at the parent diff --git a/lib/adodb/drivers/adodb-postgres8.inc.php b/lib/adodb/drivers/adodb-postgres8.inc.php new file mode 100644 index 00000000..3134e3c3 --- /dev/null +++ b/lib/adodb/drivers/adodb-postgres8.inc.php @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/lib/adodb/drivers/adodb-sqlite.inc.php b/lib/adodb/drivers/adodb-sqlite.inc.php index f756c3cd..bb95a42e 100644 --- a/lib/adodb/drivers/adodb-sqlite.inc.php +++ b/lib/adodb/drivers/adodb-sqlite.inc.php @@ -1,6 +1,6 @@ fetchMode !== false) $savem = $this->SetFetchMode(false); - $rs = $this->Execute("PRAGMA table_info('$tab')"); + $rs = $this->Execute("PRAGMA table_info('$table')"); if (isset($savem)) $this->SetFetchMode($savem); if (!$rs) { $ADODB_FETCH_MODE = $save; @@ -190,14 +190,14 @@ class ADODB_sqlite extends ADOConnection { return $rez; } - 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 $offset" : ''; $limitStr = ($nrows >= 0) ? " LIMIT $nrows" : ($offset >= 0 ? ' LIMIT 999999999' : ''); 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; } @@ -261,7 +261,7 @@ class ADODB_sqlite extends ADOConnection { return @sqlite_close($this->_connectionID); } - function &MetaIndexes($table, $primary = FALSE, $owner=false) + function MetaIndexes($table, $primary = FALSE, $owner=false, $owner = false) { $false = false; // save old fetch mode @@ -350,7 +350,7 @@ class ADORecordset_sqlite extends ADORecordSet { } - function &FetchField($fieldOffset = -1) + function FetchField($fieldOffset = -1) { $fld = new ADOFieldObject; $fld->name = sqlite_field_name($this->_queryID, $fieldOffset); @@ -393,5 +393,6 @@ class ADORecordset_sqlite extends ADORecordSet { function _close() { } + } -?> +?> \ No newline at end of file diff --git a/lib/adodb/drivers/adodb-sqlitepo.inc.php b/lib/adodb/drivers/adodb-sqlitepo.inc.php new file mode 100644 index 00000000..2bdb99a7 --- /dev/null +++ b/lib/adodb/drivers/adodb-sqlitepo.inc.php @@ -0,0 +1,62 @@ +ADODB_sqlite(); + } +} + +/*-------------------------------------------------------------------------------------- + Class Name: Recordset +--------------------------------------------------------------------------------------*/ + +class ADORecordset_sqlitepo extends ADORecordset_sqlite { + + var $databaseType = 'sqlitepo'; + + function ADORecordset_sqlitepo($queryID,$mode=false) + { + $this->ADORecordset_sqlite($queryID,$mode); + } + + // Modified to strip table names from returned fields + function _fetch($ignore_fields=false) + { + $this->fields = array(); + $fields = @sqlite_fetch_array($this->_queryID,$this->fetchMode); + if(is_array($fields)) + foreach($fields as $n => $v) + { + if(($p = strpos($n, ".")) !== false) + $n = substr($n, $p+1); + $this->fields[$n] = $v; + } + + return !empty($this->fields); + } +} +?> \ No newline at end of file