|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 /* 00003 * Set tabs to 4 for best viewing. 00004 * 00005 * Latest version is available at http://adodb.sourceforge.net 00006 * 00007 * This is the main include file for ADOdb. 00008 * Database specific drivers are stored in the adodb/drivers/adodb-*.inc.php 00009 * 00010 * The ADOdb files are formatted so that doxygen can be used to generate documentation. 00011 * Doxygen is a documentation generation tool and can be downloaded from http://doxygen.org/ 00012 */ 00013 00035 if (!defined('_ADODB_LAYER')) { 00036 define('_ADODB_LAYER',1); 00037 00038 //============================================================================================== 00039 // CONSTANT DEFINITIONS 00040 //============================================================================================== 00041 00042 00047 if (!defined('ADODB_DIR')) define('ADODB_DIR',dirname(__FILE__)); 00048 00049 //============================================================================================== 00050 // GLOBAL VARIABLES 00051 //============================================================================================== 00052 00053 GLOBAL 00054 $ADODB_vers, // database version 00055 $ADODB_COUNTRECS, // count number of records returned - slows down query 00056 $ADODB_CACHE_DIR, // directory to cache recordsets 00057 $ADODB_CACHE, 00058 $ADODB_CACHE_CLASS, 00059 $ADODB_EXTENSION, // ADODB extension installed 00060 $ADODB_COMPAT_FETCH, // If $ADODB_COUNTRECS and this is true, $rs->fields is available on EOF 00061 $ADODB_FETCH_MODE, // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default... 00062 $ADODB_GETONE_EOF, 00063 $ADODB_QUOTE_FIELDNAMES; // Allows you to force quotes (backticks) around field names in queries generated by getinsertsql and getupdatesql. 00064 00065 //============================================================================================== 00066 // GLOBAL SETUP 00067 //============================================================================================== 00068 00069 $ADODB_EXTENSION = defined('ADODB_EXTENSION'); 00070 00071 //********************************************************// 00072 /* 00073 Controls $ADODB_FORCE_TYPE mode. Default is ADODB_FORCE_VALUE (3). 00074 Used in GetUpdateSql and GetInsertSql functions. Thx to Niko, nuko#mbnet.fi 00075 00076 0 = ignore empty fields. All empty fields in array are ignored. 00077 1 = force null. All empty, php null and string 'null' fields are changed to sql NULL values. 00078 2 = force empty. All empty, php null and string 'null' fields are changed to sql empty '' or 0 values. 00079 3 = force value. Value is left as it is. Php null and string 'null' are set to sql NULL values and empty fields '' are set to empty '' sql values. 00080 */ 00081 define('ADODB_FORCE_IGNORE',0); 00082 define('ADODB_FORCE_NULL',1); 00083 define('ADODB_FORCE_EMPTY',2); 00084 define('ADODB_FORCE_VALUE',3); 00085 //********************************************************// 00086 00087 00088 if (!$ADODB_EXTENSION || ADODB_EXTENSION < 4.0) { 00089 00090 define('ADODB_BAD_RS','<p>Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;</p>'); 00091 00092 // allow [ ] @ ` " and . in table names 00093 define('ADODB_TABLE_REGEX','([]0-9a-z_\:\"\`\.\@\[-]*)'); 00094 00095 // prefetching used by oracle 00096 if (!defined('ADODB_PREFETCH_ROWS')) define('ADODB_PREFETCH_ROWS',10); 00097 00098 00099 /* 00100 Controls ADODB_FETCH_ASSOC field-name case. Default is 2, use native case-names. 00101 This currently works only with mssql, odbc, oci8po and ibase derived drivers. 00102 00103 0 = assoc lowercase field names. $rs->fields['orderid'] 00104 1 = assoc uppercase field names. $rs->fields['ORDERID'] 00105 2 = use native-case field names. $rs->fields['OrderID'] 00106 */ 00107 00108 define('ADODB_FETCH_DEFAULT',0); 00109 define('ADODB_FETCH_NUM',1); 00110 define('ADODB_FETCH_ASSOC',2); 00111 define('ADODB_FETCH_BOTH',3); 00112 00113 if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100); 00114 00115 // PHP's version scheme makes converting to numbers difficult - workaround 00116 $_adodb_ver = (float) PHP_VERSION; 00117 if ($_adodb_ver >= 5.2) { 00118 define('ADODB_PHPVER',0x5200); 00119 } else if ($_adodb_ver >= 5.0) { 00120 define('ADODB_PHPVER',0x5000); 00121 } else 00122 die("PHP5 or later required. You are running ".PHP_VERSION); 00123 } 00124 00125 00126 //if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2); 00127 00128 00132 function ADODB_str_replace($src, $dest, $data) 00133 { 00134 if (ADODB_PHPVER >= 0x4050) return str_replace($src,$dest,$data); 00135 00136 $s = reset($src); 00137 $d = reset($dest); 00138 while ($s !== false) { 00139 $data = str_replace($s,$d,$data); 00140 $s = next($src); 00141 $d = next($dest); 00142 } 00143 return $data; 00144 } 00145 00146 function ADODB_Setup() 00147 { 00148 GLOBAL 00149 $ADODB_vers, // database version 00150 $ADODB_COUNTRECS, // count number of records returned - slows down query 00151 $ADODB_CACHE_DIR, // directory to cache recordsets 00152 $ADODB_FETCH_MODE, 00153 $ADODB_CACHE, 00154 $ADODB_CACHE_CLASS, 00155 $ADODB_FORCE_TYPE, 00156 $ADODB_GETONE_EOF, 00157 $ADODB_QUOTE_FIELDNAMES; 00158 00159 if (empty($ADODB_CACHE_CLASS)) $ADODB_CACHE_CLASS = 'ADODB_Cache_File' ; 00160 $ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT; 00161 $ADODB_FORCE_TYPE = ADODB_FORCE_VALUE; 00162 $ADODB_GETONE_EOF = null; 00163 00164 if (!isset($ADODB_CACHE_DIR)) { 00165 $ADODB_CACHE_DIR = '/tmp'; //(isset($_ENV['TMP'])) ? $_ENV['TMP'] : '/tmp'; 00166 } else { 00167 // do not accept url based paths, eg. http:/ or ftp:/ 00168 if (strpos($ADODB_CACHE_DIR,'://') !== false) 00169 die("Illegal path http:// or ftp://"); 00170 } 00171 00172 00173 // Initialize random number generator for randomizing cache flushes 00174 // -- note Since PHP 4.2.0, the seed becomes optional and defaults to a random value if omitted. 00175 srand(((double)microtime())*1000000); 00176 00180 $ADODB_vers = 'V5.14 8 Sept 2011 (c) 2000-2011 John Lim (jlim#natsoft.com). All rights reserved. Released BSD & LGPL.'; 00181 00187 if (!isset($ADODB_COUNTRECS)) $ADODB_COUNTRECS = true; 00188 } 00189 00190 00191 //============================================================================================== 00192 // CHANGE NOTHING BELOW UNLESS YOU ARE DESIGNING ADODB 00193 //============================================================================================== 00194 00195 ADODB_Setup(); 00196 00197 //============================================================================================== 00198 // CLASS ADOFieldObject 00199 //============================================================================================== 00203 class ADOFieldObject { 00204 var $name = ''; 00205 var $max_length=0; 00206 var $type=""; 00207 /* 00208 // additional fields by dannym... (danny_milo@yahoo.com) 00209 var $not_null = false; 00210 // actually, this has already been built-in in the postgres, fbsql AND mysql module? ^-^ 00211 // so we can as well make not_null standard (leaving it at "false" does not harm anyways) 00212 00213 var $has_default = false; // this one I have done only in mysql and postgres for now ... 00214 // others to come (dannym) 00215 var $default_value; // default, if any, and supported. Check has_default first. 00216 */ 00217 } 00218 00219 // for transaction handling 00220 00221 function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) 00222 { 00223 //print "Errorno ($fn errno=$errno m=$errmsg) "; 00224 $thisConnection->_transOK = false; 00225 if ($thisConnection->_oldRaiseFn) { 00226 $fn = $thisConnection->_oldRaiseFn; 00227 $fn($dbms, $fn, $errno, $errmsg, $p1, $p2,$thisConnection); 00228 } 00229 } 00230 00231 //------------------ 00232 // class for caching 00233 class ADODB_Cache_File { 00234 00235 var $createdir = true; // requires creation of temp dirs 00236 00237 function ADODB_Cache_File() 00238 { 00239 global $ADODB_INCLUDED_CSV; 00240 if (empty($ADODB_INCLUDED_CSV)) include_once(ADODB_DIR.'/adodb-csvlib.inc.php'); 00241 } 00242 00243 // write serialised recordset to cache item/file 00244 function writecache($filename, $contents, $debug, $secs2cache) 00245 { 00246 return adodb_write_file($filename, $contents,$debug); 00247 } 00248 00249 // load serialised recordset and unserialise it 00250 function &readcache($filename, &$err, $secs2cache, $rsClass) 00251 { 00252 $rs = csv2rs($filename,$err,$secs2cache,$rsClass); 00253 return $rs; 00254 } 00255 00256 // flush all items in cache 00257 function flushall($debug=false) 00258 { 00259 global $ADODB_CACHE_DIR; 00260 00261 $rez = false; 00262 00263 if (strlen($ADODB_CACHE_DIR) > 1) { 00264 $rez = $this->_dirFlush($ADODB_CACHE_DIR); 00265 if ($debug) ADOConnection::outp( "flushall: $dir<br><pre>\n". $rez."</pre>"); 00266 } 00267 return $rez; 00268 } 00269 00270 // flush one file in cache 00271 function flushcache($f, $debug=false) 00272 { 00273 if (!@unlink($f)) { 00274 if ($debug) ADOConnection::outp( "flushcache: failed for $f"); 00275 } 00276 } 00277 00278 function getdirname($hash) 00279 { 00280 global $ADODB_CACHE_DIR; 00281 if (!isset($this->notSafeMode)) $this->notSafeMode = !ini_get('safe_mode'); 00282 return ($this->notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($hash,0,2) : $ADODB_CACHE_DIR; 00283 } 00284 00285 // create temp directories 00286 function createdir($hash, $debug) 00287 { 00288 $dir = $this->getdirname($hash); 00289 if ($this->notSafeMode && !file_exists($dir)) { 00290 $oldu = umask(0); 00291 if (!@mkdir($dir,0771)) if(!is_dir($dir) && $debug) ADOConnection::outp("Cannot create $dir"); 00292 umask($oldu); 00293 } 00294 00295 return $dir; 00296 } 00297 00304 function _dirFlush($dir, $kill_top_level = false) 00305 { 00306 if(!$dh = @opendir($dir)) return; 00307 00308 while (($obj = readdir($dh))) { 00309 if($obj=='.' || $obj=='..') continue; 00310 $f = $dir.'/'.$obj; 00311 00312 if (strpos($obj,'.cache')) @unlink($f); 00313 if (is_dir($f)) $this->_dirFlush($f, true); 00314 } 00315 if ($kill_top_level === true) @rmdir($dir); 00316 return true; 00317 } 00318 } 00319 00320 //============================================================================================== 00321 // CLASS ADOConnection 00322 //============================================================================================== 00323 00327 class ADOConnection { 00328 // 00329 // PUBLIC VARS 00330 // 00331 var $dataProvider = 'native'; 00332 var $databaseType = ''; 00333 var $database = ''; 00334 var $host = ''; 00335 var $user = ''; 00336 var $password = ''; 00337 var $debug = false; 00338 var $maxblobsize = 262144; 00339 var $concat_operator = '+'; 00340 var $substr = 'substr'; 00341 var $length = 'length'; 00342 var $random = 'rand()'; 00343 var $upperCase = 'upper'; 00344 var $fmtDate = "'Y-m-d'"; 00345 var $fmtTimeStamp = "'Y-m-d, h:i:s A'"; 00346 var $true = '1'; 00347 var $false = '0'; 00348 var $replaceQuote = "\\'"; 00349 var $nameQuote = '"'; 00350 var $charSet=false; 00351 var $metaDatabasesSQL = ''; 00352 var $metaTablesSQL = ''; 00353 var $uniqueOrderBy = false; 00354 var $emptyDate = ' '; 00355 var $emptyTimeStamp = ' '; 00356 var $lastInsID = false; 00357 //-- 00358 var $hasInsertID = false; 00359 var $hasAffectedRows = false; 00360 var $hasTop = false; 00361 var $hasLimit = false; 00362 var $readOnly = false; 00363 var $hasMoveFirst = false; 00364 var $hasGenID = false; 00365 var $hasTransactions = true; 00366 //-- 00367 var $genID = 0; 00368 var $raiseErrorFn = false; 00369 var $isoDates = false; 00370 var $cacheSecs = 3600; 00371 00372 // memcache 00373 var $memCache = false; 00374 var $memCacheHost; 00375 var $memCachePort = 11211; 00376 var $memCacheCompress = false; 00377 00378 var $sysDate = false; 00379 var $sysTimeStamp = false; 00380 var $sysUTimeStamp = false; // name of function that returns the current timestamp accurate to the microsecond or nearest fraction 00381 var $arrayClass = 'ADORecordSet_array'; 00382 00383 var $noNullStrings = false; 00384 var $numCacheHits = 0; 00385 var $numCacheMisses = 0; 00386 var $pageExecuteCountRows = true; 00387 var $uniqueSort = false; 00388 var $leftOuter = false; 00389 var $rightOuter = false; 00390 var $ansiOuter = false; 00391 var $autoRollback = false; // autoRollback on PConnect(). 00392 var $poorAffectedRows = false; // affectedRows not working or unreliable 00393 00394 var $fnExecute = false; 00395 var $fnCacheExecute = false; 00396 var $blobEncodeType = false; // false=not required, 'I'=encode to integer, 'C'=encode to char 00397 var $rsPrefix = "ADORecordSet_"; 00398 00399 var $autoCommit = true; 00400 var $transOff = 0; 00401 var $transCnt = 0; 00402 00403 var $fetchMode=false; 00404 00405 var $null2null = 'null'; // in autoexecute/getinsertsql/getupdatesql, this value will be converted to a null 00406 var $bulkBind = false; // enable 2D Execute array 00407 // 00408 // PRIVATE VARS 00409 // 00410 var $_oldRaiseFn = false; 00411 var $_transOK = null; 00412 var $_connectionID = false; 00413 var $_errorMsg = false; 00414 00415 var $_errorCode = false; 00416 var $_queryID = false; 00417 00418 var $_isPersistentConnection = false; 00419 var $_bindInputArray = false; 00420 var $_evalAll = false; 00421 var $_affected = false; 00422 var $_logsql = false; 00423 var $_transmode = ''; // transaction mode 00424 00425 00426 00430 function ADOConnection() 00431 { 00432 die('Virtual Class -- cannot instantiate'); 00433 } 00434 00435 static function Version() 00436 { 00437 global $ADODB_vers; 00438 00439 $ok = preg_match( '/^[Vv]([0-9\.]+)/', $ADODB_vers, $matches ); 00440 if (!$ok) return (float) substr($ADODB_vers,1); 00441 else return $matches[1]; 00442 } 00443 00450 function ServerInfo() 00451 { 00452 return array('description' => '', 'version' => ''); 00453 } 00454 00455 function IsConnected() 00456 { 00457 return !empty($this->_connectionID); 00458 } 00459 00460 function _findvers($str) 00461 { 00462 if (preg_match('/([0-9]+\.([0-9\.])+)/',$str, $arr)) return $arr[1]; 00463 else return ''; 00464 } 00465 00470 static function outp($msg,$newline=true) 00471 { 00472 global $ADODB_FLUSH,$ADODB_OUTP; 00473 00474 if (defined('ADODB_OUTP')) { 00475 $fn = ADODB_OUTP; 00476 $fn($msg,$newline); 00477 return; 00478 } else if (isset($ADODB_OUTP)) { 00479 $fn = $ADODB_OUTP; 00480 $fn($msg,$newline); 00481 return; 00482 } 00483 00484 if ($newline) $msg .= "<br>\n"; 00485 00486 if (isset($_SERVER['HTTP_USER_AGENT']) || !$newline) echo $msg; 00487 else echo strip_tags($msg); 00488 00489 00490 if (!empty($ADODB_FLUSH) && ob_get_length() !== false) flush(); // do not flush if output buffering enabled - useless - thx to Jesse Mullan 00491 00492 } 00493 00494 function Time() 00495 { 00496 $rs = $this->_Execute("select $this->sysTimeStamp"); 00497 if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields)); 00498 00499 return false; 00500 } 00501 00513 function Connect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "", $forceNew = false) 00514 { 00515 if ($argHostname != "") $this->host = $argHostname; 00516 if ($argUsername != "") $this->user = $argUsername; 00517 if ($argPassword != "") $this->password = 'not stored'; // not stored for security reasons 00518 if ($argDatabaseName != "") $this->database = $argDatabaseName; 00519 00520 $this->_isPersistentConnection = false; 00521 00522 if ($forceNew) { 00523 if ($rez=$this->_nconnect($this->host, $this->user, $argPassword, $this->database)) return true; 00524 } else { 00525 if ($rez=$this->_connect($this->host, $this->user, $argPassword, $this->database)) return true; 00526 } 00527 if (isset($rez)) { 00528 $err = $this->ErrorMsg(); 00529 if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'"; 00530 $ret = false; 00531 } else { 00532 $err = "Missing extension for ".$this->dataProvider; 00533 $ret = 0; 00534 } 00535 if ($fn = $this->raiseErrorFn) 00536 $fn($this->databaseType,'CONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this); 00537 00538 00539 $this->_connectionID = false; 00540 if ($this->debug) ADOConnection::outp( $this->host.': '.$err); 00541 return $ret; 00542 } 00543 00544 function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName) 00545 { 00546 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName); 00547 } 00548 00549 00560 function NConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") 00561 { 00562 return $this->Connect($argHostname, $argUsername, $argPassword, $argDatabaseName, true); 00563 } 00564 00575 function PConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") 00576 { 00577 00578 if (defined('ADODB_NEVER_PERSIST')) 00579 return $this->Connect($argHostname,$argUsername,$argPassword,$argDatabaseName); 00580 00581 if ($argHostname != "") $this->host = $argHostname; 00582 if ($argUsername != "") $this->user = $argUsername; 00583 if ($argPassword != "") $this->password = 'not stored'; 00584 if ($argDatabaseName != "") $this->database = $argDatabaseName; 00585 00586 $this->_isPersistentConnection = true; 00587 00588 if ($rez = $this->_pconnect($this->host, $this->user, $argPassword, $this->database)) return true; 00589 if (isset($rez)) { 00590 $err = $this->ErrorMsg(); 00591 if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'"; 00592 $ret = false; 00593 } else { 00594 $err = "Missing extension for ".$this->dataProvider; 00595 $ret = 0; 00596 } 00597 if ($fn = $this->raiseErrorFn) { 00598 $fn($this->databaseType,'PCONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this); 00599 } 00600 00601 $this->_connectionID = false; 00602 if ($this->debug) ADOConnection::outp( $this->host.': '.$err); 00603 return $ret; 00604 } 00605 00606 function outp_throw($msg,$src='WARN',$sql='') 00607 { 00608 if (defined('ADODB_ERROR_HANDLER') && ADODB_ERROR_HANDLER == 'adodb_throw') { 00609 adodb_throw($this->databaseType,$src,-9999,$msg,$sql,false,$this); 00610 return; 00611 } 00612 ADOConnection::outp($msg); 00613 } 00614 00615 // create cache class. Code is backward compat with old memcache implementation 00616 function _CreateCache() 00617 { 00618 global $ADODB_CACHE, $ADODB_CACHE_CLASS; 00619 00620 if ($this->memCache) { 00621 global $ADODB_INCLUDED_MEMCACHE; 00622 00623 if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php'); 00624 $ADODB_CACHE = new ADODB_Cache_MemCache($this); 00625 } else 00626 $ADODB_CACHE = new $ADODB_CACHE_CLASS($this); 00627 00628 } 00629 00630 // Format date column in sql string given an input format that understands Y M D 00631 function SQLDate($fmt, $col=false) 00632 { 00633 if (!$col) $col = $this->sysDate; 00634 return $col; // child class implement 00635 } 00636 00652 function Prepare($sql) 00653 { 00654 return $sql; 00655 } 00656 00671 function PrepareSP($sql,$param=true) 00672 { 00673 return $this->Prepare($sql,$param); 00674 } 00675 00679 function Quote($s) 00680 { 00681 return $this->qstr($s,false); 00682 } 00683 00687 function QMagic($s) 00688 { 00689 return $this->qstr($s,get_magic_quotes_gpc()); 00690 } 00691 00692 function q(&$s) 00693 { 00694 #if (!empty($this->qNull)) if ($s == 'null') return $s; 00695 $s = $this->qstr($s,false); 00696 } 00697 00701 function ErrorNative() 00702 { 00703 return $this->ErrorNo(); 00704 } 00705 00706 00710 function nextId($seq_name) 00711 { 00712 return $this->GenID($seq_name); 00713 } 00714 00722 function RowLock($table,$where,$col='1 as adodbignore') 00723 { 00724 return false; 00725 } 00726 00727 function CommitLock($table) 00728 { 00729 return $this->CommitTrans(); 00730 } 00731 00732 function RollbackLock($table) 00733 { 00734 return $this->RollbackTrans(); 00735 } 00736 00746 function SetFetchMode($mode) 00747 { 00748 $old = $this->fetchMode; 00749 $this->fetchMode = $mode; 00750 00751 if ($old === false) { 00752 global $ADODB_FETCH_MODE; 00753 return $ADODB_FETCH_MODE; 00754 } 00755 return $old; 00756 } 00757 00758 00762 function Query($sql, $inputarr=false) 00763 { 00764 $rs = $this->Execute($sql, $inputarr); 00765 if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error(); 00766 return $rs; 00767 } 00768 00769 00773 function LimitQuery($sql, $offset, $count, $params=false) 00774 { 00775 $rs = $this->SelectLimit($sql, $count, $offset, $params); 00776 if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error(); 00777 return $rs; 00778 } 00779 00780 00784 function Disconnect() 00785 { 00786 return $this->Close(); 00787 } 00788 00789 /* 00790 Returns placeholder for parameter, eg. 00791 $DB->Param('a') 00792 00793 will return ':a' for Oracle, and '?' for most other databases... 00794 00795 For databases that require positioned params, eg $1, $2, $3 for postgresql, 00796 pass in Param(false) before setting the first parameter. 00797 */ 00798 function Param($name,$type='C') 00799 { 00800 return '?'; 00801 } 00802 00803 /* 00804 InParameter and OutParameter are self-documenting versions of Parameter(). 00805 */ 00806 function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) 00807 { 00808 return $this->Parameter($stmt,$var,$name,false,$maxLen,$type); 00809 } 00810 00811 /* 00812 */ 00813 function OutParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) 00814 { 00815 return $this->Parameter($stmt,$var,$name,true,$maxLen,$type); 00816 00817 } 00818 00819 00820 /* 00821 Usage in oracle 00822 $stmt = $db->Prepare('select * from table where id =:myid and group=:group'); 00823 $db->Parameter($stmt,$id,'myid'); 00824 $db->Parameter($stmt,$group,'group',64); 00825 $db->Execute(); 00826 00827 @param $stmt Statement returned by Prepare() or PrepareSP(). 00828 @param $var PHP variable to bind to 00829 @param $name Name of stored procedure variable name to bind to. 00830 @param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8. 00831 @param [$maxLen] Holds an maximum length of the variable. 00832 @param [$type] The data type of $var. Legal values depend on driver. 00833 00834 */ 00835 function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false) 00836 { 00837 return false; 00838 } 00839 00840 00841 function IgnoreErrors($saveErrs=false) 00842 { 00843 if (!$saveErrs) { 00844 $saveErrs = array($this->raiseErrorFn,$this->_transOK); 00845 $this->raiseErrorFn = false; 00846 return $saveErrs; 00847 } else { 00848 $this->raiseErrorFn = $saveErrs[0]; 00849 $this->_transOK = $saveErrs[1]; 00850 } 00851 } 00852 00863 function StartTrans($errfn = 'ADODB_TransMonitor') 00864 { 00865 if ($this->transOff > 0) { 00866 $this->transOff += 1; 00867 return true; 00868 } 00869 00870 $this->_oldRaiseFn = $this->raiseErrorFn; 00871 $this->raiseErrorFn = $errfn; 00872 $this->_transOK = true; 00873 00874 if ($this->debug && $this->transCnt > 0) ADOConnection::outp("Bad Transaction: StartTrans called within BeginTrans"); 00875 $ok = $this->BeginTrans(); 00876 $this->transOff = 1; 00877 return $ok; 00878 } 00879 00880 00889 function CompleteTrans($autoComplete = true) 00890 { 00891 if ($this->transOff > 1) { 00892 $this->transOff -= 1; 00893 return true; 00894 } 00895 $this->raiseErrorFn = $this->_oldRaiseFn; 00896 00897 $this->transOff = 0; 00898 if ($this->_transOK && $autoComplete) { 00899 if (!$this->CommitTrans()) { 00900 $this->_transOK = false; 00901 if ($this->debug) ADOConnection::outp("Smart Commit failed"); 00902 } else 00903 if ($this->debug) ADOConnection::outp("Smart Commit occurred"); 00904 } else { 00905 $this->_transOK = false; 00906 $this->RollbackTrans(); 00907 if ($this->debug) ADOCOnnection::outp("Smart Rollback occurred"); 00908 } 00909 00910 return $this->_transOK; 00911 } 00912 00913 /* 00914 At the end of a StartTrans/CompleteTrans block, perform a rollback. 00915 */ 00916 function FailTrans() 00917 { 00918 if ($this->debug) 00919 if ($this->transOff == 0) { 00920 ADOConnection::outp("FailTrans outside StartTrans/CompleteTrans"); 00921 } else { 00922 ADOConnection::outp("FailTrans was called"); 00923 adodb_backtrace(); 00924 } 00925 $this->_transOK = false; 00926 } 00927 00931 function HasFailedTrans() 00932 { 00933 if ($this->transOff > 0) return $this->_transOK == false; 00934 return false; 00935 } 00936 00944 function Execute($sql,$inputarr=false) 00945 { 00946 if ($this->fnExecute) { 00947 $fn = $this->fnExecute; 00948 $ret = $fn($this,$sql,$inputarr); 00949 if (isset($ret)) return $ret; 00950 } 00951 if ($inputarr) { 00952 if (!is_array($inputarr)) $inputarr = array($inputarr); 00953 00954 $element0 = reset($inputarr); 00955 # is_object check because oci8 descriptors can be passed in 00956 $array_2d = $this->bulkBind && is_array($element0) && !is_object(reset($element0)); 00957 00958 //remove extra memory copy of input -mikefedyk 00959 unset($element0); 00960 00961 if (!is_array($sql) && !$this->_bindInputArray) { 00962 $sqlarr = explode('?',$sql); 00963 $nparams = sizeof($sqlarr)-1; 00964 if (!$array_2d) $inputarr = array($inputarr); 00965 00966 foreach($inputarr as $arr) { 00967 $sql = ''; $i = 0; 00968 //Use each() instead of foreach to reduce memory usage -mikefedyk 00969 while(list(, $v) = each($arr)) { 00970 $sql .= $sqlarr[$i]; 00971 // from Ron Baldwin <ron.baldwin#sourceprose.com> 00972 // Only quote string types 00973 $typ = gettype($v); 00974 if ($typ == 'string') 00975 //New memory copy of input created here -mikefedyk 00976 $sql .= $this->qstr($v); 00977 else if ($typ == 'double') 00978 $sql .= str_replace(',','.',$v); // locales fix so 1.1 does not get converted to 1,1 00979 else if ($typ == 'boolean') 00980 $sql .= $v ? $this->true : $this->false; 00981 else if ($typ == 'object') { 00982 if (method_exists($v, '__toString')) $sql .= $this->qstr($v->__toString()); 00983 else $sql .= $this->qstr((string) $v); 00984 } else if ($v === null) 00985 $sql .= 'NULL'; 00986 else 00987 $sql .= $v; 00988 $i += 1; 00989 00990 if ($i == $nparams) break; 00991 } // while 00992 if (isset($sqlarr[$i])) { 00993 $sql .= $sqlarr[$i]; 00994 if ($i+1 != sizeof($sqlarr)) $this->outp_throw( "Input Array does not match ?: ".htmlspecialchars($sql),'Execute'); 00995 } else if ($i != sizeof($sqlarr)) 00996 $this->outp_throw( "Input array does not match ?: ".htmlspecialchars($sql),'Execute'); 00997 00998 $ret = $this->_Execute($sql); 00999 if (!$ret) return $ret; 01000 } 01001 } else { 01002 if ($array_2d) { 01003 if (is_string($sql)) 01004 $stmt = $this->Prepare($sql); 01005 else 01006 $stmt = $sql; 01007 01008 foreach($inputarr as $arr) { 01009 $ret = $this->_Execute($stmt,$arr); 01010 if (!$ret) return $ret; 01011 } 01012 } else { 01013 $ret = $this->_Execute($sql,$inputarr); 01014 } 01015 } 01016 } else { 01017 $ret = $this->_Execute($sql,false); 01018 } 01019 01020 return $ret; 01021 } 01022 01023 01024 function _Execute($sql,$inputarr=false) 01025 { 01026 if ($this->debug) { 01027 global $ADODB_INCLUDED_LIB; 01028 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 01029 $this->_queryID = _adodb_debug_execute($this, $sql,$inputarr); 01030 } else { 01031 $this->_queryID = @$this->_query($sql,$inputarr); 01032 } 01033 01034 /************************ 01035 // OK, query executed 01036 *************************/ 01037 01038 if ($this->_queryID === false) { // error handling if query fails 01039 if ($this->debug == 99) adodb_backtrace(true,5); 01040 $fn = $this->raiseErrorFn; 01041 if ($fn) { 01042 $fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,$inputarr,$this); 01043 } 01044 $false = false; 01045 return $false; 01046 } 01047 01048 if ($this->_queryID === true) { // return simplified recordset for inserts/updates/deletes with lower overhead 01049 $rsclass = $this->rsPrefix.'empty'; 01050 $rs = (class_exists($rsclass)) ? new $rsclass(): new ADORecordSet_empty(); 01051 01052 return $rs; 01053 } 01054 01055 // return real recordset from select statement 01056 $rsclass = $this->rsPrefix.$this->databaseType; 01057 $rs = new $rsclass($this->_queryID,$this->fetchMode); 01058 $rs->connection = $this; // Pablo suggestion 01059 $rs->Init(); 01060 if (is_array($sql)) $rs->sql = $sql[0]; 01061 else $rs->sql = $sql; 01062 if ($rs->_numOfRows <= 0) { 01063 global $ADODB_COUNTRECS; 01064 if ($ADODB_COUNTRECS) { 01065 if (!$rs->EOF) { 01066 $rs = $this->_rs2rs($rs,-1,-1,!is_array($sql)); 01067 $rs->_queryID = $this->_queryID; 01068 } else 01069 $rs->_numOfRows = 0; 01070 } 01071 } 01072 return $rs; 01073 } 01074 01075 function CreateSequence($seqname='adodbseq',$startID=1) 01076 { 01077 if (empty($this->_genSeqSQL)) return false; 01078 return $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID)); 01079 } 01080 01081 function DropSequence($seqname='adodbseq') 01082 { 01083 if (empty($this->_dropSeqSQL)) return false; 01084 return $this->Execute(sprintf($this->_dropSeqSQL,$seqname)); 01085 } 01086 01095 function GenID($seqname='adodbseq',$startID=1) 01096 { 01097 if (!$this->hasGenID) { 01098 return 0; // formerly returns false pre 1.60 01099 } 01100 01101 $getnext = sprintf($this->_genIDSQL,$seqname); 01102 01103 $holdtransOK = $this->_transOK; 01104 01105 $save_handler = $this->raiseErrorFn; 01106 $this->raiseErrorFn = ''; 01107 @($rs = $this->Execute($getnext)); 01108 $this->raiseErrorFn = $save_handler; 01109 01110 if (!$rs) { 01111 $this->_transOK = $holdtransOK; //if the status was ok before reset 01112 $createseq = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID)); 01113 $rs = $this->Execute($getnext); 01114 } 01115 if ($rs && !$rs->EOF) $this->genID = reset($rs->fields); 01116 else $this->genID = 0; // false 01117 01118 if ($rs) $rs->Close(); 01119 01120 return $this->genID; 01121 } 01122 01128 function Insert_ID($table='',$column='') 01129 { 01130 if ($this->_logsql && $this->lastInsID) return $this->lastInsID; 01131 if ($this->hasInsertID) return $this->_insertid($table,$column); 01132 if ($this->debug) { 01133 ADOConnection::outp( '<p>Insert_ID error</p>'); 01134 adodb_backtrace(); 01135 } 01136 return false; 01137 } 01138 01139 01146 function PO_Insert_ID($table="", $id="") 01147 { 01148 if ($this->hasInsertID){ 01149 return $this->Insert_ID($table,$id); 01150 } else { 01151 return $this->GetOne("SELECT MAX($id) FROM $table"); 01152 } 01153 } 01154 01158 function Affected_Rows() 01159 { 01160 if ($this->hasAffectedRows) { 01161 if ($this->fnExecute === 'adodb_log_sql') { 01162 if ($this->_logsql && $this->_affected !== false) return $this->_affected; 01163 } 01164 $val = $this->_affectedrows(); 01165 return ($val < 0) ? false : $val; 01166 } 01167 01168 if ($this->debug) ADOConnection::outp( '<p>Affected_Rows error</p>',false); 01169 return false; 01170 } 01171 01172 01176 function ErrorMsg() 01177 { 01178 if ($this->_errorMsg) return '!! '.strtoupper($this->dataProvider.' '.$this->databaseType).': '.$this->_errorMsg; 01179 else return ''; 01180 } 01181 01182 01186 function ErrorNo() 01187 { 01188 return ($this->_errorMsg) ? -1 : 0; 01189 } 01190 01191 function MetaError($err=false) 01192 { 01193 include_once(ADODB_DIR."/adodb-error.inc.php"); 01194 if ($err === false) $err = $this->ErrorNo(); 01195 return adodb_error($this->dataProvider,$this->databaseType,$err); 01196 } 01197 01198 function MetaErrorMsg($errno) 01199 { 01200 include_once(ADODB_DIR."/adodb-error.inc.php"); 01201 return adodb_errormsg($errno); 01202 } 01203 01207 function MetaPrimaryKeys($table, $owner=false) 01208 { 01209 // owner not used in base class - see oci8 01210 $p = array(); 01211 $objs = $this->MetaColumns($table); 01212 if ($objs) { 01213 foreach($objs as $v) { 01214 if (!empty($v->primary_key)) 01215 $p[] = $v->name; 01216 } 01217 } 01218 if (sizeof($p)) return $p; 01219 if (function_exists('ADODB_VIEW_PRIMARYKEYS')) 01220 return ADODB_VIEW_PRIMARYKEYS($this->databaseType, $this->database, $table, $owner); 01221 return false; 01222 } 01223 01227 function MetaForeignKeys($table, $owner=false, $upper=false) 01228 { 01229 return false; 01230 } 01237 function SelectDB($dbName) 01238 {return false;} 01239 01240 01260 function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0) 01261 { 01262 if ($this->hasTop && $nrows > 0) { 01263 // suggested by Reinhard Balling. Access requires top after distinct 01264 // Informix requires first before distinct - F Riosa 01265 $ismssql = (strpos($this->databaseType,'mssql') !== false); 01266 if ($ismssql) $isaccess = false; 01267 else $isaccess = (strpos($this->databaseType,'access') !== false); 01268 01269 if ($offset <= 0) { 01270 01271 // access includes ties in result 01272 if ($isaccess) { 01273 $sql = preg_replace( 01274 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); 01275 01276 if ($secs2cache != 0) { 01277 $ret = $this->CacheExecute($secs2cache, $sql,$inputarr); 01278 } else { 01279 $ret = $this->Execute($sql,$inputarr); 01280 } 01281 return $ret; // PHP5 fix 01282 } else if ($ismssql){ 01283 $sql = preg_replace( 01284 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); 01285 } else { 01286 $sql = preg_replace( 01287 '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); 01288 } 01289 } else { 01290 $nn = $nrows + $offset; 01291 if ($isaccess || $ismssql) { 01292 $sql = preg_replace( 01293 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.$nn.' ',$sql); 01294 } else { 01295 $sql = preg_replace( 01296 '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.$nn.' ',$sql); 01297 } 01298 } 01299 } 01300 01301 // if $offset>0, we want to skip rows, and $ADODB_COUNTRECS is set, we buffer rows 01302 // 0 to offset-1 which will be discarded anyway. So we disable $ADODB_COUNTRECS. 01303 global $ADODB_COUNTRECS; 01304 01305 $savec = $ADODB_COUNTRECS; 01306 $ADODB_COUNTRECS = false; 01307 01308 01309 if ($secs2cache != 0) $rs = $this->CacheExecute($secs2cache,$sql,$inputarr); 01310 else $rs = $this->Execute($sql,$inputarr); 01311 01312 $ADODB_COUNTRECS = $savec; 01313 if ($rs && !$rs->EOF) { 01314 $rs = $this->_rs2rs($rs,$nrows,$offset); 01315 } 01316 //print_r($rs); 01317 return $rs; 01318 } 01319 01325 function SerializableRS(&$rs) 01326 { 01327 $rs2 = $this->_rs2rs($rs); 01328 $ignore = false; 01329 $rs2->connection = $ignore; 01330 01331 return $rs2; 01332 } 01333 01344 function &_rs2rs(&$rs,$nrows=-1,$offset=-1,$close=true) 01345 { 01346 if (! $rs) { 01347 $false = false; 01348 return $false; 01349 } 01350 $dbtype = $rs->databaseType; 01351 if (!$dbtype) { 01352 $rs = $rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ? 01353 return $rs; 01354 } 01355 if (($dbtype == 'array' || $dbtype == 'csv') && $nrows == -1 && $offset == -1) { 01356 $rs->MoveFirst(); 01357 $rs = $rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ? 01358 return $rs; 01359 } 01360 $flds = array(); 01361 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) { 01362 $flds[] = $rs->FetchField($i); 01363 } 01364 01365 $arr = $rs->GetArrayLimit($nrows,$offset); 01366 //print_r($arr); 01367 if ($close) $rs->Close(); 01368 01369 $arrayClass = $this->arrayClass; 01370 01371 $rs2 = new $arrayClass(); 01372 $rs2->connection = $this; 01373 $rs2->sql = $rs->sql; 01374 $rs2->dataProvider = $this->dataProvider; 01375 $rs2->InitArrayFields($arr,$flds); 01376 $rs2->fetchMode = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode; 01377 return $rs2; 01378 } 01379 01380 /* 01381 * Return all rows. Compat with PEAR DB 01382 */ 01383 function GetAll($sql, $inputarr=false) 01384 { 01385 $arr = $this->GetArray($sql,$inputarr); 01386 return $arr; 01387 } 01388 01389 function GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false) 01390 { 01391 $rs = $this->Execute($sql, $inputarr); 01392 if (!$rs) { 01393 $false = false; 01394 return $false; 01395 } 01396 $arr = $rs->GetAssoc($force_array,$first2cols); 01397 return $arr; 01398 } 01399 01400 function CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false) 01401 { 01402 if (!is_numeric($secs2cache)) { 01403 $first2cols = $force_array; 01404 $force_array = $inputarr; 01405 } 01406 $rs = $this->CacheExecute($secs2cache, $sql, $inputarr); 01407 if (!$rs) { 01408 $false = false; 01409 return $false; 01410 } 01411 $arr = $rs->GetAssoc($force_array,$first2cols); 01412 return $arr; 01413 } 01414 01422 function GetOne($sql,$inputarr=false) 01423 { 01424 global $ADODB_COUNTRECS,$ADODB_GETONE_EOF; 01425 $crecs = $ADODB_COUNTRECS; 01426 $ADODB_COUNTRECS = false; 01427 01428 $ret = false; 01429 $rs = $this->Execute($sql,$inputarr); 01430 if ($rs) { 01431 if ($rs->EOF) $ret = $ADODB_GETONE_EOF; 01432 else $ret = reset($rs->fields); 01433 01434 $rs->Close(); 01435 } 01436 $ADODB_COUNTRECS = $crecs; 01437 return $ret; 01438 } 01439 01440 // $where should include 'WHERE fld=value' 01441 function GetMedian($table, $field,$where = '') 01442 { 01443 $total = $this->GetOne("select count(*) from $table $where"); 01444 if (!$total) return false; 01445 01446 $midrow = (integer) ($total/2); 01447 $rs = $this->SelectLimit("select $field from $table $where order by 1",1,$midrow); 01448 if ($rs && !$rs->EOF) return reset($rs->fields); 01449 return false; 01450 } 01451 01452 01453 function CacheGetOne($secs2cache,$sql=false,$inputarr=false) 01454 { 01455 global $ADODB_GETONE_EOF; 01456 $ret = false; 01457 $rs = $this->CacheExecute($secs2cache,$sql,$inputarr); 01458 if ($rs) { 01459 if ($rs->EOF) $ret = $ADODB_GETONE_EOF; 01460 else $ret = reset($rs->fields); 01461 $rs->Close(); 01462 } 01463 01464 return $ret; 01465 } 01466 01467 function GetCol($sql, $inputarr = false, $trim = false) 01468 { 01469 01470 $rs = $this->Execute($sql, $inputarr); 01471 if ($rs) { 01472 $rv = array(); 01473 if ($trim) { 01474 while (!$rs->EOF) { 01475 $rv[] = trim(reset($rs->fields)); 01476 $rs->MoveNext(); 01477 } 01478 } else { 01479 while (!$rs->EOF) { 01480 $rv[] = reset($rs->fields); 01481 $rs->MoveNext(); 01482 } 01483 } 01484 $rs->Close(); 01485 } else 01486 $rv = false; 01487 return $rv; 01488 } 01489 01490 function CacheGetCol($secs, $sql = false, $inputarr = false,$trim=false) 01491 { 01492 $rs = $this->CacheExecute($secs, $sql, $inputarr); 01493 if ($rs) { 01494 $rv = array(); 01495 if ($trim) { 01496 while (!$rs->EOF) { 01497 $rv[] = trim(reset($rs->fields)); 01498 $rs->MoveNext(); 01499 } 01500 } else { 01501 while (!$rs->EOF) { 01502 $rv[] = reset($rs->fields); 01503 $rs->MoveNext(); 01504 } 01505 } 01506 $rs->Close(); 01507 } else 01508 $rv = false; 01509 01510 return $rv; 01511 } 01512 01513 function Transpose(&$rs,$addfieldnames=true) 01514 { 01515 $rs2 = $this->_rs2rs($rs); 01516 $false = false; 01517 if (!$rs2) return $false; 01518 01519 $rs2->_transpose($addfieldnames); 01520 return $rs2; 01521 } 01522 01523 /* 01524 Calculate the offset of a date for a particular database and generate 01525 appropriate SQL. Useful for calculating future/past dates and storing 01526 in a database. 01527 01528 If dayFraction=1.5 means 1.5 days from now, 1.0/24 for 1 hour. 01529 */ 01530 function OffsetDate($dayFraction,$date=false) 01531 { 01532 if (!$date) $date = $this->sysDate; 01533 return '('.$date.'+'.$dayFraction.')'; 01534 } 01535 01536 01542 function GetArray($sql,$inputarr=false) 01543 { 01544 global $ADODB_COUNTRECS; 01545 01546 $savec = $ADODB_COUNTRECS; 01547 $ADODB_COUNTRECS = false; 01548 $rs = $this->Execute($sql,$inputarr); 01549 $ADODB_COUNTRECS = $savec; 01550 if (!$rs) 01551 if (defined('ADODB_PEAR')) { 01552 $cls = ADODB_PEAR_Error(); 01553 return $cls; 01554 } else { 01555 $false = false; 01556 return $false; 01557 } 01558 $arr = $rs->GetArray(); 01559 $rs->Close(); 01560 return $arr; 01561 } 01562 01563 function CacheGetAll($secs2cache,$sql=false,$inputarr=false) 01564 { 01565 $arr = $this->CacheGetArray($secs2cache,$sql,$inputarr); 01566 return $arr; 01567 } 01568 01569 function CacheGetArray($secs2cache,$sql=false,$inputarr=false) 01570 { 01571 global $ADODB_COUNTRECS; 01572 01573 $savec = $ADODB_COUNTRECS; 01574 $ADODB_COUNTRECS = false; 01575 $rs = $this->CacheExecute($secs2cache,$sql,$inputarr); 01576 $ADODB_COUNTRECS = $savec; 01577 01578 if (!$rs) 01579 if (defined('ADODB_PEAR')) { 01580 $cls = ADODB_PEAR_Error(); 01581 return $cls; 01582 } else { 01583 $false = false; 01584 return $false; 01585 } 01586 $arr = $rs->GetArray(); 01587 $rs->Close(); 01588 return $arr; 01589 } 01590 01591 function GetRandRow($sql, $arr= false) 01592 { 01593 $rezarr = $this->GetAll($sql, $arr); 01594 $sz = sizeof($rezarr); 01595 return $rezarr[abs(rand()) % $sz]; 01596 } 01597 01604 function GetRow($sql,$inputarr=false) 01605 { 01606 global $ADODB_COUNTRECS; 01607 $crecs = $ADODB_COUNTRECS; 01608 $ADODB_COUNTRECS = false; 01609 01610 $rs = $this->Execute($sql,$inputarr); 01611 01612 $ADODB_COUNTRECS = $crecs; 01613 if ($rs) { 01614 if (!$rs->EOF) $arr = $rs->fields; 01615 else $arr = array(); 01616 $rs->Close(); 01617 return $arr; 01618 } 01619 01620 $false = false; 01621 return $false; 01622 } 01623 01624 function CacheGetRow($secs2cache,$sql=false,$inputarr=false) 01625 { 01626 $rs = $this->CacheExecute($secs2cache,$sql,$inputarr); 01627 if ($rs) { 01628 if (!$rs->EOF) $arr = $rs->fields; 01629 else $arr = array(); 01630 01631 $rs->Close(); 01632 return $arr; 01633 } 01634 $false = false; 01635 return $false; 01636 } 01637 01658 function Replace($table, $fieldArray, $keyCol, $autoQuote=false, $has_autoinc=false) 01659 { 01660 global $ADODB_INCLUDED_LIB; 01661 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 01662 01663 return _adodb_replace($this, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc); 01664 } 01665 01666 01685 function CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false) 01686 { 01687 if (!is_numeric($secs2cache)) { 01688 if ($sql === false) $sql = -1; 01689 if ($offset == -1) $offset = false; 01690 // sql, nrows, offset,inputarr 01691 $rs = $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs); 01692 } else { 01693 if ($sql === false) $this->outp_throw("Warning: \$sql missing from CacheSelectLimit()",'CacheSelectLimit'); 01694 $rs = $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache); 01695 } 01696 return $rs; 01697 } 01698 01699 01709 function CacheFlush($sql=false,$inputarr=false) 01710 { 01711 global $ADODB_CACHE_DIR, $ADODB_CACHE; 01712 01713 if (empty($ADODB_CACHE)) return false; 01714 01715 if (!$sql) { 01716 $ADODB_CACHE->flushall($this->debug); 01717 return; 01718 } 01719 01720 $f = $this->_gencachename($sql.serialize($inputarr),false); 01721 return $ADODB_CACHE->flushcache($f, $this->debug); 01722 } 01723 01724 01739 function _gencachename($sql,$createdir) 01740 { 01741 global $ADODB_CACHE, $ADODB_CACHE_DIR; 01742 01743 if ($this->fetchMode === false) { 01744 global $ADODB_FETCH_MODE; 01745 $mode = $ADODB_FETCH_MODE; 01746 } else { 01747 $mode = $this->fetchMode; 01748 } 01749 $m = md5($sql.$this->databaseType.$this->database.$this->user.$mode); 01750 if (!$ADODB_CACHE->createdir) return $m; 01751 if (!$createdir) $dir = $ADODB_CACHE->getdirname($m); 01752 else $dir = $ADODB_CACHE->createdir($m, $this->debug); 01753 01754 return $dir.'/adodb_'.$m.'.cache'; 01755 } 01756 01757 01767 function CacheExecute($secs2cache,$sql=false,$inputarr=false) 01768 { 01769 global $ADODB_CACHE; 01770 01771 if (empty($ADODB_CACHE)) $this->_CreateCache(); 01772 01773 if (!is_numeric($secs2cache)) { 01774 $inputarr = $sql; 01775 $sql = $secs2cache; 01776 $secs2cache = $this->cacheSecs; 01777 } 01778 01779 if (is_array($sql)) { 01780 $sqlparam = $sql; 01781 $sql = $sql[0]; 01782 } else 01783 $sqlparam = $sql; 01784 01785 01786 $md5file = $this->_gencachename($sql.serialize($inputarr),true); 01787 $err = ''; 01788 01789 if ($secs2cache > 0){ 01790 $rs = $ADODB_CACHE->readcache($md5file,$err,$secs2cache,$this->arrayClass); 01791 $this->numCacheHits += 1; 01792 } else { 01793 $err='Timeout 1'; 01794 $rs = false; 01795 $this->numCacheMisses += 1; 01796 } 01797 01798 if (!$rs) { 01799 // no cached rs found 01800 if ($this->debug) { 01801 if (get_magic_quotes_runtime() && !$this->memCache) { 01802 ADOConnection::outp("Please disable magic_quotes_runtime - it corrupts cache files :("); 01803 } 01804 if ($this->debug !== -1) ADOConnection::outp( " $md5file cache failure: $err (this is a notice and not an error)"); 01805 } 01806 01807 $rs = $this->Execute($sqlparam,$inputarr); 01808 01809 if ($rs) { 01810 01811 $eof = $rs->EOF; 01812 $rs = $this->_rs2rs($rs); // read entire recordset into memory immediately 01813 $rs->timeCreated = time(); // used by caching 01814 $txt = _rs2serialize($rs,false,$sql); // serialize 01815 01816 $ok = $ADODB_CACHE->writecache($md5file,$txt,$this->debug, $secs2cache); 01817 if (!$ok) { 01818 if ($ok === false) { 01819 $em = 'Cache write error'; 01820 $en = -32000; 01821 01822 if ($fn = $this->raiseErrorFn) { 01823 $fn($this->databaseType,'CacheExecute', $en, $em, $md5file,$sql,$this); 01824 } 01825 } else { 01826 $em = 'Cache file locked warning'; 01827 $en = -32001; 01828 // do not call error handling for just a warning 01829 } 01830 01831 if ($this->debug) ADOConnection::outp( " ".$em); 01832 } 01833 if ($rs->EOF && !$eof) { 01834 $rs->MoveFirst(); 01835 //$rs = csv2rs($md5file,$err); 01836 $rs->connection = $this; // Pablo suggestion 01837 } 01838 01839 } else if (!$this->memCache) 01840 $ADODB_CACHE->flushcache($md5file); 01841 } else { 01842 $this->_errorMsg = ''; 01843 $this->_errorCode = 0; 01844 01845 if ($this->fnCacheExecute) { 01846 $fn = $this->fnCacheExecute; 01847 $fn($this, $secs2cache, $sql, $inputarr); 01848 } 01849 // ok, set cached object found 01850 $rs->connection = $this; // Pablo suggestion 01851 if ($this->debug){ 01852 if ($this->debug == 99) adodb_backtrace(); 01853 $inBrowser = isset($_SERVER['HTTP_USER_AGENT']); 01854 $ttl = $rs->timeCreated + $secs2cache - time(); 01855 $s = is_array($sql) ? $sql[0] : $sql; 01856 if ($inBrowser) $s = '<i>'.htmlspecialchars($s).'</i>'; 01857 01858 ADOConnection::outp( " $md5file reloaded, ttl=$ttl [ $s ]"); 01859 } 01860 } 01861 return $rs; 01862 } 01863 01864 01865 /* 01866 Similar to PEAR DB's autoExecute(), except that 01867 $mode can be 'INSERT' or 'UPDATE' or DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE 01868 If $mode == 'UPDATE', then $where is compulsory as a safety measure. 01869 01870 $forceUpdate means that even if the data has not changed, perform update. 01871 */ 01872 function AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false) 01873 { 01874 $false = false; 01875 $sql = 'SELECT * FROM '.$table; 01876 if ($where!==FALSE) $sql .= ' WHERE '.$where; 01877 else if ($mode == 'UPDATE' || $mode == 2 /* DB_AUTOQUERY_UPDATE */) { 01878 $this->outp_throw('AutoExecute: Illegal mode=UPDATE with empty WHERE clause','AutoExecute'); 01879 return $false; 01880 } 01881 01882 $rs = $this->SelectLimit($sql,1); 01883 if (!$rs) return $false; // table does not exist 01884 $rs->tableName = $table; 01885 $rs->sql = $sql; 01886 01887 switch((string) $mode) { 01888 case 'UPDATE': 01889 case '2': 01890 $sql = $this->GetUpdateSQL($rs, $fields_values, $forceUpdate, $magicq); 01891 break; 01892 case 'INSERT': 01893 case '1': 01894 $sql = $this->GetInsertSQL($rs, $fields_values, $magicq); 01895 break; 01896 default: 01897 $this->outp_throw("AutoExecute: Unknown mode=$mode",'AutoExecute'); 01898 return $false; 01899 } 01900 $ret = false; 01901 if ($sql) $ret = $this->Execute($sql); 01902 if ($ret) $ret = true; 01903 return $ret; 01904 } 01905 01906 01918 function GetUpdateSQL(&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=null) 01919 { 01920 global $ADODB_INCLUDED_LIB; 01921 01922 //********************************************************// 01923 //This is here to maintain compatibility 01924 //with older adodb versions. Sets force type to force nulls if $forcenulls is set. 01925 if (!isset($force)) { 01926 global $ADODB_FORCE_TYPE; 01927 $force = $ADODB_FORCE_TYPE; 01928 } 01929 //********************************************************// 01930 01931 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 01932 return _adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq,$force); 01933 } 01934 01943 function GetInsertSQL(&$rs, $arrFields,$magicq=false,$force=null) 01944 { 01945 global $ADODB_INCLUDED_LIB; 01946 if (!isset($force)) { 01947 global $ADODB_FORCE_TYPE; 01948 $force = $ADODB_FORCE_TYPE; 01949 01950 } 01951 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 01952 return _adodb_getinsertsql($this,$rs,$arrFields,$magicq,$force); 01953 } 01954 01955 01975 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') 01976 { 01977 return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false; 01978 } 01979 01989 function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB') 01990 { 01991 $fd = fopen($path,'rb'); 01992 if ($fd === false) return false; 01993 $val = fread($fd,filesize($path)); 01994 fclose($fd); 01995 return $this->UpdateBlob($table,$column,$val,$where,$blobtype); 01996 } 01997 01998 function BlobDecode($blob) 01999 { 02000 return $blob; 02001 } 02002 02003 function BlobEncode($blob) 02004 { 02005 return $blob; 02006 } 02007 02008 function SetCharSet($charset) 02009 { 02010 return false; 02011 } 02012 02013 function IfNull( $field, $ifNull ) 02014 { 02015 return " CASE WHEN $field is null THEN $ifNull ELSE $field END "; 02016 } 02017 02018 function LogSQL($enable=true) 02019 { 02020 include_once(ADODB_DIR.'/adodb-perf.inc.php'); 02021 02022 if ($enable) $this->fnExecute = 'adodb_log_sql'; 02023 else $this->fnExecute = false; 02024 02025 $old = $this->_logsql; 02026 $this->_logsql = $enable; 02027 if ($enable && !$old) $this->_affected = false; 02028 return $old; 02029 } 02030 02031 function GetCharSet() 02032 { 02033 return false; 02034 } 02035 02043 function UpdateClob($table,$column,$val,$where) 02044 { 02045 return $this->UpdateBlob($table,$column,$val,$where,'CLOB'); 02046 } 02047 02048 // not the fastest implementation - quick and dirty - jlim 02049 // for best performance, use the actual $rs->MetaType(). 02050 function MetaType($t,$len=-1,$fieldobj=false) 02051 { 02052 02053 if (empty($this->_metars)) { 02054 $rsclass = $this->rsPrefix.$this->databaseType; 02055 $this->_metars = new $rsclass(false,$this->fetchMode); 02056 $this->_metars->connection = $this; 02057 } 02058 return $this->_metars->MetaType($t,$len,$fieldobj); 02059 } 02060 02061 02066 function SetDateLocale($locale = 'En') 02067 { 02068 $this->locale = $locale; 02069 switch (strtoupper($locale)) 02070 { 02071 case 'EN': 02072 $this->fmtDate="'Y-m-d'"; 02073 $this->fmtTimeStamp = "'Y-m-d H:i:s'"; 02074 break; 02075 02076 case 'US': 02077 $this->fmtDate = "'m-d-Y'"; 02078 $this->fmtTimeStamp = "'m-d-Y H:i:s'"; 02079 break; 02080 02081 case 'PT_BR': 02082 case 'NL': 02083 case 'FR': 02084 case 'RO': 02085 case 'IT': 02086 $this->fmtDate="'d-m-Y'"; 02087 $this->fmtTimeStamp = "'d-m-Y H:i:s'"; 02088 break; 02089 02090 case 'GE': 02091 $this->fmtDate="'d.m.Y'"; 02092 $this->fmtTimeStamp = "'d.m.Y H:i:s'"; 02093 break; 02094 02095 default: 02096 $this->fmtDate="'Y-m-d'"; 02097 $this->fmtTimeStamp = "'Y-m-d H:i:s'"; 02098 break; 02099 } 02100 } 02101 02115 function GetActiveRecordsClass( 02116 $class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false, 02117 $extra=array(), 02118 $relations=array()) 02119 { 02120 global $_ADODB_ACTIVE_DBS; 02121 ## reduce overhead of adodb.inc.php -- moved to adodb-active-record.inc.php 02122 ## if adodb-active-recordx is loaded -- should be no issue as they will probably use Find() 02123 if (!isset($_ADODB_ACTIVE_DBS))include_once(ADODB_DIR.'/adodb-active-record.inc.php'); 02124 return adodb_GetActiveRecordsClass($this, $class, $table, $whereOrderBy, $bindarr, $primkeyArr, $extra, $relations); 02125 } 02126 02127 function GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false) 02128 { 02129 $arr = $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr); 02130 return $arr; 02131 } 02132 02136 function Close() 02137 { 02138 $rez = $this->_close(); 02139 $this->_connectionID = false; 02140 return $rez; 02141 } 02142 02148 function BeginTrans() 02149 { 02150 if ($this->debug) ADOConnection::outp("BeginTrans: Transactions not supported for this driver"); 02151 return false; 02152 } 02153 02154 /* set transaction mode */ 02155 function SetTransactionMode( $transaction_mode ) 02156 { 02157 $transaction_mode = $this->MetaTransaction($transaction_mode, $this->dataProvider); 02158 $this->_transmode = $transaction_mode; 02159 } 02160 /* 02161 http://msdn2.microsoft.com/en-US/ms173763.aspx 02162 http://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-isolation.html 02163 http://www.postgresql.org/docs/8.1/interactive/sql-set-transaction.html 02164 http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_10005.htm 02165 */ 02166 function MetaTransaction($mode,$db) 02167 { 02168 $mode = strtoupper($mode); 02169 $mode = str_replace('ISOLATION LEVEL ','',$mode); 02170 02171 switch($mode) { 02172 02173 case 'READ UNCOMMITTED': 02174 switch($db) { 02175 case 'oci8': 02176 case 'oracle': 02177 return 'ISOLATION LEVEL READ COMMITTED'; 02178 default: 02179 return 'ISOLATION LEVEL READ UNCOMMITTED'; 02180 } 02181 break; 02182 02183 case 'READ COMMITTED': 02184 return 'ISOLATION LEVEL READ COMMITTED'; 02185 break; 02186 02187 case 'REPEATABLE READ': 02188 switch($db) { 02189 case 'oci8': 02190 case 'oracle': 02191 return 'ISOLATION LEVEL SERIALIZABLE'; 02192 default: 02193 return 'ISOLATION LEVEL REPEATABLE READ'; 02194 } 02195 break; 02196 02197 case 'SERIALIZABLE': 02198 return 'ISOLATION LEVEL SERIALIZABLE'; 02199 break; 02200 02201 default: 02202 return $mode; 02203 } 02204 } 02205 02213 function CommitTrans($ok=true) 02214 { return true;} 02215 02216 02222 function RollbackTrans() 02223 { return false;} 02224 02225 02232 function MetaDatabases() 02233 { 02234 global $ADODB_FETCH_MODE; 02235 02236 if ($this->metaDatabasesSQL) { 02237 $save = $ADODB_FETCH_MODE; 02238 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 02239 02240 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); 02241 02242 $arr = $this->GetCol($this->metaDatabasesSQL); 02243 if (isset($savem)) $this->SetFetchMode($savem); 02244 $ADODB_FETCH_MODE = $save; 02245 02246 return $arr; 02247 } 02248 02249 return false; 02250 } 02251 02252 02263 function MetaTables($ttype=false,$showSchema=false,$mask=false) 02264 { 02265 global $ADODB_FETCH_MODE; 02266 02267 02268 $false = false; 02269 if ($mask) { 02270 return $false; 02271 } 02272 if ($this->metaTablesSQL) { 02273 $save = $ADODB_FETCH_MODE; 02274 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 02275 02276 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); 02277 02278 $rs = $this->Execute($this->metaTablesSQL); 02279 if (isset($savem)) $this->SetFetchMode($savem); 02280 $ADODB_FETCH_MODE = $save; 02281 02282 if ($rs === false) return $false; 02283 $arr = $rs->GetArray(); 02284 $arr2 = array(); 02285 02286 if ($hast = ($ttype && isset($arr[0][1]))) { 02287 $showt = strncmp($ttype,'T',1); 02288 } 02289 02290 for ($i=0; $i < sizeof($arr); $i++) { 02291 if ($hast) { 02292 if ($showt == 0) { 02293 if (strncmp($arr[$i][1],'T',1) == 0) $arr2[] = trim($arr[$i][0]); 02294 } else { 02295 if (strncmp($arr[$i][1],'V',1) == 0) $arr2[] = trim($arr[$i][0]); 02296 } 02297 } else 02298 $arr2[] = trim($arr[$i][0]); 02299 } 02300 $rs->Close(); 02301 return $arr2; 02302 } 02303 return $false; 02304 } 02305 02306 02307 function _findschema(&$table,&$schema) 02308 { 02309 if (!$schema && ($at = strpos($table,'.')) !== false) { 02310 $schema = substr($table,0,$at); 02311 $table = substr($table,$at+1); 02312 } 02313 } 02314 02325 function MetaColumns($table,$normalize=true) 02326 { 02327 global $ADODB_FETCH_MODE; 02328 02329 $false = false; 02330 02331 if (!empty($this->metaColumnsSQL)) { 02332 02333 $schema = false; 02334 $this->_findschema($table,$schema); 02335 02336 $save = $ADODB_FETCH_MODE; 02337 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 02338 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); 02339 $rs = $this->Execute(sprintf($this->metaColumnsSQL,($normalize)?strtoupper($table):$table)); 02340 if (isset($savem)) $this->SetFetchMode($savem); 02341 $ADODB_FETCH_MODE = $save; 02342 if ($rs === false || $rs->EOF) return $false; 02343 02344 $retarr = array(); 02345 while (!$rs->EOF) { //print_r($rs->fields); 02346 $fld = new ADOFieldObject(); 02347 $fld->name = $rs->fields[0]; 02348 $fld->type = $rs->fields[1]; 02349 if (isset($rs->fields[3]) && $rs->fields[3]) { 02350 if ($rs->fields[3]>0) $fld->max_length = $rs->fields[3]; 02351 $fld->scale = $rs->fields[4]; 02352 if ($fld->scale>0) $fld->max_length += 1; 02353 } else 02354 $fld->max_length = $rs->fields[2]; 02355 02356 if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld; 02357 else $retarr[strtoupper($fld->name)] = $fld; 02358 $rs->MoveNext(); 02359 } 02360 $rs->Close(); 02361 return $retarr; 02362 } 02363 return $false; 02364 } 02365 02384 function MetaIndexes($table, $primary = false, $owner = false) 02385 { 02386 $false = false; 02387 return $false; 02388 } 02389 02396 function MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */) 02397 { 02398 $objarr = $this->MetaColumns($table); 02399 if (!is_array($objarr)) { 02400 $false = false; 02401 return $false; 02402 } 02403 $arr = array(); 02404 if ($numIndexes) { 02405 $i = 0; 02406 if ($useattnum) { 02407 foreach($objarr as $v) 02408 $arr[$v->attnum] = $v->name; 02409 02410 } else 02411 foreach($objarr as $v) $arr[$i++] = $v->name; 02412 } else 02413 foreach($objarr as $v) $arr[strtoupper($v->name)] = $v->name; 02414 02415 return $arr; 02416 } 02417 02428 function Concat() 02429 { 02430 $arr = func_get_args(); 02431 return implode($this->concat_operator, $arr); 02432 } 02433 02434 02442 function DBDate($d, $isfld=false) 02443 { 02444 if (empty($d) && $d !== 0) return 'null'; 02445 if ($isfld) return $d; 02446 02447 if (is_object($d)) return $d->format($this->fmtDate); 02448 02449 02450 if (is_string($d) && !is_numeric($d)) { 02451 if ($d === 'null' || strncmp($d,"'",1) === 0) return $d; 02452 if ($this->isoDates) return "'$d'"; 02453 $d = ADOConnection::UnixDate($d); 02454 } 02455 02456 return adodb_date($this->fmtDate,$d); 02457 } 02458 02459 function BindDate($d) 02460 { 02461 $d = $this->DBDate($d); 02462 if (strncmp($d,"'",1)) return $d; 02463 02464 return substr($d,1,strlen($d)-2); 02465 } 02466 02467 function BindTimeStamp($d) 02468 { 02469 $d = $this->DBTimeStamp($d); 02470 if (strncmp($d,"'",1)) return $d; 02471 02472 return substr($d,1,strlen($d)-2); 02473 } 02474 02475 02483 function DBTimeStamp($ts,$isfld=false) 02484 { 02485 if (empty($ts) && $ts !== 0) return 'null'; 02486 if ($isfld) return $ts; 02487 if (is_object($ts)) return $ts->format($this->fmtTimeStamp); 02488 02489 # strlen(14) allows YYYYMMDDHHMMSS format 02490 if (!is_string($ts) || (is_numeric($ts) && strlen($ts)<14)) 02491 return adodb_date($this->fmtTimeStamp,$ts); 02492 02493 if ($ts === 'null') return $ts; 02494 if ($this->isoDates && strlen($ts) !== 14) return "'$ts'"; 02495 02496 $ts = ADOConnection::UnixTimeStamp($ts); 02497 return adodb_date($this->fmtTimeStamp,$ts); 02498 } 02499 02506 static function UnixDate($v) 02507 { 02508 if (is_object($v)) { 02509 // odbtp support 02510 //( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 ) 02511 return adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year); 02512 } 02513 02514 if (is_numeric($v) && strlen($v) !== 8) return $v; 02515 if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|", 02516 ($v), $rr)) return false; 02517 02518 if ($rr[1] <= TIMESTAMP_FIRST_YEAR) return 0; 02519 // h-m-s-MM-DD-YY 02520 return @adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]); 02521 } 02522 02523 02530 static function UnixTimeStamp($v) 02531 { 02532 if (is_object($v)) { 02533 // odbtp support 02534 //( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 ) 02535 return adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year); 02536 } 02537 02538 if (!preg_match( 02539 "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]*(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", 02540 ($v), $rr)) return false; 02541 02542 if ($rr[1] <= TIMESTAMP_FIRST_YEAR && $rr[2]<= 1) return 0; 02543 02544 // h-m-s-MM-DD-YY 02545 if (!isset($rr[5])) return adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]); 02546 return @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]); 02547 } 02548 02560 function UserDate($v,$fmt='Y-m-d',$gmt=false) 02561 { 02562 $tt = $this->UnixDate($v); 02563 02564 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR 02565 if (($tt === false || $tt == -1) && $v != false) return $v; 02566 else if ($tt == 0) return $this->emptyDate; 02567 else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR 02568 } 02569 02570 return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt); 02571 02572 } 02573 02581 function UserTimeStamp($v,$fmt='Y-m-d H:i:s',$gmt=false) 02582 { 02583 if (!isset($v)) return $this->emptyTimeStamp; 02584 # strlen(14) allows YYYYMMDDHHMMSS format 02585 if (is_numeric($v) && strlen($v)<14) return ($gmt) ? adodb_gmdate($fmt,$v) : adodb_date($fmt,$v); 02586 $tt = $this->UnixTimeStamp($v); 02587 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR 02588 if (($tt === false || $tt == -1) && $v != false) return $v; 02589 if ($tt == 0) return $this->emptyTimeStamp; 02590 return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt); 02591 } 02592 02593 function escape($s,$magic_quotes=false) 02594 { 02595 return $this->addq($s,$magic_quotes); 02596 } 02597 02601 function addq($s,$magic_quotes=false) 02602 { 02603 if (!$magic_quotes) { 02604 02605 if ($this->replaceQuote[0] == '\\'){ 02606 // only since php 4.0.5 02607 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s); 02608 //$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s)); 02609 } 02610 return str_replace("'",$this->replaceQuote,$s); 02611 } 02612 02613 // undo magic quotes for " 02614 $s = str_replace('\\"','"',$s); 02615 02616 if ($this->replaceQuote == "\\'" || ini_get('magic_quotes_sybase')) // ' already quoted, no need to change anything 02617 return $s; 02618 else {// change \' to '' for sybase/mssql 02619 $s = str_replace('\\\\','\\',$s); 02620 return str_replace("\\'",$this->replaceQuote,$s); 02621 } 02622 } 02623 02635 function qstr($s,$magic_quotes=false) 02636 { 02637 if (!$magic_quotes) { 02638 02639 if ($this->replaceQuote[0] == '\\'){ 02640 // only since php 4.0.5 02641 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s); 02642 //$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s)); 02643 } 02644 return "'".str_replace("'",$this->replaceQuote,$s)."'"; 02645 } 02646 02647 // undo magic quotes for " 02648 $s = str_replace('\\"','"',$s); 02649 02650 if ($this->replaceQuote == "\\'" || ini_get('magic_quotes_sybase')) // ' already quoted, no need to change anything 02651 return "'$s'"; 02652 else {// change \' to '' for sybase/mssql 02653 $s = str_replace('\\\\','\\',$s); 02654 return "'".str_replace("\\'",$this->replaceQuote,$s)."'"; 02655 } 02656 } 02657 02658 02676 function PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) 02677 { 02678 global $ADODB_INCLUDED_LIB; 02679 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 02680 if ($this->pageExecuteCountRows) $rs = _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache); 02681 else $rs = _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache); 02682 return $rs; 02683 } 02684 02685 02698 function CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) 02699 { 02700 /*switch($this->dataProvider) { 02701 case 'postgres': 02702 case 'mysql': 02703 break; 02704 default: $secs2cache = 0; break; 02705 }*/ 02706 $rs = $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache); 02707 return $rs; 02708 } 02709 02710 } // end class ADOConnection 02711 02712 02713 02714 //============================================================================================== 02715 // CLASS ADOFetchObj 02716 //============================================================================================== 02717 02721 class ADOFetchObj { 02722 }; 02723 02724 //============================================================================================== 02725 // CLASS ADORecordSet_empty 02726 //============================================================================================== 02727 02728 class ADODB_Iterator_empty implements Iterator { 02729 02730 private $rs; 02731 02732 function __construct($rs) 02733 { 02734 $this->rs = $rs; 02735 } 02736 function rewind() 02737 { 02738 } 02739 02740 function valid() 02741 { 02742 return !$this->rs->EOF; 02743 } 02744 02745 function key() 02746 { 02747 return false; 02748 } 02749 02750 function current() 02751 { 02752 return false; 02753 } 02754 02755 function next() 02756 { 02757 } 02758 02759 function __call($func, $params) 02760 { 02761 return call_user_func_array(array($this->rs, $func), $params); 02762 } 02763 02764 function hasMore() 02765 { 02766 return false; 02767 } 02768 02769 } 02770 02771 02775 class ADORecordSet_empty implements IteratorAggregate 02776 { 02777 var $dataProvider = 'empty'; 02778 var $databaseType = false; 02779 var $EOF = true; 02780 var $_numOfRows = 0; 02781 var $fields = false; 02782 var $connection = false; 02783 function RowCount() {return 0;} 02784 function RecordCount() {return 0;} 02785 function PO_RecordCount(){return 0;} 02786 function Close(){return true;} 02787 function FetchRow() {return false;} 02788 function FieldCount(){ return 0;} 02789 function Init() {} 02790 function getIterator() {return new ADODB_Iterator_empty($this);} 02791 } 02792 02793 //============================================================================================== 02794 // DATE AND TIME FUNCTIONS 02795 //============================================================================================== 02796 if (!defined('ADODB_DATE_VERSION')) include(ADODB_DIR.'/adodb-time.inc.php'); 02797 02798 //============================================================================================== 02799 // CLASS ADORecordSet 02800 //============================================================================================== 02801 02802 class ADODB_Iterator implements Iterator { 02803 02804 private $rs; 02805 02806 function __construct($rs) 02807 { 02808 $this->rs = $rs; 02809 } 02810 function rewind() 02811 { 02812 $this->rs->MoveFirst(); 02813 } 02814 02815 function valid() 02816 { 02817 return !$this->rs->EOF; 02818 } 02819 02820 function key() 02821 { 02822 return $this->rs->_currentRow; 02823 } 02824 02825 function current() 02826 { 02827 return $this->rs->fields; 02828 } 02829 02830 function next() 02831 { 02832 $this->rs->MoveNext(); 02833 } 02834 02835 function __call($func, $params) 02836 { 02837 return call_user_func_array(array($this->rs, $func), $params); 02838 } 02839 02840 02841 function hasMore() 02842 { 02843 return !$this->rs->EOF; 02844 } 02845 02846 } 02847 02848 02849 02856 class ADORecordSet implements IteratorAggregate { 02857 /* 02858 * public variables 02859 */ 02860 var $dataProvider = "native"; 02861 var $fields = false; 02862 var $blobSize = 100; 02863 02864 var $canSeek = false; 02865 var $sql; 02866 var $EOF = false; 02867 02868 var $emptyTimeStamp = ' '; 02869 var $emptyDate = ' '; 02870 var $debug = false; 02871 var $timeCreated=0; 02872 02873 var $bind = false; 02874 var $fetchMode; 02875 var $connection = false; 02876 /* 02877 * private variables 02878 */ 02879 var $_numOfRows = -1; 02880 var $_numOfFields = -1; 02881 var $_queryID = -1; 02882 var $_currentRow = -1; 02883 var $_closed = false; 02884 var $_inited = false; 02885 var $_obj; 02886 var $_names; 02888 var $_currentPage = -1; 02889 var $_atFirstPage = false; 02890 var $_atLastPage = false; 02891 var $_lastPageNo = -1; 02892 var $_maxRecordCount = 0; 02893 var $datetime = false; 02894 02901 function ADORecordSet($queryID) 02902 { 02903 $this->_queryID = $queryID; 02904 } 02905 02906 function getIterator() 02907 { 02908 return new ADODB_Iterator($this); 02909 } 02910 02911 /* this is experimental - i don't really know what to return... */ 02912 function __toString() 02913 { 02914 include_once(ADODB_DIR.'/toexport.inc.php'); 02915 return _adodb_export($this,',',',',false,true); 02916 } 02917 02918 02919 function Init() 02920 { 02921 if ($this->_inited) return; 02922 $this->_inited = true; 02923 if ($this->_queryID) @$this->_initrs(); 02924 else { 02925 $this->_numOfRows = 0; 02926 $this->_numOfFields = 0; 02927 } 02928 if ($this->_numOfRows != 0 && $this->_numOfFields && $this->_currentRow == -1) { 02929 02930 $this->_currentRow = 0; 02931 if ($this->EOF = ($this->_fetch() === false)) { 02932 $this->_numOfRows = 0; // _numOfRows could be -1 02933 } 02934 } else { 02935 $this->EOF = true; 02936 } 02937 } 02938 02939 02960 function GetMenu($name,$defstr='',$blank1stItem=true,$multiple=false, 02961 $size=0, $selectAttr='',$compareFields0=true) 02962 { 02963 global $ADODB_INCLUDED_LIB; 02964 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 02965 return _adodb_getmenu($this, $name,$defstr,$blank1stItem,$multiple, 02966 $size, $selectAttr,$compareFields0); 02967 } 02968 02969 02970 02978 function GetMenu2($name,$defstr='',$blank1stItem=true,$multiple=false,$size=0, $selectAttr='') 02979 { 02980 return $this->GetMenu($name,$defstr,$blank1stItem,$multiple, 02981 $size, $selectAttr,false); 02982 } 02983 02984 /* 02985 Grouped Menu 02986 */ 02987 function GetMenu3($name,$defstr='',$blank1stItem=true,$multiple=false, 02988 $size=0, $selectAttr='') 02989 { 02990 global $ADODB_INCLUDED_LIB; 02991 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 02992 return _adodb_getmenu_gp($this, $name,$defstr,$blank1stItem,$multiple, 02993 $size, $selectAttr,false); 02994 } 02995 03003 function GetArray($nRows = -1) 03004 { 03005 global $ADODB_EXTENSION; if ($ADODB_EXTENSION) { 03006 $results = adodb_getall($this,$nRows); 03007 return $results; 03008 } 03009 $results = array(); 03010 $cnt = 0; 03011 while (!$this->EOF && $nRows != $cnt) { 03012 $results[] = $this->fields; 03013 $this->MoveNext(); 03014 $cnt++; 03015 } 03016 return $results; 03017 } 03018 03019 function GetAll($nRows = -1) 03020 { 03021 $arr = $this->GetArray($nRows); 03022 return $arr; 03023 } 03024 03025 /* 03026 * Some databases allow multiple recordsets to be returned. This function 03027 * will return true if there is a next recordset, or false if no more. 03028 */ 03029 function NextRecordSet() 03030 { 03031 return false; 03032 } 03033 03043 function GetArrayLimit($nrows,$offset=-1) 03044 { 03045 if ($offset <= 0) { 03046 $arr = $this->GetArray($nrows); 03047 return $arr; 03048 } 03049 03050 $this->Move($offset); 03051 03052 $results = array(); 03053 $cnt = 0; 03054 while (!$this->EOF && $nrows != $cnt) { 03055 $results[$cnt++] = $this->fields; 03056 $this->MoveNext(); 03057 } 03058 03059 return $results; 03060 } 03061 03062 03070 function GetRows($nRows = -1) 03071 { 03072 $arr = $this->GetArray($nRows); 03073 return $arr; 03074 } 03075 03092 function GetAssoc($force_array = false, $first2cols = false) 03093 { 03094 global $ADODB_EXTENSION; 03095 03096 $cols = $this->_numOfFields; 03097 if ($cols < 2) { 03098 $false = false; 03099 return $false; 03100 } 03101 $numIndex = isset($this->fields[0]); 03102 $results = array(); 03103 03104 if (!$first2cols && ($cols > 2 || $force_array)) { 03105 if ($ADODB_EXTENSION) { 03106 if ($numIndex) { 03107 while (!$this->EOF) { 03108 $results[trim($this->fields[0])] = array_slice($this->fields, 1); 03109 adodb_movenext($this); 03110 } 03111 } else { 03112 while (!$this->EOF) { 03113 // Fix for array_slice re-numbering numeric associative keys 03114 $keys = array_slice(array_keys($this->fields), 1); 03115 $sliced_array = array(); 03116 03117 foreach($keys as $key) { 03118 $sliced_array[$key] = $this->fields[$key]; 03119 } 03120 03121 $results[trim(reset($this->fields))] = $sliced_array; 03122 adodb_movenext($this); 03123 } 03124 } 03125 } else { 03126 if ($numIndex) { 03127 while (!$this->EOF) { 03128 $results[trim($this->fields[0])] = array_slice($this->fields, 1); 03129 $this->MoveNext(); 03130 } 03131 } else { 03132 while (!$this->EOF) { 03133 // Fix for array_slice re-numbering numeric associative keys 03134 $keys = array_slice(array_keys($this->fields), 1); 03135 $sliced_array = array(); 03136 03137 foreach($keys as $key) { 03138 $sliced_array[$key] = $this->fields[$key]; 03139 } 03140 03141 $results[trim(reset($this->fields))] = $sliced_array; 03142 $this->MoveNext(); 03143 } 03144 } 03145 } 03146 } else { 03147 if ($ADODB_EXTENSION) { 03148 // return scalar values 03149 if ($numIndex) { 03150 while (!$this->EOF) { 03151 // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string 03152 $results[trim(($this->fields[0]))] = $this->fields[1]; 03153 adodb_movenext($this); 03154 } 03155 } else { 03156 while (!$this->EOF) { 03157 // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string 03158 $v1 = trim(reset($this->fields)); 03159 $v2 = ''.next($this->fields); 03160 $results[$v1] = $v2; 03161 adodb_movenext($this); 03162 } 03163 } 03164 } else { 03165 if ($numIndex) { 03166 while (!$this->EOF) { 03167 // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string 03168 $results[trim(($this->fields[0]))] = $this->fields[1]; 03169 $this->MoveNext(); 03170 } 03171 } else { 03172 while (!$this->EOF) { 03173 // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string 03174 $v1 = trim(reset($this->fields)); 03175 $v2 = ''.next($this->fields); 03176 $results[$v1] = $v2; 03177 $this->MoveNext(); 03178 } 03179 } 03180 } 03181 } 03182 03183 $ref = $results; # workaround accelerator incompat with PHP 4.4 :( 03184 return $ref; 03185 } 03186 03187 03195 function UserTimeStamp($v,$fmt='Y-m-d H:i:s') 03196 { 03197 if (is_numeric($v) && strlen($v)<14) return adodb_date($fmt,$v); 03198 $tt = $this->UnixTimeStamp($v); 03199 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR 03200 if (($tt === false || $tt == -1) && $v != false) return $v; 03201 if ($tt === 0) return $this->emptyTimeStamp; 03202 return adodb_date($fmt,$tt); 03203 } 03204 03205 03212 function UserDate($v,$fmt='Y-m-d') 03213 { 03214 $tt = $this->UnixDate($v); 03215 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR 03216 if (($tt === false || $tt == -1) && $v != false) return $v; 03217 else if ($tt == 0) return $this->emptyDate; 03218 else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR 03219 } 03220 return adodb_date($fmt,$tt); 03221 } 03222 03223 03229 static function UnixDate($v) 03230 { 03231 return ADOConnection::UnixDate($v); 03232 } 03233 03234 03240 static function UnixTimeStamp($v) 03241 { 03242 return ADOConnection::UnixTimeStamp($v); 03243 } 03244 03245 03249 function Free() 03250 { 03251 return $this->Close(); 03252 } 03253 03254 03258 function NumRows() 03259 { 03260 return $this->_numOfRows; 03261 } 03262 03263 03267 function NumCols() 03268 { 03269 return $this->_numOfFields; 03270 } 03271 03278 function FetchRow() 03279 { 03280 if ($this->EOF) { 03281 $false = false; 03282 return $false; 03283 } 03284 $arr = $this->fields; 03285 $this->_currentRow++; 03286 if (!$this->_fetch()) $this->EOF = true; 03287 return $arr; 03288 } 03289 03290 03297 function FetchInto(&$arr) 03298 { 03299 if ($this->EOF) return (defined('PEAR_ERROR_RETURN')) ? new PEAR_Error('EOF',-1): false; 03300 $arr = $this->fields; 03301 $this->MoveNext(); 03302 return 1; // DB_OK 03303 } 03304 03305 03311 function MoveFirst() 03312 { 03313 if ($this->_currentRow == 0) return true; 03314 return $this->Move(0); 03315 } 03316 03317 03323 function MoveLast() 03324 { 03325 if ($this->_numOfRows >= 0) return $this->Move($this->_numOfRows-1); 03326 if ($this->EOF) return false; 03327 while (!$this->EOF) { 03328 $f = $this->fields; 03329 $this->MoveNext(); 03330 } 03331 $this->fields = $f; 03332 $this->EOF = false; 03333 return true; 03334 } 03335 03336 03342 function MoveNext() 03343 { 03344 if (!$this->EOF) { 03345 $this->_currentRow++; 03346 if ($this->_fetch()) return true; 03347 } 03348 $this->EOF = true; 03349 /* -- tested error handling when scrolling cursor -- seems useless. 03350 $conn = $this->connection; 03351 if ($conn && $conn->raiseErrorFn && ($errno = $conn->ErrorNo())) { 03352 $fn = $conn->raiseErrorFn; 03353 $fn($conn->databaseType,'MOVENEXT',$errno,$conn->ErrorMsg().' ('.$this->sql.')',$conn->host,$conn->database); 03354 } 03355 */ 03356 return false; 03357 } 03358 03359 03368 function Move($rowNumber = 0) 03369 { 03370 $this->EOF = false; 03371 if ($rowNumber == $this->_currentRow) return true; 03372 if ($rowNumber >= $this->_numOfRows) 03373 if ($this->_numOfRows != -1) $rowNumber = $this->_numOfRows-2; 03374 03375 if ($this->canSeek) { 03376 03377 if ($this->_seek($rowNumber)) { 03378 $this->_currentRow = $rowNumber; 03379 if ($this->_fetch()) { 03380 return true; 03381 } 03382 } else { 03383 $this->EOF = true; 03384 return false; 03385 } 03386 } else { 03387 if ($rowNumber < $this->_currentRow) return false; 03388 global $ADODB_EXTENSION; 03389 if ($ADODB_EXTENSION) { 03390 while (!$this->EOF && $this->_currentRow < $rowNumber) { 03391 adodb_movenext($this); 03392 } 03393 } else { 03394 03395 while (! $this->EOF && $this->_currentRow < $rowNumber) { 03396 $this->_currentRow++; 03397 03398 if (!$this->_fetch()) $this->EOF = true; 03399 } 03400 } 03401 return !($this->EOF); 03402 } 03403 03404 $this->fields = false; 03405 $this->EOF = true; 03406 return false; 03407 } 03408 03409 03418 function Fields($colname) 03419 { 03420 return $this->fields[$colname]; 03421 } 03422 03423 function GetAssocKeys($upper=true) 03424 { 03425 $this->bind = array(); 03426 for ($i=0; $i < $this->_numOfFields; $i++) { 03427 $o = $this->FetchField($i); 03428 if ($upper === 2) $this->bind[$o->name] = $i; 03429 else $this->bind[($upper) ? strtoupper($o->name) : strtolower($o->name)] = $i; 03430 } 03431 } 03432 03442 function GetRowAssoc($upper=1) 03443 { 03444 $record = array(); 03445 // if (!$this->fields) return $record; 03446 03447 if (!$this->bind) { 03448 $this->GetAssocKeys($upper); 03449 } 03450 03451 foreach($this->bind as $k => $v) { 03452 $record[$k] = $this->fields[$v]; 03453 } 03454 03455 return $record; 03456 } 03457 03458 03464 function Close() 03465 { 03466 // free connection object - this seems to globally free the object 03467 // and not merely the reference, so don't do this... 03468 // $this->connection = false; 03469 if (!$this->_closed) { 03470 $this->_closed = true; 03471 return $this->_close(); 03472 } else 03473 return true; 03474 } 03475 03481 function RecordCount() {return $this->_numOfRows;} 03482 03483 03484 /* 03485 * If we are using PageExecute(), this will return the maximum possible rows 03486 * that can be returned when paging a recordset. 03487 */ 03488 function MaxRecordCount() 03489 { 03490 return ($this->_maxRecordCount) ? $this->_maxRecordCount : $this->RecordCount(); 03491 } 03492 03498 function RowCount() {return $this->_numOfRows;} 03499 03500 03509 function PO_RecordCount($table="", $condition="") { 03510 03511 $lnumrows = $this->_numOfRows; 03512 // the database doesn't support native recordcount, so we do a workaround 03513 if ($lnumrows == -1 && $this->connection) { 03514 IF ($table) { 03515 if ($condition) $condition = " WHERE " . $condition; 03516 $resultrows = $this->connection->Execute("SELECT COUNT(*) FROM $table $condition"); 03517 if ($resultrows) $lnumrows = reset($resultrows->fields); 03518 } 03519 } 03520 return $lnumrows; 03521 } 03522 03523 03527 function CurrentRow() {return $this->_currentRow;} 03528 03534 function AbsolutePosition() {return $this->_currentRow;} 03535 03540 function FieldCount() {return $this->_numOfFields;} 03541 03542 03550 function FetchField($fieldoffset = -1) 03551 { 03552 // must be defined by child class 03553 03554 $false = false; 03555 return $false; 03556 } 03557 03562 function FieldTypesArray() 03563 { 03564 $arr = array(); 03565 for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) 03566 $arr[] = $this->FetchField($i); 03567 return $arr; 03568 } 03569 03576 function FetchObj() 03577 { 03578 $o = $this->FetchObject(false); 03579 return $o; 03580 } 03581 03590 function FetchObject($isupper=true) 03591 { 03592 if (empty($this->_obj)) { 03593 $this->_obj = new ADOFetchObj(); 03594 $this->_names = array(); 03595 for ($i=0; $i <$this->_numOfFields; $i++) { 03596 $f = $this->FetchField($i); 03597 $this->_names[] = $f->name; 03598 } 03599 } 03600 $i = 0; 03601 if (PHP_VERSION >= 5) $o = clone($this->_obj); 03602 else $o = $this->_obj; 03603 03604 for ($i=0; $i <$this->_numOfFields; $i++) { 03605 $name = $this->_names[$i]; 03606 if ($isupper) $n = strtoupper($name); 03607 else $n = $name; 03608 03609 $o->$n = $this->Fields($name); 03610 } 03611 return $o; 03612 } 03613 03623 function FetchNextObj() 03624 { 03625 $o = $this->FetchNextObject(false); 03626 return $o; 03627 } 03628 03629 03641 function FetchNextObject($isupper=true) 03642 { 03643 $o = false; 03644 if ($this->_numOfRows != 0 && !$this->EOF) { 03645 $o = $this->FetchObject($isupper); 03646 $this->_currentRow++; 03647 if ($this->_fetch()) return $o; 03648 } 03649 $this->EOF = true; 03650 return $o; 03651 } 03652 03677 function MetaType($t,$len=-1,$fieldobj=false) 03678 { 03679 if (is_object($t)) { 03680 $fieldobj = $t; 03681 $t = $fieldobj->type; 03682 $len = $fieldobj->max_length; 03683 } 03684 // changed in 2.32 to hashing instead of switch stmt for speed... 03685 static $typeMap = array( 03686 'VARCHAR' => 'C', 03687 'VARCHAR2' => 'C', 03688 'CHAR' => 'C', 03689 'C' => 'C', 03690 'STRING' => 'C', 03691 'NCHAR' => 'C', 03692 'NVARCHAR' => 'C', 03693 'VARYING' => 'C', 03694 'BPCHAR' => 'C', 03695 'CHARACTER' => 'C', 03696 'INTERVAL' => 'C', # Postgres 03697 'MACADDR' => 'C', # postgres 03698 'VAR_STRING' => 'C', # mysql 03699 ## 03700 'LONGCHAR' => 'X', 03701 'TEXT' => 'X', 03702 'NTEXT' => 'X', 03703 'M' => 'X', 03704 'X' => 'X', 03705 'CLOB' => 'X', 03706 'NCLOB' => 'X', 03707 'LVARCHAR' => 'X', 03708 ## 03709 'BLOB' => 'B', 03710 'IMAGE' => 'B', 03711 'BINARY' => 'B', 03712 'VARBINARY' => 'B', 03713 'LONGBINARY' => 'B', 03714 'B' => 'B', 03715 ## 03716 'YEAR' => 'D', // mysql 03717 'DATE' => 'D', 03718 'D' => 'D', 03719 ## 03720 'UNIQUEIDENTIFIER' => 'C', # MS SQL Server 03721 ## 03722 'SMALLDATETIME' => 'T', 03723 'TIME' => 'T', 03724 'TIMESTAMP' => 'T', 03725 'DATETIME' => 'T', 03726 'TIMESTAMPTZ' => 'T', 03727 'T' => 'T', 03728 'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql 03729 ## 03730 'BOOL' => 'L', 03731 'BOOLEAN' => 'L', 03732 'BIT' => 'L', 03733 'L' => 'L', 03734 ## 03735 'COUNTER' => 'R', 03736 'R' => 'R', 03737 'SERIAL' => 'R', // ifx 03738 'INT IDENTITY' => 'R', 03739 ## 03740 'INT' => 'I', 03741 'INT2' => 'I', 03742 'INT4' => 'I', 03743 'INT8' => 'I', 03744 'INTEGER' => 'I', 03745 'INTEGER UNSIGNED' => 'I', 03746 'SHORT' => 'I', 03747 'TINYINT' => 'I', 03748 'SMALLINT' => 'I', 03749 'I' => 'I', 03750 ## 03751 'LONG' => 'N', // interbase is numeric, oci8 is blob 03752 'BIGINT' => 'N', // this is bigger than PHP 32-bit integers 03753 'DECIMAL' => 'N', 03754 'DEC' => 'N', 03755 'REAL' => 'N', 03756 'DOUBLE' => 'N', 03757 'DOUBLE PRECISION' => 'N', 03758 'SMALLFLOAT' => 'N', 03759 'FLOAT' => 'N', 03760 'NUMBER' => 'N', 03761 'NUM' => 'N', 03762 'NUMERIC' => 'N', 03763 'MONEY' => 'N', 03764 03765 ## informix 9.2 03766 'SQLINT' => 'I', 03767 'SQLSERIAL' => 'I', 03768 'SQLSMINT' => 'I', 03769 'SQLSMFLOAT' => 'N', 03770 'SQLFLOAT' => 'N', 03771 'SQLMONEY' => 'N', 03772 'SQLDECIMAL' => 'N', 03773 'SQLDATE' => 'D', 03774 'SQLVCHAR' => 'C', 03775 'SQLCHAR' => 'C', 03776 'SQLDTIME' => 'T', 03777 'SQLINTERVAL' => 'N', 03778 'SQLBYTES' => 'B', 03779 'SQLTEXT' => 'X', 03780 ## informix 10 03781 "SQLINT8" => 'I8', 03782 "SQLSERIAL8" => 'I8', 03783 "SQLNCHAR" => 'C', 03784 "SQLNVCHAR" => 'C', 03785 "SQLLVARCHAR" => 'X', 03786 "SQLBOOL" => 'L' 03787 ); 03788 03789 $tmap = false; 03790 $t = strtoupper($t); 03791 $tmap = (isset($typeMap[$t])) ? $typeMap[$t] : 'N'; 03792 switch ($tmap) { 03793 case 'C': 03794 03795 // is the char field is too long, return as text field... 03796 if ($this->blobSize >= 0) { 03797 if ($len > $this->blobSize) return 'X'; 03798 } else if ($len > 250) { 03799 return 'X'; 03800 } 03801 return 'C'; 03802 03803 case 'I': 03804 if (!empty($fieldobj->primary_key)) return 'R'; 03805 return 'I'; 03806 03807 case false: 03808 return 'N'; 03809 03810 case 'B': 03811 if (isset($fieldobj->binary)) 03812 return ($fieldobj->binary) ? 'B' : 'X'; 03813 return 'B'; 03814 03815 case 'D': 03816 if (!empty($this->connection) && !empty($this->connection->datetime)) return 'T'; 03817 return 'D'; 03818 03819 default: 03820 if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B'; 03821 return $tmap; 03822 } 03823 } 03824 03825 03826 function _close() {} 03827 03831 function AbsolutePage($page=-1) 03832 { 03833 if ($page != -1) $this->_currentPage = $page; 03834 return $this->_currentPage; 03835 } 03836 03840 function AtFirstPage($status=false) 03841 { 03842 if ($status != false) $this->_atFirstPage = $status; 03843 return $this->_atFirstPage; 03844 } 03845 03846 function LastPageNo($page = false) 03847 { 03848 if ($page != false) $this->_lastPageNo = $page; 03849 return $this->_lastPageNo; 03850 } 03851 03855 function AtLastPage($status=false) 03856 { 03857 if ($status != false) $this->_atLastPage = $status; 03858 return $this->_atLastPage; 03859 } 03860 03861 } // end class ADORecordSet 03862 03863 //============================================================================================== 03864 // CLASS ADORecordSet_array 03865 //============================================================================================== 03866 03874 class ADORecordSet_array extends ADORecordSet 03875 { 03876 var $databaseType = 'array'; 03877 03878 var $_array; // holds the 2-dimensional data array 03879 var $_types; // the array of types of each column (C B I L M) 03880 var $_colnames; // names of each column in array 03881 var $_skiprow1; // skip 1st row because it holds column names 03882 var $_fieldobjects; // holds array of field objects 03883 var $canSeek = true; 03884 var $affectedrows = false; 03885 var $insertid = false; 03886 var $sql = ''; 03887 var $compat = false; 03892 function ADORecordSet_array($fakeid=1) 03893 { 03894 global $ADODB_FETCH_MODE,$ADODB_COMPAT_FETCH; 03895 03896 // fetch() on EOF does not delete $this->fields 03897 $this->compat = !empty($ADODB_COMPAT_FETCH); 03898 $this->ADORecordSet($fakeid); // fake queryID 03899 $this->fetchMode = $ADODB_FETCH_MODE; 03900 } 03901 03902 function _transpose($addfieldnames=true) 03903 { 03904 global $ADODB_INCLUDED_LIB; 03905 03906 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 03907 $hdr = true; 03908 03909 $fobjs = $addfieldnames ? $this->_fieldobjects : false; 03910 adodb_transpose($this->_array, $newarr, $hdr, $fobjs); 03911 //adodb_pr($newarr); 03912 03913 $this->_skiprow1 = false; 03914 $this->_array = $newarr; 03915 $this->_colnames = $hdr; 03916 03917 adodb_probetypes($newarr,$this->_types); 03918 03919 $this->_fieldobjects = array(); 03920 03921 foreach($hdr as $k => $name) { 03922 $f = new ADOFieldObject(); 03923 $f->name = $name; 03924 $f->type = $this->_types[$k]; 03925 $f->max_length = -1; 03926 $this->_fieldobjects[] = $f; 03927 } 03928 $this->fields = reset($this->_array); 03929 03930 $this->_initrs(); 03931 03932 } 03933 03945 function InitArray($array,$typearr,$colnames=false) 03946 { 03947 $this->_array = $array; 03948 $this->_types = $typearr; 03949 if ($colnames) { 03950 $this->_skiprow1 = false; 03951 $this->_colnames = $colnames; 03952 } else { 03953 $this->_skiprow1 = true; 03954 $this->_colnames = $array[0]; 03955 } 03956 $this->Init(); 03957 } 03966 function InitArrayFields(&$array,&$fieldarr) 03967 { 03968 $this->_array = $array; 03969 $this->_skiprow1= false; 03970 if ($fieldarr) { 03971 $this->_fieldobjects = $fieldarr; 03972 } 03973 $this->Init(); 03974 } 03975 03976 function GetArray($nRows=-1) 03977 { 03978 if ($nRows == -1 && $this->_currentRow <= 0 && !$this->_skiprow1) { 03979 return $this->_array; 03980 } else { 03981 $arr = ADORecordSet::GetArray($nRows); 03982 return $arr; 03983 } 03984 } 03985 03986 function _initrs() 03987 { 03988 $this->_numOfRows = sizeof($this->_array); 03989 if ($this->_skiprow1) $this->_numOfRows -= 1; 03990 03991 $this->_numOfFields =(isset($this->_fieldobjects)) ? 03992 sizeof($this->_fieldobjects):sizeof($this->_types); 03993 } 03994 03995 /* Use associative array to get fields array */ 03996 function Fields($colname) 03997 { 03998 $mode = isset($this->adodbFetchMode) ? $this->adodbFetchMode : $this->fetchMode; 03999 04000 if ($mode & ADODB_FETCH_ASSOC) { 04001 if (!isset($this->fields[$colname]) && !is_null($this->fields[$colname])) $colname = strtolower($colname); 04002 return $this->fields[$colname]; 04003 } 04004 if (!$this->bind) { 04005 $this->bind = array(); 04006 for ($i=0; $i < $this->_numOfFields; $i++) { 04007 $o = $this->FetchField($i); 04008 $this->bind[strtoupper($o->name)] = $i; 04009 } 04010 } 04011 return $this->fields[$this->bind[strtoupper($colname)]]; 04012 } 04013 04014 function FetchField($fieldOffset = -1) 04015 { 04016 if (isset($this->_fieldobjects)) { 04017 return $this->_fieldobjects[$fieldOffset]; 04018 } 04019 $o = new ADOFieldObject(); 04020 $o->name = $this->_colnames[$fieldOffset]; 04021 $o->type = $this->_types[$fieldOffset]; 04022 $o->max_length = -1; // length not known 04023 04024 return $o; 04025 } 04026 04027 function _seek($row) 04028 { 04029 if (sizeof($this->_array) && 0 <= $row && $row < $this->_numOfRows) { 04030 $this->_currentRow = $row; 04031 if ($this->_skiprow1) $row += 1; 04032 $this->fields = $this->_array[$row]; 04033 return true; 04034 } 04035 return false; 04036 } 04037 04038 function MoveNext() 04039 { 04040 if (!$this->EOF) { 04041 $this->_currentRow++; 04042 04043 $pos = $this->_currentRow; 04044 04045 if ($this->_numOfRows <= $pos) { 04046 if (!$this->compat) $this->fields = false; 04047 } else { 04048 if ($this->_skiprow1) $pos += 1; 04049 $this->fields = $this->_array[$pos]; 04050 return true; 04051 } 04052 $this->EOF = true; 04053 } 04054 04055 return false; 04056 } 04057 04058 function _fetch() 04059 { 04060 $pos = $this->_currentRow; 04061 04062 if ($this->_numOfRows <= $pos) { 04063 if (!$this->compat) $this->fields = false; 04064 return false; 04065 } 04066 if ($this->_skiprow1) $pos += 1; 04067 $this->fields = $this->_array[$pos]; 04068 return true; 04069 } 04070 04071 function _close() 04072 { 04073 return true; 04074 } 04075 04076 } // ADORecordSet_array 04077 04078 //============================================================================================== 04079 // HELPER FUNCTIONS 04080 //============================================================================================== 04081 04087 function ADOLoadDB($dbType) 04088 { 04089 return ADOLoadCode($dbType); 04090 } 04091 04095 function ADOLoadCode($dbType) 04096 { 04097 global $ADODB_LASTDB; 04098 04099 if (!$dbType) return false; 04100 $db = strtolower($dbType); 04101 switch ($db) { 04102 case 'ado': 04103 if (PHP_VERSION >= 5) $db = 'ado5'; 04104 $class = 'ado'; 04105 break; 04106 case 'ifx': 04107 case 'maxsql': $class = $db = 'mysqlt'; break; 04108 case 'postgres': 04109 case 'postgres8': 04110 case 'pgsql': $class = $db = 'postgres7'; break; 04111 default: 04112 $class = $db; break; 04113 } 04114 04115 $file = ADODB_DIR."/drivers/adodb-".$db.".inc.php"; 04116 @include_once($file); 04117 $ADODB_LASTDB = $class; 04118 if (class_exists("ADODB_" . $class)) return $class; 04119 04120 //ADOConnection::outp(adodb_pr(get_declared_classes(),true)); 04121 if (!file_exists($file)) ADOConnection::outp("Missing file: $file"); 04122 else ADOConnection::outp("Syntax error in file: $file"); 04123 return false; 04124 } 04125 04129 function NewADOConnection($db='') 04130 { 04131 $tmp = ADONewConnection($db); 04132 return $tmp; 04133 } 04134 04143 function ADONewConnection($db='') 04144 { 04145 GLOBAL $ADODB_NEWCONNECTION, $ADODB_LASTDB; 04146 04147 if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2); 04148 $errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false; 04149 $false = false; 04150 if (($at = strpos($db,'://')) !== FALSE) { 04151 $origdsn = $db; 04152 $fakedsn = 'fake'.substr($origdsn,$at); 04153 if (($at2 = strpos($origdsn,'@/')) !== FALSE) { 04154 // special handling of oracle, which might not have host 04155 $fakedsn = str_replace('@/','@adodb-fakehost/',$fakedsn); 04156 } 04157 04158 if ((strpos($origdsn, 'sqlite')) !== FALSE && stripos($origdsn, '%2F') === FALSE) { 04159 // special handling for SQLite, it only might have the path to the database file. 04160 // If you try to connect to a SQLite database using a dsn like 'sqlite:///path/to/database', the 'parse_url' php function 04161 // will throw you an exception with a message such as "unable to parse url" 04162 list($scheme, $path) = explode('://', $origdsn); 04163 $dsna['scheme'] = $scheme; 04164 if ($qmark = strpos($path,'?')) { 04165 $dsn['query'] = substr($path,$qmark+1); 04166 $path = substr($path,0,$qmark); 04167 } 04168 $dsna['path'] = '/' . urlencode($path); 04169 } else 04170 $dsna = @parse_url($fakedsn); 04171 04172 if (!$dsna) { 04173 return $false; 04174 } 04175 $dsna['scheme'] = substr($origdsn,0,$at); 04176 if ($at2 !== FALSE) { 04177 $dsna['host'] = ''; 04178 } 04179 04180 if (strncmp($origdsn,'pdo',3) == 0) { 04181 $sch = explode('_',$dsna['scheme']); 04182 if (sizeof($sch)>1) { 04183 04184 $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; 04185 if ($sch[1] == 'sqlite') 04186 $dsna['host'] = rawurlencode($sch[1].':'.rawurldecode($dsna['host'])); 04187 else 04188 $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host'])); 04189 $dsna['scheme'] = 'pdo'; 04190 } 04191 } 04192 04193 $db = @$dsna['scheme']; 04194 if (!$db) return $false; 04195 $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; 04196 $dsna['user'] = isset($dsna['user']) ? rawurldecode($dsna['user']) : ''; 04197 $dsna['pass'] = isset($dsna['pass']) ? rawurldecode($dsna['pass']) : ''; 04198 $dsna['path'] = isset($dsna['path']) ? rawurldecode(substr($dsna['path'],1)) : ''; # strip off initial / 04199 04200 if (isset($dsna['query'])) { 04201 $opt1 = explode('&',$dsna['query']); 04202 foreach($opt1 as $k => $v) { 04203 $arr = explode('=',$v); 04204 $opt[$arr[0]] = isset($arr[1]) ? rawurldecode($arr[1]) : 1; 04205 } 04206 } else $opt = array(); 04207 } 04208 /* 04209 * phptype: Database backend used in PHP (mysql, odbc etc.) 04210 * dbsyntax: Database used with regards to SQL syntax etc. 04211 * protocol: Communication protocol to use (tcp, unix etc.) 04212 * hostspec: Host specification (hostname[:port]) 04213 * database: Database to use on the DBMS server 04214 * username: User name for login 04215 * password: Password for login 04216 */ 04217 if (!empty($ADODB_NEWCONNECTION)) { 04218 $obj = $ADODB_NEWCONNECTION($db); 04219 04220 } 04221 04222 if(empty($obj)) { 04223 04224 if (!isset($ADODB_LASTDB)) $ADODB_LASTDB = ''; 04225 if (empty($db)) $db = $ADODB_LASTDB; 04226 04227 if ($db != $ADODB_LASTDB) $db = ADOLoadCode($db); 04228 04229 if (!$db) { 04230 if (isset($origdsn)) $db = $origdsn; 04231 if ($errorfn) { 04232 // raise an error 04233 $ignore = false; 04234 $errorfn('ADONewConnection', 'ADONewConnection', -998, 04235 "could not load the database driver for '$db'", 04236 $db,false,$ignore); 04237 } else 04238 ADOConnection::outp( "<p>ADONewConnection: Unable to load database driver '$db'</p>",false); 04239 04240 return $false; 04241 } 04242 04243 $cls = 'ADODB_'.$db; 04244 if (!class_exists($cls)) { 04245 adodb_backtrace(); 04246 return $false; 04247 } 04248 04249 $obj = new $cls(); 04250 } 04251 04252 # constructor should not fail 04253 if ($obj) { 04254 if ($errorfn) $obj->raiseErrorFn = $errorfn; 04255 if (isset($dsna)) { 04256 if (isset($dsna['port'])) $obj->port = $dsna['port']; 04257 foreach($opt as $k => $v) { 04258 switch(strtolower($k)) { 04259 case 'new': 04260 $nconnect = true; $persist = true; break; 04261 case 'persist': 04262 case 'persistent': $persist = $v; break; 04263 case 'debug': $obj->debug = (integer) $v; break; 04264 #ibase 04265 case 'role': $obj->role = $v; break; 04266 case 'dialect': $obj->dialect = (integer) $v; break; 04267 case 'charset': $obj->charset = $v; $obj->charSet=$v; break; 04268 case 'buffers': $obj->buffers = $v; break; 04269 case 'fetchmode': $obj->SetFetchMode($v); break; 04270 #ado 04271 case 'charpage': $obj->charPage = $v; break; 04272 #mysql, mysqli 04273 case 'clientflags': $obj->clientFlags = $v; break; 04274 #mysql, mysqli, postgres 04275 case 'port': $obj->port = $v; break; 04276 #mysqli 04277 case 'socket': $obj->socket = $v; break; 04278 #oci8 04279 case 'nls_date_format': $obj->NLS_DATE_FORMAT = $v; break; 04280 case 'cachesecs': $obj->cacheSecs = $v; break; 04281 case 'memcache': 04282 $varr = explode(':',$v); 04283 $vlen = sizeof($varr); 04284 if ($vlen == 0) break; 04285 $obj->memCache = true; 04286 $obj->memCacheHost = explode(',',$varr[0]); 04287 if ($vlen == 1) break; 04288 $obj->memCachePort = $varr[1]; 04289 if ($vlen == 2) break; 04290 $obj->memCacheCompress = $varr[2] ? true : false; 04291 break; 04292 } 04293 } 04294 if (empty($persist)) 04295 $ok = $obj->Connect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']); 04296 else if (empty($nconnect)) 04297 $ok = $obj->PConnect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']); 04298 else 04299 $ok = $obj->NConnect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']); 04300 04301 if (!$ok) return $false; 04302 } 04303 } 04304 return $obj; 04305 } 04306 04307 04308 04309 // $perf == true means called by NewPerfMonitor(), otherwise for data dictionary 04310 function _adodb_getdriver($provider,$drivername,$perf=false) 04311 { 04312 switch ($provider) { 04313 case 'odbtp': if (strncmp('odbtp_',$drivername,6)==0) return substr($drivername,6); 04314 case 'odbc' : if (strncmp('odbc_',$drivername,5)==0) return substr($drivername,5); 04315 case 'ado' : if (strncmp('ado_',$drivername,4)==0) return substr($drivername,4); 04316 case 'native': break; 04317 default: 04318 return $provider; 04319 } 04320 04321 switch($drivername) { 04322 case 'mysqlt': 04323 case 'mysqli': 04324 $drivername='mysql'; 04325 break; 04326 case 'postgres7': 04327 case 'postgres8': 04328 $drivername = 'postgres'; 04329 break; 04330 case 'firebird15': $drivername = 'firebird'; break; 04331 case 'oracle': $drivername = 'oci8'; break; 04332 case 'access': if ($perf) $drivername = ''; break; 04333 case 'db2' : break; 04334 case 'sapdb' : break; 04335 default: 04336 $drivername = 'generic'; 04337 break; 04338 } 04339 return $drivername; 04340 } 04341 04342 function NewPerfMonitor(&$conn) 04343 { 04344 $false = false; 04345 $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType,true); 04346 if (!$drivername || $drivername == 'generic') return $false; 04347 include_once(ADODB_DIR.'/adodb-perf.inc.php'); 04348 @include_once(ADODB_DIR."/perf/perf-$drivername.inc.php"); 04349 $class = "Perf_$drivername"; 04350 if (!class_exists($class)) return $false; 04351 $perf = new $class($conn); 04352 04353 return $perf; 04354 } 04355 04356 function NewDataDictionary(&$conn,$drivername=false) 04357 { 04358 $false = false; 04359 if (!$drivername) $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType); 04360 04361 include_once(ADODB_DIR.'/adodb-lib.inc.php'); 04362 include_once(ADODB_DIR.'/adodb-datadict.inc.php'); 04363 $path = ADODB_DIR."/datadict/datadict-$drivername.inc.php"; 04364 04365 if (!file_exists($path)) { 04366 ADOConnection::outp("Dictionary driver '$path' not available"); 04367 return $false; 04368 } 04369 include_once($path); 04370 $class = "ADODB2_$drivername"; 04371 $dict = new $class(); 04372 $dict->dataProvider = $conn->dataProvider; 04373 $dict->connection = $conn; 04374 $dict->upperName = strtoupper($drivername); 04375 $dict->quote = $conn->nameQuote; 04376 if (!empty($conn->_connectionID)) 04377 $dict->serverInfo = $conn->ServerInfo(); 04378 04379 return $dict; 04380 } 04381 04382 04383 04384 /* 04385 Perform a print_r, with pre tags for better formatting. 04386 */ 04387 function adodb_pr($var,$as_string=false) 04388 { 04389 if ($as_string) ob_start(); 04390 04391 if (isset($_SERVER['HTTP_USER_AGENT'])) { 04392 echo " <pre>\n";print_r($var);echo "</pre>\n"; 04393 } else 04394 print_r($var); 04395 04396 if ($as_string) { 04397 $s = ob_get_contents(); 04398 ob_end_clean(); 04399 return $s; 04400 } 04401 } 04402 04403 /* 04404 Perform a stack-crawl and pretty print it. 04405 04406 @param printOrArr Pass in a boolean to indicate print, or an $exception->trace array (assumes that print is true then). 04407 @param levels Number of levels to display 04408 */ 04409 function adodb_backtrace($printOrArr=true,$levels=9999,$ishtml=null) 04410 { 04411 global $ADODB_INCLUDED_LIB; 04412 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 04413 return _adodb_backtrace($printOrArr,$levels,0,$ishtml); 04414 } 04415 04416 04417 } 04418 ?>