"TYPO3 4.0.1: typo3_src-4.0.1/typo3/sysext/adodb/adodb/adodb.inc.php Source File", "datetime" => "Sat Dec 2 19:22:24 2006", "date" => "2 Dec 2006", "doxygenversion" => "1.4.6", "projectname" => "TYPO3 4.0.1", "projectnumber" => "4.0.1" ); get_header($doxygen_vars); ?>
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_EXTENSION, // ADODB extension installed 00058 $ADODB_COMPAT_FETCH, // If $ADODB_COUNTRECS and this is true, $rs->fields is available on EOF 00059 $ADODB_FETCH_MODE; // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default... 00060 00061 //============================================================================================== 00062 // GLOBAL SETUP 00063 //============================================================================================== 00064 00065 $ADODB_EXTENSION = defined('ADODB_EXTENSION'); 00066 00067 //********************************************************// 00068 /* 00069 Controls $ADODB_FORCE_TYPE mode. Default is ADODB_FORCE_VALUE (3). 00070 Used in GetUpdateSql and GetInsertSql functions. Thx to Niko, nuko#mbnet.fi 00071 00072 0 = ignore empty fields. All empty fields in array are ignored. 00073 1 = force null. All empty, php null and string 'null' fields are changed to sql NULL values. 00074 2 = force empty. All empty, php null and string 'null' fields are changed to sql empty '' or 0 values. 00075 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. 00076 */ 00077 define('ADODB_FORCE_IGNORE',0); 00078 define('ADODB_FORCE_NULL',1); 00079 define('ADODB_FORCE_EMPTY',2); 00080 define('ADODB_FORCE_VALUE',3); 00081 //********************************************************// 00082 00083 00084 if (!$ADODB_EXTENSION || ADODB_EXTENSION < 4.0) { 00085 00086 define('ADODB_BAD_RS','<p>Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;</p>'); 00087 00088 // allow [ ] @ ` " and . in table names 00089 define('ADODB_TABLE_REGEX','([]0-9a-z_\:\"\`\.\@\[-]*)'); 00090 00091 // prefetching used by oracle 00092 if (!defined('ADODB_PREFETCH_ROWS')) define('ADODB_PREFETCH_ROWS',10); 00093 00094 00095 /* 00096 Controls ADODB_FETCH_ASSOC field-name case. Default is 2, use native case-names. 00097 This currently works only with mssql, odbc, oci8po and ibase derived drivers. 00098 00099 0 = assoc lowercase field names. $rs->fields['orderid'] 00100 1 = assoc uppercase field names. $rs->fields['ORDERID'] 00101 2 = use native-case field names. $rs->fields['OrderID'] 00102 */ 00103 00104 define('ADODB_FETCH_DEFAULT',0); 00105 define('ADODB_FETCH_NUM',1); 00106 define('ADODB_FETCH_ASSOC',2); 00107 define('ADODB_FETCH_BOTH',3); 00108 00109 if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100); 00110 00111 // PHP's version scheme makes converting to numbers difficult - workaround 00112 $_adodb_ver = (float) PHP_VERSION; 00113 if ($_adodb_ver >= 5.0) { 00114 define('ADODB_PHPVER',0x5000); 00115 } else if ($_adodb_ver > 4.299999) { # 4.3 00116 define('ADODB_PHPVER',0x4300); 00117 } else if ($_adodb_ver > 4.199999) { # 4.2 00118 define('ADODB_PHPVER',0x4200); 00119 } else if (strnatcmp(PHP_VERSION,'4.0.5')>=0) { 00120 define('ADODB_PHPVER',0x4050); 00121 } else { 00122 define('ADODB_PHPVER',0x4000); 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_FORCE_TYPE; 00154 00155 $ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT; 00156 $ADODB_FORCE_TYPE = ADODB_FORCE_VALUE; 00157 00158 00159 if (!isset($ADODB_CACHE_DIR)) { 00160 $ADODB_CACHE_DIR = '/tmp'; //(isset($_ENV['TMP'])) ? $_ENV['TMP'] : '/tmp'; 00161 } else { 00162 // do not accept url based paths, eg. http:/ or ftp:/ 00163 if (strpos($ADODB_CACHE_DIR,'://') !== false) 00164 die("Illegal path http:// or ftp://"); 00165 } 00166 00167 00168 // Initialize random number generator for randomizing cache flushes 00169 srand(((double)microtime())*1000000); 00170 00174 $ADODB_vers = 'V4.90 8 June 2006 (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.'; 00175 00181 if (!isset($ADODB_COUNTRECS)) $ADODB_COUNTRECS = true; 00182 } 00183 00184 00185 //============================================================================================== 00186 // CHANGE NOTHING BELOW UNLESS YOU ARE DESIGNING ADODB 00187 //============================================================================================== 00188 00189 ADODB_Setup(); 00190 00191 //============================================================================================== 00192 // CLASS ADOFieldObject 00193 //============================================================================================== 00197 class ADOFieldObject { 00198 var $name = ''; 00199 var $max_length=0; 00200 var $type=""; 00201 /* 00202 // additional fields by dannym... (danny_milo@yahoo.com) 00203 var $not_null = false; 00204 // actually, this has already been built-in in the postgres, fbsql AND mysql module? ^-^ 00205 // so we can as well make not_null standard (leaving it at "false" does not harm anyways) 00206 00207 var $has_default = false; // this one I have done only in mysql and postgres for now ... 00208 // others to come (dannym) 00209 var $default_value; // default, if any, and supported. Check has_default first. 00210 */ 00211 } 00212 00213 00214 00215 function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) 00216 { 00217 //print "Errorno ($fn errno=$errno m=$errmsg) "; 00218 $thisConnection->_transOK = false; 00219 if ($thisConnection->_oldRaiseFn) { 00220 $fn = $thisConnection->_oldRaiseFn; 00221 $fn($dbms, $fn, $errno, $errmsg, $p1, $p2,$thisConnection); 00222 } 00223 } 00224 00225 //============================================================================================== 00226 // CLASS ADOConnection 00227 //============================================================================================== 00228 00232 class ADOConnection { 00233 // 00234 // PUBLIC VARS 00235 // 00236 var $dataProvider = 'native'; 00237 var $databaseType = ''; 00238 var $database = ''; 00239 var $host = ''; 00240 var $user = ''; 00241 var $password = ''; 00242 var $debug = false; 00243 var $maxblobsize = 262144; 00244 var $concat_operator = '+'; 00245 var $substr = 'substr'; 00246 var $length = 'length'; 00247 var $random = 'rand()'; 00248 var $upperCase = 'upper'; 00249 var $fmtDate = "'Y-m-d'"; 00250 var $fmtTimeStamp = "'Y-m-d, h:i:s A'"; 00251 var $true = '1'; 00252 var $false = '0'; 00253 var $replaceQuote = "\\'"; 00254 var $nameQuote = '"'; 00255 var $charSet=false; 00256 var $metaDatabasesSQL = ''; 00257 var $metaTablesSQL = ''; 00258 var $uniqueOrderBy = false; 00259 var $emptyDate = ' '; 00260 var $emptyTimeStamp = ' '; 00261 var $lastInsID = false; 00262 //-- 00263 var $hasInsertID = false; 00264 var $hasAffectedRows = false; 00265 var $hasTop = false; 00266 var $hasLimit = false; 00267 var $readOnly = false; 00268 var $hasMoveFirst = false; 00269 var $hasGenID = false; 00270 var $hasTransactions = true; 00271 //-- 00272 var $genID = 0; 00273 var $raiseErrorFn = false; 00274 var $isoDates = false; 00275 var $cacheSecs = 3600; 00276 var $sysDate = false; 00277 var $sysTimeStamp = false; 00278 var $arrayClass = 'ADORecordSet_array'; 00279 00280 var $noNullStrings = false; 00281 var $numCacheHits = 0; 00282 var $numCacheMisses = 0; 00283 var $pageExecuteCountRows = true; 00284 var $uniqueSort = false; 00285 var $leftOuter = false; 00286 var $rightOuter = false; 00287 var $ansiOuter = false; 00288 var $autoRollback = false; // autoRollback on PConnect(). 00289 var $poorAffectedRows = false; // affectedRows not working or unreliable 00290 00291 var $fnExecute = false; 00292 var $fnCacheExecute = false; 00293 var $blobEncodeType = false; // false=not required, 'I'=encode to integer, 'C'=encode to char 00294 var $rsPrefix = "ADORecordSet_"; 00295 00296 var $autoCommit = true; 00297 var $transOff = 0; 00298 var $transCnt = 0; 00299 00300 var $fetchMode=false; 00301 // 00302 // PRIVATE VARS 00303 // 00304 var $_oldRaiseFn = false; 00305 var $_transOK = null; 00306 var $_connectionID = false; 00307 var $_errorMsg = false; 00308 00309 var $_errorCode = false; 00310 var $_queryID = false; 00311 00312 var $_isPersistentConnection = false; 00313 var $_bindInputArray = false; 00314 var $_evalAll = false; 00315 var $_affected = false; 00316 var $_logsql = false; 00317 var $_transmode = ''; // transaction mode 00318 00322 function ADOConnection() 00323 { 00324 die('Virtual Class -- cannot instantiate'); 00325 } 00326 00327 function Version() 00328 { 00329 global $ADODB_vers; 00330 00331 return (float) substr($ADODB_vers,1); 00332 } 00333 00340 function ServerInfo() 00341 { 00342 return array('description' => '', 'version' => ''); 00343 } 00344 00345 function IsConnected() 00346 { 00347 return !empty($this->_connectionID); 00348 } 00349 00350 function _findvers($str) 00351 { 00352 if (preg_match('/([0-9]+\.([0-9\.])+)/',$str, $arr)) return $arr[1]; 00353 else return ''; 00354 } 00355 00360 function outp($msg,$newline=true) 00361 { 00362 global $ADODB_FLUSH,$ADODB_OUTP; 00363 00364 if (defined('ADODB_OUTP')) { 00365 $fn = ADODB_OUTP; 00366 $fn($msg,$newline); 00367 return; 00368 } else if (isset($ADODB_OUTP)) { 00369 $fn = $ADODB_OUTP; 00370 $fn($msg,$newline); 00371 return; 00372 } 00373 00374 if ($newline) $msg .= "<br>\n"; 00375 00376 if (isset($_SERVER['HTTP_USER_AGENT']) || !$newline) echo $msg; 00377 else echo strip_tags($msg); 00378 00379 00380 if (!empty($ADODB_FLUSH) && ob_get_length() !== false) flush(); // do not flush if output buffering enabled - useless - thx to Jesse Mullan 00381 00382 } 00383 00384 function Time() 00385 { 00386 $rs =& $this->_Execute("select $this->sysTimeStamp"); 00387 if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields)); 00388 00389 return false; 00390 } 00391 00403 function Connect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "", $forceNew = false) 00404 { 00405 if ($argHostname != "") $this->host = $argHostname; 00406 if ($argUsername != "") $this->user = $argUsername; 00407 if ($argPassword != "") $this->password = $argPassword; // not stored for security reasons 00408 if ($argDatabaseName != "") $this->database = $argDatabaseName; 00409 00410 $this->_isPersistentConnection = false; 00411 if ($forceNew) { 00412 if ($rez=$this->_nconnect($this->host, $this->user, $this->password, $this->database)) return true; 00413 } else { 00414 if ($rez=$this->_connect($this->host, $this->user, $this->password, $this->database)) return true; 00415 } 00416 if (isset($rez)) { 00417 $err = $this->ErrorMsg(); 00418 if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'"; 00419 $ret = false; 00420 } else { 00421 $err = "Missing extension for ".$this->dataProvider; 00422 $ret = 0; 00423 } 00424 if ($fn = $this->raiseErrorFn) 00425 $fn($this->databaseType,'CONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this); 00426 00427 00428 $this->_connectionID = false; 00429 if ($this->debug) ADOConnection::outp( $this->host.': '.$err); 00430 return $ret; 00431 } 00432 00433 function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName) 00434 { 00435 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName); 00436 } 00437 00438 00449 function NConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") 00450 { 00451 return $this->Connect($argHostname, $argUsername, $argPassword, $argDatabaseName, true); 00452 } 00453 00464 function PConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") 00465 { 00466 if (defined('ADODB_NEVER_PERSIST')) 00467 return $this->Connect($argHostname,$argUsername,$argPassword,$argDatabaseName); 00468 00469 if ($argHostname != "") $this->host = $argHostname; 00470 if ($argUsername != "") $this->user = $argUsername; 00471 if ($argPassword != "") $this->password = $argPassword; 00472 if ($argDatabaseName != "") $this->database = $argDatabaseName; 00473 00474 $this->_isPersistentConnection = true; 00475 if ($rez = $this->_pconnect($this->host, $this->user, $this->password, $this->database)) return true; 00476 if (isset($rez)) { 00477 $err = $this->ErrorMsg(); 00478 if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'"; 00479 $ret = false; 00480 } else { 00481 $err = "Missing extension for ".$this->dataProvider; 00482 $ret = 0; 00483 } 00484 if ($fn = $this->raiseErrorFn) { 00485 $fn($this->databaseType,'PCONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this); 00486 } 00487 00488 $this->_connectionID = false; 00489 if ($this->debug) ADOConnection::outp( $this->host.': '.$err); 00490 return $ret; 00491 } 00492 00493 // Format date column in sql string given an input format that understands Y M D 00494 function SQLDate($fmt, $col=false) 00495 { 00496 if (!$col) $col = $this->sysDate; 00497 return $col; // child class implement 00498 } 00499 00515 function Prepare($sql) 00516 { 00517 return $sql; 00518 } 00519 00534 function PrepareSP($sql,$param=true) 00535 { 00536 return $this->Prepare($sql,$param); 00537 } 00538 00542 function Quote($s) 00543 { 00544 return $this->qstr($s,false); 00545 } 00546 00550 function QMagic($s) 00551 { 00552 return $this->qstr($s,get_magic_quotes_gpc()); 00553 } 00554 00555 function q(&$s) 00556 { 00557 #if (!empty($this->qNull)) if ($s == 'null') return $s; 00558 $s = $this->qstr($s,false); 00559 } 00560 00564 function ErrorNative() 00565 { 00566 return $this->ErrorNo(); 00567 } 00568 00569 00573 function nextId($seq_name) 00574 { 00575 return $this->GenID($seq_name); 00576 } 00577 00585 function RowLock($table,$where) 00586 { 00587 return false; 00588 } 00589 00590 function CommitLock($table) 00591 { 00592 return $this->CommitTrans(); 00593 } 00594 00595 function RollbackLock($table) 00596 { 00597 return $this->RollbackTrans(); 00598 } 00599 00609 function SetFetchMode($mode) 00610 { 00611 $old = $this->fetchMode; 00612 $this->fetchMode = $mode; 00613 00614 if ($old === false) { 00615 global $ADODB_FETCH_MODE; 00616 return $ADODB_FETCH_MODE; 00617 } 00618 return $old; 00619 } 00620 00621 00625 function &Query($sql, $inputarr=false) 00626 { 00627 $rs = &$this->Execute($sql, $inputarr); 00628 if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error(); 00629 return $rs; 00630 } 00631 00632 00636 function &LimitQuery($sql, $offset, $count, $params=false) 00637 { 00638 $rs = &$this->SelectLimit($sql, $count, $offset, $params); 00639 if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error(); 00640 return $rs; 00641 } 00642 00643 00647 function Disconnect() 00648 { 00649 return $this->Close(); 00650 } 00651 00652 /* 00653 Returns placeholder for parameter, eg. 00654 $DB->Param('a') 00655 00656 will return ':a' for Oracle, and '?' for most other databases... 00657 00658 For databases that require positioned params, eg $1, $2, $3 for postgresql, 00659 pass in Param(false) before setting the first parameter. 00660 */ 00661 function Param($name,$type='C') 00662 { 00663 return '?'; 00664 } 00665 00666 /* 00667 InParameter and OutParameter are self-documenting versions of Parameter(). 00668 */ 00669 function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) 00670 { 00671 return $this->Parameter($stmt,$var,$name,false,$maxLen,$type); 00672 } 00673 00674 /* 00675 */ 00676 function OutParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) 00677 { 00678 return $this->Parameter($stmt,$var,$name,true,$maxLen,$type); 00679 00680 } 00681 00682 /* 00683 Usage in oracle 00684 $stmt = $db->Prepare('select * from table where id =:myid and group=:group'); 00685 $db->Parameter($stmt,$id,'myid'); 00686 $db->Parameter($stmt,$group,'group',64); 00687 $db->Execute(); 00688 00689 @param $stmt Statement returned by Prepare() or PrepareSP(). 00690 @param $var PHP variable to bind to 00691 @param $name Name of stored procedure variable name to bind to. 00692 @param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8. 00693 @param [$maxLen] Holds an maximum length of the variable. 00694 @param [$type] The data type of $var. Legal values depend on driver. 00695 00696 */ 00697 function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false) 00698 { 00699 return false; 00700 } 00701 00712 function StartTrans($errfn = 'ADODB_TransMonitor') 00713 { 00714 if ($this->transOff > 0) { 00715 $this->transOff += 1; 00716 return; 00717 } 00718 00719 $this->_oldRaiseFn = $this->raiseErrorFn; 00720 $this->raiseErrorFn = $errfn; 00721 $this->_transOK = true; 00722 00723 if ($this->debug && $this->transCnt > 0) ADOConnection::outp("Bad Transaction: StartTrans called within BeginTrans"); 00724 $this->BeginTrans(); 00725 $this->transOff = 1; 00726 } 00727 00728 00737 function CompleteTrans($autoComplete = true) 00738 { 00739 if ($this->transOff > 1) { 00740 $this->transOff -= 1; 00741 return true; 00742 } 00743 $this->raiseErrorFn = $this->_oldRaiseFn; 00744 00745 $this->transOff = 0; 00746 if ($this->_transOK && $autoComplete) { 00747 if (!$this->CommitTrans()) { 00748 $this->_transOK = false; 00749 if ($this->debug) ADOConnection::outp("Smart Commit failed"); 00750 } else 00751 if ($this->debug) ADOConnection::outp("Smart Commit occurred"); 00752 } else { 00753 $this->_transOK = false; 00754 $this->RollbackTrans(); 00755 if ($this->debug) ADOCOnnection::outp("Smart Rollback occurred"); 00756 } 00757 00758 return $this->_transOK; 00759 } 00760 00761 /* 00762 At the end of a StartTrans/CompleteTrans block, perform a rollback. 00763 */ 00764 function FailTrans() 00765 { 00766 if ($this->debug) 00767 if ($this->transOff == 0) { 00768 ADOConnection::outp("FailTrans outside StartTrans/CompleteTrans"); 00769 } else { 00770 ADOConnection::outp("FailTrans was called"); 00771 adodb_backtrace(); 00772 } 00773 $this->_transOK = false; 00774 } 00775 00779 function HasFailedTrans() 00780 { 00781 if ($this->transOff > 0) return $this->_transOK == false; 00782 return false; 00783 } 00784 00792 function &Execute($sql,$inputarr=false) 00793 { 00794 if ($this->fnExecute) { 00795 $fn = $this->fnExecute; 00796 $ret =& $fn($this,$sql,$inputarr); 00797 if (isset($ret)) return $ret; 00798 } 00799 if ($inputarr) { 00800 if (!is_array($inputarr)) $inputarr = array($inputarr); 00801 00802 $element0 = reset($inputarr); 00803 # is_object check because oci8 descriptors can be passed in 00804 $array_2d = is_array($element0) && !is_object(reset($element0)); 00805 //remove extra memory copy of input -mikefedyk 00806 unset($element0); 00807 00808 if (!is_array($sql) && !$this->_bindInputArray) { 00809 $sqlarr = explode('?',$sql); 00810 00811 if (!$array_2d) $inputarr = array($inputarr); 00812 foreach($inputarr as $arr) { 00813 $sql = ''; $i = 0; 00814 //Use each() instead of foreach to reduce memory usage -mikefedyk 00815 while(list(, $v) = each($arr)) { 00816 $sql .= $sqlarr[$i]; 00817 // from Ron Baldwin <ron.baldwin#sourceprose.com> 00818 // Only quote string types 00819 $typ = gettype($v); 00820 if ($typ == 'string') 00821 //New memory copy of input created here -mikefedyk 00822 $sql .= $this->qstr($v); 00823 else if ($typ == 'double') 00824 $sql .= str_replace(',','.',$v); // locales fix so 1.1 does not get converted to 1,1 00825 else if ($typ == 'boolean') 00826 $sql .= $v ? $this->true : $this->false; 00827 else if ($typ == 'object') { 00828 if (method_exists($v, '__toString')) $sql .= $this->qstr($v->__toString()); 00829 else $sql .= $this->qstr((string) $v); 00830 } else if ($v === null) 00831 $sql .= 'NULL'; 00832 else 00833 $sql .= $v; 00834 $i += 1; 00835 } 00836 if (isset($sqlarr[$i])) { 00837 $sql .= $sqlarr[$i]; 00838 if ($i+1 != sizeof($sqlarr)) ADOConnection::outp( "Input Array does not match ?: ".htmlspecialchars($sql)); 00839 } else if ($i != sizeof($sqlarr)) 00840 ADOConnection::outp( "Input array does not match ?: ".htmlspecialchars($sql)); 00841 00842 $ret =& $this->_Execute($sql); 00843 if (!$ret) return $ret; 00844 } 00845 } else { 00846 if ($array_2d) { 00847 if (is_string($sql)) 00848 $stmt = $this->Prepare($sql); 00849 else 00850 $stmt = $sql; 00851 00852 foreach($inputarr as $arr) { 00853 $ret =& $this->_Execute($stmt,$arr); 00854 if (!$ret) return $ret; 00855 } 00856 } else { 00857 $ret =& $this->_Execute($sql,$inputarr); 00858 } 00859 } 00860 } else { 00861 $ret =& $this->_Execute($sql,false); 00862 } 00863 00864 return $ret; 00865 } 00866 00867 00868 function &_Execute($sql,$inputarr=false) 00869 { 00870 if ($this->debug) { 00871 global $ADODB_INCLUDED_LIB; 00872 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 00873 $this->_queryID = _adodb_debug_execute($this, $sql,$inputarr); 00874 } else { 00875 $this->_queryID = @$this->_query($sql,$inputarr); 00876 } 00877 00878 /************************ 00879 // OK, query executed 00880 *************************/ 00881 00882 if ($this->_queryID === false) { // error handling if query fails 00883 if ($this->debug == 99) adodb_backtrace(true,5); 00884 $fn = $this->raiseErrorFn; 00885 if ($fn) { 00886 $fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,$inputarr,$this); 00887 } 00888 $false = false; 00889 return $false; 00890 } 00891 00892 if ($this->_queryID === true) { // return simplified recordset for inserts/updates/deletes with lower overhead 00893 $rs =& new ADORecordSet_empty(); 00894 return $rs; 00895 } 00896 00897 // return real recordset from select statement 00898 $rsclass = $this->rsPrefix.$this->databaseType; 00899 $rs = new $rsclass($this->_queryID,$this->fetchMode); 00900 $rs->connection = &$this; // Pablo suggestion 00901 $rs->Init(); 00902 if (is_array($sql)) $rs->sql = $sql[0]; 00903 else $rs->sql = $sql; 00904 if ($rs->_numOfRows <= 0) { 00905 global $ADODB_COUNTRECS; 00906 if ($ADODB_COUNTRECS) { 00907 if (!$rs->EOF) { 00908 $rs = &$this->_rs2rs($rs,-1,-1,!is_array($sql)); 00909 $rs->_queryID = $this->_queryID; 00910 } else 00911 $rs->_numOfRows = 0; 00912 } 00913 } 00914 return $rs; 00915 } 00916 00917 function CreateSequence($seqname='adodbseq',$startID=1) 00918 { 00919 if (empty($this->_genSeqSQL)) return false; 00920 return $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID)); 00921 } 00922 00923 function DropSequence($seqname='adodbseq') 00924 { 00925 if (empty($this->_dropSeqSQL)) return false; 00926 return $this->Execute(sprintf($this->_dropSeqSQL,$seqname)); 00927 } 00928 00937 function GenID($seqname='adodbseq',$startID=1) 00938 { 00939 if (!$this->hasGenID) { 00940 return 0; // formerly returns false pre 1.60 00941 } 00942 00943 $getnext = sprintf($this->_genIDSQL,$seqname); 00944 00945 $holdtransOK = $this->_transOK; 00946 00947 $save_handler = $this->raiseErrorFn; 00948 $this->raiseErrorFn = ''; 00949 @($rs = $this->Execute($getnext)); 00950 $this->raiseErrorFn = $save_handler; 00951 00952 if (!$rs) { 00953 $this->_transOK = $holdtransOK; //if the status was ok before reset 00954 $createseq = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID)); 00955 $rs = $this->Execute($getnext); 00956 } 00957 if ($rs && !$rs->EOF) $this->genID = reset($rs->fields); 00958 else $this->genID = 0; // false 00959 00960 if ($rs) $rs->Close(); 00961 00962 return $this->genID; 00963 } 00964 00970 function Insert_ID($table='',$column='') 00971 { 00972 if ($this->_logsql && $this->lastInsID) return $this->lastInsID; 00973 if ($this->hasInsertID) return $this->_insertid($table,$column); 00974 if ($this->debug) { 00975 ADOConnection::outp( '<p>Insert_ID error</p>'); 00976 adodb_backtrace(); 00977 } 00978 return false; 00979 } 00980 00981 00988 function PO_Insert_ID($table="", $id="") 00989 { 00990 if ($this->hasInsertID){ 00991 return $this->Insert_ID($table,$id); 00992 } else { 00993 return $this->GetOne("SELECT MAX($id) FROM $table"); 00994 } 00995 } 00996 01000 function Affected_Rows() 01001 { 01002 if ($this->hasAffectedRows) { 01003 if ($this->fnExecute === 'adodb_log_sql') { 01004 if ($this->_logsql && $this->_affected !== false) return $this->_affected; 01005 } 01006 $val = $this->_affectedrows(); 01007 return ($val < 0) ? false : $val; 01008 } 01009 01010 if ($this->debug) ADOConnection::outp( '<p>Affected_Rows error</p>',false); 01011 return false; 01012 } 01013 01014 01018 function ErrorMsg() 01019 { 01020 if ($this->_errorMsg) return '!! '.strtoupper($this->dataProvider.' '.$this->databaseType).': '.$this->_errorMsg; 01021 else return ''; 01022 } 01023 01024 01028 function ErrorNo() 01029 { 01030 return ($this->_errorMsg) ? -1 : 0; 01031 } 01032 01033 function MetaError($err=false) 01034 { 01035 include_once(ADODB_DIR."/adodb-error.inc.php"); 01036 if ($err === false) $err = $this->ErrorNo(); 01037 return adodb_error($this->dataProvider,$this->databaseType,$err); 01038 } 01039 01040 function MetaErrorMsg($errno) 01041 { 01042 include_once(ADODB_DIR."/adodb-error.inc.php"); 01043 return adodb_errormsg($errno); 01044 } 01045 01049 function MetaPrimaryKeys($table, $owner=false) 01050 { 01051 // owner not used in base class - see oci8 01052 $p = array(); 01053 $objs =& $this->MetaColumns($table); 01054 if ($objs) { 01055 foreach($objs as $v) { 01056 if (!empty($v->primary_key)) 01057 $p[] = $v->name; 01058 } 01059 } 01060 if (sizeof($p)) return $p; 01061 if (function_exists('ADODB_VIEW_PRIMARYKEYS')) 01062 return ADODB_VIEW_PRIMARYKEYS($this->databaseType, $this->database, $table, $owner); 01063 return false; 01064 } 01065 01069 function MetaForeignKeys($table, $owner=false, $upper=false) 01070 { 01071 return false; 01072 } 01079 function SelectDB($dbName) 01080 {return false;} 01081 01082 01102 function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0) 01103 { 01104 if ($this->hasTop && $nrows > 0) { 01105 // suggested by Reinhard Balling. Access requires top after distinct 01106 // Informix requires first before distinct - F Riosa 01107 $ismssql = (strpos($this->databaseType,'mssql') !== false); 01108 if ($ismssql) $isaccess = false; 01109 else $isaccess = (strpos($this->databaseType,'access') !== false); 01110 01111 if ($offset <= 0) { 01112 01113 // access includes ties in result 01114 if ($isaccess) { 01115 $sql = preg_replace( 01116 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); 01117 01118 if ($secs2cache>0) { 01119 $ret =& $this->CacheExecute($secs2cache, $sql,$inputarr); 01120 } else { 01121 $ret =& $this->Execute($sql,$inputarr); 01122 } 01123 return $ret; // PHP5 fix 01124 } else if ($ismssql){ 01125 $sql = preg_replace( 01126 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); 01127 } else { 01128 $sql = preg_replace( 01129 '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); 01130 } 01131 } else { 01132 $nn = $nrows + $offset; 01133 if ($isaccess || $ismssql) { 01134 $sql = preg_replace( 01135 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.$nn.' ',$sql); 01136 } else { 01137 $sql = preg_replace( 01138 '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.$nn.' ',$sql); 01139 } 01140 } 01141 } 01142 01143 // if $offset>0, we want to skip rows, and $ADODB_COUNTRECS is set, we buffer rows 01144 // 0 to offset-1 which will be discarded anyway. So we disable $ADODB_COUNTRECS. 01145 global $ADODB_COUNTRECS; 01146 01147 $savec = $ADODB_COUNTRECS; 01148 $ADODB_COUNTRECS = false; 01149 01150 if ($offset>0){ 01151 if ($secs2cache>0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); 01152 else $rs = &$this->Execute($sql,$inputarr); 01153 } else { 01154 if ($secs2cache>0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); 01155 else $rs = &$this->Execute($sql,$inputarr); 01156 } 01157 $ADODB_COUNTRECS = $savec; 01158 if ($rs && !$rs->EOF) { 01159 $rs =& $this->_rs2rs($rs,$nrows,$offset); 01160 } 01161 //print_r($rs); 01162 return $rs; 01163 } 01164 01170 function &SerializableRS(&$rs) 01171 { 01172 $rs2 =& $this->_rs2rs($rs); 01173 $ignore = false; 01174 $rs2->connection =& $ignore; 01175 01176 return $rs2; 01177 } 01178 01189 function &_rs2rs(&$rs,$nrows=-1,$offset=-1,$close=true) 01190 { 01191 if (! $rs) { 01192 $false = false; 01193 return $false; 01194 } 01195 $dbtype = $rs->databaseType; 01196 if (!$dbtype) { 01197 $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ? 01198 return $rs; 01199 } 01200 if (($dbtype == 'array' || $dbtype == 'csv') && $nrows == -1 && $offset == -1) { 01201 $rs->MoveFirst(); 01202 $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ? 01203 return $rs; 01204 } 01205 $flds = array(); 01206 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) { 01207 $flds[] = $rs->FetchField($i); 01208 } 01209 01210 $arr =& $rs->GetArrayLimit($nrows,$offset); 01211 //print_r($arr); 01212 if ($close) $rs->Close(); 01213 01214 $arrayClass = $this->arrayClass; 01215 01216 $rs2 = new $arrayClass(); 01217 $rs2->connection = &$this; 01218 $rs2->sql = $rs->sql; 01219 $rs2->dataProvider = $this->dataProvider; 01220 $rs2->InitArrayFields($arr,$flds); 01221 $rs2->fetchMode = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode; 01222 return $rs2; 01223 } 01224 01225 /* 01226 * Return all rows. Compat with PEAR DB 01227 */ 01228 function &GetAll($sql, $inputarr=false) 01229 { 01230 $arr =& $this->GetArray($sql,$inputarr); 01231 return $arr; 01232 } 01233 01234 function &GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false) 01235 { 01236 $rs =& $this->Execute($sql, $inputarr); 01237 if (!$rs) { 01238 $false = false; 01239 return $false; 01240 } 01241 $arr =& $rs->GetAssoc($force_array,$first2cols); 01242 return $arr; 01243 } 01244 01245 function &CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false) 01246 { 01247 if (!is_numeric($secs2cache)) { 01248 $first2cols = $force_array; 01249 $force_array = $inputarr; 01250 } 01251 $rs =& $this->CacheExecute($secs2cache, $sql, $inputarr); 01252 if (!$rs) { 01253 $false = false; 01254 return $false; 01255 } 01256 $arr =& $rs->GetAssoc($force_array,$first2cols); 01257 return $arr; 01258 } 01259 01267 function GetOne($sql,$inputarr=false) 01268 { 01269 global $ADODB_COUNTRECS; 01270 $crecs = $ADODB_COUNTRECS; 01271 $ADODB_COUNTRECS = false; 01272 01273 $ret = false; 01274 $rs = &$this->Execute($sql,$inputarr); 01275 if ($rs) { 01276 if (!$rs->EOF) $ret = reset($rs->fields); 01277 $rs->Close(); 01278 } 01279 $ADODB_COUNTRECS = $crecs; 01280 return $ret; 01281 } 01282 01283 function CacheGetOne($secs2cache,$sql=false,$inputarr=false) 01284 { 01285 $ret = false; 01286 $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); 01287 if ($rs) { 01288 if (!$rs->EOF) $ret = reset($rs->fields); 01289 $rs->Close(); 01290 } 01291 01292 return $ret; 01293 } 01294 01295 function GetCol($sql, $inputarr = false, $trim = false) 01296 { 01297 $rv = false; 01298 $rs = &$this->Execute($sql, $inputarr); 01299 if ($rs) { 01300 $rv = array(); 01301 if ($trim) { 01302 while (!$rs->EOF) { 01303 $rv[] = trim(reset($rs->fields)); 01304 $rs->MoveNext(); 01305 } 01306 } else { 01307 while (!$rs->EOF) { 01308 $rv[] = reset($rs->fields); 01309 $rs->MoveNext(); 01310 } 01311 } 01312 $rs->Close(); 01313 } 01314 return $rv; 01315 } 01316 01317 function CacheGetCol($secs, $sql = false, $inputarr = false,$trim=false) 01318 { 01319 $rv = false; 01320 $rs = &$this->CacheExecute($secs, $sql, $inputarr); 01321 if ($rs) { 01322 if ($trim) { 01323 while (!$rs->EOF) { 01324 $rv[] = trim(reset($rs->fields)); 01325 $rs->MoveNext(); 01326 } 01327 } else { 01328 while (!$rs->EOF) { 01329 $rv[] = reset($rs->fields); 01330 $rs->MoveNext(); 01331 } 01332 } 01333 $rs->Close(); 01334 } 01335 return $rv; 01336 } 01337 01338 /* 01339 Calculate the offset of a date for a particular database and generate 01340 appropriate SQL. Useful for calculating future/past dates and storing 01341 in a database. 01342 01343 If dayFraction=1.5 means 1.5 days from now, 1.0/24 for 1 hour. 01344 */ 01345 function OffsetDate($dayFraction,$date=false) 01346 { 01347 if (!$date) $date = $this->sysDate; 01348 return '('.$date.'+'.$dayFraction.')'; 01349 } 01350 01351 01357 function &GetArray($sql,$inputarr=false) 01358 { 01359 global $ADODB_COUNTRECS; 01360 01361 $savec = $ADODB_COUNTRECS; 01362 $ADODB_COUNTRECS = false; 01363 $rs =& $this->Execute($sql,$inputarr); 01364 $ADODB_COUNTRECS = $savec; 01365 if (!$rs) 01366 if (defined('ADODB_PEAR')) { 01367 $cls = ADODB_PEAR_Error(); 01368 return $cls; 01369 } else { 01370 $false = false; 01371 return $false; 01372 } 01373 $arr =& $rs->GetArray(); 01374 $rs->Close(); 01375 return $arr; 01376 } 01377 01378 function &CacheGetAll($secs2cache,$sql=false,$inputarr=false) 01379 { 01380 return $this->CacheGetArray($secs2cache,$sql,$inputarr); 01381 } 01382 01383 function &CacheGetArray($secs2cache,$sql=false,$inputarr=false) 01384 { 01385 global $ADODB_COUNTRECS; 01386 01387 $savec = $ADODB_COUNTRECS; 01388 $ADODB_COUNTRECS = false; 01389 $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr); 01390 $ADODB_COUNTRECS = $savec; 01391 01392 if (!$rs) 01393 if (defined('ADODB_PEAR')) { 01394 $cls = ADODB_PEAR_Error(); 01395 return $cls; 01396 } else { 01397 $false = false; 01398 return $false; 01399 } 01400 $arr =& $rs->GetArray(); 01401 $rs->Close(); 01402 return $arr; 01403 } 01404 01405 01406 01413 function &GetRow($sql,$inputarr=false) 01414 { 01415 global $ADODB_COUNTRECS; 01416 $crecs = $ADODB_COUNTRECS; 01417 $ADODB_COUNTRECS = false; 01418 01419 $rs =& $this->Execute($sql,$inputarr); 01420 01421 $ADODB_COUNTRECS = $crecs; 01422 if ($rs) { 01423 if (!$rs->EOF) $arr = $rs->fields; 01424 else $arr = array(); 01425 $rs->Close(); 01426 return $arr; 01427 } 01428 01429 $false = false; 01430 return $false; 01431 } 01432 01433 function &CacheGetRow($secs2cache,$sql=false,$inputarr=false) 01434 { 01435 $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr); 01436 if ($rs) { 01437 $arr = false; 01438 if (!$rs->EOF) $arr = $rs->fields; 01439 $rs->Close(); 01440 return $arr; 01441 } 01442 $false = false; 01443 return $false; 01444 } 01445 01466 function Replace($table, $fieldArray, $keyCol, $autoQuote=false, $has_autoinc=false) 01467 { 01468 global $ADODB_INCLUDED_LIB; 01469 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 01470 01471 return _adodb_replace($this, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc); 01472 } 01473 01474 01493 function &CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false) 01494 { 01495 if (!is_numeric($secs2cache)) { 01496 if ($sql === false) $sql = -1; 01497 if ($offset == -1) $offset = false; 01498 // sql, nrows, offset,inputarr 01499 $rs =& $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs); 01500 } else { 01501 if ($sql === false) ADOConnection::outp( "Warning: \$sql missing from CacheSelectLimit()"); 01502 $rs =& $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache); 01503 } 01504 return $rs; 01505 } 01506 01507 01517 function CacheFlush($sql=false,$inputarr=false) 01518 { 01519 global $ADODB_CACHE_DIR; 01520 01521 if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) { 01522 /*if (strncmp(PHP_OS,'WIN',3) === 0) 01523 $dir = str_replace('/', '\\', $ADODB_CACHE_DIR); 01524 else */ 01525 $dir = $ADODB_CACHE_DIR; 01526 01527 if ($this->debug) { 01528 ADOConnection::outp( "CacheFlush: $dir<br><pre>\n", $this->_dirFlush($dir),"</pre>"); 01529 } else { 01530 $this->_dirFlush($dir); 01531 } 01532 return; 01533 } 01534 01535 global $ADODB_INCLUDED_CSV; 01536 if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); 01537 01538 $f = $this->_gencachename($sql.serialize($inputarr),false); 01539 adodb_write_file($f,''); // is adodb_write_file needed? 01540 if (!@unlink($f)) { 01541 if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f"); 01542 } 01543 } 01544 01551 function _dirFlush($dir, $kill_top_level = false) { 01552 if(!$dh = @opendir($dir)) return; 01553 01554 while (($obj = readdir($dh))) { 01555 if($obj=='.' || $obj=='..') 01556 continue; 01557 01558 if (!@unlink($dir.'/'.$obj)) 01559 $this->_dirFlush($dir.'/'.$obj, true); 01560 } 01561 if ($kill_top_level === true) 01562 @rmdir($dir); 01563 return true; 01564 } 01565 01566 01567 function xCacheFlush($sql=false,$inputarr=false) 01568 { 01569 global $ADODB_CACHE_DIR; 01570 01571 if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) { 01572 if (strncmp(PHP_OS,'WIN',3) === 0) { 01573 $cmd = 'del /s '.str_replace('/','\\',$ADODB_CACHE_DIR).'\adodb_*.cache'; 01574 } else { 01575 //$cmd = 'find "'.$ADODB_CACHE_DIR.'" -type f -maxdepth 1 -print0 | xargs -0 rm -f'; 01576 $cmd = 'rm -rf '.$ADODB_CACHE_DIR.'/[0-9a-f][0-9a-f]/'; 01577 // old version 'rm -f `find '.$ADODB_CACHE_DIR.' -name adodb_*.cache`'; 01578 } 01579 if ($this->debug) { 01580 ADOConnection::outp( "CacheFlush: $cmd<br><pre>\n", system($cmd),"</pre>"); 01581 } else { 01582 exec($cmd); 01583 } 01584 return; 01585 } 01586 01587 global $ADODB_INCLUDED_CSV; 01588 if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); 01589 01590 $f = $this->_gencachename($sql.serialize($inputarr),false); 01591 adodb_write_file($f,''); // is adodb_write_file needed? 01592 if (!@unlink($f)) { 01593 if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f"); 01594 } 01595 } 01596 01611 function _gencachename($sql,$createdir) 01612 { 01613 global $ADODB_CACHE_DIR; 01614 static $notSafeMode; 01615 01616 if ($this->fetchMode === false) { 01617 global $ADODB_FETCH_MODE; 01618 $mode = $ADODB_FETCH_MODE; 01619 } else { 01620 $mode = $this->fetchMode; 01621 } 01622 $m = md5($sql.$this->databaseType.$this->database.$this->user.$mode); 01623 01624 if (!isset($notSafeMode)) $notSafeMode = !ini_get('safe_mode'); 01625 $dir = ($notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($m,0,2) : $ADODB_CACHE_DIR; 01626 01627 if ($createdir && $notSafeMode && !file_exists($dir)) { 01628 $oldu = umask(0); 01629 if (!mkdir($dir,0771)) 01630 if ($this->debug) ADOConnection::outp( "Unable to mkdir $dir for $sql"); 01631 umask($oldu); 01632 } 01633 return $dir.'/adodb_'.$m.'.cache'; 01634 } 01635 01636 01646 function &CacheExecute($secs2cache,$sql=false,$inputarr=false) 01647 { 01648 01649 01650 if (!is_numeric($secs2cache)) { 01651 $inputarr = $sql; 01652 $sql = $secs2cache; 01653 $secs2cache = $this->cacheSecs; 01654 } 01655 01656 if (is_array($sql)) { 01657 $sqlparam = $sql; 01658 $sql = $sql[0]; 01659 } else 01660 $sqlparam = $sql; 01661 01662 global $ADODB_INCLUDED_CSV; 01663 if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); 01664 01665 $md5file = $this->_gencachename($sql.serialize($inputarr),true); 01666 $err = ''; 01667 01668 if ($secs2cache > 0){ 01669 $rs = &csv2rs($md5file,$err,$secs2cache,$this->arrayClass); 01670 $this->numCacheHits += 1; 01671 } else { 01672 $err='Timeout 1'; 01673 $rs = false; 01674 $this->numCacheMisses += 1; 01675 } 01676 if (!$rs) { 01677 // no cached rs found 01678 if ($this->debug) { 01679 if (get_magic_quotes_runtime()) { 01680 ADOConnection::outp("Please disable magic_quotes_runtime - it corrupts cache files :("); 01681 } 01682 if ($this->debug !== -1) ADOConnection::outp( " $md5file cache failure: $err (see sql below)"); 01683 } 01684 01685 $rs = &$this->Execute($sqlparam,$inputarr); 01686 01687 if ($rs) { 01688 $eof = $rs->EOF; 01689 $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately 01690 $txt = _rs2serialize($rs,false,$sql); // serialize 01691 01692 if (!adodb_write_file($md5file,$txt,$this->debug)) { 01693 if ($fn = $this->raiseErrorFn) { 01694 $fn($this->databaseType,'CacheExecute',-32000,"Cache write error",$md5file,$sql,$this); 01695 } 01696 if ($this->debug) ADOConnection::outp( " Cache write error"); 01697 } 01698 if ($rs->EOF && !$eof) { 01699 $rs->MoveFirst(); 01700 //$rs = &csv2rs($md5file,$err); 01701 $rs->connection = &$this; // Pablo suggestion 01702 } 01703 01704 } else 01705 @unlink($md5file); 01706 } else { 01707 $this->_errorMsg = ''; 01708 $this->_errorCode = 0; 01709 01710 if ($this->fnCacheExecute) { 01711 $fn = $this->fnCacheExecute; 01712 $fn($this, $secs2cache, $sql, $inputarr); 01713 } 01714 // ok, set cached object found 01715 $rs->connection = &$this; // Pablo suggestion 01716 if ($this->debug){ 01717 01718 $inBrowser = isset($_SERVER['HTTP_USER_AGENT']); 01719 $ttl = $rs->timeCreated + $secs2cache - time(); 01720 $s = is_array($sql) ? $sql[0] : $sql; 01721 if ($inBrowser) $s = '<i>'.htmlspecialchars($s).'</i>'; 01722 01723 ADOConnection::outp( " $md5file reloaded, ttl=$ttl [ $s ]"); 01724 } 01725 } 01726 return $rs; 01727 } 01728 01729 01730 /* 01731 Similar to PEAR DB's autoExecute(), except that 01732 $mode can be 'INSERT' or 'UPDATE' or DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE 01733 If $mode == 'UPDATE', then $where is compulsory as a safety measure. 01734 01735 $forceUpdate means that even if the data has not changed, perform update. 01736 */ 01737 function& AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false) 01738 { 01739 $false = false; 01740 $sql = 'SELECT * FROM '.$table; 01741 if ($where!==FALSE) $sql .= ' WHERE '.$where; 01742 else if ($mode == 'UPDATE' || $mode == 2 /* DB_AUTOQUERY_UPDATE */) { 01743 ADOConnection::outp('AutoExecute: Illegal mode=UPDATE with empty WHERE clause'); 01744 return $false; 01745 } 01746 01747 $rs =& $this->SelectLimit($sql,1); 01748 if (!$rs) return $false; // table does not exist 01749 $rs->tableName = $table; 01750 01751 switch((string) $mode) { 01752 case 'UPDATE': 01753 case '2': 01754 $sql = $this->GetUpdateSQL($rs, $fields_values, $forceUpdate, $magicq); 01755 break; 01756 case 'INSERT': 01757 case '1': 01758 $sql = $this->GetInsertSQL($rs, $fields_values, $magicq); 01759 break; 01760 default: 01761 ADOConnection::outp("AutoExecute: Unknown mode=$mode"); 01762 return $false; 01763 } 01764 $ret = false; 01765 if ($sql) $ret = $this->Execute($sql); 01766 if ($ret) $ret = true; 01767 return $ret; 01768 } 01769 01770 01782 function GetUpdateSQL(&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=null) 01783 { 01784 global $ADODB_INCLUDED_LIB; 01785 01786 //********************************************************// 01787 //This is here to maintain compatibility 01788 //with older adodb versions. Sets force type to force nulls if $forcenulls is set. 01789 if (!isset($force)) { 01790 global $ADODB_FORCE_TYPE; 01791 $force = $ADODB_FORCE_TYPE; 01792 } 01793 //********************************************************// 01794 01795 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 01796 return _adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq,$force); 01797 } 01798 01807 function GetInsertSQL(&$rs, $arrFields,$magicq=false,$force=null) 01808 { 01809 global $ADODB_INCLUDED_LIB; 01810 if (!isset($force)) { 01811 global $ADODB_FORCE_TYPE; 01812 $force = $ADODB_FORCE_TYPE; 01813 01814 } 01815 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 01816 return _adodb_getinsertsql($this,$rs,$arrFields,$magicq,$force); 01817 } 01818 01819 01839 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') 01840 { 01841 return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false; 01842 } 01843 01853 function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB') 01854 { 01855 $fd = fopen($path,'rb'); 01856 if ($fd === false) return false; 01857 $val = fread($fd,filesize($path)); 01858 fclose($fd); 01859 return $this->UpdateBlob($table,$column,$val,$where,$blobtype); 01860 } 01861 01862 function BlobDecode($blob) 01863 { 01864 return $blob; 01865 } 01866 01867 function BlobEncode($blob) 01868 { 01869 return $blob; 01870 } 01871 01872 function SetCharSet($charset) 01873 { 01874 return false; 01875 } 01876 01877 function IfNull( $field, $ifNull ) 01878 { 01879 return " CASE WHEN $field is null THEN $ifNull ELSE $field END "; 01880 } 01881 01882 function LogSQL($enable=true) 01883 { 01884 include_once(ADODB_DIR.'/adodb-perf.inc.php'); 01885 01886 if ($enable) $this->fnExecute = 'adodb_log_sql'; 01887 else $this->fnExecute = false; 01888 01889 $old = $this->_logsql; 01890 $this->_logsql = $enable; 01891 if ($enable && !$old) $this->_affected = false; 01892 return $old; 01893 } 01894 01895 function GetCharSet() 01896 { 01897 return false; 01898 } 01899 01907 function UpdateClob($table,$column,$val,$where) 01908 { 01909 return $this->UpdateBlob($table,$column,$val,$where,'CLOB'); 01910 } 01911 01912 // not the fastest implementation - quick and dirty - jlim 01913 // for best performance, use the actual $rs->MetaType(). 01914 function MetaType($t,$len=-1,$fieldobj=false) 01915 { 01916 01917 if (empty($this->_metars)) { 01918 $rsclass = $this->rsPrefix.$this->databaseType; 01919 $this->_metars =& new $rsclass(false,$this->fetchMode); 01920 $this->_metars->connection =& $this; 01921 } 01922 return $this->_metars->MetaType($t,$len,$fieldobj); 01923 } 01924 01925 01930 function SetDateLocale($locale = 'En') 01931 { 01932 $this->locale = $locale; 01933 switch (strtoupper($locale)) 01934 { 01935 case 'EN': 01936 $this->fmtDate="'Y-m-d'"; 01937 $this->fmtTimeStamp = "'Y-m-d H:i:s'"; 01938 break; 01939 01940 case 'US': 01941 $this->fmtDate = "'m-d-Y'"; 01942 $this->fmtTimeStamp = "'m-d-Y H:i:s'"; 01943 break; 01944 01945 case 'NL': 01946 case 'FR': 01947 case 'RO': 01948 case 'IT': 01949 $this->fmtDate="'d-m-Y'"; 01950 $this->fmtTimeStamp = "'d-m-Y H:i:s'"; 01951 break; 01952 01953 case 'GE': 01954 $this->fmtDate="'d.m.Y'"; 01955 $this->fmtTimeStamp = "'d.m.Y H:i:s'"; 01956 break; 01957 01958 default: 01959 $this->fmtDate="'Y-m-d'"; 01960 $this->fmtTimeStamp = "'Y-m-d H:i:s'"; 01961 break; 01962 } 01963 } 01964 01965 function &GetActiveRecordsClass($class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false) 01966 { 01967 global $_ADODB_ACTIVE_DBS; 01968 01969 $save = $this->SetFetchMode(ADODB_FETCH_NUM); 01970 if (empty($whereOrderBy)) $whereOrderBy = '1=1'; 01971 $rows = $this->GetAll("select * from ".$table.' WHERE '.$whereOrderBy,$bindarr); 01972 $this->SetFetchMode($save); 01973 01974 $false = false; 01975 01976 if ($rows === false) { 01977 return $false; 01978 } 01979 01980 01981 if (!isset($_ADODB_ACTIVE_DBS)) { 01982 include(ADODB_DIR.'/adodb-active-record.inc.php'); 01983 } 01984 if (!class_exists($class)) { 01985 ADOConnection::outp("Unknown class $class in GetActiveRcordsClass()"); 01986 return $false; 01987 } 01988 $arr = array(); 01989 foreach($rows as $row) { 01990 01991 $obj =& new $class($table,$primkeyArr,$this); 01992 if ($obj->ErrorMsg()){ 01993 $this->_errorMsg = $obj->ErrorMsg(); 01994 return $false; 01995 } 01996 $obj->Set($row); 01997 $arr[] =& $obj; 01998 } 01999 return $arr; 02000 } 02001 02002 function &GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false) 02003 { 02004 $arr =& $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr); 02005 return $arr; 02006 } 02007 02011 function Close() 02012 { 02013 $rez = $this->_close(); 02014 $this->_connectionID = false; 02015 return $rez; 02016 } 02017 02023 function BeginTrans() {return false;} 02024 02025 /* set transaction mode */ 02026 function SetTransactionMode( $transaction_mode ) 02027 { 02028 $transaction_mode = $this->MetaTransaction($transaction_mode, $this->dataProvider); 02029 $this->_transmode = $transaction_mode; 02030 } 02031 /* 02032 http://msdn2.microsoft.com/en-US/ms173763.aspx 02033 http://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-isolation.html 02034 http://www.postgresql.org/docs/8.1/interactive/sql-set-transaction.html 02035 http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_10005.htm 02036 */ 02037 function MetaTransaction($mode,$db) 02038 { 02039 $mode = strtoupper($mode); 02040 $mode = str_replace('ISOLATION LEVEL ','',$mode); 02041 02042 switch($mode) { 02043 02044 case 'READ UNCOMMITTED': 02045 switch($db) { 02046 case 'oci8': 02047 case 'oracle': 02048 return 'ISOLATION LEVEL READ COMMITTED'; 02049 default: 02050 return 'ISOLATION LEVEL READ UNCOMMITTED'; 02051 } 02052 break; 02053 02054 case 'READ COMMITTED': 02055 return 'ISOLATION LEVEL READ COMMITTED'; 02056 break; 02057 02058 case 'REPEATABLE READ': 02059 switch($db) { 02060 case 'oci8': 02061 case 'oracle': 02062 return 'ISOLATION LEVEL SERIALIZABLE'; 02063 default: 02064 return 'ISOLATION LEVEL REPEATABLE READ'; 02065 } 02066 break; 02067 02068 case 'SERIALIZABLE': 02069 return 'ISOLATION LEVEL SERIALIZABLE'; 02070 break; 02071 02072 default: 02073 return $mode; 02074 } 02075 } 02076 02084 function CommitTrans($ok=true) 02085 { return true;} 02086 02087 02093 function RollbackTrans() 02094 { return false;} 02095 02096 02103 function MetaDatabases() 02104 { 02105 global $ADODB_FETCH_MODE; 02106 02107 if ($this->metaDatabasesSQL) { 02108 $save = $ADODB_FETCH_MODE; 02109 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 02110 02111 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); 02112 02113 $arr = $this->GetCol($this->metaDatabasesSQL); 02114 if (isset($savem)) $this->SetFetchMode($savem); 02115 $ADODB_FETCH_MODE = $save; 02116 02117 return $arr; 02118 } 02119 02120 return false; 02121 } 02122 02123 02134 function &MetaTables($ttype=false,$showSchema=false,$mask=false) 02135 { 02136 global $ADODB_FETCH_MODE; 02137 02138 02139 $false = false; 02140 if ($mask) { 02141 return $false; 02142 } 02143 if ($this->metaTablesSQL) { 02144 $save = $ADODB_FETCH_MODE; 02145 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 02146 02147 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); 02148 02149 $rs = $this->Execute($this->metaTablesSQL); 02150 if (isset($savem)) $this->SetFetchMode($savem); 02151 $ADODB_FETCH_MODE = $save; 02152 02153 if ($rs === false) return $false; 02154 $arr =& $rs->GetArray(); 02155 $arr2 = array(); 02156 02157 if ($hast = ($ttype && isset($arr[0][1]))) { 02158 $showt = strncmp($ttype,'T',1); 02159 } 02160 02161 for ($i=0; $i < sizeof($arr); $i++) { 02162 if ($hast) { 02163 if ($showt == 0) { 02164 if (strncmp($arr[$i][1],'T',1) == 0) $arr2[] = trim($arr[$i][0]); 02165 } else { 02166 if (strncmp($arr[$i][1],'V',1) == 0) $arr2[] = trim($arr[$i][0]); 02167 } 02168 } else 02169 $arr2[] = trim($arr[$i][0]); 02170 } 02171 $rs->Close(); 02172 return $arr2; 02173 } 02174 return $false; 02175 } 02176 02177 02178 function _findschema(&$table,&$schema) 02179 { 02180 if (!$schema && ($at = strpos($table,'.')) !== false) { 02181 $schema = substr($table,0,$at); 02182 $table = substr($table,$at+1); 02183 } 02184 } 02185 02196 function &MetaColumns($table,$normalize=true) 02197 { 02198 global $ADODB_FETCH_MODE; 02199 02200 $false = false; 02201 02202 if (!empty($this->metaColumnsSQL)) { 02203 02204 $schema = false; 02205 $this->_findschema($table,$schema); 02206 02207 $save = $ADODB_FETCH_MODE; 02208 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 02209 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); 02210 $rs = $this->Execute(sprintf($this->metaColumnsSQL,($normalize)?strtoupper($table):$table)); 02211 if (isset($savem)) $this->SetFetchMode($savem); 02212 $ADODB_FETCH_MODE = $save; 02213 if ($rs === false || $rs->EOF) return $false; 02214 02215 $retarr = array(); 02216 while (!$rs->EOF) { //print_r($rs->fields); 02217 $fld = new ADOFieldObject(); 02218 $fld->name = $rs->fields[0]; 02219 $fld->type = $rs->fields[1]; 02220 if (isset($rs->fields[3]) && $rs->fields[3]) { 02221 if ($rs->fields[3]>0) $fld->max_length = $rs->fields[3]; 02222 $fld->scale = $rs->fields[4]; 02223 if ($fld->scale>0) $fld->max_length += 1; 02224 } else 02225 $fld->max_length = $rs->fields[2]; 02226 02227 if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld; 02228 else $retarr[strtoupper($fld->name)] = $fld; 02229 $rs->MoveNext(); 02230 } 02231 $rs->Close(); 02232 return $retarr; 02233 } 02234 return $false; 02235 } 02236 02255 function &MetaIndexes($table, $primary = false, $owner = false) 02256 { 02257 $false = false; 02258 return $false; 02259 } 02260 02267 function &MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */) 02268 { 02269 $objarr =& $this->MetaColumns($table); 02270 if (!is_array($objarr)) { 02271 $false = false; 02272 return $false; 02273 } 02274 $arr = array(); 02275 if ($numIndexes) { 02276 $i = 0; 02277 if ($useattnum) { 02278 foreach($objarr as $v) 02279 $arr[$v->attnum] = $v->name; 02280 02281 } else 02282 foreach($objarr as $v) $arr[$i++] = $v->name; 02283 } else 02284 foreach($objarr as $v) $arr[strtoupper($v->name)] = $v->name; 02285 02286 return $arr; 02287 } 02288 02299 function Concat() 02300 { 02301 $arr = func_get_args(); 02302 return implode($this->concat_operator, $arr); 02303 } 02304 02305 02313 function DBDate($d) 02314 { 02315 if (empty($d) && $d !== 0) return 'null'; 02316 02317 if (is_string($d) && !is_numeric($d)) { 02318 if ($d === 'null' || strncmp($d,"'",1) === 0) return $d; 02319 if ($this->isoDates) return "'$d'"; 02320 $d = ADOConnection::UnixDate($d); 02321 } 02322 02323 return adodb_date($this->fmtDate,$d); 02324 } 02325 02326 function BindDate($d) 02327 { 02328 $d = $this->DBDate($d); 02329 if (strncmp($d,"'",1)) return $d; 02330 02331 return substr($d,1,strlen($d)-2); 02332 } 02333 02334 function BindTimeStamp($d) 02335 { 02336 $d = $this->DBTimeStamp($d); 02337 if (strncmp($d,"'",1)) return $d; 02338 02339 return substr($d,1,strlen($d)-2); 02340 } 02341 02342 02350 function DBTimeStamp($ts) 02351 { 02352 if (empty($ts) && $ts !== 0) return 'null'; 02353 02354 # strlen(14) allows YYYYMMDDHHMMSS format 02355 if (!is_string($ts) || (is_numeric($ts) && strlen($ts)<14)) 02356 return adodb_date($this->fmtTimeStamp,$ts); 02357 02358 if ($ts === 'null') return $ts; 02359 if ($this->isoDates && strlen($ts) !== 14) return "'$ts'"; 02360 02361 $ts = ADOConnection::UnixTimeStamp($ts); 02362 return adodb_date($this->fmtTimeStamp,$ts); 02363 } 02364 02371 function UnixDate($v) 02372 { 02373 if (is_object($v)) { 02374 // odbtp support 02375 //( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 ) 02376 return adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year); 02377 } 02378 02379 if (is_numeric($v) && strlen($v) !== 8) return $v; 02380 if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|", 02381 ($v), $rr)) return false; 02382 02383 if ($rr[1] <= TIMESTAMP_FIRST_YEAR) return 0; 02384 // h-m-s-MM-DD-YY 02385 return @adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]); 02386 } 02387 02388 02395 function UnixTimeStamp($v) 02396 { 02397 if (is_object($v)) { 02398 // odbtp support 02399 //( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 ) 02400 return adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year); 02401 } 02402 02403 if (!preg_match( 02404 "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]*(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", 02405 ($v), $rr)) return false; 02406 02407 if ($rr[1] <= TIMESTAMP_FIRST_YEAR && $rr[2]<= 1) return 0; 02408 02409 // h-m-s-MM-DD-YY 02410 if (!isset($rr[5])) return adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]); 02411 return @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]); 02412 } 02413 02425 function UserDate($v,$fmt='Y-m-d',$gmt=false) 02426 { 02427 $tt = $this->UnixDate($v); 02428 02429 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR 02430 if (($tt === false || $tt == -1) && $v != false) return $v; 02431 else if ($tt == 0) return $this->emptyDate; 02432 else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR 02433 } 02434 02435 return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt); 02436 02437 } 02438 02446 function UserTimeStamp($v,$fmt='Y-m-d H:i:s',$gmt=false) 02447 { 02448 if (!isset($v)) return $this->emptyTimeStamp; 02449 # strlen(14) allows YYYYMMDDHHMMSS format 02450 if (is_numeric($v) && strlen($v)<14) return ($gmt) ? adodb_gmdate($fmt,$v) : adodb_date($fmt,$v); 02451 $tt = $this->UnixTimeStamp($v); 02452 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR 02453 if (($tt === false || $tt == -1) && $v != false) return $v; 02454 if ($tt == 0) return $this->emptyTimeStamp; 02455 return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt); 02456 } 02457 02458 function escape($s,$magic_quotes=false) 02459 { 02460 return $this->addq($s,$magic_quotes); 02461 } 02462 02466 function addq($s,$magic_quotes=false) 02467 { 02468 if (!$magic_quotes) { 02469 02470 if ($this->replaceQuote[0] == '\\'){ 02471 // only since php 4.0.5 02472 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s); 02473 //$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s)); 02474 } 02475 return str_replace("'",$this->replaceQuote,$s); 02476 } 02477 02478 // undo magic quotes for " 02479 $s = str_replace('\\"','"',$s); 02480 02481 if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything 02482 return $s; 02483 else {// change \' to '' for sybase/mssql 02484 $s = str_replace('\\\\','\\',$s); 02485 return str_replace("\\'",$this->replaceQuote,$s); 02486 } 02487 } 02488 02500 function qstr($s,$magic_quotes=false) 02501 { 02502 if (!$magic_quotes) { 02503 02504 if ($this->replaceQuote[0] == '\\'){ 02505 // only since php 4.0.5 02506 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s); 02507 //$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s)); 02508 } 02509 return "'".str_replace("'",$this->replaceQuote,$s)."'"; 02510 } 02511 02512 // undo magic quotes for " 02513 $s = str_replace('\\"','"',$s); 02514 02515 if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything 02516 return "'$s'"; 02517 else {// change \' to '' for sybase/mssql 02518 $s = str_replace('\\\\','\\',$s); 02519 return "'".str_replace("\\'",$this->replaceQuote,$s)."'"; 02520 } 02521 } 02522 02523 02541 function &PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) 02542 { 02543 global $ADODB_INCLUDED_LIB; 02544 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 02545 if ($this->pageExecuteCountRows) $rs =& _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache); 02546 else $rs =& _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache); 02547 return $rs; 02548 } 02549 02550 02563 function &CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) 02564 { 02565 /*switch($this->dataProvider) { 02566 case 'postgres': 02567 case 'mysql': 02568 break; 02569 default: $secs2cache = 0; break; 02570 }*/ 02571 $rs =& $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache); 02572 return $rs; 02573 } 02574 02575 } // end class ADOConnection 02576 02577 02578 02579 //============================================================================================== 02580 // CLASS ADOFetchObj 02581 //============================================================================================== 02582 02586 class ADOFetchObj { 02587 }; 02588 02589 //============================================================================================== 02590 // CLASS ADORecordSet_empty 02591 //============================================================================================== 02592 02596 class ADORecordSet_empty 02597 { 02598 var $dataProvider = 'empty'; 02599 var $databaseType = false; 02600 var $EOF = true; 02601 var $_numOfRows = 0; 02602 var $fields = false; 02603 var $connection = false; 02604 function RowCount() {return 0;} 02605 function RecordCount() {return 0;} 02606 function PO_RecordCount(){return 0;} 02607 function Close(){return true;} 02608 function FetchRow() {return false;} 02609 function FieldCount(){ return 0;} 02610 function Init() {} 02611 } 02612 02613 //============================================================================================== 02614 // DATE AND TIME FUNCTIONS 02615 //============================================================================================== 02616 if (!defined('ADODB_DATE_VERSION')) include(ADODB_DIR.'/adodb-time.inc.php'); 02617 02618 //============================================================================================== 02619 // CLASS ADORecordSet 02620 //============================================================================================== 02621 02622 if (PHP_VERSION < 5) include_once(ADODB_DIR.'/adodb-php4.inc.php'); 02623 else include_once(ADODB_DIR.'/adodb-iterator.inc.php'); 02630 class ADORecordSet extends ADODB_BASE_RS { 02631 /* 02632 * public variables 02633 */ 02634 var $dataProvider = "native"; 02635 var $fields = false; 02636 var $blobSize = 100; 02637 02638 var $canSeek = false; 02639 var $sql; 02640 var $EOF = false; 02641 02642 var $emptyTimeStamp = ' '; 02643 var $emptyDate = ' '; 02644 var $debug = false; 02645 var $timeCreated=0; 02646 02647 var $bind = false; 02648 var $fetchMode; 02649 var $connection = false; 02650 /* 02651 * private variables 02652 */ 02653 var $_numOfRows = -1; 02654 var $_numOfFields = -1; 02655 var $_queryID = -1; 02656 var $_currentRow = -1; 02657 var $_closed = false; 02658 var $_inited = false; 02659 var $_obj; 02660 var $_names; 02662 var $_currentPage = -1; 02663 var $_atFirstPage = false; 02664 var $_atLastPage = false; 02665 var $_lastPageNo = -1; 02666 var $_maxRecordCount = 0; 02667 var $datetime = false; 02668 02675 function ADORecordSet($queryID) 02676 { 02677 $this->_queryID = $queryID; 02678 } 02679 02680 02681 02682 function Init() 02683 { 02684 if ($this->_inited) return; 02685 $this->_inited = true; 02686 if ($this->_queryID) @$this->_initrs(); 02687 else { 02688 $this->_numOfRows = 0; 02689 $this->_numOfFields = 0; 02690 } 02691 if ($this->_numOfRows != 0 && $this->_numOfFields && $this->_currentRow == -1) { 02692 02693 $this->_currentRow = 0; 02694 if ($this->EOF = ($this->_fetch() === false)) { 02695 $this->_numOfRows = 0; // _numOfRows could be -1 02696 } 02697 } else { 02698 $this->EOF = true; 02699 } 02700 } 02701 02702 02723 function GetMenu($name,$defstr='',$blank1stItem=true,$multiple=false, 02724 $size=0, $selectAttr='',$compareFields0=true) 02725 { 02726 global $ADODB_INCLUDED_LIB; 02727 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 02728 return _adodb_getmenu($this, $name,$defstr,$blank1stItem,$multiple, 02729 $size, $selectAttr,$compareFields0); 02730 } 02731 02732 02733 02741 function GetMenu2($name,$defstr='',$blank1stItem=true,$multiple=false,$size=0, $selectAttr='') 02742 { 02743 return $this->GetMenu($name,$defstr,$blank1stItem,$multiple, 02744 $size, $selectAttr,false); 02745 } 02746 02747 /* 02748 Grouped Menu 02749 */ 02750 function GetMenu3($name,$defstr='',$blank1stItem=true,$multiple=false, 02751 $size=0, $selectAttr='') 02752 { 02753 global $ADODB_INCLUDED_LIB; 02754 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 02755 return _adodb_getmenu_gp($this, $name,$defstr,$blank1stItem,$multiple, 02756 $size, $selectAttr,false); 02757 } 02758 02766 function &GetArray($nRows = -1) 02767 { 02768 global $ADODB_EXTENSION; if ($ADODB_EXTENSION) { 02769 $results = adodb_getall($this,$nRows); 02770 return $results; 02771 } 02772 $results = array(); 02773 $cnt = 0; 02774 while (!$this->EOF && $nRows != $cnt) { 02775 $results[] = $this->fields; 02776 $this->MoveNext(); 02777 $cnt++; 02778 } 02779 return $results; 02780 } 02781 02782 function &GetAll($nRows = -1) 02783 { 02784 $arr =& $this->GetArray($nRows); 02785 return $arr; 02786 } 02787 02788 /* 02789 * Some databases allow multiple recordsets to be returned. This function 02790 * will return true if there is a next recordset, or false if no more. 02791 */ 02792 function NextRecordSet() 02793 { 02794 return false; 02795 } 02796 02806 function &GetArrayLimit($nrows,$offset=-1) 02807 { 02808 if ($offset <= 0) { 02809 $arr =& $this->GetArray($nrows); 02810 return $arr; 02811 } 02812 02813 $this->Move($offset); 02814 02815 $results = array(); 02816 $cnt = 0; 02817 while (!$this->EOF && $nrows != $cnt) { 02818 $results[$cnt++] = $this->fields; 02819 $this->MoveNext(); 02820 } 02821 02822 return $results; 02823 } 02824 02825 02833 function &GetRows($nRows = -1) 02834 { 02835 $arr =& $this->GetArray($nRows); 02836 return $arr; 02837 } 02838 02855 function &GetAssoc($force_array = false, $first2cols = false) 02856 { 02857 global $ADODB_EXTENSION; 02858 02859 $cols = $this->_numOfFields; 02860 if ($cols < 2) { 02861 $false = false; 02862 return $false; 02863 } 02864 $numIndex = isset($this->fields[0]); 02865 $results = array(); 02866 02867 if (!$first2cols && ($cols > 2 || $force_array)) { 02868 if ($ADODB_EXTENSION) { 02869 if ($numIndex) { 02870 while (!$this->EOF) { 02871 $results[trim($this->fields[0])] = array_slice($this->fields, 1); 02872 adodb_movenext($this); 02873 } 02874 } else { 02875 while (!$this->EOF) { 02876 $results[trim(reset($this->fields))] = array_slice($this->fields, 1); 02877 adodb_movenext($this); 02878 } 02879 } 02880 } else { 02881 if ($numIndex) { 02882 while (!$this->EOF) { 02883 $results[trim($this->fields[0])] = array_slice($this->fields, 1); 02884 $this->MoveNext(); 02885 } 02886 } else { 02887 while (!$this->EOF) { 02888 $results[trim(reset($this->fields))] = array_slice($this->fields, 1); 02889 $this->MoveNext(); 02890 } 02891 } 02892 } 02893 } else { 02894 if ($ADODB_EXTENSION) { 02895 // return scalar values 02896 if ($numIndex) { 02897 while (!$this->EOF) { 02898 // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string 02899 $results[trim(($this->fields[0]))] = $this->fields[1]; 02900 adodb_movenext($this); 02901 } 02902 } else { 02903 while (!$this->EOF) { 02904 // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string 02905 $v1 = trim(reset($this->fields)); 02906 $v2 = ''.next($this->fields); 02907 $results[$v1] = $v2; 02908 adodb_movenext($this); 02909 } 02910 } 02911 } else { 02912 if ($numIndex) { 02913 while (!$this->EOF) { 02914 // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string 02915 $results[trim(($this->fields[0]))] = $this->fields[1]; 02916 $this->MoveNext(); 02917 } 02918 } else { 02919 while (!$this->EOF) { 02920 // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string 02921 $v1 = trim(reset($this->fields)); 02922 $v2 = ''.next($this->fields); 02923 $results[$v1] = $v2; 02924 $this->MoveNext(); 02925 } 02926 } 02927 } 02928 } 02929 02930 $ref =& $results; # workaround accelerator incompat with PHP 4.4 :( 02931 return $ref; 02932 } 02933 02934 02942 function UserTimeStamp($v,$fmt='Y-m-d H:i:s') 02943 { 02944 if (is_numeric($v) && strlen($v)<14) return adodb_date($fmt,$v); 02945 $tt = $this->UnixTimeStamp($v); 02946 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR 02947 if (($tt === false || $tt == -1) && $v != false) return $v; 02948 if ($tt === 0) return $this->emptyTimeStamp; 02949 return adodb_date($fmt,$tt); 02950 } 02951 02952 02959 function UserDate($v,$fmt='Y-m-d') 02960 { 02961 $tt = $this->UnixDate($v); 02962 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR 02963 if (($tt === false || $tt == -1) && $v != false) return $v; 02964 else if ($tt == 0) return $this->emptyDate; 02965 else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR 02966 } 02967 return adodb_date($fmt,$tt); 02968 } 02969 02970 02976 function UnixDate($v) 02977 { 02978 return ADOConnection::UnixDate($v); 02979 } 02980 02981 02987 function UnixTimeStamp($v) 02988 { 02989 return ADOConnection::UnixTimeStamp($v); 02990 } 02991 02992 02996 function Free() 02997 { 02998 return $this->Close(); 02999 } 03000 03001 03005 function NumRows() 03006 { 03007 return $this->_numOfRows; 03008 } 03009 03010 03014 function NumCols() 03015 { 03016 return $this->_numOfFields; 03017 } 03018 03025 function &FetchRow() 03026 { 03027 if ($this->EOF) { 03028 $false = false; 03029 return $false; 03030 } 03031 $arr = $this->fields; 03032 $this->_currentRow++; 03033 if (!$this->_fetch()) $this->EOF = true; 03034 return $arr; 03035 } 03036 03037 03044 function FetchInto(&$arr) 03045 { 03046 if ($this->EOF) return (defined('PEAR_ERROR_RETURN')) ? new PEAR_Error('EOF',-1): false; 03047 $arr = $this->fields; 03048 $this->MoveNext(); 03049 return 1; // DB_OK 03050 } 03051 03052 03058 function MoveFirst() 03059 { 03060 if ($this->_currentRow == 0) return true; 03061 return $this->Move(0); 03062 } 03063 03064 03070 function MoveLast() 03071 { 03072 if ($this->_numOfRows >= 0) return $this->Move($this->_numOfRows-1); 03073 if ($this->EOF) return false; 03074 while (!$this->EOF) { 03075 $f = $this->fields; 03076 $this->MoveNext(); 03077 } 03078 $this->fields = $f; 03079 $this->EOF = false; 03080 return true; 03081 } 03082 03083 03089 function MoveNext() 03090 { 03091 if (!$this->EOF) { 03092 $this->_currentRow++; 03093 if ($this->_fetch()) return true; 03094 } 03095 $this->EOF = true; 03096 /* -- tested error handling when scrolling cursor -- seems useless. 03097 $conn = $this->connection; 03098 if ($conn && $conn->raiseErrorFn && ($errno = $conn->ErrorNo())) { 03099 $fn = $conn->raiseErrorFn; 03100 $fn($conn->databaseType,'MOVENEXT',$errno,$conn->ErrorMsg().' ('.$this->sql.')',$conn->host,$conn->database); 03101 } 03102 */ 03103 return false; 03104 } 03105 03106 03115 function Move($rowNumber = 0) 03116 { 03117 $this->EOF = false; 03118 if ($rowNumber == $this->_currentRow) return true; 03119 if ($rowNumber >= $this->_numOfRows) 03120 if ($this->_numOfRows != -1) $rowNumber = $this->_numOfRows-2; 03121 03122 if ($this->canSeek) { 03123 03124 if ($this->_seek($rowNumber)) { 03125 $this->_currentRow = $rowNumber; 03126 if ($this->_fetch()) { 03127 return true; 03128 } 03129 } else { 03130 $this->EOF = true; 03131 return false; 03132 } 03133 } else { 03134 if ($rowNumber < $this->_currentRow) return false; 03135 global $ADODB_EXTENSION; 03136 if ($ADODB_EXTENSION) { 03137 while (!$this->EOF && $this->_currentRow < $rowNumber) { 03138 adodb_movenext($this); 03139 } 03140 } else { 03141 03142 while (! $this->EOF && $this->_currentRow < $rowNumber) { 03143 $this->_currentRow++; 03144 03145 if (!$this->_fetch()) $this->EOF = true; 03146 } 03147 } 03148 return !($this->EOF); 03149 } 03150 03151 $this->fields = false; 03152 $this->EOF = true; 03153 return false; 03154 } 03155 03156 03165 function Fields($colname) 03166 { 03167 return $this->fields[$colname]; 03168 } 03169 03170 function GetAssocKeys($upper=true) 03171 { 03172 $this->bind = array(); 03173 for ($i=0; $i < $this->_numOfFields; $i++) { 03174 $o = $this->FetchField($i); 03175 if ($upper === 2) $this->bind[$o->name] = $i; 03176 else $this->bind[($upper) ? strtoupper($o->name) : strtolower($o->name)] = $i; 03177 } 03178 } 03179 03189 function &GetRowAssoc($upper=1) 03190 { 03191 $record = array(); 03192 // if (!$this->fields) return $record; 03193 03194 if (!$this->bind) { 03195 $this->GetAssocKeys($upper); 03196 } 03197 03198 foreach($this->bind as $k => $v) { 03199 $record[$k] = $this->fields[$v]; 03200 } 03201 03202 return $record; 03203 } 03204 03205 03211 function Close() 03212 { 03213 // free connection object - this seems to globally free the object 03214 // and not merely the reference, so don't do this... 03215 // $this->connection = false; 03216 if (!$this->_closed) { 03217 $this->_closed = true; 03218 return $this->_close(); 03219 } else 03220 return true; 03221 } 03222 03228 function RecordCount() {return $this->_numOfRows;} 03229 03230 03231 /* 03232 * If we are using PageExecute(), this will return the maximum possible rows 03233 * that can be returned when paging a recordset. 03234 */ 03235 function MaxRecordCount() 03236 { 03237 return ($this->_maxRecordCount) ? $this->_maxRecordCount : $this->RecordCount(); 03238 } 03239 03245 function RowCount() {return $this->_numOfRows;} 03246 03247 03256 function PO_RecordCount($table="", $condition="") { 03257 03258 $lnumrows = $this->_numOfRows; 03259 // the database doesn't support native recordcount, so we do a workaround 03260 if ($lnumrows == -1 && $this->connection) { 03261 IF ($table) { 03262 if ($condition) $condition = " WHERE " . $condition; 03263 $resultrows = &$this->connection->Execute("SELECT COUNT(*) FROM $table $condition"); 03264 if ($resultrows) $lnumrows = reset($resultrows->fields); 03265 } 03266 } 03267 return $lnumrows; 03268 } 03269 03270 03274 function CurrentRow() {return $this->_currentRow;} 03275 03281 function AbsolutePosition() {return $this->_currentRow;} 03282 03287 function FieldCount() {return $this->_numOfFields;} 03288 03289 03297 function &FetchField($fieldoffset) 03298 { 03299 // must be defined by child class 03300 } 03301 03306 function& FieldTypesArray() 03307 { 03308 $arr = array(); 03309 for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) 03310 $arr[] = $this->FetchField($i); 03311 return $arr; 03312 } 03313 03320 function &FetchObj() 03321 { 03322 $o =& $this->FetchObject(false); 03323 return $o; 03324 } 03325 03334 function &FetchObject($isupper=true) 03335 { 03336 if (empty($this->_obj)) { 03337 $this->_obj = new ADOFetchObj(); 03338 $this->_names = array(); 03339 for ($i=0; $i <$this->_numOfFields; $i++) { 03340 $f = $this->FetchField($i); 03341 $this->_names[] = $f->name; 03342 } 03343 } 03344 $i = 0; 03345 if (PHP_VERSION >= 5) $o = clone($this->_obj); 03346 else $o = $this->_obj; 03347 03348 for ($i=0; $i <$this->_numOfFields; $i++) { 03349 $name = $this->_names[$i]; 03350 if ($isupper) $n = strtoupper($name); 03351 else $n = $name; 03352 03353 $o->$n = $this->Fields($name); 03354 } 03355 return $o; 03356 } 03357 03367 function &FetchNextObj() 03368 { 03369 $o =& $this->FetchNextObject(false); 03370 return $o; 03371 } 03372 03373 03385 function &FetchNextObject($isupper=true) 03386 { 03387 $o = false; 03388 if ($this->_numOfRows != 0 && !$this->EOF) { 03389 $o = $this->FetchObject($isupper); 03390 $this->_currentRow++; 03391 if ($this->_fetch()) return $o; 03392 } 03393 $this->EOF = true; 03394 return $o; 03395 } 03396 03421 function MetaType($t,$len=-1,$fieldobj=false) 03422 { 03423 if (is_object($t)) { 03424 $fieldobj = $t; 03425 $t = $fieldobj->type; 03426 $len = $fieldobj->max_length; 03427 } 03428 // changed in 2.32 to hashing instead of switch stmt for speed... 03429 static $typeMap = array( 03430 'VARCHAR' => 'C', 03431 'VARCHAR2' => 'C', 03432 'CHAR' => 'C', 03433 'C' => 'C', 03434 'STRING' => 'C', 03435 'NCHAR' => 'C', 03436 'NVARCHAR' => 'C', 03437 'VARYING' => 'C', 03438 'BPCHAR' => 'C', 03439 'CHARACTER' => 'C', 03440 'INTERVAL' => 'C', # Postgres 03441 'MACADDR' => 'C', # postgres 03442 ## 03443 'LONGCHAR' => 'X', 03444 'TEXT' => 'X', 03445 'NTEXT' => 'X', 03446 'M' => 'X', 03447 'X' => 'X', 03448 'CLOB' => 'X', 03449 'NCLOB' => 'X', 03450 'LVARCHAR' => 'X', 03451 ## 03452 'BLOB' => 'B', 03453 'IMAGE' => 'B', 03454 'BINARY' => 'B', 03455 'VARBINARY' => 'B', 03456 'LONGBINARY' => 'B', 03457 'B' => 'B', 03458 ## 03459 'YEAR' => 'D', // mysql 03460 'DATE' => 'D', 03461 'D' => 'D', 03462 ## 03463 'TIME' => 'T', 03464 'TIMESTAMP' => 'T', 03465 'DATETIME' => 'T', 03466 'TIMESTAMPTZ' => 'T', 03467 'T' => 'T', 03468 'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql 03469 ## 03470 'BOOL' => 'L', 03471 'BOOLEAN' => 'L', 03472 'BIT' => 'L', 03473 'L' => 'L', 03474 ## 03475 'COUNTER' => 'R', 03476 'R' => 'R', 03477 'SERIAL' => 'R', // ifx 03478 'INT IDENTITY' => 'R', 03479 ## 03480 'INT' => 'I', 03481 'INT2' => 'I', 03482 'INT4' => 'I', 03483 'INT8' => 'I', 03484 'INTEGER' => 'I', 03485 'INTEGER UNSIGNED' => 'I', 03486 'SHORT' => 'I', 03487 'TINYINT' => 'I', 03488 'SMALLINT' => 'I', 03489 'I' => 'I', 03490 ## 03491 'LONG' => 'N', // interbase is numeric, oci8 is blob 03492 'BIGINT' => 'N', // this is bigger than PHP 32-bit integers 03493 'DECIMAL' => 'N', 03494 'DEC' => 'N', 03495 'REAL' => 'N', 03496 'DOUBLE' => 'N', 03497 'DOUBLE PRECISION' => 'N', 03498 'SMALLFLOAT' => 'N', 03499 'FLOAT' => 'N', 03500 'NUMBER' => 'N', 03501 'NUM' => 'N', 03502 'NUMERIC' => 'N', 03503 'MONEY' => 'N', 03504 03505 ## informix 9.2 03506 'SQLINT' => 'I', 03507 'SQLSERIAL' => 'I', 03508 'SQLSMINT' => 'I', 03509 'SQLSMFLOAT' => 'N', 03510 'SQLFLOAT' => 'N', 03511 'SQLMONEY' => 'N', 03512 'SQLDECIMAL' => 'N', 03513 'SQLDATE' => 'D', 03514 'SQLVCHAR' => 'C', 03515 'SQLCHAR' => 'C', 03516 'SQLDTIME' => 'T', 03517 'SQLINTERVAL' => 'N', 03518 'SQLBYTES' => 'B', 03519 'SQLTEXT' => 'X' 03520 ); 03521 03522 $tmap = false; 03523 $t = strtoupper($t); 03524 $tmap = (isset($typeMap[$t])) ? $typeMap[$t] : 'N'; 03525 switch ($tmap) { 03526 case 'C': 03527 03528 // is the char field is too long, return as text field... 03529 if ($this->blobSize >= 0) { 03530 if ($len > $this->blobSize) return 'X'; 03531 } else if ($len > 250) { 03532 return 'X'; 03533 } 03534 return 'C'; 03535 03536 case 'I': 03537 if (!empty($fieldobj->primary_key)) return 'R'; 03538 return 'I'; 03539 03540 case false: 03541 return 'N'; 03542 03543 case 'B': 03544 if (isset($fieldobj->binary)) 03545 return ($fieldobj->binary) ? 'B' : 'X'; 03546 return 'B'; 03547 03548 case 'D': 03549 if (!empty($this->connection) && !empty($this->connection->datetime)) return 'T'; 03550 return 'D'; 03551 03552 default: 03553 if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B'; 03554 return $tmap; 03555 } 03556 } 03557 03558 function _close() {} 03559 03563 function AbsolutePage($page=-1) 03564 { 03565 if ($page != -1) $this->_currentPage = $page; 03566 return $this->_currentPage; 03567 } 03568 03572 function AtFirstPage($status=false) 03573 { 03574 if ($status != false) $this->_atFirstPage = $status; 03575 return $this->_atFirstPage; 03576 } 03577 03578 function LastPageNo($page = false) 03579 { 03580 if ($page != false) $this->_lastPageNo = $page; 03581 return $this->_lastPageNo; 03582 } 03583 03587 function AtLastPage($status=false) 03588 { 03589 if ($status != false) $this->_atLastPage = $status; 03590 return $this->_atLastPage; 03591 } 03592 03593 } // end class ADORecordSet 03594 03595 //============================================================================================== 03596 // CLASS ADORecordSet_array 03597 //============================================================================================== 03598 03606 class ADORecordSet_array extends ADORecordSet 03607 { 03608 var $databaseType = 'array'; 03609 03610 var $_array; // holds the 2-dimensional data array 03611 var $_types; // the array of types of each column (C B I L M) 03612 var $_colnames; // names of each column in array 03613 var $_skiprow1; // skip 1st row because it holds column names 03614 var $_fieldarr; // holds array of field objects 03615 var $canSeek = true; 03616 var $affectedrows = false; 03617 var $insertid = false; 03618 var $sql = ''; 03619 var $compat = false; 03624 function ADORecordSet_array($fakeid=1) 03625 { 03626 global $ADODB_FETCH_MODE,$ADODB_COMPAT_FETCH; 03627 03628 // fetch() on EOF does not delete $this->fields 03629 $this->compat = !empty($ADODB_COMPAT_FETCH); 03630 $this->ADORecordSet($fakeid); // fake queryID 03631 $this->fetchMode = $ADODB_FETCH_MODE; 03632 } 03633 03634 03646 function InitArray($array,$typearr,$colnames=false) 03647 { 03648 $this->_array = $array; 03649 $this->_types = $typearr; 03650 if ($colnames) { 03651 $this->_skiprow1 = false; 03652 $this->_colnames = $colnames; 03653 } else { 03654 $this->_skiprow1 = true; 03655 $this->_colnames = $array[0]; 03656 } 03657 $this->Init(); 03658 } 03667 function InitArrayFields(&$array,&$fieldarr) 03668 { 03669 $this->_array =& $array; 03670 $this->_skiprow1= false; 03671 if ($fieldarr) { 03672 $this->_fieldobjects =& $fieldarr; 03673 } 03674 $this->Init(); 03675 } 03676 03677 function &GetArray($nRows=-1) 03678 { 03679 if ($nRows == -1 && $this->_currentRow <= 0 && !$this->_skiprow1) { 03680 return $this->_array; 03681 } else { 03682 $arr =& ADORecordSet::GetArray($nRows); 03683 return $arr; 03684 } 03685 } 03686 03687 function _initrs() 03688 { 03689 $this->_numOfRows = sizeof($this->_array); 03690 if ($this->_skiprow1) $this->_numOfRows -= 1; 03691 03692 $this->_numOfFields =(isset($this->_fieldobjects)) ? 03693 sizeof($this->_fieldobjects):sizeof($this->_types); 03694 } 03695 03696 /* Use associative array to get fields array */ 03697 function Fields($colname) 03698 { 03699 $mode = isset($this->adodbFetchMode) ? $this->adodbFetchMode : $this->fetchMode; 03700 03701 if ($mode & ADODB_FETCH_ASSOC) { 03702 if (!isset($this->fields[$colname])) $colname = strtolower($colname); 03703 return $this->fields[$colname]; 03704 } 03705 if (!$this->bind) { 03706 $this->bind = array(); 03707 for ($i=0; $i < $this->_numOfFields; $i++) { 03708 $o = $this->FetchField($i); 03709 $this->bind[strtoupper($o->name)] = $i; 03710 } 03711 } 03712 return $this->fields[$this->bind[strtoupper($colname)]]; 03713 } 03714 03715 function &FetchField($fieldOffset = -1) 03716 { 03717 if (isset($this->_fieldobjects)) { 03718 return $this->_fieldobjects[$fieldOffset]; 03719 } 03720 $o = new ADOFieldObject(); 03721 $o->name = $this->_colnames[$fieldOffset]; 03722 $o->type = $this->_types[$fieldOffset]; 03723 $o->max_length = -1; // length not known 03724 03725 return $o; 03726 } 03727 03728 function _seek($row) 03729 { 03730 if (sizeof($this->_array) && 0 <= $row && $row < $this->_numOfRows) { 03731 $this->_currentRow = $row; 03732 if ($this->_skiprow1) $row += 1; 03733 $this->fields = $this->_array[$row]; 03734 return true; 03735 } 03736 return false; 03737 } 03738 03739 function MoveNext() 03740 { 03741 if (!$this->EOF) { 03742 $this->_currentRow++; 03743 03744 $pos = $this->_currentRow; 03745 03746 if ($this->_numOfRows <= $pos) { 03747 if (!$this->compat) $this->fields = false; 03748 } else { 03749 if ($this->_skiprow1) $pos += 1; 03750 $this->fields = $this->_array[$pos]; 03751 return true; 03752 } 03753 $this->EOF = true; 03754 } 03755 03756 return false; 03757 } 03758 03759 function _fetch() 03760 { 03761 $pos = $this->_currentRow; 03762 03763 if ($this->_numOfRows <= $pos) { 03764 if (!$this->compat) $this->fields = false; 03765 return false; 03766 } 03767 if ($this->_skiprow1) $pos += 1; 03768 $this->fields = $this->_array[$pos]; 03769 return true; 03770 } 03771 03772 function _close() 03773 { 03774 return true; 03775 } 03776 03777 } // ADORecordSet_array 03778 03779 //============================================================================================== 03780 // HELPER FUNCTIONS 03781 //============================================================================================== 03782 03788 function ADOLoadDB($dbType) 03789 { 03790 return ADOLoadCode($dbType); 03791 } 03792 03796 function ADOLoadCode($dbType) 03797 { 03798 global $ADODB_LASTDB; 03799 03800 if (!$dbType) return false; 03801 $db = strtolower($dbType); 03802 switch ($db) { 03803 case 'ado': 03804 if (PHP_VERSION >= 5) $db = 'ado5'; 03805 $class = 'ado'; 03806 break; 03807 case 'ifx': 03808 case 'maxsql': $class = $db = 'mysqlt'; break; 03809 case 'postgres': 03810 case 'postgres8': 03811 case 'pgsql': $class = $db = 'postgres7'; break; 03812 default: 03813 $class = $db; break; 03814 } 03815 03816 $file = ADODB_DIR."/drivers/adodb-".$db.".inc.php"; 03817 @include_once($file); 03818 $ADODB_LASTDB = $class; 03819 if (class_exists("ADODB_" . $class)) return $class; 03820 03821 //ADOConnection::outp(adodb_pr(get_declared_classes(),true)); 03822 if (!file_exists($file)) ADOConnection::outp("Missing file: $file"); 03823 else ADOConnection::outp("Syntax error in file: $file"); 03824 return false; 03825 } 03826 03830 function &NewADOConnection($db='') 03831 { 03832 $tmp =& ADONewConnection($db); 03833 return $tmp; 03834 } 03835 03844 function &ADONewConnection($db='') 03845 { 03846 GLOBAL $ADODB_NEWCONNECTION, $ADODB_LASTDB; 03847 03848 if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2); 03849 $errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false; 03850 $false = false; 03851 if ($at = strpos($db,'://')) { 03852 $origdsn = $db; 03853 if (PHP_VERSION < 5) $dsna = @parse_url($db); 03854 else { 03855 $fakedsn = 'fake'.substr($db,$at); 03856 $dsna = @parse_url($fakedsn); 03857 $dsna['scheme'] = substr($db,0,$at); 03858 03859 if (strncmp($db,'pdo',3) == 0) { 03860 $sch = explode('_',$dsna['scheme']); 03861 if (sizeof($sch)>1) { 03862 $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; 03863 $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host'])); 03864 $dsna['scheme'] = 'pdo'; 03865 } 03866 } 03867 } 03868 03869 if (!$dsna) { 03870 // special handling of oracle, which might not have host 03871 $db = str_replace('@/','@adodb-fakehost/',$db); 03872 $dsna = parse_url($db); 03873 if (!$dsna) return $false; 03874 $dsna['host'] = ''; 03875 } 03876 $db = @$dsna['scheme']; 03877 if (!$db) return $false; 03878 $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; 03879 $dsna['user'] = isset($dsna['user']) ? rawurldecode($dsna['user']) : ''; 03880 $dsna['pass'] = isset($dsna['pass']) ? rawurldecode($dsna['pass']) : ''; 03881 $dsna['path'] = isset($dsna['path']) ? rawurldecode(substr($dsna['path'],1)) : ''; # strip off initial / 03882 03883 if (isset($dsna['query'])) { 03884 $opt1 = explode('&',$dsna['query']); 03885 foreach($opt1 as $k => $v) { 03886 $arr = explode('=',$v); 03887 $opt[$arr[0]] = isset($arr[1]) ? rawurldecode($arr[1]) : 1; 03888 } 03889 } else $opt = array(); 03890 } 03891 /* 03892 * phptype: Database backend used in PHP (mysql, odbc etc.) 03893 * dbsyntax: Database used with regards to SQL syntax etc. 03894 * protocol: Communication protocol to use (tcp, unix etc.) 03895 * hostspec: Host specification (hostname[:port]) 03896 * database: Database to use on the DBMS server 03897 * username: User name for login 03898 * password: Password for login 03899 */ 03900 if (!empty($ADODB_NEWCONNECTION)) { 03901 $obj = $ADODB_NEWCONNECTION($db); 03902 03903 } else { 03904 03905 if (!isset($ADODB_LASTDB)) $ADODB_LASTDB = ''; 03906 if (empty($db)) $db = $ADODB_LASTDB; 03907 03908 if ($db != $ADODB_LASTDB) $db = ADOLoadCode($db); 03909 03910 if (!$db) { 03911 if (isset($origdsn)) $db = $origdsn; 03912 if ($errorfn) { 03913 // raise an error 03914 $ignore = false; 03915 $errorfn('ADONewConnection', 'ADONewConnection', -998, 03916 "could not load the database driver for '$db'", 03917 $db,false,$ignore); 03918 } else 03919 ADOConnection::outp( "<p>ADONewConnection: Unable to load database driver '$db'</p>",false); 03920 03921 return $false; 03922 } 03923 03924 $cls = 'ADODB_'.$db; 03925 if (!class_exists($cls)) { 03926 adodb_backtrace(); 03927 return $false; 03928 } 03929 03930 $obj = new $cls(); 03931 } 03932 03933 # constructor should not fail 03934 if ($obj) { 03935 if ($errorfn) $obj->raiseErrorFn = $errorfn; 03936 if (isset($dsna)) { 03937 if (isset($dsna['port'])) $obj->port = $dsna['port']; 03938 foreach($opt as $k => $v) { 03939 switch(strtolower($k)) { 03940 case 'new': 03941 $nconnect = true; $persist = true; break; 03942 case 'persist': 03943 case 'persistent': $persist = $v; break; 03944 case 'debug': $obj->debug = (integer) $v; break; 03945 #ibase 03946 case 'role': $obj->role = $v; break; 03947 case 'dialect': $obj->dialect = (integer) $v; break; 03948 case 'charset': $obj->charset = $v; $obj->charSet=$v; break; 03949 case 'buffers': $obj->buffers = $v; break; 03950 case 'fetchmode': $obj->SetFetchMode($v); break; 03951 #ado 03952 case 'charpage': $obj->charPage = $v; break; 03953 #mysql, mysqli 03954 case 'clientflags': $obj->clientFlags = $v; break; 03955 #mysql, mysqli, postgres 03956 case 'port': $obj->port = $v; break; 03957 #mysqli 03958 case 'socket': $obj->socket = $v; break; 03959 #oci8 03960 case 'nls_date_format': $obj->NLS_DATE_FORMAT = $v; break; 03961 } 03962 } 03963 if (empty($persist)) 03964 $ok = $obj->Connect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']); 03965 else if (empty($nconnect)) 03966 $ok = $obj->PConnect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']); 03967 else 03968 $ok = $obj->NConnect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']); 03969 03970 if (!$ok) return $false; 03971 } 03972 } 03973 return $obj; 03974 } 03975 03976 03977 03978 // $perf == true means called by NewPerfMonitor(), otherwise for data dictionary 03979 function _adodb_getdriver($provider,$drivername,$perf=false) 03980 { 03981 switch ($provider) { 03982 case 'odbtp': if (strncmp('odbtp_',$drivername,6)==0) return substr($drivername,6); 03983 case 'odbc' : if (strncmp('odbc_',$drivername,5)==0) return substr($drivername,5); 03984 case 'ado' : if (strncmp('ado_',$drivername,4)==0) return substr($drivername,4); 03985 case 'native': break; 03986 default: 03987 return $provider; 03988 } 03989 03990 switch($drivername) { 03991 case 'mysqlt': 03992 case 'mysqli': 03993 $drivername='mysql'; 03994 break; 03995 case 'postgres7': 03996 case 'postgres8': 03997 $drivername = 'postgres'; 03998 break; 03999 case 'firebird15': $drivername = 'firebird'; break; 04000 case 'oracle': $drivername = 'oci8'; break; 04001 case 'access': if ($perf) $drivername = ''; break; 04002 case 'db2' : break; 04003 case 'sapdb' : break; 04004 default: 04005 $drivername = 'generic'; 04006 break; 04007 } 04008 return $drivername; 04009 } 04010 04011 function &NewPerfMonitor(&$conn) 04012 { 04013 $false = false; 04014 $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType,true); 04015 if (!$drivername || $drivername == 'generic') return $false; 04016 include_once(ADODB_DIR.'/adodb-perf.inc.php'); 04017 @include_once(ADODB_DIR."/perf/perf-$drivername.inc.php"); 04018 $class = "Perf_$drivername"; 04019 if (!class_exists($class)) return $false; 04020 $perf = new $class($conn); 04021 04022 return $perf; 04023 } 04024 04025 function &NewDataDictionary(&$conn,$drivername=false) 04026 { 04027 $false = false; 04028 if (!$drivername) $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType); 04029 04030 include_once(ADODB_DIR.'/adodb-lib.inc.php'); 04031 include_once(ADODB_DIR.'/adodb-datadict.inc.php'); 04032 $path = ADODB_DIR."/datadict/datadict-$drivername.inc.php"; 04033 04034 if (!file_exists($path)) { 04035 ADOConnection::outp("Dictionary driver '$path' not available"); 04036 return $false; 04037 } 04038 include_once($path); 04039 $class = "ADODB2_$drivername"; 04040 $dict = new $class(); 04041 $dict->dataProvider = $conn->dataProvider; 04042 $dict->connection = &$conn; 04043 $dict->upperName = strtoupper($drivername); 04044 $dict->quote = $conn->nameQuote; 04045 if (!empty($conn->_connectionID)) 04046 $dict->serverInfo = $conn->ServerInfo(); 04047 04048 return $dict; 04049 } 04050 04051 04052 04053 /* 04054 Perform a print_r, with pre tags for better formatting. 04055 */ 04056 function adodb_pr($var,$as_string=false) 04057 { 04058 if ($as_string) ob_start(); 04059 04060 if (isset($_SERVER['HTTP_USER_AGENT'])) { 04061 echo " <pre>\n";print_r($var);echo "</pre>\n"; 04062 } else 04063 print_r($var); 04064 04065 if ($as_string) { 04066 $s = ob_get_contents(); 04067 ob_end_clean(); 04068 return $s; 04069 } 04070 } 04071 04072 /* 04073 Perform a stack-crawl and pretty print it. 04074 04075 @param printOrArr Pass in a boolean to indicate print, or an $exception->trace array (assumes that print is true then). 04076 @param levels Number of levels to display 04077 */ 04078 function adodb_backtrace($printOrArr=true,$levels=9999) 04079 { 04080 global $ADODB_INCLUDED_LIB; 04081 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 04082 return _adodb_backtrace($printOrArr,$levels); 04083 } 04084 04085 04086 } 04087 ?>