diff options
Diffstat (limited to 'libraries/adodb/adodb.inc.php')
| -rwxr-xr-x | libraries/adodb/adodb.inc.php | 943 |
1 files changed, 561 insertions, 382 deletions
diff --git a/libraries/adodb/adodb.inc.php b/libraries/adodb/adodb.inc.php index 5567f789..02b375ae 100755 --- a/libraries/adodb/adodb.inc.php +++ b/libraries/adodb/adodb.inc.php @@ -12,9 +12,9 @@ */ /** - \mainpage + \mainpage - @version V4.94 23 Jan 2007 (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved. + @version V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved. Released under both BSD license and Lesser GPL library license. You can choose which license you prefer. @@ -54,9 +54,12 @@ $ADODB_vers, // database version $ADODB_COUNTRECS, // count number of records returned - slows down query $ADODB_CACHE_DIR, // directory to cache recordsets + $ADODB_CACHE, + $ADODB_CACHE_CLASS, $ADODB_EXTENSION, // ADODB extension installed $ADODB_COMPAT_FETCH, // If $ADODB_COUNTRECS and this is true, $rs->fields is available on EOF $ADODB_FETCH_MODE, // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default... + $ADODB_GETONE_EOF, $ADODB_QUOTE_FIELDNAMES; // Allows you to force quotes (backticks) around field names in queries generated by getinsertsql and getupdatesql. //============================================================================================== @@ -115,17 +118,11 @@ define('ADODB_PHPVER',0x5200); } else if ($_adodb_ver >= 5.0) { define('ADODB_PHPVER',0x5000); - } else if ($_adodb_ver > 4.299999) { # 4.3 - define('ADODB_PHPVER',0x4300); - } else if ($_adodb_ver > 4.199999) { # 4.2 - define('ADODB_PHPVER',0x4200); - } else if (strnatcmp(PHP_VERSION,'4.0.5')>=0) { - define('ADODB_PHPVER',0x4050); - } else { - define('ADODB_PHPVER',0x4000); - } + } else + die("PHP5 or later required. You are running ".PHP_VERSION); } + //if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2); @@ -153,12 +150,16 @@ $ADODB_COUNTRECS, // count number of records returned - slows down query $ADODB_CACHE_DIR, // directory to cache recordsets $ADODB_FETCH_MODE, + $ADODB_CACHE, + $ADODB_CACHE_CLASS, $ADODB_FORCE_TYPE, + $ADODB_GETONE_EOF, $ADODB_QUOTE_FIELDNAMES; + if (empty($ADODB_CACHE_CLASS)) $ADODB_CACHE_CLASS = 'ADODB_Cache_File' ; $ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT; $ADODB_FORCE_TYPE = ADODB_FORCE_VALUE; - + $ADODB_GETONE_EOF = null; if (!isset($ADODB_CACHE_DIR)) { $ADODB_CACHE_DIR = '/tmp'; //(isset($_ENV['TMP'])) ? $_ENV['TMP'] : '/tmp'; @@ -171,12 +172,12 @@ // Initialize random number generator for randomizing cache flushes // -- note Since PHP 4.2.0, the seed becomes optional and defaults to a random value if omitted. - srand(((double)microtime())*1000000); + srand(((double)microtime())*1000000); /** * ADODB version as a string. */ - $ADODB_vers = 'V4.94 23 Jan 2007 (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.'; + $ADODB_vers = 'V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved. Released BSD & LGPL.'; /** * Determines whether recordset->RecordCount() is used. @@ -215,7 +216,7 @@ */ } - + // for transaction handling function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) { @@ -227,6 +228,95 @@ } } + //------------------ + // class for caching + class ADODB_Cache_File { + + var $createdir = true; // requires creation of temp dirs + + function ADODB_Cache_File() + { + global $ADODB_INCLUDED_CSV; + if (empty($ADODB_INCLUDED_CSV)) include_once(ADODB_DIR.'/adodb-csvlib.inc.php'); + } + + // write serialised recordset to cache item/file + function writecache($filename, $contents, $debug, $secs2cache) + { + return adodb_write_file($filename, $contents,$debug); + } + + // load serialised recordset and unserialise it + function &readcache($filename, &$err, $secs2cache, $rsClass) + { + $rs = csv2rs($filename,$err,$secs2cache,$rsClass); + return $rs; + } + + // flush all items in cache + function flushall($debug=false) + { + global $ADODB_CACHE_DIR; + + $rez = false; + + if (strlen($ADODB_CACHE_DIR) > 1) { + $rez = $this->_dirFlush($ADODB_CACHE_DIR); + if ($debug) ADOConnection::outp( "flushall: $dir<br><pre>\n". $rez."</pre>"); + } + return $rez; + } + + // flush one file in cache + function flushcache($f, $debug=false) + { + if (!@unlink($f)) { + if ($debug) ADOConnection::outp( "flushcache: failed for $f"); + } + } + + function getdirname($hash) + { + global $ADODB_CACHE_DIR; + if (!isset($this->notSafeMode)) $this->notSafeMode = !ini_get('safe_mode'); + return ($this->notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($hash,0,2) : $ADODB_CACHE_DIR; + } + + // create temp directories + function createdir($hash, $debug) + { + $dir = $this->getdirname($hash); + if ($this->notSafeMode && !file_exists($dir)) { + $oldu = umask(0); + if (!@mkdir($dir,0771)) if(!is_dir($dir) && $debug) ADOConnection::outp("Cannot create $dir"); + umask($oldu); + } + + return $dir; + } + + /** + * Private function to erase all of the files and subdirectories in a directory. + * + * Just specify the directory, and tell it if you want to delete the directory or just clear it out. + * Note: $kill_top_level is used internally in the function to flush subdirectories. + */ + function _dirFlush($dir, $kill_top_level = false) + { + if(!$dh = @opendir($dir)) return; + + while (($obj = readdir($dh))) { + if($obj=='.' || $obj=='..') continue; + $f = $dir.'/'.$obj; + + if (strpos($obj,'.cache')) @unlink($f); + if (is_dir($f)) $this->_dirFlush($f, true); + } + if ($kill_top_level === true) @rmdir($dir); + return true; + } + } + //============================================================================================== // CLASS ADOConnection //============================================================================================== @@ -287,6 +377,7 @@ var $sysDate = false; /// name of function that returns the current date var $sysTimeStamp = false; /// name of function that returns the current timestamp + var $sysUTimeStamp = false; // name of function that returns the current timestamp accurate to the microsecond or nearest fraction var $arrayClass = 'ADORecordSet_array'; /// name of class used to generate array recordsets, which are pre-downloaded recordsets var $noNullStrings = false; /// oracle specific stuff - if true ensures that '' is converted to ' ' @@ -340,7 +431,7 @@ die('Virtual Class -- cannot instantiate'); } - function Version() + static function Version() { global $ADODB_vers; @@ -373,7 +464,7 @@ * All error messages go through this bottleneck function. * You can define your own handler by defining the function name in ADODB_OUTP. */ - function outp($msg,$newline=true) + static function outp($msg,$newline=true) { global $ADODB_FLUSH,$ADODB_OUTP; @@ -399,7 +490,7 @@ function Time() { - $rs =& $this->_Execute("select $this->sysTimeStamp"); + $rs = $this->_Execute("select $this->sysTimeStamp"); if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields)); return false; @@ -424,6 +515,10 @@ if ($argDatabaseName != "") $this->database = $argDatabaseName; $this->_isPersistentConnection = false; + + global $ADODB_CACHE; + if (empty($ADODB_CACHE)) $this->_CreateCache(); + if ($forceNew) { if ($rez=$this->_nconnect($this->host, $this->user, $this->password, $this->database)) return true; } else { @@ -479,6 +574,7 @@ */ function PConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") { + if (defined('ADODB_NEVER_PERSIST')) return $this->Connect($argHostname,$argUsername,$argPassword,$argDatabaseName); @@ -488,6 +584,10 @@ if ($argDatabaseName != "") $this->database = $argDatabaseName; $this->_isPersistentConnection = true; + + global $ADODB_CACHE; + if (empty($ADODB_CACHE)) $this->_CreateCache(); + if ($rez = $this->_pconnect($this->host, $this->user, $this->password, $this->database)) return true; if (isset($rez)) { $err = $this->ErrorMsg(); @@ -506,6 +606,30 @@ return $ret; } + function outp_throw($msg,$src='WARN',$sql='') + { + if (defined('ADODB_ERROR_HANDLER') && ADODB_ERROR_HANDLER == 'adodb_throw') { + adodb_throw($this->databaseType,$src,-9999,$msg,$sql,false,$this); + return; + } + ADOConnection::outp($msg); + } + + // create cache class. Code is backward compat with old memcache implementation + function _CreateCache() + { + global $ADODB_CACHE, $ADODB_CACHE_CLASS; + + if ($this->memCache) { + global $ADODB_INCLUDED_MEMCACHE; + + if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php'); + $ADODB_CACHE = new ADODB_Cache_MemCache($this); + } else + $ADODB_CACHE = new $ADODB_CACHE_CLASS($this); + + } + // Format date column in sql string given an input format that understands Y M D function SQLDate($fmt, $col=false) { @@ -532,7 +656,7 @@ { return $sql; } - + /** * Some databases, eg. mssql require a different function for preparing * stored procedures. So we cannot use Prepare(). @@ -551,7 +675,7 @@ { return $this->Prepare($sql,$param); } - + /** * PEAR DB Compat */ @@ -570,6 +694,7 @@ function q(&$s) { + #if (!empty($this->qNull)) if ($s == 'null') return $s; $s = $this->qstr($s,false); } @@ -637,9 +762,9 @@ /** * PEAR DB Compat - do not use internally. */ - function &Query($sql, $inputarr=false) + function Query($sql, $inputarr=false) { - $rs = &$this->Execute($sql, $inputarr); + $rs = $this->Execute($sql, $inputarr); if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error(); return $rs; } @@ -648,9 +773,9 @@ /** * PEAR DB Compat - do not use internally */ - function &LimitQuery($sql, $offset, $count, $params=false) + function LimitQuery($sql, $offset, $count, $params=false) { - $rs = &$this->SelectLimit($sql, $count, $offset, $params); + $rs = $this->SelectLimit($sql, $count, $offset, $params); if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error(); return $rs; } @@ -742,7 +867,7 @@ { if ($this->transOff > 0) { $this->transOff += 1; - return; + return true; } $this->_oldRaiseFn = $this->raiseErrorFn; @@ -750,8 +875,9 @@ $this->_transOK = true; if ($this->debug && $this->transCnt > 0) ADOConnection::outp("Bad Transaction: StartTrans called within BeginTrans"); - $this->BeginTrans(); + $ok = $this->BeginTrans(); $this->transOff = 1; + return $ok; } @@ -818,11 +944,11 @@ * @param [inputarr] holds the input data to bind to. Null elements will be set to null. * @return RecordSet or false */ - function &Execute($sql,$inputarr=false) + function Execute($sql,$inputarr=false) { if ($this->fnExecute) { $fn = $this->fnExecute; - $ret =& $fn($this,$sql,$inputarr); + $ret = $fn($this,$sql,$inputarr); if (isset($ret)) return $ret; } if ($inputarr) { @@ -836,7 +962,7 @@ if (!is_array($sql) && !$this->_bindInputArray) { $sqlarr = explode('?',$sql); - + $nparams = sizeof($sqlarr)-1; if (!$array_2d) $inputarr = array($inputarr); foreach($inputarr as $arr) { $sql = ''; $i = 0; @@ -861,14 +987,16 @@ else $sql .= $v; $i += 1; - } + + if ($i == $nparams) break; + } // while if (isset($sqlarr[$i])) { $sql .= $sqlarr[$i]; - if ($i+1 != sizeof($sqlarr)) ADOConnection::outp( "Input Array does not match ?: ".htmlspecialchars($sql)); + if ($i+1 != sizeof($sqlarr)) $this->outp_throw( "Input Array does not match ?: ".htmlspecialchars($sql),'Execute'); } else if ($i != sizeof($sqlarr)) - ADOConnection::outp( "Input array does not match ?: ".htmlspecialchars($sql)); + $this->outp_throw( "Input array does not match ?: ".htmlspecialchars($sql),'Execute'); - $ret =& $this->_Execute($sql); + $ret = $this->_Execute($sql); if (!$ret) return $ret; } } else { @@ -879,22 +1007,22 @@ $stmt = $sql; foreach($inputarr as $arr) { - $ret =& $this->_Execute($stmt,$arr); + $ret = $this->_Execute($stmt,$arr); if (!$ret) return $ret; } } else { - $ret =& $this->_Execute($sql,$inputarr); + $ret = $this->_Execute($sql,$inputarr); } } } else { - $ret =& $this->_Execute($sql,false); + $ret = $this->_Execute($sql,false); } return $ret; } - function &_Execute($sql,$inputarr=false) + function _Execute($sql,$inputarr=false) { if ($this->debug) { global $ADODB_INCLUDED_LIB; @@ -919,14 +1047,16 @@ } if ($this->_queryID === true) { // return simplified recordset for inserts/updates/deletes with lower overhead - $rs = new ADORecordSet_empty(); + $rsclass = $this->rsPrefix.'empty'; + $rs = (class_exists($rsclass)) ? new $rsclass(): new ADORecordSet_empty(); + return $rs; } // return real recordset from select statement $rsclass = $this->rsPrefix.$this->databaseType; $rs = new $rsclass($this->_queryID,$this->fetchMode); - $rs->connection = &$this; // Pablo suggestion + $rs->connection = $this; // Pablo suggestion $rs->Init(); if (is_array($sql)) $rs->sql = $sql[0]; else $rs->sql = $sql; @@ -934,7 +1064,7 @@ global $ADODB_COUNTRECS; if ($ADODB_COUNTRECS) { if (!$rs->EOF) { - $rs = &$this->_rs2rs($rs,-1,-1,!is_array($sql)); + $rs = $this->_rs2rs($rs,-1,-1,!is_array($sql)); $rs->_queryID = $this->_queryID; } else $rs->_numOfRows = 0; @@ -1079,7 +1209,7 @@ { // owner not used in base class - see oci8 $p = array(); - $objs =& $this->MetaColumns($table); + $objs = $this->MetaColumns($table); if ($objs) { foreach($objs as $v) { if (!empty($v->primary_key)) @@ -1128,7 +1258,7 @@ * @param [secs2cache] is a private parameter only used by jlim * @return the recordset ($rs->databaseType == 'array') */ - function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0) + function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0) { if ($this->hasTop && $nrows > 0) { // suggested by Reinhard Balling. Access requires top after distinct @@ -1137,7 +1267,7 @@ if ($ismssql) $isaccess = false; else $isaccess = (strpos($this->databaseType,'access') !== false); - if ($offset <= 0) { + if ($offset <= 0) { // access includes ties in result if ($isaccess) { @@ -1145,9 +1275,9 @@ '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); if ($secs2cache != 0) { - $ret =& $this->CacheExecute($secs2cache, $sql,$inputarr); + $ret = $this->CacheExecute($secs2cache, $sql,$inputarr); } else { - $ret =& $this->Execute($sql,$inputarr); + $ret = $this->Execute($sql,$inputarr); } return $ret; // PHP5 fix } else if ($ismssql){ @@ -1176,16 +1306,13 @@ $savec = $ADODB_COUNTRECS; $ADODB_COUNTRECS = false; - if ($offset>0){ - if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); - else $rs = &$this->Execute($sql,$inputarr); - } else { - if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); - else $rs = &$this->Execute($sql,$inputarr); - } + + if ($secs2cache != 0) $rs = $this->CacheExecute($secs2cache,$sql,$inputarr); + else $rs = $this->Execute($sql,$inputarr); + $ADODB_COUNTRECS = $savec; if ($rs && !$rs->EOF) { - $rs =& $this->_rs2rs($rs,$nrows,$offset); + $rs = $this->_rs2rs($rs,$nrows,$offset); } //print_r($rs); return $rs; @@ -1196,11 +1323,11 @@ * * @param rs the recordset to serialize */ - function &SerializableRS(&$rs) + function SerializableRS(&$rs) { - $rs2 =& $this->_rs2rs($rs); + $rs2 = $this->_rs2rs($rs); $ignore = false; - $rs2->connection =& $ignore; + $rs2->connection = $ignore; return $rs2; } @@ -1223,12 +1350,12 @@ } $dbtype = $rs->databaseType; if (!$dbtype) { - $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ? + $rs = $rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ? return $rs; } if (($dbtype == 'array' || $dbtype == 'csv') && $nrows == -1 && $offset == -1) { $rs->MoveFirst(); - $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ? + $rs = $rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ? return $rs; } $flds = array(); @@ -1236,14 +1363,14 @@ $flds[] = $rs->FetchField($i); } - $arr =& $rs->GetArrayLimit($nrows,$offset); + $arr = $rs->GetArrayLimit($nrows,$offset); //print_r($arr); if ($close) $rs->Close(); $arrayClass = $this->arrayClass; $rs2 = new $arrayClass(); - $rs2->connection = &$this; + $rs2->connection = $this; $rs2->sql = $rs->sql; $rs2->dataProvider = $this->dataProvider; $rs2->InitArrayFields($arr,$flds); @@ -1254,35 +1381,35 @@ /* * Return all rows. Compat with PEAR DB */ - function &GetAll($sql, $inputarr=false) + function GetAll($sql, $inputarr=false) { - $arr =& $this->GetArray($sql,$inputarr); + $arr = $this->GetArray($sql,$inputarr); return $arr; } - function &GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false) + function GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false) { - $rs =& $this->Execute($sql, $inputarr); + $rs = $this->Execute($sql, $inputarr); if (!$rs) { $false = false; return $false; } - $arr =& $rs->GetAssoc($force_array,$first2cols); + $arr = $rs->GetAssoc($force_array,$first2cols); return $arr; } - function &CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false) + function CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false) { if (!is_numeric($secs2cache)) { $first2cols = $force_array; $force_array = $inputarr; } - $rs =& $this->CacheExecute($secs2cache, $sql, $inputarr); + $rs = $this->CacheExecute($secs2cache, $sql, $inputarr); if (!$rs) { $false = false; return $false; } - $arr =& $rs->GetAssoc($force_array,$first2cols); + $arr = $rs->GetAssoc($force_array,$first2cols); return $arr; } @@ -1295,26 +1422,43 @@ */ function GetOne($sql,$inputarr=false) { - global $ADODB_COUNTRECS; + global $ADODB_COUNTRECS,$ADODB_GETONE_EOF; $crecs = $ADODB_COUNTRECS; $ADODB_COUNTRECS = false; $ret = false; - $rs = &$this->Execute($sql,$inputarr); + $rs = $this->Execute($sql,$inputarr); if ($rs) { - if (!$rs->EOF) $ret = reset($rs->fields); + if ($rs->EOF) $ret = $ADODB_GETONE_EOF; + else $ret = reset($rs->fields); + $rs->Close(); } $ADODB_COUNTRECS = $crecs; return $ret; } + // $where should include 'WHERE fld=value' + function GetMedian($table, $field,$where = '') + { + $total = $this->GetOne("select count(*) from $table $where"); + if (!$total) return false; + + $midrow = (integer) ($total/2); + $rs = $this->SelectLimit("select $field from $table $where order by 1",1,$midrow); + if ($rs && !$rs->EOF) return reset($rs->fields); + return false; + } + + function CacheGetOne($secs2cache,$sql=false,$inputarr=false) { + global $ADODB_GETONE_EOF; $ret = false; - $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); - if ($rs) { - if (!$rs->EOF) $ret = reset($rs->fields); + $rs = $this->CacheExecute($secs2cache,$sql,$inputarr); + if ($rs) { + if ($rs->EOF) $ret = $ADODB_GETONE_EOF; + else $ret = reset($rs->fields); $rs->Close(); } @@ -1323,8 +1467,8 @@ function GetCol($sql, $inputarr = false, $trim = false) { - $rv = false; - $rs = &$this->Execute($sql, $inputarr); + + $rs = $this->Execute($sql, $inputarr); if ($rs) { $rv = array(); if ($trim) { @@ -1339,15 +1483,16 @@ } } $rs->Close(); - } + } else + $rv = false; return $rv; } function CacheGetCol($secs, $sql = false, $inputarr = false,$trim=false) { - $rv = false; - $rs = &$this->CacheExecute($secs, $sql, $inputarr); + $rs = $this->CacheExecute($secs, $sql, $inputarr); if ($rs) { + $rv = array(); if ($trim) { while (!$rs->EOF) { $rv[] = trim(reset($rs->fields)); @@ -1360,13 +1505,15 @@ } } $rs->Close(); - } + } else + $rv = false; + return $rv; } - function &Transpose(&$rs,$addfieldnames=true) + function Transpose(&$rs,$addfieldnames=true) { - $rs2 =& $this->_rs2rs($rs); + $rs2 = $this->_rs2rs($rs); $false = false; if (!$rs2) return $false; @@ -1393,13 +1540,13 @@ * @param sql SQL statement * @param [inputarr] input bind array */ - function &GetArray($sql,$inputarr=false) + function GetArray($sql,$inputarr=false) { global $ADODB_COUNTRECS; $savec = $ADODB_COUNTRECS; $ADODB_COUNTRECS = false; - $rs =& $this->Execute($sql,$inputarr); + $rs = $this->Execute($sql,$inputarr); $ADODB_COUNTRECS = $savec; if (!$rs) if (defined('ADODB_PEAR')) { @@ -1409,24 +1556,24 @@ $false = false; return $false; } - $arr =& $rs->GetArray(); + $arr = $rs->GetArray(); $rs->Close(); return $arr; } - function &CacheGetAll($secs2cache,$sql=false,$inputarr=false) + function CacheGetAll($secs2cache,$sql=false,$inputarr=false) { - $arr =& $this->CacheGetArray($secs2cache,$sql,$inputarr); + $arr = $this->CacheGetArray($secs2cache,$sql,$inputarr); return $arr; } - function &CacheGetArray($secs2cache,$sql=false,$inputarr=false) + function CacheGetArray($secs2cache,$sql=false,$inputarr=false) { global $ADODB_COUNTRECS; $savec = $ADODB_COUNTRECS; $ADODB_COUNTRECS = false; - $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr); + $rs = $this->CacheExecute($secs2cache,$sql,$inputarr); $ADODB_COUNTRECS = $savec; if (!$rs) @@ -1437,12 +1584,17 @@ $false = false; return $false; } - $arr =& $rs->GetArray(); + $arr = $rs->GetArray(); $rs->Close(); return $arr; } - + function GetRandRow($sql, $arr= false) + { + $rezarr = $this->GetAll($sql, $arr); + $sz = sizeof($rezarr); + return $rezarr[abs(rand()) % $sz]; + } /** * Return one row of sql statement. Recordset is disposed for you. @@ -1450,13 +1602,13 @@ * @param sql SQL statement * @param [inputarr] input bind array */ - function &GetRow($sql,$inputarr=false) + function GetRow($sql,$inputarr=false) { global $ADODB_COUNTRECS; $crecs = $ADODB_COUNTRECS; $ADODB_COUNTRECS = false; - $rs =& $this->Execute($sql,$inputarr); + $rs = $this->Execute($sql,$inputarr); $ADODB_COUNTRECS = $crecs; if ($rs) { @@ -1470,12 +1622,13 @@ return $false; } - function &CacheGetRow($secs2cache,$sql=false,$inputarr=false) + function CacheGetRow($secs2cache,$sql=false,$inputarr=false) { - $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr); + $rs = $this->CacheExecute($secs2cache,$sql,$inputarr); if ($rs) { - $arr = false; if (!$rs->EOF) $arr = $rs->fields; + else $arr = array(); + $rs->Close(); return $arr; } @@ -1530,16 +1683,16 @@ * @param [inputarr] array of bind variables * @return the recordset ($rs->databaseType == 'array') */ - function &CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false) + function CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false) { if (!is_numeric($secs2cache)) { if ($sql === false) $sql = -1; if ($offset == -1) $offset = false; // sql, nrows, offset,inputarr - $rs =& $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs); + $rs = $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs); } else { - if ($sql === false) ADOConnection::outp( "Warning: \$sql missing from CacheSelectLimit()"); - $rs =& $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache); + if ($sql === false) $this->outp_throw("Warning: \$sql missing from CacheSelectLimit()",'CacheSelectLimit'); + $rs = $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache); } return $rs; } @@ -1549,102 +1702,24 @@ * Flush cached recordsets that match a particular $sql statement. * If $sql == false, then we purge all files in the cache. */ - function CacheFlush($sql=false,$inputarr=false) - { - global $ADODB_CACHE_DIR; - - if ($this->memCache) { - global $ADODB_INCLUDED_MEMCACHE; - - $key = false; - if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php'); - if ($sql) $key = $this->_gencachename($sql.serialize($inputarr),false,true); - FlushMemCache($key, $this->memCacheHost, $this->memCachePort, $this->debug); - return; - } - - if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) { - /*if (strncmp(PHP_OS,'WIN',3) === 0) - $dir = str_replace('/', '\\', $ADODB_CACHE_DIR); - else */ - $dir = $ADODB_CACHE_DIR; - - if ($this->debug) - ADOConnection::outp( "CacheFlush: $dir<br><pre>\n", $this->_dirFlush($dir),"</pre>"); - else - $this->_dirFlush($dir); - return; - } - - global $ADODB_INCLUDED_CSV; - if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); - - $f = $this->_gencachename($sql.serialize($inputarr),false); - adodb_write_file($f,''); // is adodb_write_file needed? - if (!@unlink($f)) - if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f"); - } /** - * Private function to erase all of the files and subdirectories in a directory. - * - * Just specify the directory, and tell it if you want to delete the directory or just clear it out. - * Note: $kill_top_level is used internally in the function to flush subdirectories. - */ - function _dirFlush($dir, $kill_top_level = false) { - if(!$dh = @opendir($dir)) return; - - while (($obj = readdir($dh))) { - if($obj=='.' || $obj=='..') - continue; - - if (!@unlink($dir.'/'.$obj)) - $this->_dirFlush($dir.'/'.$obj, true); - } - if ($kill_top_level === true) - @rmdir($dir); - return true; - } - - - function xCacheFlush($sql=false,$inputarr=false) + * Flush cached recordsets that match a particular $sql statement. + * If $sql == false, then we purge all files in the cache. + */ + function CacheFlush($sql=false,$inputarr=false) { - global $ADODB_CACHE_DIR; - - if ($this->memCache) { - global $ADODB_INCLUDED_MEMCACHE; - $key = false; - if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php'); - if ($sql) $key = $this->_gencachename($sql.serialize($inputarr),false,true); - flushmemCache($key, $this->memCacheHost, $this->memCachePort, $this->debug); - return; - } - - if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) { - if (strncmp(PHP_OS,'WIN',3) === 0) { - $cmd = 'del /s '.str_replace('/','\\',$ADODB_CACHE_DIR).'\adodb_*.cache'; - } else { - //$cmd = 'find "'.$ADODB_CACHE_DIR.'" -type f -maxdepth 1 -print0 | xargs -0 rm -f'; - $cmd = 'rm -rf '.$ADODB_CACHE_DIR.'/[0-9a-f][0-9a-f]/'; - // old version 'rm -f `find '.$ADODB_CACHE_DIR.' -name adodb_*.cache`'; - } - if ($this->debug) { - ADOConnection::outp( "CacheFlush: $cmd<br><pre>\n", system($cmd),"</pre>"); - } else { - exec($cmd); - } - return; - } + global $ADODB_CACHE_DIR, $ADODB_CACHE; - global $ADODB_INCLUDED_CSV; - if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); + if (!$sql) { + $ADODB_CACHE->flushall($this->debug); + return; + } $f = $this->_gencachename($sql.serialize($inputarr),false); - adodb_write_file($f,''); // is adodb_write_file needed? - if (!@unlink($f)) { - if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f"); - } + return $ADODB_CACHE->flushcache($f, $this->debug); } + /** * Private function to generate filename for caching. @@ -1660,10 +1735,9 @@ * Assuming that we can have 50,000 files per directory with good performance, * then we can scale to 12.8 million unique cached recordsets. Wow! */ - function _gencachename($sql,$createdir,$memcache=false) + function _gencachename($sql,$createdir) { - global $ADODB_CACHE_DIR; - static $notSafeMode; + global $ADODB_CACHE, $ADODB_CACHE_DIR; if ($this->fetchMode === false) { global $ADODB_FETCH_MODE; @@ -1672,17 +1746,10 @@ $mode = $this->fetchMode; } $m = md5($sql.$this->databaseType.$this->database.$this->user.$mode); - if ($memcache) return $m; + if (!$ADODB_CACHE->createdir) return $m; + if (!$createdir) $dir = $ADODB_CACHE->getdirname($m); + else $dir = $ADODB_CACHE->createdir($m, $this->debug); - if (!isset($notSafeMode)) $notSafeMode = !ini_get('safe_mode'); - $dir = ($notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($m,0,2) : $ADODB_CACHE_DIR; - - if ($createdir && $notSafeMode && !file_exists($dir)) { - $oldu = umask(0); - if (!mkdir($dir,0771)) - if ($this->debug) ADOConnection::outp( "Unable to mkdir $dir for $sql"); - umask($oldu); - } return $dir.'/adodb_'.$m.'.cache'; } @@ -1696,10 +1763,10 @@ * @param [inputarr] holds the input data to bind to * @return RecordSet or false */ - function &CacheExecute($secs2cache,$sql=false,$inputarr=false) + function CacheExecute($secs2cache,$sql=false,$inputarr=false) { - - + global $ADODB_CACHE; + if (!is_numeric($secs2cache)) { $inputarr = $sql; $sql = $secs2cache; @@ -1712,29 +1779,19 @@ } else $sqlparam = $sql; - if ($this->memCache) { - global $ADODB_INCLUDED_MEMCACHE; - if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php'); - $md5file = $this->_gencachename($sql.serialize($inputarr),false,true); - } else { - global $ADODB_INCLUDED_CSV; - if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); - $md5file = $this->_gencachename($sql.serialize($inputarr),true); - } - + + $md5file = $this->_gencachename($sql.serialize($inputarr),true); $err = ''; if ($secs2cache > 0){ - if ($this->memCache) - $rs = &getmemCache($md5file,$err,$secs2cache, $this->memCacheHost, $this->memCachePort); - else - $rs = &csv2rs($md5file,$err,$secs2cache,$this->arrayClass); + $rs = $ADODB_CACHE->readcache($md5file,$err,$secs2cache,$this->arrayClass); $this->numCacheHits += 1; } else { $err='Timeout 1'; $rs = false; $this->numCacheMisses += 1; } + if (!$rs) { // no cached rs found if ($this->debug) { @@ -1744,34 +1801,40 @@ if ($this->debug !== -1) ADOConnection::outp( " $md5file cache failure: $err (see sql below)"); } - $rs = &$this->Execute($sqlparam,$inputarr); + $rs = $this->Execute($sqlparam,$inputarr); + + if ($rs) { - if ($rs && $this->memCache) { - $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately - if(!putmemCache($md5file, $rs, $this->memCacheHost, $this->memCachePort, $this->memCacheCompress, $this->debug)) { - if ($fn = $this->raiseErrorFn) - $fn($this->databaseType,'CacheExecute',-32000,"Cache write error",$md5file,$sql,$this); - if ($this->debug) ADOConnection::outp( " Cache write error"); - } - } else if ($rs) { $eof = $rs->EOF; - $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately + $rs = $this->_rs2rs($rs); // read entire recordset into memory immediately + $rs->timeCreated = time(); // used by caching $txt = _rs2serialize($rs,false,$sql); // serialize - - if (!adodb_write_file($md5file,$txt,$this->debug)) { - if ($fn = $this->raiseErrorFn) { - $fn($this->databaseType,'CacheExecute',-32000,"Cache write error",$md5file,$sql,$this); + + $ok = $ADODB_CACHE->writecache($md5file,$txt,$this->debug, $secs2cache); + if (!$ok) { + if ($ok === false) { + $em = 'Cache write error'; + $en = -32000; + + if ($fn = $this->raiseErrorFn) { + $fn($this->databaseType,'CacheExecute', $en, $em, $md5file,$sql,$this); + } + } else { + $em = 'Cache file locked warning'; + $en = -32001; + // do not call error handling for just a warning } - if ($this->debug) ADOConnection::outp( " Cache write error"); + + if ($this->debug) ADOConnection::outp( " ".$em); } if ($rs->EOF && !$eof) { $rs->MoveFirst(); - //$rs = &csv2rs($md5file,$err); - $rs->connection = &$this; // Pablo suggestion + //$rs = csv2rs($md5file,$err); + $rs->connection = $this; // Pablo suggestion } } else if (!$this->memCache) - @unlink($md5file); + $ADODB_CACHE->flushcache($md5file); } else { $this->_errorMsg = ''; $this->_errorCode = 0; @@ -1781,9 +1844,9 @@ $fn($this, $secs2cache, $sql, $inputarr); } // ok, set cached object found - $rs->connection = &$this; // Pablo suggestion - if ($this->debug){ - + $rs->connection = $this; // Pablo suggestion + if ($this->debug){ + if ($this->debug == 99) adodb_backtrace(); $inBrowser = isset($_SERVER['HTTP_USER_AGENT']); $ttl = $rs->timeCreated + $secs2cache - time(); $s = is_array($sql) ? $sql[0] : $sql; @@ -1803,17 +1866,17 @@ $forceUpdate means that even if the data has not changed, perform update. */ - function& AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false) + function AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false) { $false = false; $sql = 'SELECT * FROM '.$table; if ($where!==FALSE) $sql .= ' WHERE '.$where; else if ($mode == 'UPDATE' || $mode == 2 /* DB_AUTOQUERY_UPDATE */) { - ADOConnection::outp('AutoExecute: Illegal mode=UPDATE with empty WHERE clause'); + $this->outp_throw('AutoExecute: Illegal mode=UPDATE with empty WHERE clause','AutoExecute'); return $false; } - $rs =& $this->SelectLimit($sql,1); + $rs = $this->SelectLimit($sql,1); if (!$rs) return $false; // table does not exist $rs->tableName = $table; @@ -1827,7 +1890,7 @@ $sql = $this->GetInsertSQL($rs, $fields_values, $magicq); break; default: - ADOConnection::outp("AutoExecute: Unknown mode=$mode"); + $this->outp_throw("AutoExecute: Unknown mode=$mode",'AutoExecute'); return $false; } $ret = false; @@ -1986,7 +2049,7 @@ if (empty($this->_metars)) { $rsclass = $this->rsPrefix.$this->databaseType; $this->_metars = new $rsclass(false,$this->fetchMode); - $this->_metars->connection =& $this; + $this->_metars->connection = $this; } return $this->_metars->MetaType($t,$len,$fieldobj); } @@ -2032,46 +2095,34 @@ } } - function &GetActiveRecordsClass($class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false) + /** + * GetActiveRecordsClass Performs an 'ALL' query + * + * @param mixed $class This string represents the class of the current active record + * @param mixed $table Table used by the active record object + * @param mixed $whereOrderBy Where, order, by clauses + * @param mixed $bindarr + * @param mixed $primkeyArr + * @param array $extra Query extras: limit, offset... + * @param mixed $relations Associative array: table's foreign name, "hasMany", "belongsTo" + * @access public + * @return void + */ + function GetActiveRecordsClass( + $class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false, + $extra=array(), + $relations=array()) { global $_ADODB_ACTIVE_DBS; - - $save = $this->SetFetchMode(ADODB_FETCH_NUM); - if (empty($whereOrderBy)) $whereOrderBy = '1=1'; - $rows = $this->GetAll("select * from ".$table.' WHERE '.$whereOrderBy,$bindarr); - $this->SetFetchMode($save); - - $false = false; - - if ($rows === false) { - return $false; - } - - - if (!isset($_ADODB_ACTIVE_DBS)) { - include(ADODB_DIR.'/adodb-active-record.inc.php'); - } - if (!class_exists($class)) { - ADOConnection::outp("Unknown class $class in GetActiveRcordsClass()"); - return $false; - } - $arr = array(); - foreach($rows as $row) { - - $obj = new $class($table,$primkeyArr,$this); - if ($obj->ErrorMsg()){ - $this->_errorMsg = $obj->ErrorMsg(); - return $false; - } - $obj->Set($row); - $arr[] = $obj; - } - return $arr; + ## reduce overhead of adodb.inc.php -- moved to adodb-active-record.inc.php + ## if adodb-active-recordx is loaded -- should be no issue as they will probably use Find() + if (!isset($_ADODB_ACTIVE_DBS))include_once(ADODB_DIR.'/adodb-active-record.inc.php'); + return adodb_GetActiveRecordsClass($this, $class, $table, $whereOrderBy, $bindarr, $primkeyArr, $extra, $relations); } - function &GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false) + function GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false) { - $arr =& $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr); + $arr = $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr); return $arr; } @@ -2174,27 +2225,27 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return an array of database names. */ - function MetaDatabases() - { - global $ADODB_FETCH_MODE; + function MetaDatabases() + { + global $ADODB_FETCH_MODE; - if ($this->metaDatabasesSQL) { - $save = $ADODB_FETCH_MODE; - $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - - if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); + if ($this->metaDatabasesSQL) { + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + + if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); + + $arr = $this->GetCol($this->metaDatabasesSQL); + if (isset($savem)) $this->SetFetchMode($savem); + $ADODB_FETCH_MODE = $save; - $arr = $this->GetCol($this->metaDatabasesSQL); - if (isset($savem)) $this->SetFetchMode($savem); - $ADODB_FETCH_MODE = $save; + return $arr; + } - return $arr; + return false; } - - return false; - } - + /** * @param ttype can either be 'VIEW' or 'TABLE' or false. * If false, both views and tables are returned. @@ -2205,7 +2256,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return array of tables for current database. */ - function &MetaTables($ttype=false,$showSchema=false,$mask=false) + function MetaTables($ttype=false,$showSchema=false,$mask=false) { global $ADODB_FETCH_MODE; @@ -2225,7 +2276,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 $ADODB_FETCH_MODE = $save; if ($rs === false) return $false; - $arr =& $rs->GetArray(); + $arr = $rs->GetArray(); $arr2 = array(); if ($hast = ($ttype && isset($arr[0][1]))) { @@ -2267,7 +2318,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return array of ADOFieldObjects for current table. */ - function &MetaColumns($table,$normalize=true) + function MetaColumns($table,$normalize=true) { global $ADODB_FETCH_MODE; @@ -2326,7 +2377,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 ) ) */ - function &MetaIndexes($table, $primary = false, $owner = false) + function MetaIndexes($table, $primary = false, $owner = false) { $false = false; return $false; @@ -2338,9 +2389,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return array of column names for current table. */ - function &MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */) + function MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */) { - $objarr =& $this->MetaColumns($table); + $objarr = $this->MetaColumns($table); if (!is_array($objarr)) { $false = false; return $false; @@ -2384,10 +2435,14 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return date string in database date format */ - function DBDate($d) + function DBDate($d, $isfld=false) { if (empty($d) && $d !== 0) return 'null'; - + if ($isfld) return $d; + + if (is_object($d)) return $d->format($this->fmtDate); + + if (is_string($d) && !is_numeric($d)) { if ($d === 'null' || strncmp($d,"'",1) === 0) return $d; if ($this->isoDates) return "'$d'"; @@ -2421,10 +2476,12 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return timestamp string in database timestamp format */ - function DBTimeStamp($ts) + function DBTimeStamp($ts,$isfld=false) { if (empty($ts) && $ts !== 0) return 'null'; - + if ($isfld) return $ts; + if (is_object($ts)) return $ts->format($this->fmtTimeStamp); + # strlen(14) allows YYYYMMDDHHMMSS format if (!is_string($ts) || (is_numeric($ts) && strlen($ts)<14)) return adodb_date($this->fmtTimeStamp,$ts); @@ -2442,7 +2499,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format */ - function UnixDate($v) + static function UnixDate($v) { if (is_object($v)) { // odbtp support @@ -2466,7 +2523,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format */ - function UnixTimeStamp($v) + static function UnixTimeStamp($v) { if (is_object($v)) { // odbtp support @@ -2552,7 +2609,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 // undo magic quotes for " $s = str_replace('\\"','"',$s); - if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything + if ($this->replaceQuote == "\\'" || ini_get('magic_quotes_sybase')) // ' already quoted, no need to change anything return $s; else {// change \' to '' for sybase/mssql $s = str_replace('\\\\','\\',$s); @@ -2586,7 +2643,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 // undo magic quotes for " $s = str_replace('\\"','"',$s); - if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything + if ($this->replaceQuote == "\\'" || ini_get('magic_quotes_sybase')) // ' already quoted, no need to change anything return "'$s'"; else {// change \' to '' for sybase/mssql $s = str_replace('\\\\','\\',$s); @@ -2612,12 +2669,12 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * NOTE: phpLens uses a different algorithm and does not use PageExecute(). * */ - function &PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) + function PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) { global $ADODB_INCLUDED_LIB; if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); - if ($this->pageExecuteCountRows) $rs =& _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache); - else $rs =& _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache); + if ($this->pageExecuteCountRows) $rs = _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache); + else $rs = _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache); return $rs; } @@ -2634,7 +2691,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * @param [inputarr] array of bind variables * @return the recordset ($rs->databaseType == 'array') */ - function &CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) + function CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) { /*switch($this->dataProvider) { case 'postgres': @@ -2642,7 +2699,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 break; default: $secs2cache = 0; break; }*/ - $rs =& $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache); + $rs = $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache); return $rs; } @@ -2664,10 +2721,54 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 // CLASS ADORecordSet_empty //============================================================================================== + class ADODB_Iterator_empty implements Iterator { + + private $rs; + + function __construct($rs) + { + $this->rs = $rs; + } + function rewind() + { + } + + function valid() + { + return !$this->rs->EOF; + } + + function key() + { + return false; + } + + function current() + { + return false; + } + + function next() + { + } + + function __call($func, $params) + { + return call_user_func_array(array($this->rs, $func), $params); + } + + function hasMore() + { + return false; + } + + } + + /** * Lightweight recordset when there are no records to be returned */ - class ADORecordSet_empty + class ADORecordSet_empty implements IteratorAggregate { var $dataProvider = 'empty'; var $databaseType = false; @@ -2682,6 +2783,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 function FetchRow() {return false;} function FieldCount(){ return 0;} function Init() {} + function getIterator() {return new ADODB_Iterator_empty($this);} } //============================================================================================== @@ -2693,15 +2795,61 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 // CLASS ADORecordSet //============================================================================================== - if (PHP_VERSION < 5) include_once(ADODB_DIR.'/adodb-php4.inc.php'); - else include_once(ADODB_DIR.'/adodb-iterator.inc.php'); + class ADODB_Iterator implements Iterator { + + private $rs; + + function __construct($rs) + { + $this->rs = $rs; + } + function rewind() + { + $this->rs->MoveFirst(); + } + + function valid() + { + return !$this->rs->EOF; + } + + function key() + { + return $this->rs->_currentRow; + } + + function current() + { + return $this->rs->fields; + } + + function next() + { + $this->rs->MoveNext(); + } + + function __call($func, $params) + { + return call_user_func_array(array($this->rs, $func), $params); + } + + + function hasMore() + { + return !$this->rs->EOF; + } + + } + + + /** * RecordSet class that represents the dataset returned by the database. * To keep memory overhead low, this class holds only the current row in memory. * No prefetching of data is done, so the RecordCount() can return -1 ( which * means recordcount not known). */ - class ADORecordSet extends ADODB_BASE_RS { + class ADORecordSet implements IteratorAggregate { /* * public variables */ @@ -2751,6 +2899,17 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 $this->_queryID = $queryID; } + function getIterator() + { + return new ADODB_Iterator($this); + } + + /* this is experimental - i don't really know what to return... */ + function __toString() + { + include_once(ADODB_DIR.'/toexport.inc.php'); + return _adodb_export($this,',',',',false,true); + } function Init() @@ -2837,13 +2996,12 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return an array indexed by the rows (0-based) from the recordset */ - function &GetArray($nRows = -1) + function GetArray($nRows = -1) { - global $ADODB_EXTENSION; - if ($ADODB_EXTENSION) { - $results = adodb_getall($this,$nRows); - return $results; - } + global $ADODB_EXTENSION; if ($ADODB_EXTENSION) { + $results = adodb_getall($this,$nRows); + return $results; + } $results = array(); $cnt = 0; while (!$this->EOF && $nRows != $cnt) { @@ -2854,9 +3012,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 return $results; } - function &GetAll($nRows = -1) + function GetAll($nRows = -1) { - $arr =& $this->GetArray($nRows); + $arr = $this->GetArray($nRows); return $arr; } @@ -2878,10 +3036,10 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return an array indexed by the rows (0-based) from the recordset */ - function &GetArrayLimit($nrows,$offset=-1) + function GetArrayLimit($nrows,$offset=-1) { if ($offset <= 0) { - $arr =& $this->GetArray($nrows); + $arr = $this->GetArray($nrows); return $arr; } @@ -2905,9 +3063,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return an array indexed by the rows (0-based) from the recordset */ - function &GetRows($nRows = -1) + function GetRows($nRows = -1) { - $arr =& $this->GetArray($nRows); + $arr = $this->GetArray($nRows); return $arr; } @@ -2927,7 +3085,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * @return an associative array indexed by the first column of the array, * or false if the data has less than 2 cols. */ - function &GetAssoc($force_array = false, $first2cols = false) + function GetAssoc($force_array = false, $first2cols = false) { global $ADODB_EXTENSION; @@ -3018,7 +3176,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 } } - $ref =& $results; # workaround accelerator incompat with PHP 4.4 :( + $ref = $results; # workaround accelerator incompat with PHP 4.4 :( return $ref; } @@ -3064,7 +3222,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format */ - function UnixDate($v) + static function UnixDate($v) { return ADOConnection::UnixDate($v); } @@ -3075,7 +3233,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format */ - function UnixTimeStamp($v) + static function UnixTimeStamp($v) { return ADOConnection::UnixTimeStamp($v); } @@ -3113,7 +3271,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return false or array containing the current record */ - function &FetchRow() + function FetchRow() { if ($this->EOF) { $false = false; @@ -3277,7 +3435,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * $upper 0 = lowercase, 1 = uppercase, 2 = whatever is returned by FetchField */ - function &GetRowAssoc($upper=1) + function GetRowAssoc($upper=1) { $record = array(); // if (!$this->fields) return $record; @@ -3351,7 +3509,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 if ($lnumrows == -1 && $this->connection) { IF ($table) { if ($condition) $condition = " WHERE " . $condition; - $resultrows = &$this->connection->Execute("SELECT COUNT(*) FROM $table $condition"); + $resultrows = $this->connection->Execute("SELECT COUNT(*) FROM $table $condition"); if ($resultrows) $lnumrows = reset($resultrows->fields); } } @@ -3385,7 +3543,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return the ADOFieldObject for that column, or false. */ - function &FetchField($fieldoffset = -1) + function FetchField($fieldoffset = -1) { // must be defined by child class @@ -3397,7 +3555,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * Get the ADOFieldObjects of all columns in an array. * */ - function& FieldTypesArray() + function FieldTypesArray() { $arr = array(); for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) @@ -3411,9 +3569,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return the object with the properties set to the fields of the current row */ - function &FetchObj() + function FetchObj() { - $o =& $this->FetchObject(false); + $o = $this->FetchObject(false); return $o; } @@ -3425,7 +3583,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return the object with the properties set to the fields of the current row */ - function &FetchObject($isupper=true) + function FetchObject($isupper=true) { if (empty($this->_obj)) { $this->_obj = new ADOFetchObj(); @@ -3458,9 +3616,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * Fixed bug reported by tim@orotech.net */ - function &FetchNextObj() + function FetchNextObj() { - $o =& $this->FetchNextObject(false); + $o = $this->FetchNextObject(false); return $o; } @@ -3476,7 +3634,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * Fixed bug reported by tim@orotech.net */ - function &FetchNextObject($isupper=true) + function FetchNextObject($isupper=true) { $o = false; if ($this->_numOfRows != 0 && !$this->EOF) { @@ -3533,6 +3691,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 'CHARACTER' => 'C', 'INTERVAL' => 'C', # Postgres 'MACADDR' => 'C', # postgres + 'VAR_STRING' => 'C', # mysql ## 'LONGCHAR' => 'X', 'TEXT' => 'X', @@ -3556,6 +3715,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 ## 'UNIQUEIDENTIFIER' => 'C', # MS SQL Server ## + 'SMALLDATETIME' => 'T', 'TIME' => 'T', 'TIMESTAMP' => 'T', 'DATETIME' => 'T', @@ -3747,7 +3907,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 //adodb_pr($newarr); $this->_skiprow1 = false; - $this->_array =& $newarr; + $this->_array = $newarr; $this->_colnames = $hdr; adodb_probetypes($newarr,$this->_types); @@ -3801,20 +3961,20 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 */ function InitArrayFields(&$array,&$fieldarr) { - $this->_array =& $array; + $this->_array = $array; $this->_skiprow1= false; if ($fieldarr) { - $this->_fieldobjects =& $fieldarr; + $this->_fieldobjects = $fieldarr; } $this->Init(); } - function &GetArray($nRows=-1) + function GetArray($nRows=-1) { if ($nRows == -1 && $this->_currentRow <= 0 && !$this->_skiprow1) { return $this->_array; } else { - $arr =& ADORecordSet::GetArray($nRows); + $arr = ADORecordSet::GetArray($nRows); return $arr; } } @@ -3834,7 +3994,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 $mode = isset($this->adodbFetchMode) ? $this->adodbFetchMode : $this->fetchMode; if ($mode & ADODB_FETCH_ASSOC) { - if (!isset($this->fields[$colname])) $colname = strtolower($colname); + if (!isset($this->fields[$colname]) && !is_null($this->fields[$colname])) $colname = strtolower($colname); return $this->fields[$colname]; } if (!$this->bind) { @@ -3847,7 +4007,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 return $this->fields[$this->bind[strtoupper($colname)]]; } - function &FetchField($fieldOffset = -1) + function FetchField($fieldOffset = -1) { if (isset($this->_fieldobjects)) { return $this->_fieldobjects[$fieldOffset]; @@ -3962,9 +4122,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 /** * synonym for ADONewConnection for people like me who cannot remember the correct name */ - function &NewADOConnection($db='') + function NewADOConnection($db='') { - $tmp =& ADONewConnection($db); + $tmp = ADONewConnection($db); return $tmp; } @@ -3976,38 +4136,42 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * * @return the freshly created instance of the Connection class. */ - function &ADONewConnection($db='') + function ADONewConnection($db='') { GLOBAL $ADODB_NEWCONNECTION, $ADODB_LASTDB; if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2); $errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false; $false = false; - if ($at = strpos($db,'://')) { + if (($at = strpos($db,'://')) !== FALSE) { $origdsn = $db; - if (PHP_VERSION < 5) $dsna = @parse_url($db); - else { - $fakedsn = 'fake'.substr($db,$at); + $fakedsn = 'fake'.substr($origdsn,$at); + if (($at2 = strpos($origdsn,'@/')) !== FALSE) { + // special handling of oracle, which might not have host + $fakedsn = str_replace('@/','@adodb-fakehost/',$fakedsn); + } $dsna = @parse_url($fakedsn); - $dsna['scheme'] = substr($db,0,$at); + if (!$dsna) { + return $false; + } + $dsna['scheme'] = substr($origdsn,0,$at); + if ($at2 !== FALSE) { + $dsna['host'] = ''; + } - if (strncmp($db,'pdo',3) == 0) { - $sch = explode('_',$dsna['scheme']); - if (sizeof($sch)>1) { - $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; + if (strncmp($origdsn,'pdo',3) == 0) { + $sch = explode('_',$dsna['scheme']); + if (sizeof($sch)>1) { + + $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; + if ($sch[1] == 'sqlite') + $dsna['host'] = rawurlencode($sch[1].':'.rawurldecode($dsna['host'])); + else $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host'])); - $dsna['scheme'] = 'pdo'; - } + $dsna['scheme'] = 'pdo'; } } - if (!$dsna) { - // special handling of oracle, which might not have host - $db = str_replace('@/','@adodb-fakehost/',$db); - $dsna = parse_url($db); - if (!$dsna) return $false; - $dsna['host'] = ''; - } $db = @$dsna['scheme']; if (!$db) return $false; $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; @@ -4035,7 +4199,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 if (!empty($ADODB_NEWCONNECTION)) { $obj = $ADODB_NEWCONNECTION($db); - } else { + } + + if(empty($obj)) { if (!isset($ADODB_LASTDB)) $ADODB_LASTDB = ''; if (empty($db)) $db = $ADODB_LASTDB; @@ -4072,7 +4238,8 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 if (isset($dsna['port'])) $obj->port = $dsna['port']; foreach($opt as $k => $v) { switch(strtolower($k)) { - case 'new': $nconnect = true; $persist = true; break; + case 'new': + $nconnect = true; $persist = true; break; case 'persist': case 'persistent': $persist = $v; break; case 'debug': $obj->debug = (integer) $v; break; @@ -4092,6 +4259,18 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 case 'socket': $obj->socket = $v; break; #oci8 case 'nls_date_format': $obj->NLS_DATE_FORMAT = $v; break; + case 'cachesecs': $obj->cacheSecs = $v; break; + case 'memcache': + $varr = explode(':',$v); + $vlen = sizeof($varr); + if ($vlen == 0) break; + $obj->memCache = true; + $obj->memCacheHost = explode(',',$varr[0]); + if ($vlen == 1) break; + $obj->memCachePort = $varr[1]; + if ($vlen == 2) break; + $obj->memCacheCompress = $varr[2] ? true : false; + break; } } if (empty($persist)) @@ -4142,7 +4321,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 return $drivername; } - function &NewPerfMonitor(&$conn) + function NewPerfMonitor(&$conn) { $false = false; $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType,true); @@ -4156,7 +4335,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 return $perf; } - function &NewDataDictionary(&$conn,$drivername=false) + function NewDataDictionary(&$conn,$drivername=false) { $false = false; if (!$drivername) $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType); @@ -4173,7 +4352,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 $class = "ADODB2_$drivername"; $dict = new $class(); $dict->dataProvider = $conn->dataProvider; - $dict->connection = &$conn; + $dict->connection = $conn; $dict->upperName = strtoupper($drivername); $dict->quote = $conn->nameQuote; if (!empty($conn->_connectionID)) @@ -4209,13 +4388,13 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 @param printOrArr Pass in a boolean to indicate print, or an $exception->trace array (assumes that print is true then). @param levels Number of levels to display */ - function adodb_backtrace($printOrArr=true,$levels=9999) + function adodb_backtrace($printOrArr=true,$levels=9999,$ishtml=null) { global $ADODB_INCLUDED_LIB; if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); - return _adodb_backtrace($printOrArr,$levels); + return _adodb_backtrace($printOrArr,$levels,0,$ishtml); } } -?> +?>
\ No newline at end of file |
