From: skodak Date: Tue, 29 Aug 2006 20:23:17 +0000 (+0000) Subject: import of new ADODB v4.92 library X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=c0e3c8d2b2c4ef64dd43d199229cde20b5520cbd;p=moodle.git import of new ADODB v4.92 library --- diff --git a/lib/adodb/adodb-active-record.inc.php b/lib/adodb/adodb-active-record.inc.php index 96aa66122c..767193fbc5 100644 --- a/lib/adodb/adodb-active-record.inc.php +++ b/lib/adodb/adodb-active-record.inc.php @@ -1,7 +1,7 @@ UpdateActiveTable($pkeyarr); } + function __wakeup() + { + $class = get_class($this); + new $class; + } + function _pluralize($table) { $ut = strtoupper($table); diff --git a/lib/adodb/adodb-csvlib.inc.php b/lib/adodb/adodb-csvlib.inc.php index 78b75be6ff..a2826ca077 100644 --- a/lib/adodb/adodb-csvlib.inc.php +++ b/lib/adodb/adodb-csvlib.inc.php @@ -8,7 +8,7 @@ $ADODB_INCLUDED_CSV = 1; /* - V4.91 2 Aug 2006 (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved. + V4.92 29 Aug 2006 (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved. Released under both BSD license and Lesser GPL library license. Whenever there is any discrepancy between the two licenses, the BSD license will take precedence. See License.txt. diff --git a/lib/adodb/adodb-datadict.inc.php b/lib/adodb/adodb-datadict.inc.php index fd25aab9b2..27ef41afb1 100644 --- a/lib/adodb/adodb-datadict.inc.php +++ b/lib/adodb/adodb-datadict.inc.php @@ -1,7 +1,7 @@ sizeof($array)) $max = sizeof($array); + else $max = $probe; + + + for ($j=0;$j < $max; $j++) { + $row =& $array[$j]; + if (!$row) break; + $i = -1; + foreach($row as $v) { + $i += 1; + + if (isset($types[$i]) && $types[$i]=='C') continue; + + //print " ($i ".$types[$i]. "$v) "; + $v = trim($v); + + if (!preg_match('/^[+-]{0,1}[0-9\.]+$/',$v)) { + $types[$i] = 'C'; // once C, always C + + continue; + } + if ($j == 0) { + // If empty string, we presume is character + // test for integer for 1st row only + // after that it is up to testing other rows to prove + // that it is not an integer + if (strlen($v) == 0) $types[$i] = 'C'; + if (strpos($v,'.') !== false) $types[$i] = 'N'; + else $types[$i] = 'I'; + continue; + } + + if (strpos($v,'.') !== false) $types[$i] = 'N'; + + } + } +} + +function &adodb_transpose(&$arr, &$newarr, &$hdr) +{ + $oldX = sizeof(reset($arr)); + $oldY = sizeof($arr); + + if ($hdr) { + $startx = 1; + $hdr = array(); + for ($y = 0; $y < $oldY; $y++) { + $hdr[] = $arr[$y][0]; + } + } else + $startx = 0; + + for ($x = $startx; $x < $oldX; $x++) { + $newarr[] = array(); + for ($y = 0; $y < $oldY; $y++) { + $newarr[$x-$startx][] = $arr[$y][$x]; + } + } +} // Force key to upper. // See also http://www.php.net/manual/en/function.array-change-key-case.php @@ -297,14 +360,14 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0) { $qryRecs = 0; - if (preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) || + 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)) { // 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); + $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)) { @@ -313,12 +376,8 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0) $rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")"; } else if (strncmp($zthis->databaseType,'postgres',8) == 0) { - - $info = $zthis->ServerInfo(); - if (substr($info['version'],0,3) >= 7.1) { // good till version 999 - $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$sql); - $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_"; - } + $rewritesql = preg_replace('/(\sORDER\s+BY\s[^)]*)/is','',$sql); + $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_"; } } else { // now replace SELECT ... FROM with SELECT COUNT(*) FROM @@ -383,7 +442,6 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0) $rstest->Close(); if ($qryRecs == -1) return 0; } - return $qryRecs; } diff --git a/lib/adodb/adodb-memcache.lib.inc.php b/lib/adodb/adodb-memcache.lib.inc.php new file mode 100644 index 0000000000..fc4748a36c --- /dev/null +++ b/lib/adodb/adodb-memcache.lib.inc.php @@ -0,0 +1,118 @@ +pconnect($host, $port)) { + $err = 'Can\'t connect to memcache server on: '.$host.':'.$port; + return $false; + } + + $rs = $memcache->get($key); + if (!$rs) { + $err = 'Item with such key doesn\'t exists on the memcached server.'; + return $false; + } + + $tdiff = intval($rs->timeCreated+$timeout - time()); + if ($tdiff <= 2) { + switch($tdiff) { + case 2: + if ((rand() & 15) == 0) { + $err = "Timeout 2"; + return $false; + } + break; + case 1: + if ((rand() & 3) == 0) { + $err = "Timeout 1"; + return $false; + } + break; + default: + $err = "Timeout 0"; + return $false; + } + } + return $rs; + } + + function putmemcache($key, $rs, $host, $port, $compress, $debug=false) + { + $false = false; + $true = true; + + if (!function_exists('memcache_pconnect')) { + if ($debug) ADOConnection::outp(" Memcache module PECL extension not found!
\n"); + return $false; + } + + $memcache = new Memcache; + if (!@$memcache->pconnect($host, $port)) { + if ($debug) ADOConnection::outp(" Can't connect to memcache server on: $host:$port
\n"); + return $false; + } + + $rs->timeCreated = time(); + if (!$memcache->set($key, $rs, $compress, 0)) { + if ($debug) ADOConnection::outp(" Failed to save data at the memcached server!
\n"); + return $false; + } + return $true; + } + + function flushmemcache($key=false, $host, $port, $debug=false) + { + if (!function_exists('memcache_pconnect')) { + if ($debug) ADOConnection::outp(" Memcache module PECL extension not found!
\n"); + return; + } + + $memcache = new Memcache; + if (!@$memcache->pconnect($host, $port)) { + if ($debug) ADOConnection::outp(" Can't connect to memcache server on: $host:$port
\n"); + return; + } + + if ($key) { + if (!$memcache->delete($key)) { + if ($debug) ADOConnection::outp("CacheFlush: $key entery doesn't exist on memcached server!
\n"); + } else { + if ($debug) ADOConnection::outp("CacheFlush: $key entery flushed from memcached server!
\n"); + } + } else { + if (!$memcache->flush()) { + if ($debug) ADOConnection::outp("CacheFlush: Failure flushing all enteries from memcached server!
\n"); + } else { + if ($debug) ADOConnection::outp("CacheFlush: All enteries flushed from memcached server!
\n"); + } + } + return; + } +?> diff --git a/lib/adodb/adodb-pager.inc.php b/lib/adodb/adodb-pager.inc.php index d196af034a..5892488cf9 100644 --- a/lib/adodb/adodb-pager.inc.php +++ b/lib/adodb/adodb-pager.inc.php @@ -1,7 +1,7 @@ RecordCount() is used. @@ -273,6 +273,13 @@ var $raiseErrorFn = false; /// error function to call var $isoDates = false; /// accepts dates in ISO format var $cacheSecs = 3600; /// cache for 1 hour + + // memcache + var $memCache = false; /// should we use memCache instead of caching in files + var $memCacheHost; /// memCache host + var $memCachePort = 11211; /// memCache port + var $memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib) + var $sysDate = false; /// name of function that returns the current date var $sysTimeStamp = false; /// name of function that returns the current timestamp var $arrayClass = 'ADORecordSet_array'; /// name of class used to generate array recordsets, which are pre-downloaded recordsets @@ -678,6 +685,7 @@ return $this->Parameter($stmt,$var,$name,true,$maxLen,$type); } + /* Usage in oracle @@ -699,6 +707,19 @@ return false; } + + function IgnoreErrors($saveErrs=false) + { + if (!$saveErrs) { + $saveErrs = array($this->raiseErrorFn,$this->_transOK); + $this->raiseErrorFn = false; + return $saveErrs; + } else { + $this->raiseErrorFn = $saveErrs[0]; + $this->_transOK = $saveErrs[1]; + } + } + /** Improved method of initiating a transaction. Used together with CompleteTrans(). Advantages include: @@ -1108,14 +1129,14 @@ if ($ismssql) $isaccess = false; else $isaccess = (strpos($this->databaseType,'access') !== false); - if ($offset <= 0) { + if ($offset <= 0) { // access includes ties in result if ($isaccess) { $sql = preg_replace( '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); - if ($secs2cache >= 0) { + if ($secs2cache != 0) { $ret =& $this->CacheExecute($secs2cache, $sql,$inputarr); } else { $ret =& $this->Execute($sql,$inputarr); @@ -1148,10 +1169,10 @@ $ADODB_COUNTRECS = false; if ($offset>0){ - if ($secs2cache >= 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); + 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); + if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); else $rs = &$this->Execute($sql,$inputarr); } $ADODB_COUNTRECS = $savec; @@ -1334,6 +1355,16 @@ } return $rv; } + + function &Transpose(&$rs) + { + $rs2 =& $this->_rs2rs($rs); + $false = false; + if (!$rs2) return $false; + + $rs2->_transpose(); + return $rs2; + } /* Calculate the offset of a date for a particular database and generate @@ -1348,6 +1379,7 @@ return '('.$date.'+'.$dayFraction.')'; } + /** * * @param sql SQL statement @@ -1517,6 +1549,16 @@ { 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); @@ -1567,6 +1609,15 @@ { 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'; @@ -1607,7 +1658,7 @@ * 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) + function _gencachename($sql,$createdir,$memcache=false) { global $ADODB_CACHE_DIR; static $notSafeMode; @@ -1619,6 +1670,7 @@ $mode = $this->fetchMode; } $m = md5($sql.$this->databaseType.$this->database.$this->user.$mode); + if ($memcache) return $m; if (!isset($notSafeMode)) $notSafeMode = !ini_get('safe_mode'); $dir = ($notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($m,0,2) : $ADODB_CACHE_DIR; @@ -1658,14 +1710,23 @@ } 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); + if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); + $md5file = $this->_gencachename($sql.serialize($inputarr),true); + } + $err = ''; if ($secs2cache > 0){ - $rs = &csv2rs($md5file,$err,$secs2cache,$this->arrayClass); + if ($this->memCache) + $rs = &getmemCache($md5file,$err,$secs2cache, $this->memCacheHost, $this->memCachePort); + else + $rs = &csv2rs($md5file,$err,$secs2cache,$this->arrayClass); $this->numCacheHits += 1; } else { $err='Timeout 1'; @@ -1675,7 +1736,7 @@ if (!$rs) { // no cached rs found if ($this->debug) { - if (get_magic_quotes_runtime()) { + if (get_magic_quotes_runtime() && !$this->memCache) { ADOConnection::outp("Please disable magic_quotes_runtime - it corrupts cache files :("); } if ($this->debug !== -1) ADOConnection::outp( " $md5file cache failure: $err (see sql below)"); @@ -1683,6 +1744,14 @@ $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 @@ -1701,6 +1770,7 @@ } } else + if (!$this->memCache) @unlink($md5file); } else { $this->_errorMsg = ''; @@ -3573,6 +3643,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 } } + function _close() {} /** @@ -3629,7 +3700,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 var $_types; // the array of types of each column (C B I L M) var $_colnames; // names of each column in array var $_skiprow1; // skip 1st row because it holds column names - var $_fieldarr; // holds array of field objects + var $_fieldobjects; // holds array of field objects var $canSeek = true; var $affectedrows = false; var $insertid = false; @@ -3649,6 +3720,37 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 $this->fetchMode = $ADODB_FETCH_MODE; } + function _transpose() + { + global $ADODB_INCLUDED_LIB; + + if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); + $hdr = true; + + adodb_transpose($this->_array, $newarr, $hdr); + //adodb_pr($newarr); + + $this->_skiprow1 = false; + $this->_array =& $newarr; + $this->_colnames = $hdr; + + adodb_probetypes($newarr,$this->_types); + + $this->_fieldobjects = array(); + + foreach($hdr as $k => $name) { + $f = new ADOFieldObject(); + $f->name = $name; + $f->type = $this->_types[$k]; + $f->max_length = -1; + $this->_fieldobjects[] = $f; + + } + $this->fields = reset($this->_array); + + $this->_initrs(); + + } /** * Setup the array. diff --git a/lib/adodb/datadict/datadict-access.inc.php b/lib/adodb/datadict/datadict-access.inc.php index a34137e4e8..046789811d 100644 --- a/lib/adodb/datadict/datadict-access.inc.php +++ b/lib/adodb/datadict/datadict-access.inc.php @@ -1,7 +1,7 @@ ADODB_ibase(); diff --git a/lib/adodb/drivers/adodb-csv.inc.php b/lib/adodb/drivers/adodb-csv.inc.php index aeef91f9d3..205cc4e232 100644 --- a/lib/adodb/drivers/adodb-csv.inc.php +++ b/lib/adodb/drivers/adodb-csv.inc.php @@ -1,6 +1,6 @@ _connectionID != false; } + // format and return date string in database timestamp format + function DBTimeStamp($ts) + { + if (empty($ts) && $ts !== 0) return 'null'; + if (is_string($ts)) $ts = ADORecordSet::UnixTimeStamp($ts); + return 'TO_DATE('.adodb_date($this->fmtTimeStamp,$ts).",'YYYY-MM-DD HH24:MI:SS')"; + } // Format date column in sql string given an input format that understands Y M D function SQLDate($fmt, $col=false) { // use right() and replace() ? if (!$col) $col = $this->sysDate; + + /* use TO_CHAR() if $fmt is TO_CHAR() allowed fmt */ + if ($fmt== 'Y-m-d H:i:s') + return 'TO_CHAR('.$col.", 'YYYY-MM-DD HH24:MI:SS')"; + $s = ''; $len = strlen($fmt); @@ -135,31 +147,38 @@ class ADODB_db2 extends ADOConnection { switch($ch) { case 'Y': case 'y': + if ($len==1) return "year($col)"; $s .= "char(year($col))"; break; case 'M': + if ($len==1) return "monthname($col)"; $s .= "substr(monthname($col),1,3)"; break; case 'm': + if ($len==1) return "month($col)"; $s .= "right(digits(month($col)),2)"; break; case 'D': case 'd': + if ($len==1) return "day($col)"; $s .= "right(digits(day($col)),2)"; break; case 'H': case 'h': + if ($len==1) return "hour($col)"; if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)"; else $s .= "''"; break; case 'i': case 'I': + if ($len==1) return "minute($col)"; if ($col != $this->sysDate) $s .= "right(digits(minute($col)),2)"; else $s .= "''"; break; case 'S': case 's': + if ($len==1) return "second($col)"; if ($col != $this->sysDate) $s .= "right(digits(second($col)),2)"; else $s .= "''"; diff --git a/lib/adodb/drivers/adodb-fbsql.inc.php b/lib/adodb/drivers/adodb-fbsql.inc.php index 592f944bf7..1b900be593 100644 --- a/lib/adodb/drivers/adodb-fbsql.inc.php +++ b/lib/adodb/drivers/adodb-fbsql.inc.php @@ -1,6 +1,6 @@ _connectionID = @odbtp_connect($HostOrInterface,$UserOrDSN,$argPassword,$argDatabase); + odbtp_convert_datetime($this->_connectionID,true); + if ($this->_connectionID === false) { $this->_errorMsg = $this->ErrorMsg() ; return false; diff --git a/lib/adodb/drivers/adodb-odbtp_unicode.inc.php b/lib/adodb/drivers/adodb-odbtp_unicode.inc.php index d943b7069f..11a793ca9b 100644 --- a/lib/adodb/drivers/adodb-odbtp_unicode.inc.php +++ b/lib/adodb/drivers/adodb-odbtp_unicode.inc.php @@ -1,6 +1,6 @@ _bindInputArray = true; - + $parentDriver->_nestedSQL = true; if ($this->_initdate) { $parentDriver->Execute("ALTER SESSION SET NLS_DATE_FORMAT='".$this->NLS_DATE_FORMAT."'"); } diff --git a/lib/adodb/drivers/adodb-pdo_pgsql.inc.php b/lib/adodb/drivers/adodb-pdo_pgsql.inc.php index 32f12035cf..8f378377f6 100644 --- a/lib/adodb/drivers/adodb-pdo_pgsql.inc.php +++ b/lib/adodb/drivers/adodb-pdo_pgsql.inc.php @@ -1,7 +1,7 @@ hasTransactions = false; ## <<< BUG IN PDO pgsql driver $parentDriver->hasInsertID = true; + $parentDriver->_nestedSQL = true; } function ServerInfo() diff --git a/lib/adodb/drivers/adodb-postgres.inc.php b/lib/adodb/drivers/adodb-postgres.inc.php index 0e60eb1c98..fc356f9676 100644 --- a/lib/adodb/drivers/adodb-postgres.inc.php +++ b/lib/adodb/drivers/adodb-postgres.inc.php @@ -1,6 +1,6 @@ port)) $str .= " port=".$this->port; } diff --git a/lib/adodb/drivers/adodb-postgres7.inc.php b/lib/adodb/drivers/adodb-postgres7.inc.php index 6ccb6da8fa..c6e0b82535 100644 --- a/lib/adodb/drivers/adodb-postgres7.inc.php +++ b/lib/adodb/drivers/adodb-postgres7.inc.php @@ -1,6 +1,6 @@ rsPrefix .= 'assoc_'; } $this->_bindInputArray = PHP_VERSION >= 5.1; + + $info = $zthis->ServerInfo(); + $this->pgVersion = (float) substr($info['version'],0,3); + if ($this->pgVersion >= 7.1) { // good till version 999 + $this->_nestedSQL = true; + } } diff --git a/lib/adodb/drivers/adodb-postgres8.inc.php b/lib/adodb/drivers/adodb-postgres8.inc.php index 692264fc7d..b3390a4176 100644 --- a/lib/adodb/drivers/adodb-postgres8.inc.php +++ b/lib/adodb/drivers/adodb-postgres8.inc.php @@ -1,6 +1,6 @@