Documentation TYPO3 par Ameos |
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.2) { 00114 define('ADODB_PHPVER',0x5200); 00115 } else if ($_adodb_ver >= 5.0) { 00116 define('ADODB_PHPVER',0x5000); 00117 } else if ($_adodb_ver > 4.299999) { # 4.3 00118 define('ADODB_PHPVER',0x4300); 00119 } else if ($_adodb_ver > 4.199999) { # 4.2 00120 define('ADODB_PHPVER',0x4200); 00121 } else if (strnatcmp(PHP_VERSION,'4.0.5')>=0) { 00122 define('ADODB_PHPVER',0x4050); 00123 } else { 00124 define('ADODB_PHPVER',0x4000); 00125 } 00126 } 00127 00128 //if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2); 00129 00130 00134 function ADODB_str_replace($src, $dest, $data) 00135 { 00136 if (ADODB_PHPVER >= 0x4050) return str_replace($src,$dest,$data); 00137 00138 $s = reset($src); 00139 $d = reset($dest); 00140 while ($s !== false) { 00141 $data = str_replace($s,$d,$data); 00142 $s = next($src); 00143 $d = next($dest); 00144 } 00145 return $data; 00146 } 00147 00148 function ADODB_Setup() 00149 { 00150 GLOBAL 00151 $ADODB_vers, // database version 00152 $ADODB_COUNTRECS, // count number of records returned - slows down query 00153 $ADODB_CACHE_DIR, // directory to cache recordsets 00154 $ADODB_FETCH_MODE, 00155 $ADODB_FORCE_TYPE; 00156 00157 $ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT; 00158 $ADODB_FORCE_TYPE = ADODB_FORCE_VALUE; 00159 00160 00161 if (!isset($ADODB_CACHE_DIR)) { 00162 $ADODB_CACHE_DIR = '/tmp'; //(isset($_ENV['TMP'])) ? $_ENV['TMP'] : '/tmp'; 00163 } else { 00164 // do not accept url based paths, eg. http:/ or ftp:/ 00165 if (strpos($ADODB_CACHE_DIR,'://') !== false) 00166 die("Illegal path http:// or ftp://"); 00167 } 00168 00169 00170 // Initialize random number generator for randomizing cache flushes 00171 // -- note Since PHP 4.2.0, the seed becomes optional and defaults to a random value if omitted. 00172 srand(((double)microtime())*1000000); 00173 00177 $ADODB_vers = 'V4.93 10 Oct 2006 (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.'; 00178 00184 if (!isset($ADODB_COUNTRECS)) $ADODB_COUNTRECS = true; 00185 } 00186 00187 00188 //============================================================================================== 00189 // CHANGE NOTHING BELOW UNLESS YOU ARE DESIGNING ADODB 00190 //============================================================================================== 00191 00192 ADODB_Setup(); 00193 00194 //============================================================================================== 00195 // CLASS ADOFieldObject 00196 //============================================================================================== 00200 class ADOFieldObject { 00201 var $name = ''; 00202 var $max_length=0; 00203 var $type=""; 00204 /* 00205 // additional fields by dannym... (danny_milo@yahoo.com) 00206 var $not_null = false; 00207 // actually, this has already been built-in in the postgres, fbsql AND mysql module? ^-^ 00208 // so we can as well make not_null standard (leaving it at "false" does not harm anyways) 00209 00210 var $has_default = false; // this one I have done only in mysql and postgres for now ... 00211 // others to come (dannym) 00212 var $default_value; // default, if any, and supported. Check has_default first. 00213 */ 00214 } 00215 00216 00217 00218 function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) 00219 { 00220 //print "Errorno ($fn errno=$errno m=$errmsg) "; 00221 $thisConnection->_transOK = false; 00222 if ($thisConnection->_oldRaiseFn) { 00223 $fn = $thisConnection->_oldRaiseFn; 00224 $fn($dbms, $fn, $errno, $errmsg, $p1, $p2,$thisConnection); 00225 } 00226 } 00227 00228 //============================================================================================== 00229 // CLASS ADOConnection 00230 //============================================================================================== 00231 00235 class ADOConnection { 00236 // 00237 // PUBLIC VARS 00238 // 00239 var $dataProvider = 'native'; 00240 var $databaseType = ''; 00241 var $database = ''; 00242 var $host = ''; 00243 var $user = ''; 00244 var $password = ''; 00245 var $debug = false; 00246 var $maxblobsize = 262144; 00247 var $concat_operator = '+'; 00248 var $substr = 'substr'; 00249 var $length = 'length'; 00250 var $random = 'rand()'; 00251 var $upperCase = 'upper'; 00252 var $fmtDate = "'Y-m-d'"; 00253 var $fmtTimeStamp = "'Y-m-d, h:i:s A'"; 00254 var $true = '1'; 00255 var $false = '0'; 00256 var $replaceQuote = "\\'"; 00257 var $nameQuote = '"'; 00258 var $charSet=false; 00259 var $metaDatabasesSQL = ''; 00260 var $metaTablesSQL = ''; 00261 var $uniqueOrderBy = false; 00262 var $emptyDate = ' '; 00263 var $emptyTimeStamp = ' '; 00264 var $lastInsID = false; 00265 //-- 00266 var $hasInsertID = false; 00267 var $hasAffectedRows = false; 00268 var $hasTop = false; 00269 var $hasLimit = false; 00270 var $readOnly = false; 00271 var $hasMoveFirst = false; 00272 var $hasGenID = false; 00273 var $hasTransactions = true; 00274 //-- 00275 var $genID = 0; 00276 var $raiseErrorFn = false; 00277 var $isoDates = false; 00278 var $cacheSecs = 3600; 00279 00280 // memcache 00281 var $memCache = false; 00282 var $memCacheHost; 00283 var $memCachePort = 11211; 00284 var $memCacheCompress = false; 00285 00286 var $sysDate = false; 00287 var $sysTimeStamp = false; 00288 var $arrayClass = 'ADORecordSet_array'; 00289 00290 var $noNullStrings = false; 00291 var $numCacheHits = 0; 00292 var $numCacheMisses = 0; 00293 var $pageExecuteCountRows = true; 00294 var $uniqueSort = false; 00295 var $leftOuter = false; 00296 var $rightOuter = false; 00297 var $ansiOuter = false; 00298 var $autoRollback = false; // autoRollback on PConnect(). 00299 var $poorAffectedRows = false; // affectedRows not working or unreliable 00300 00301 var $fnExecute = false; 00302 var $fnCacheExecute = false; 00303 var $blobEncodeType = false; // false=not required, 'I'=encode to integer, 'C'=encode to char 00304 var $rsPrefix = "ADORecordSet_"; 00305 00306 var $autoCommit = true; 00307 var $transOff = 0; 00308 var $transCnt = 0; 00309 00310 var $fetchMode=false; 00311 00312 var $null2null = 'null'; // in autoexecute/getinsertsql/getupdatesql, this value will be converted to a null 00313 // 00314 // PRIVATE VARS 00315 // 00316 var $_oldRaiseFn = false; 00317 var $_transOK = null; 00318 var $_connectionID = false; 00319 var $_errorMsg = false; 00320 00321 var $_errorCode = false; 00322 var $_queryID = false; 00323 00324 var $_isPersistentConnection = false; 00325 var $_bindInputArray = false; 00326 var $_evalAll = false; 00327 var $_affected = false; 00328 var $_logsql = false; 00329 var $_transmode = ''; // transaction mode 00330 00331 00332 00336 function ADOConnection() 00337 { 00338 die('Virtual Class -- cannot instantiate'); 00339 } 00340 00341 function Version() 00342 { 00343 global $ADODB_vers; 00344 00345 return (float) substr($ADODB_vers,1); 00346 } 00347 00354 function ServerInfo() 00355 { 00356 return array('description' => '', 'version' => ''); 00357 } 00358 00359 function IsConnected() 00360 { 00361 return !empty($this->_connectionID); 00362 } 00363 00364 function _findvers($str) 00365 { 00366 if (preg_match('/([0-9]+\.([0-9\.])+)/',$str, $arr)) return $arr[1]; 00367 else return ''; 00368 } 00369 00374 function outp($msg,$newline=true) 00375 { 00376 global $ADODB_FLUSH,$ADODB_OUTP; 00377 00378 if (defined('ADODB_OUTP')) { 00379 $fn = ADODB_OUTP; 00380 $fn($msg,$newline); 00381 return; 00382 } else if (isset($ADODB_OUTP)) { 00383 $fn = $ADODB_OUTP; 00384 $fn($msg,$newline); 00385 return; 00386 } 00387 00388 if ($newline) $msg .= "<br>\n"; 00389 00390 if (isset($_SERVER['HTTP_USER_AGENT']) || !$newline) echo $msg; 00391 else echo strip_tags($msg); 00392 00393 00394 if (!empty($ADODB_FLUSH) && ob_get_length() !== false) flush(); // do not flush if output buffering enabled - useless - thx to Jesse Mullan 00395 00396 } 00397 00398 function Time() 00399 { 00400 $rs =& $this->_Execute("select $this->sysTimeStamp"); 00401 if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields)); 00402 00403 return false; 00404 } 00405 00417 function Connect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "", $forceNew = false) 00418 { 00419 if ($argHostname != "") $this->host = $argHostname; 00420 if ($argUsername != "") $this->user = $argUsername; 00421 if ($argPassword != "") $this->password = $argPassword; // not stored for security reasons 00422 if ($argDatabaseName != "") $this->database = $argDatabaseName; 00423 00424 $this->_isPersistentConnection = false; 00425 if ($forceNew) { 00426 if ($rez=$this->_nconnect($this->host, $this->user, $this->password, $this->database)) return true; 00427 } else { 00428 if ($rez=$this->_connect($this->host, $this->user, $this->password, $this->database)) return true; 00429 } 00430 if (isset($rez)) { 00431 $err = $this->ErrorMsg(); 00432 if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'"; 00433 $ret = false; 00434 } else { 00435 $err = "Missing extension for ".$this->dataProvider; 00436 $ret = 0; 00437 } 00438 if ($fn = $this->raiseErrorFn) 00439 $fn($this->databaseType,'CONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this); 00440 00441 00442 $this->_connectionID = false; 00443 if ($this->debug) ADOConnection::outp( $this->host.': '.$err); 00444 return $ret; 00445 } 00446 00447 function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName) 00448 { 00449 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName); 00450 } 00451 00452 00463 function NConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") 00464 { 00465 return $this->Connect($argHostname, $argUsername, $argPassword, $argDatabaseName, true); 00466 } 00467 00478 function PConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") 00479 { 00480 if (defined('ADODB_NEVER_PERSIST')) 00481 return $this->Connect($argHostname,$argUsername,$argPassword,$argDatabaseName); 00482 00483 if ($argHostname != "") $this->host = $argHostname; 00484 if ($argUsername != "") $this->user = $argUsername; 00485 if ($argPassword != "") $this->password = $argPassword; 00486 if ($argDatabaseName != "") $this->database = $argDatabaseName; 00487 00488 $this->_isPersistentConnection = true; 00489 if ($rez = $this->_pconnect($this->host, $this->user, $this->password, $this->database)) return true; 00490 if (isset($rez)) { 00491 $err = $this->ErrorMsg(); 00492 if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'"; 00493 $ret = false; 00494 } else { 00495 $err = "Missing extension for ".$this->dataProvider; 00496 $ret = 0; 00497 } 00498 if ($fn = $this->raiseErrorFn) { 00499 $fn($this->databaseType,'PCONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this); 00500 } 00501 00502 $this->_connectionID = false; 00503 if ($this->debug) ADOConnection::outp( $this->host.': '.$err); 00504 return $ret; 00505 } 00506 00507 // Format date column in sql string given an input format that understands Y M D 00508 function SQLDate($fmt, $col=false) 00509 { 00510 if (!$col) $col = $this->sysDate; 00511 return $col; // child class implement 00512 } 00513 00529 function Prepare($sql) 00530 { 00531 return $sql; 00532 } 00533 00548 function PrepareSP($sql,$param=true) 00549 { 00550 return $this->Prepare($sql,$param); 00551 } 00552 00556 function Quote($s) 00557 { 00558 return $this->qstr($s,false); 00559 } 00560 00564 function QMagic($s) 00565 { 00566 return $this->qstr($s,get_magic_quotes_gpc()); 00567 } 00568 00569 function q(&$s) 00570 { 00571 #if (!empty($this->qNull)) if ($s == 'null') return $s; 00572 $s = $this->qstr($s,false); 00573 } 00574 00578 function ErrorNative() 00579 { 00580 return $this->ErrorNo(); 00581 } 00582 00583 00587 function nextId($seq_name) 00588 { 00589 return $this->GenID($seq_name); 00590 } 00591 00599 function RowLock($table,$where) 00600 { 00601 return false; 00602 } 00603 00604 function CommitLock($table) 00605 { 00606 return $this->CommitTrans(); 00607 } 00608 00609 function RollbackLock($table) 00610 { 00611 return $this->RollbackTrans(); 00612 } 00613 00623 function SetFetchMode($mode) 00624 { 00625 $old = $this->fetchMode; 00626 $this->fetchMode = $mode; 00627 00628 if ($old === false) { 00629 global $ADODB_FETCH_MODE; 00630 return $ADODB_FETCH_MODE; 00631 } 00632 return $old; 00633 } 00634 00635 00639 function &Query($sql, $inputarr=false) 00640 { 00641 $rs = &$this->Execute($sql, $inputarr); 00642 if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error(); 00643 return $rs; 00644 } 00645 00646 00650 function &LimitQuery($sql, $offset, $count, $params=false) 00651 { 00652 $rs = &$this->SelectLimit($sql, $count, $offset, $params); 00653 if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error(); 00654 return $rs; 00655 } 00656 00657 00661 function Disconnect() 00662 { 00663 return $this->Close(); 00664 } 00665 00666 /* 00667 Returns placeholder for parameter, eg. 00668 $DB->Param('a') 00669 00670 will return ':a' for Oracle, and '?' for most other databases... 00671 00672 For databases that require positioned params, eg $1, $2, $3 for postgresql, 00673 pass in Param(false) before setting the first parameter. 00674 */ 00675 function Param($name,$type='C') 00676 { 00677 return '?'; 00678 } 00679 00680 /* 00681 InParameter and OutParameter are self-documenting versions of Parameter(). 00682 */ 00683 function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) 00684 { 00685 return $this->Parameter($stmt,$var,$name,false,$maxLen,$type); 00686 } 00687 00688 /* 00689 */ 00690 function OutParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) 00691 { 00692 return $this->Parameter($stmt,$var,$name,true,$maxLen,$type); 00693 00694 } 00695 00696 00697 /* 00698 Usage in oracle 00699 $stmt = $db->Prepare('select * from table where id =:myid and group=:group'); 00700 $db->Parameter($stmt,$id,'myid'); 00701 $db->Parameter($stmt,$group,'group',64); 00702 $db->Execute(); 00703 00704 @param $stmt Statement returned by Prepare() or PrepareSP(). 00705 @param $var PHP variable to bind to 00706 @param $name Name of stored procedure variable name to bind to. 00707 @param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8. 00708 @param [$maxLen] Holds an maximum length of the variable. 00709 @param [$type] The data type of $var. Legal values depend on driver. 00710 00711 */ 00712 function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false) 00713 { 00714 return false; 00715 } 00716 00717 00718 function IgnoreErrors($saveErrs=false) 00719 { 00720 if (!$saveErrs) { 00721 $saveErrs = array($this->raiseErrorFn,$this->_transOK); 00722 $this->raiseErrorFn = false; 00723 return $saveErrs; 00724 } else { 00725 $this->raiseErrorFn = $saveErrs[0]; 00726 $this->_transOK = $saveErrs[1]; 00727 } 00728 } 00729 00740 function StartTrans($errfn = 'ADODB_TransMonitor') 00741 { 00742 if ($this->transOff > 0) { 00743 $this->transOff += 1; 00744 return; 00745 } 00746 00747 $this->_oldRaiseFn = $this->raiseErrorFn; 00748 $this->raiseErrorFn = $errfn; 00749 $this->_transOK = true; 00750 00751 if ($this->debug && $this->transCnt > 0) ADOConnection::outp("Bad Transaction: StartTrans called within BeginTrans"); 00752 $this->BeginTrans(); 00753 $this->transOff = 1; 00754 } 00755 00756 00765 function CompleteTrans($autoComplete = true) 00766 { 00767 if ($this->transOff > 1) { 00768 $this->transOff -= 1; 00769 return true; 00770 } 00771 $this->raiseErrorFn = $this->_oldRaiseFn; 00772 00773 $this->transOff = 0; 00774 if ($this->_transOK && $autoComplete) { 00775 if (!$this->CommitTrans()) { 00776 $this->_transOK = false; 00777 if ($this->debug) ADOConnection::outp("Smart Commit failed"); 00778 } else 00779 if ($this->debug) ADOConnection::outp("Smart Commit occurred"); 00780 } else { 00781 $this->_transOK = false; 00782 $this->RollbackTrans(); 00783 if ($this->debug) ADOCOnnection::outp("Smart Rollback occurred"); 00784 } 00785 00786 return $this->_transOK; 00787 } 00788 00789 /* 00790 At the end of a StartTrans/CompleteTrans block, perform a rollback. 00791 */ 00792 function FailTrans() 00793 { 00794 if ($this->debug) 00795 if ($this->transOff == 0) { 00796 ADOConnection::outp("FailTrans outside StartTrans/CompleteTrans"); 00797 } else { 00798 ADOConnection::outp("FailTrans was called"); 00799 adodb_backtrace(); 00800 } 00801 $this->_transOK = false; 00802 } 00803 00807 function HasFailedTrans() 00808 { 00809 if ($this->transOff > 0) return $this->_transOK == false; 00810 return false; 00811 } 00812 00820 function &Execute($sql,$inputarr=false) 00821 { 00822 if ($this->fnExecute) { 00823 $fn = $this->fnExecute; 00824 $ret =& $fn($this,$sql,$inputarr); 00825 if (isset($ret)) return $ret; 00826 } 00827 if ($inputarr) { 00828 if (!is_array($inputarr)) $inputarr = array($inputarr); 00829 00830 $element0 = reset($inputarr); 00831 # is_object check because oci8 descriptors can be passed in 00832 $array_2d = is_array($element0) && !is_object(reset($element0)); 00833 //remove extra memory copy of input -mikefedyk 00834 unset($element0); 00835 00836 if (!is_array($sql) && !$this->_bindInputArray) { 00837 $sqlarr = explode('?',$sql); 00838 00839 if (!$array_2d) $inputarr = array($inputarr); 00840 foreach($inputarr as $arr) { 00841 $sql = ''; $i = 0; 00842 //Use each() instead of foreach to reduce memory usage -mikefedyk 00843 while(list(, $v) = each($arr)) { 00844 $sql .= $sqlarr[$i]; 00845 // from Ron Baldwin <ron.baldwin#sourceprose.com> 00846 // Only quote string types 00847 $typ = gettype($v); 00848 if ($typ == 'string') 00849 //New memory copy of input created here -mikefedyk 00850 $sql .= $this->qstr($v); 00851 else if ($typ == 'double') 00852 $sql .= str_replace(',','.',$v); // locales fix so 1.1 does not get converted to 1,1 00853 else if ($typ == 'boolean') 00854 $sql .= $v ? $this->true : $this->false; 00855 else if ($typ == 'object') { 00856 if (method_exists($v, '__toString')) $sql .= $this->qstr($v->__toString()); 00857 else $sql .= $this->qstr((string) $v); 00858 } else if ($v === null) 00859 $sql .= 'NULL'; 00860 else 00861 $sql .= $v; 00862 $i += 1; 00863 } 00864 if (isset($sqlarr[$i])) { 00865 $sql .= $sqlarr[$i]; 00866 if ($i+1 != sizeof($sqlarr)) ADOConnection::outp( "Input Array does not match ?: ".htmlspecialchars($sql)); 00867 } else if ($i != sizeof($sqlarr)) 00868 ADOConnection::outp( "Input array does not match ?: ".htmlspecialchars($sql)); 00869 00870 $ret =& $this->_Execute($sql); 00871 if (!$ret) return $ret; 00872 } 00873 } else { 00874 if ($array_2d) { 00875 if (is_string($sql)) 00876 $stmt = $this->Prepare($sql); 00877 else 00878 $stmt = $sql; 00879 00880 foreach($inputarr as $arr) { 00881 $ret =& $this->_Execute($stmt,$arr); 00882 if (!$ret) return $ret; 00883 } 00884 } else { 00885 $ret =& $this->_Execute($sql,$inputarr); 00886 } 00887 } 00888 } else { 00889 $ret =& $this->_Execute($sql,false); 00890 } 00891 00892 return $ret; 00893 } 00894 00895 00896 function &_Execute($sql,$inputarr=false) 00897 { 00898 if ($this->debug) { 00899 global $ADODB_INCLUDED_LIB; 00900 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 00901 $this->_queryID = _adodb_debug_execute($this, $sql,$inputarr); 00902 } else { 00903 $this->_queryID = @$this->_query($sql,$inputarr); 00904 } 00905 00906 /************************ 00907 // OK, query executed 00908 *************************/ 00909 00910 if ($this->_queryID === false) { // error handling if query fails 00911 if ($this->debug == 99) adodb_backtrace(true,5); 00912 $fn = $this->raiseErrorFn; 00913 if ($fn) { 00914 $fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,$inputarr,$this); 00915 } 00916 $false = false; 00917 return $false; 00918 } 00919 00920 if ($this->_queryID === true) { // return simplified recordset for inserts/updates/deletes with lower overhead 00921 $rs =& new ADORecordSet_empty(); 00922 return $rs; 00923 } 00924 00925 // return real recordset from select statement 00926 $rsclass = $this->rsPrefix.$this->databaseType; 00927 $rs = new $rsclass($this->_queryID,$this->fetchMode); 00928 $rs->connection = &$this; // Pablo suggestion 00929 $rs->Init(); 00930 if (is_array($sql)) $rs->sql = $sql[0]; 00931 else $rs->sql = $sql; 00932 if ($rs->_numOfRows <= 0) { 00933 global $ADODB_COUNTRECS; 00934 if ($ADODB_COUNTRECS) { 00935 if (!$rs->EOF) { 00936 $rs = &$this->_rs2rs($rs,-1,-1,!is_array($sql)); 00937 $rs->_queryID = $this->_queryID; 00938 } else 00939 $rs->_numOfRows = 0; 00940 } 00941 } 00942 return $rs; 00943 } 00944 00945 function CreateSequence($seqname='adodbseq',$startID=1) 00946 { 00947 if (empty($this->_genSeqSQL)) return false; 00948 return $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID)); 00949 } 00950 00951 function DropSequence($seqname='adodbseq') 00952 { 00953 if (empty($this->_dropSeqSQL)) return false; 00954 return $this->Execute(sprintf($this->_dropSeqSQL,$seqname)); 00955 } 00956 00965 function GenID($seqname='adodbseq',$startID=1) 00966 { 00967 if (!$this->hasGenID) { 00968 return 0; // formerly returns false pre 1.60 00969 } 00970 00971 $getnext = sprintf($this->_genIDSQL,$seqname); 00972 00973 $holdtransOK = $this->_transOK; 00974 00975 $save_handler = $this->raiseErrorFn; 00976 $this->raiseErrorFn = ''; 00977 @($rs = $this->Execute($getnext)); 00978 $this->raiseErrorFn = $save_handler; 00979 00980 if (!$rs) { 00981 $this->_transOK = $holdtransOK; //if the status was ok before reset 00982 $createseq = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID)); 00983 $rs = $this->Execute($getnext); 00984 } 00985 if ($rs && !$rs->EOF) $this->genID = reset($rs->fields); 00986 else $this->genID = 0; // false 00987 00988 if ($rs) $rs->Close(); 00989 00990 return $this->genID; 00991 } 00992 00998 function Insert_ID($table='',$column='') 00999 { 01000 if ($this->_logsql && $this->lastInsID) return $this->lastInsID; 01001 if ($this->hasInsertID) return $this->_insertid($table,$column); 01002 if ($this->debug) { 01003 ADOConnection::outp( '<p>Insert_ID error</p>'); 01004 adodb_backtrace(); 01005 } 01006 return false; 01007 } 01008 01009 01016 function PO_Insert_ID($table="", $id="") 01017 { 01018 if ($this->hasInsertID){ 01019 return $this->Insert_ID($table,$id); 01020 } else { 01021 return $this->GetOne("SELECT MAX($id) FROM $table"); 01022 } 01023 } 01024 01028 function Affected_Rows() 01029 { 01030 if ($this->hasAffectedRows) { 01031 if ($this->fnExecute === 'adodb_log_sql') { 01032 if ($this->_logsql && $this->_affected !== false) return $this->_affected; 01033 } 01034 $val = $this->_affectedrows(); 01035 return ($val < 0) ? false : $val; 01036 } 01037 01038 if ($this->debug) ADOConnection::outp( '<p>Affected_Rows error</p>',false); 01039 return false; 01040 } 01041 01042 01046 function ErrorMsg() 01047 { 01048 if ($this->_errorMsg) return '!! '.strtoupper($this->dataProvider.' '.$this->databaseType).': '.$this->_errorMsg; 01049 else return ''; 01050 } 01051 01052 01056 function ErrorNo() 01057 { 01058 return ($this->_errorMsg) ? -1 : 0; 01059 } 01060 01061 function MetaError($err=false) 01062 { 01063 include_once(ADODB_DIR."/adodb-error.inc.php"); 01064 if ($err === false) $err = $this->ErrorNo(); 01065 return adodb_error($this->dataProvider,$this->databaseType,$err); 01066 } 01067 01068 function MetaErrorMsg($errno) 01069 { 01070 include_once(ADODB_DIR."/adodb-error.inc.php"); 01071 return adodb_errormsg($errno); 01072 } 01073 01077 function MetaPrimaryKeys($table, $owner=false) 01078 { 01079 // owner not used in base class - see oci8 01080 $p = array(); 01081 $objs =& $this->MetaColumns($table); 01082 if ($objs) { 01083 foreach($objs as $v) { 01084 if (!empty($v->primary_key)) 01085 $p[] = $v->name; 01086 } 01087 } 01088 if (sizeof($p)) return $p; 01089 if (function_exists('ADODB_VIEW_PRIMARYKEYS')) 01090 return ADODB_VIEW_PRIMARYKEYS($this->databaseType, $this->database, $table, $owner); 01091 return false; 01092 } 01093 01097 function MetaForeignKeys($table, $owner=false, $upper=false) 01098 { 01099 return false; 01100 } 01107 function SelectDB($dbName) 01108 {return false;} 01109 01110 01130 function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0) 01131 { 01132 if ($this->hasTop && $nrows > 0) { 01133 // suggested by Reinhard Balling. Access requires top after distinct 01134 // Informix requires first before distinct - F Riosa 01135 $ismssql = (strpos($this->databaseType,'mssql') !== false); 01136 if ($ismssql) $isaccess = false; 01137 else $isaccess = (strpos($this->databaseType,'access') !== false); 01138 01139 if ($offset <= 0) { 01140 01141 // access includes ties in result 01142 if ($isaccess) { 01143 $sql = preg_replace( 01144 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); 01145 01146 if ($secs2cache != 0) { 01147 $ret =& $this->CacheExecute($secs2cache, $sql,$inputarr); 01148 } else { 01149 $ret =& $this->Execute($sql,$inputarr); 01150 } 01151 return $ret; // PHP5 fix 01152 } else if ($ismssql){ 01153 $sql = preg_replace( 01154 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); 01155 } else { 01156 $sql = preg_replace( 01157 '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); 01158 } 01159 } else { 01160 $nn = $nrows + $offset; 01161 if ($isaccess || $ismssql) { 01162 $sql = preg_replace( 01163 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.$nn.' ',$sql); 01164 } else { 01165 $sql = preg_replace( 01166 '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.$nn.' ',$sql); 01167 } 01168 } 01169 } 01170 01171 // if $offset>0, we want to skip rows, and $ADODB_COUNTRECS is set, we buffer rows 01172 // 0 to offset-1 which will be discarded anyway. So we disable $ADODB_COUNTRECS. 01173 global $ADODB_COUNTRECS; 01174 01175 $savec = $ADODB_COUNTRECS; 01176 $ADODB_COUNTRECS = false; 01177 01178 if ($offset>0){ 01179 if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); 01180 else $rs = &$this->Execute($sql,$inputarr); 01181 } else { 01182 if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); 01183 else $rs = &$this->Execute($sql,$inputarr); 01184 } 01185 $ADODB_COUNTRECS = $savec; 01186 if ($rs && !$rs->EOF) { 01187 $rs =& $this->_rs2rs($rs,$nrows,$offset); 01188 } 01189 //print_r($rs); 01190 return $rs; 01191 } 01192 01198 function &SerializableRS(&$rs) 01199 { 01200 $rs2 =& $this->_rs2rs($rs); 01201 $ignore = false; 01202 $rs2->connection =& $ignore; 01203 01204 return $rs2; 01205 } 01206 01217 function &_rs2rs(&$rs,$nrows=-1,$offset=-1,$close=true) 01218 { 01219 if (! $rs) { 01220 $false = false; 01221 return $false; 01222 } 01223 $dbtype = $rs->databaseType; 01224 if (!$dbtype) { 01225 $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ? 01226 return $rs; 01227 } 01228 if (($dbtype == 'array' || $dbtype == 'csv') && $nrows == -1 && $offset == -1) { 01229 $rs->MoveFirst(); 01230 $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ? 01231 return $rs; 01232 } 01233 $flds = array(); 01234 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) { 01235 $flds[] = $rs->FetchField($i); 01236 } 01237 01238 $arr =& $rs->GetArrayLimit($nrows,$offset); 01239 //print_r($arr); 01240 if ($close) $rs->Close(); 01241 01242 $arrayClass = $this->arrayClass; 01243 01244 $rs2 = new $arrayClass(); 01245 $rs2->connection = &$this; 01246 $rs2->sql = $rs->sql; 01247 $rs2->dataProvider = $this->dataProvider; 01248 $rs2->InitArrayFields($arr,$flds); 01249 $rs2->fetchMode = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode; 01250 return $rs2; 01251 } 01252 01253 /* 01254 * Return all rows. Compat with PEAR DB 01255 */ 01256 function &GetAll($sql, $inputarr=false) 01257 { 01258 $arr =& $this->GetArray($sql,$inputarr); 01259 return $arr; 01260 } 01261 01262 function &GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false) 01263 { 01264 $rs =& $this->Execute($sql, $inputarr); 01265 if (!$rs) { 01266 $false = false; 01267 return $false; 01268 } 01269 $arr =& $rs->GetAssoc($force_array,$first2cols); 01270 return $arr; 01271 } 01272 01273 function &CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false) 01274 { 01275 if (!is_numeric($secs2cache)) { 01276 $first2cols = $force_array; 01277 $force_array = $inputarr; 01278 } 01279 $rs =& $this->CacheExecute($secs2cache, $sql, $inputarr); 01280 if (!$rs) { 01281 $false = false; 01282 return $false; 01283 } 01284 $arr =& $rs->GetAssoc($force_array,$first2cols); 01285 return $arr; 01286 } 01287 01295 function GetOne($sql,$inputarr=false) 01296 { 01297 global $ADODB_COUNTRECS; 01298 $crecs = $ADODB_COUNTRECS; 01299 $ADODB_COUNTRECS = false; 01300 01301 $ret = false; 01302 $rs = &$this->Execute($sql,$inputarr); 01303 if ($rs) { 01304 if (!$rs->EOF) $ret = reset($rs->fields); 01305 $rs->Close(); 01306 } 01307 $ADODB_COUNTRECS = $crecs; 01308 return $ret; 01309 } 01310 01311 function CacheGetOne($secs2cache,$sql=false,$inputarr=false) 01312 { 01313 $ret = false; 01314 $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); 01315 if ($rs) { 01316 if (!$rs->EOF) $ret = reset($rs->fields); 01317 $rs->Close(); 01318 } 01319 01320 return $ret; 01321 } 01322 01323 function GetCol($sql, $inputarr = false, $trim = false) 01324 { 01325 $rv = false; 01326 $rs = &$this->Execute($sql, $inputarr); 01327 if ($rs) { 01328 $rv = array(); 01329 if ($trim) { 01330 while (!$rs->EOF) { 01331 $rv[] = trim(reset($rs->fields)); 01332 $rs->MoveNext(); 01333 } 01334 } else { 01335 while (!$rs->EOF) { 01336 $rv[] = reset($rs->fields); 01337 $rs->MoveNext(); 01338 } 01339 } 01340 $rs->Close(); 01341 } 01342 return $rv; 01343 } 01344 01345 function CacheGetCol($secs, $sql = false, $inputarr = false,$trim=false) 01346 { 01347 $rv = false; 01348 $rs = &$this->CacheExecute($secs, $sql, $inputarr); 01349 if ($rs) { 01350 if ($trim) { 01351 while (!$rs->EOF) { 01352 $rv[] = trim(reset($rs->fields)); 01353 $rs->MoveNext(); 01354 } 01355 } else { 01356 while (!$rs->EOF) { 01357 $rv[] = reset($rs->fields); 01358 $rs->MoveNext(); 01359 } 01360 } 01361 $rs->Close(); 01362 } 01363 return $rv; 01364 } 01365 01366 function &Transpose(&$rs) 01367 { 01368 $rs2 =& $this->_rs2rs($rs); 01369 $false = false; 01370 if (!$rs2) return $false; 01371 01372 $rs2->_transpose(); 01373 return $rs2; 01374 } 01375 01376 /* 01377 Calculate the offset of a date for a particular database and generate 01378 appropriate SQL. Useful for calculating future/past dates and storing 01379 in a database. 01380 01381 If dayFraction=1.5 means 1.5 days from now, 1.0/24 for 1 hour. 01382 */ 01383 function OffsetDate($dayFraction,$date=false) 01384 { 01385 if (!$date) $date = $this->sysDate; 01386 return '('.$date.'+'.$dayFraction.')'; 01387 } 01388 01389 01395 function &GetArray($sql,$inputarr=false) 01396 { 01397 global $ADODB_COUNTRECS; 01398 01399 $savec = $ADODB_COUNTRECS; 01400 $ADODB_COUNTRECS = false; 01401 $rs =& $this->Execute($sql,$inputarr); 01402 $ADODB_COUNTRECS = $savec; 01403 if (!$rs) 01404 if (defined('ADODB_PEAR')) { 01405 $cls = ADODB_PEAR_Error(); 01406 return $cls; 01407 } else { 01408 $false = false; 01409 return $false; 01410 } 01411 $arr =& $rs->GetArray(); 01412 $rs->Close(); 01413 return $arr; 01414 } 01415 01416 function &CacheGetAll($secs2cache,$sql=false,$inputarr=false) 01417 { 01418 $arr =& $this->CacheGetArray($secs2cache,$sql,$inputarr); 01419 return $arr; 01420 } 01421 01422 function &CacheGetArray($secs2cache,$sql=false,$inputarr=false) 01423 { 01424 global $ADODB_COUNTRECS; 01425 01426 $savec = $ADODB_COUNTRECS; 01427 $ADODB_COUNTRECS = false; 01428 $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr); 01429 $ADODB_COUNTRECS = $savec; 01430 01431 if (!$rs) 01432 if (defined('ADODB_PEAR')) { 01433 $cls = ADODB_PEAR_Error(); 01434 return $cls; 01435 } else { 01436 $false = false; 01437 return $false; 01438 } 01439 $arr =& $rs->GetArray(); 01440 $rs->Close(); 01441 return $arr; 01442 } 01443 01444 01445 01452 function &GetRow($sql,$inputarr=false) 01453 { 01454 global $ADODB_COUNTRECS; 01455 $crecs = $ADODB_COUNTRECS; 01456 $ADODB_COUNTRECS = false; 01457 01458 $rs =& $this->Execute($sql,$inputarr); 01459 01460 $ADODB_COUNTRECS = $crecs; 01461 if ($rs) { 01462 if (!$rs->EOF) $arr = $rs->fields; 01463 else $arr = array(); 01464 $rs->Close(); 01465 return $arr; 01466 } 01467 01468 $false = false; 01469 return $false; 01470 } 01471 01472 function &CacheGetRow($secs2cache,$sql=false,$inputarr=false) 01473 { 01474 $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr); 01475 if ($rs) { 01476 $arr = false; 01477 if (!$rs->EOF) $arr = $rs->fields; 01478 $rs->Close(); 01479 return $arr; 01480 } 01481 $false = false; 01482 return $false; 01483 } 01484 01505 function Replace($table, $fieldArray, $keyCol, $autoQuote=false, $has_autoinc=false) 01506 { 01507 global $ADODB_INCLUDED_LIB; 01508 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 01509 01510 return _adodb_replace($this, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc); 01511 } 01512 01513 01532 function &CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false) 01533 { 01534 if (!is_numeric($secs2cache)) { 01535 if ($sql === false) $sql = -1; 01536 if ($offset == -1) $offset = false; 01537 // sql, nrows, offset,inputarr 01538 $rs =& $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs); 01539 } else { 01540 if ($sql === false) ADOConnection::outp( "Warning: \$sql missing from CacheSelectLimit()"); 01541 $rs =& $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache); 01542 } 01543 return $rs; 01544 } 01545 01546 01556 function CacheFlush($sql=false,$inputarr=false) 01557 { 01558 global $ADODB_CACHE_DIR; 01559 01560 if ($this->memCache) { 01561 global $ADODB_INCLUDED_MEMCACHE; 01562 01563 $key = false; 01564 if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php'); 01565 if ($sql) $key = $this->_gencachename($sql.serialize($inputarr),false,true); 01566 FlushMemCache($key, $this->memCacheHost, $this->memCachePort, $this->debug); 01567 return; 01568 } 01569 01570 if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) { 01571 /*if (strncmp(PHP_OS,'WIN',3) === 0) 01572 $dir = str_replace('/', '\\', $ADODB_CACHE_DIR); 01573 else */ 01574 $dir = $ADODB_CACHE_DIR; 01575 01576 if ($this->debug) { 01577 ADOConnection::outp( "CacheFlush: $dir<br><pre>\n", $this->_dirFlush($dir),"</pre>"); 01578 } else { 01579 $this->_dirFlush($dir); 01580 } 01581 return; 01582 } 01583 01584 global $ADODB_INCLUDED_CSV; 01585 if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); 01586 01587 $f = $this->_gencachename($sql.serialize($inputarr),false); 01588 adodb_write_file($f,''); // is adodb_write_file needed? 01589 if (!@unlink($f)) { 01590 if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f"); 01591 } 01592 } 01593 01600 function _dirFlush($dir, $kill_top_level = false) { 01601 if(!$dh = @opendir($dir)) return; 01602 01603 while (($obj = readdir($dh))) { 01604 if($obj=='.' || $obj=='..') 01605 continue; 01606 01607 if (!@unlink($dir.'/'.$obj)) 01608 $this->_dirFlush($dir.'/'.$obj, true); 01609 } 01610 if ($kill_top_level === true) 01611 @rmdir($dir); 01612 return true; 01613 } 01614 01615 01616 function xCacheFlush($sql=false,$inputarr=false) 01617 { 01618 global $ADODB_CACHE_DIR; 01619 01620 if ($this->memCache) { 01621 global $ADODB_INCLUDED_MEMCACHE; 01622 $key = false; 01623 if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php'); 01624 if ($sql) $key = $this->_gencachename($sql.serialize($inputarr),false,true); 01625 flushmemCache($key, $this->memCacheHost, $this->memCachePort, $this->debug); 01626 return; 01627 } 01628 01629 if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) { 01630 if (strncmp(PHP_OS,'WIN',3) === 0) { 01631 $cmd = 'del /s '.str_replace('/','\\',$ADODB_CACHE_DIR).'\adodb_*.cache'; 01632 } else { 01633 //$cmd = 'find "'.$ADODB_CACHE_DIR.'" -type f -maxdepth 1 -print0 | xargs -0 rm -f'; 01634 $cmd = 'rm -rf '.$ADODB_CACHE_DIR.'/[0-9a-f][0-9a-f]/'; 01635 // old version 'rm -f `find '.$ADODB_CACHE_DIR.' -name adodb_*.cache`'; 01636 } 01637 if ($this->debug) { 01638 ADOConnection::outp( "CacheFlush: $cmd<br><pre>\n", system($cmd),"</pre>"); 01639 } else { 01640 exec($cmd); 01641 } 01642 return; 01643 } 01644 01645 global $ADODB_INCLUDED_CSV; 01646 if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); 01647 01648 $f = $this->_gencachename($sql.serialize($inputarr),false); 01649 adodb_write_file($f,''); // is adodb_write_file needed? 01650 if (!@unlink($f)) { 01651 if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f"); 01652 } 01653 } 01654 01669 function _gencachename($sql,$createdir,$memcache=false) 01670 { 01671 global $ADODB_CACHE_DIR; 01672 static $notSafeMode; 01673 01674 if ($this->fetchMode === false) { 01675 global $ADODB_FETCH_MODE; 01676 $mode = $ADODB_FETCH_MODE; 01677 } else { 01678 $mode = $this->fetchMode; 01679 } 01680 $m = md5($sql.$this->databaseType.$this->database.$this->user.$mode); 01681 if ($memcache) return $m; 01682 01683 if (!isset($notSafeMode)) $notSafeMode = !ini_get('safe_mode'); 01684 $dir = ($notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($m,0,2) : $ADODB_CACHE_DIR; 01685 01686 if ($createdir && $notSafeMode && !file_exists($dir)) { 01687 $oldu = umask(0); 01688 if (!mkdir($dir,0771)) 01689 if ($this->debug) ADOConnection::outp( "Unable to mkdir $dir for $sql"); 01690 umask($oldu); 01691 } 01692 return $dir.'/adodb_'.$m.'.cache'; 01693 } 01694 01695 01705 function &CacheExecute($secs2cache,$sql=false,$inputarr=false) 01706 { 01707 01708 01709 if (!is_numeric($secs2cache)) { 01710 $inputarr = $sql; 01711 $sql = $secs2cache; 01712 $secs2cache = $this->cacheSecs; 01713 } 01714 01715 if (is_array($sql)) { 01716 $sqlparam = $sql; 01717 $sql = $sql[0]; 01718 } else 01719 $sqlparam = $sql; 01720 01721 if ($this->memCache) { 01722 global $ADODB_INCLUDED_MEMCACHE; 01723 if (empty($ADODB_INCLUDED_MEMCACHE)) include(ADODB_DIR.'/adodb-memcache.lib.inc.php'); 01724 $md5file = $this->_gencachename($sql.serialize($inputarr),false,true); 01725 } else { 01726 global $ADODB_INCLUDED_CSV; 01727 if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php'); 01728 $md5file = $this->_gencachename($sql.serialize($inputarr),true); 01729 } 01730 01731 $err = ''; 01732 01733 if ($secs2cache > 0){ 01734 if ($this->memCache) 01735 $rs = &getmemCache($md5file,$err,$secs2cache, $this->memCacheHost, $this->memCachePort); 01736 else 01737 $rs = &csv2rs($md5file,$err,$secs2cache,$this->arrayClass); 01738 $this->numCacheHits += 1; 01739 } else { 01740 $err='Timeout 1'; 01741 $rs = false; 01742 $this->numCacheMisses += 1; 01743 } 01744 if (!$rs) { 01745 // no cached rs found 01746 if ($this->debug) { 01747 if (get_magic_quotes_runtime() && !$this->memCache) { 01748 ADOConnection::outp("Please disable magic_quotes_runtime - it corrupts cache files :("); 01749 } 01750 if ($this->debug !== -1) ADOConnection::outp( " $md5file cache failure: $err (see sql below)"); 01751 } 01752 01753 $rs = &$this->Execute($sqlparam,$inputarr); 01754 01755 if ($rs && $this->memCache) { 01756 $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately 01757 if(!putmemCache($md5file, $rs, $this->memCacheHost, $this->memCachePort, $this->memCacheCompress, $this->debug)) { 01758 if ($fn = $this->raiseErrorFn) 01759 $fn($this->databaseType,'CacheExecute',-32000,"Cache write error",$md5file,$sql,$this); 01760 if ($this->debug) ADOConnection::outp( " Cache write error"); 01761 } 01762 } else 01763 if ($rs) { 01764 $eof = $rs->EOF; 01765 $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately 01766 $txt = _rs2serialize($rs,false,$sql); // serialize 01767 01768 if (!adodb_write_file($md5file,$txt,$this->debug)) { 01769 if ($fn = $this->raiseErrorFn) { 01770 $fn($this->databaseType,'CacheExecute',-32000,"Cache write error",$md5file,$sql,$this); 01771 } 01772 if ($this->debug) ADOConnection::outp( " Cache write error"); 01773 } 01774 if ($rs->EOF && !$eof) { 01775 $rs->MoveFirst(); 01776 //$rs = &csv2rs($md5file,$err); 01777 $rs->connection = &$this; // Pablo suggestion 01778 } 01779 01780 } else 01781 if (!$this->memCache) 01782 @unlink($md5file); 01783 } else { 01784 $this->_errorMsg = ''; 01785 $this->_errorCode = 0; 01786 01787 if ($this->fnCacheExecute) { 01788 $fn = $this->fnCacheExecute; 01789 $fn($this, $secs2cache, $sql, $inputarr); 01790 } 01791 // ok, set cached object found 01792 $rs->connection = &$this; // Pablo suggestion 01793 if ($this->debug){ 01794 01795 $inBrowser = isset($_SERVER['HTTP_USER_AGENT']); 01796 $ttl = $rs->timeCreated + $secs2cache - time(); 01797 $s = is_array($sql) ? $sql[0] : $sql; 01798 if ($inBrowser) $s = '<i>'.htmlspecialchars($s).'</i>'; 01799 01800 ADOConnection::outp( " $md5file reloaded, ttl=$ttl [ $s ]"); 01801 } 01802 } 01803 return $rs; 01804 } 01805 01806 01807 /* 01808 Similar to PEAR DB's autoExecute(), except that 01809 $mode can be 'INSERT' or 'UPDATE' or DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE 01810 If $mode == 'UPDATE', then $where is compulsory as a safety measure. 01811 01812 $forceUpdate means that even if the data has not changed, perform update. 01813 */ 01814 function& AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false) 01815 { 01816 $false = false; 01817 $sql = 'SELECT * FROM '.$table; 01818 if ($where!==FALSE) $sql .= ' WHERE '.$where; 01819 else if ($mode == 'UPDATE' || $mode == 2 /* DB_AUTOQUERY_UPDATE */) { 01820 ADOConnection::outp('AutoExecute: Illegal mode=UPDATE with empty WHERE clause'); 01821 return $false; 01822 } 01823 01824 $rs =& $this->SelectLimit($sql,1); 01825 if (!$rs) return $false; // table does not exist 01826 $rs->tableName = $table; 01827 01828 switch((string) $mode) { 01829 case 'UPDATE': 01830 case '2': 01831 $sql = $this->GetUpdateSQL($rs, $fields_values, $forceUpdate, $magicq); 01832 break; 01833 case 'INSERT': 01834 case '1': 01835 $sql = $this->GetInsertSQL($rs, $fields_values, $magicq); 01836 break; 01837 default: 01838 ADOConnection::outp("AutoExecute: Unknown mode=$mode"); 01839 return $false; 01840 } 01841 $ret = false; 01842 if ($sql) $ret = $this->Execute($sql); 01843 if ($ret) $ret = true; 01844 return $ret; 01845 } 01846 01847 01859 function GetUpdateSQL(&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=null) 01860 { 01861 global $ADODB_INCLUDED_LIB; 01862 01863 //********************************************************// 01864 //This is here to maintain compatibility 01865 //with older adodb versions. Sets force type to force nulls if $forcenulls is set. 01866 if (!isset($force)) { 01867 global $ADODB_FORCE_TYPE; 01868 $force = $ADODB_FORCE_TYPE; 01869 } 01870 //********************************************************// 01871 01872 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 01873 return _adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq,$force); 01874 } 01875 01884 function GetInsertSQL(&$rs, $arrFields,$magicq=false,$force=null) 01885 { 01886 global $ADODB_INCLUDED_LIB; 01887 if (!isset($force)) { 01888 global $ADODB_FORCE_TYPE; 01889 $force = $ADODB_FORCE_TYPE; 01890 01891 } 01892 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 01893 return _adodb_getinsertsql($this,$rs,$arrFields,$magicq,$force); 01894 } 01895 01896 01916 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') 01917 { 01918 return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false; 01919 } 01920 01930 function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB') 01931 { 01932 $fd = fopen($path,'rb'); 01933 if ($fd === false) return false; 01934 $val = fread($fd,filesize($path)); 01935 fclose($fd); 01936 return $this->UpdateBlob($table,$column,$val,$where,$blobtype); 01937 } 01938 01939 function BlobDecode($blob) 01940 { 01941 return $blob; 01942 } 01943 01944 function BlobEncode($blob) 01945 { 01946 return $blob; 01947 } 01948 01949 function SetCharSet($charset) 01950 { 01951 return false; 01952 } 01953 01954 function IfNull( $field, $ifNull ) 01955 { 01956 return " CASE WHEN $field is null THEN $ifNull ELSE $field END "; 01957 } 01958 01959 function LogSQL($enable=true) 01960 { 01961 include_once(ADODB_DIR.'/adodb-perf.inc.php'); 01962 01963 if ($enable) $this->fnExecute = 'adodb_log_sql'; 01964 else $this->fnExecute = false; 01965 01966 $old = $this->_logsql; 01967 $this->_logsql = $enable; 01968 if ($enable && !$old) $this->_affected = false; 01969 return $old; 01970 } 01971 01972 function GetCharSet() 01973 { 01974 return false; 01975 } 01976 01984 function UpdateClob($table,$column,$val,$where) 01985 { 01986 return $this->UpdateBlob($table,$column,$val,$where,'CLOB'); 01987 } 01988 01989 // not the fastest implementation - quick and dirty - jlim 01990 // for best performance, use the actual $rs->MetaType(). 01991 function MetaType($t,$len=-1,$fieldobj=false) 01992 { 01993 01994 if (empty($this->_metars)) { 01995 $rsclass = $this->rsPrefix.$this->databaseType; 01996 $this->_metars =& new $rsclass(false,$this->fetchMode); 01997 $this->_metars->connection =& $this; 01998 } 01999 return $this->_metars->MetaType($t,$len,$fieldobj); 02000 } 02001 02002 02007 function SetDateLocale($locale = 'En') 02008 { 02009 $this->locale = $locale; 02010 switch (strtoupper($locale)) 02011 { 02012 case 'EN': 02013 $this->fmtDate="'Y-m-d'"; 02014 $this->fmtTimeStamp = "'Y-m-d H:i:s'"; 02015 break; 02016 02017 case 'US': 02018 $this->fmtDate = "'m-d-Y'"; 02019 $this->fmtTimeStamp = "'m-d-Y H:i:s'"; 02020 break; 02021 02022 case 'NL': 02023 case 'FR': 02024 case 'RO': 02025 case 'IT': 02026 $this->fmtDate="'d-m-Y'"; 02027 $this->fmtTimeStamp = "'d-m-Y H:i:s'"; 02028 break; 02029 02030 case 'GE': 02031 $this->fmtDate="'d.m.Y'"; 02032 $this->fmtTimeStamp = "'d.m.Y H:i:s'"; 02033 break; 02034 02035 default: 02036 $this->fmtDate="'Y-m-d'"; 02037 $this->fmtTimeStamp = "'Y-m-d H:i:s'"; 02038 break; 02039 } 02040 } 02041 02042 function &GetActiveRecordsClass($class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false) 02043 { 02044 global $_ADODB_ACTIVE_DBS; 02045 02046 $save = $this->SetFetchMode(ADODB_FETCH_NUM); 02047 if (empty($whereOrderBy)) $whereOrderBy = '1=1'; 02048 $rows = $this->GetAll("select * from ".$table.' WHERE '.$whereOrderBy,$bindarr); 02049 $this->SetFetchMode($save); 02050 02051 $false = false; 02052 02053 if ($rows === false) { 02054 return $false; 02055 } 02056 02057 02058 if (!isset($_ADODB_ACTIVE_DBS)) { 02059 include(ADODB_DIR.'/adodb-active-record.inc.php'); 02060 } 02061 if (!class_exists($class)) { 02062 ADOConnection::outp("Unknown class $class in GetActiveRcordsClass()"); 02063 return $false; 02064 } 02065 $arr = array(); 02066 foreach($rows as $row) { 02067 02068 $obj =& new $class($table,$primkeyArr,$this); 02069 if ($obj->ErrorMsg()){ 02070 $this->_errorMsg = $obj->ErrorMsg(); 02071 return $false; 02072 } 02073 $obj->Set($row); 02074 $arr[] =& $obj; 02075 } 02076 return $arr; 02077 } 02078 02079 function &GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false) 02080 { 02081 $arr =& $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr); 02082 return $arr; 02083 } 02084 02088 function Close() 02089 { 02090 $rez = $this->_close(); 02091 $this->_connectionID = false; 02092 return $rez; 02093 } 02094 02100 function BeginTrans() {return false;} 02101 02102 /* set transaction mode */ 02103 function SetTransactionMode( $transaction_mode ) 02104 { 02105 $transaction_mode = $this->MetaTransaction($transaction_mode, $this->dataProvider); 02106 $this->_transmode = $transaction_mode; 02107 } 02108 /* 02109 http://msdn2.microsoft.com/en-US/ms173763.aspx 02110 http://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-isolation.html 02111 http://www.postgresql.org/docs/8.1/interactive/sql-set-transaction.html 02112 http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_10005.htm 02113 */ 02114 function MetaTransaction($mode,$db) 02115 { 02116 $mode = strtoupper($mode); 02117 $mode = str_replace('ISOLATION LEVEL ','',$mode); 02118 02119 switch($mode) { 02120 02121 case 'READ UNCOMMITTED': 02122 switch($db) { 02123 case 'oci8': 02124 case 'oracle': 02125 return 'ISOLATION LEVEL READ COMMITTED'; 02126 default: 02127 return 'ISOLATION LEVEL READ UNCOMMITTED'; 02128 } 02129 break; 02130 02131 case 'READ COMMITTED': 02132 return 'ISOLATION LEVEL READ COMMITTED'; 02133 break; 02134 02135 case 'REPEATABLE READ': 02136 switch($db) { 02137 case 'oci8': 02138 case 'oracle': 02139 return 'ISOLATION LEVEL SERIALIZABLE'; 02140 default: 02141 return 'ISOLATION LEVEL REPEATABLE READ'; 02142 } 02143 break; 02144 02145 case 'SERIALIZABLE': 02146 return 'ISOLATION LEVEL SERIALIZABLE'; 02147 break; 02148 02149 default: 02150 return $mode; 02151 } 02152 } 02153 02161 function CommitTrans($ok=true) 02162 { return true;} 02163 02164 02170 function RollbackTrans() 02171 { return false;} 02172 02173 02180 function MetaDatabases() 02181 { 02182 global $ADODB_FETCH_MODE; 02183 02184 if ($this->metaDatabasesSQL) { 02185 $save = $ADODB_FETCH_MODE; 02186 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 02187 02188 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); 02189 02190 $arr = $this->GetCol($this->metaDatabasesSQL); 02191 if (isset($savem)) $this->SetFetchMode($savem); 02192 $ADODB_FETCH_MODE = $save; 02193 02194 return $arr; 02195 } 02196 02197 return false; 02198 } 02199 02200 02211 function &MetaTables($ttype=false,$showSchema=false,$mask=false) 02212 { 02213 global $ADODB_FETCH_MODE; 02214 02215 02216 $false = false; 02217 if ($mask) { 02218 return $false; 02219 } 02220 if ($this->metaTablesSQL) { 02221 $save = $ADODB_FETCH_MODE; 02222 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 02223 02224 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); 02225 02226 $rs = $this->Execute($this->metaTablesSQL); 02227 if (isset($savem)) $this->SetFetchMode($savem); 02228 $ADODB_FETCH_MODE = $save; 02229 02230 if ($rs === false) return $false; 02231 $arr =& $rs->GetArray(); 02232 $arr2 = array(); 02233 02234 if ($hast = ($ttype && isset($arr[0][1]))) { 02235 $showt = strncmp($ttype,'T',1); 02236 } 02237 02238 for ($i=0; $i < sizeof($arr); $i++) { 02239 if ($hast) { 02240 if ($showt == 0) { 02241 if (strncmp($arr[$i][1],'T',1) == 0) $arr2[] = trim($arr[$i][0]); 02242 } else { 02243 if (strncmp($arr[$i][1],'V',1) == 0) $arr2[] = trim($arr[$i][0]); 02244 } 02245 } else 02246 $arr2[] = trim($arr[$i][0]); 02247 } 02248 $rs->Close(); 02249 return $arr2; 02250 } 02251 return $false; 02252 } 02253 02254 02255 function _findschema(&$table,&$schema) 02256 { 02257 if (!$schema && ($at = strpos($table,'.')) !== false) { 02258 $schema = substr($table,0,$at); 02259 $table = substr($table,$at+1); 02260 } 02261 } 02262 02273 function &MetaColumns($table,$normalize=true) 02274 { 02275 global $ADODB_FETCH_MODE; 02276 02277 $false = false; 02278 02279 if (!empty($this->metaColumnsSQL)) { 02280 02281 $schema = false; 02282 $this->_findschema($table,$schema); 02283 02284 $save = $ADODB_FETCH_MODE; 02285 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 02286 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); 02287 $rs = $this->Execute(sprintf($this->metaColumnsSQL,($normalize)?strtoupper($table):$table)); 02288 if (isset($savem)) $this->SetFetchMode($savem); 02289 $ADODB_FETCH_MODE = $save; 02290 if ($rs === false || $rs->EOF) return $false; 02291 02292 $retarr = array(); 02293 while (!$rs->EOF) { //print_r($rs->fields); 02294 $fld = new ADOFieldObject(); 02295 $fld->name = $rs->fields[0]; 02296 $fld->type = $rs->fields[1]; 02297 if (isset($rs->fields[3]) && $rs->fields[3]) { 02298 if ($rs->fields[3]>0) $fld->max_length = $rs->fields[3]; 02299 $fld->scale = $rs->fields[4]; 02300 if ($fld->scale>0) $fld->max_length += 1; 02301 } else 02302 $fld->max_length = $rs->fields[2]; 02303 02304 if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld; 02305 else $retarr[strtoupper($fld->name)] = $fld; 02306 $rs->MoveNext(); 02307 } 02308 $rs->Close(); 02309 return $retarr; 02310 } 02311 return $false; 02312 } 02313 02332 function &MetaIndexes($table, $primary = false, $owner = false) 02333 { 02334 $false = false; 02335 return $false; 02336 } 02337 02344 function &MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */) 02345 { 02346 $objarr =& $this->MetaColumns($table); 02347 if (!is_array($objarr)) { 02348 $false = false; 02349 return $false; 02350 } 02351 $arr = array(); 02352 if ($numIndexes) { 02353 $i = 0; 02354 if ($useattnum) { 02355 foreach($objarr as $v) 02356 $arr[$v->attnum] = $v->name; 02357 02358 } else 02359 foreach($objarr as $v) $arr[$i++] = $v->name; 02360 } else 02361 foreach($objarr as $v) $arr[strtoupper($v->name)] = $v->name; 02362 02363 return $arr; 02364 } 02365 02376 function Concat() 02377 { 02378 $arr = func_get_args(); 02379 return implode($this->concat_operator, $arr); 02380 } 02381 02382 02390 function DBDate($d) 02391 { 02392 if (empty($d) && $d !== 0) return 'null'; 02393 02394 if (is_string($d) && !is_numeric($d)) { 02395 if ($d === 'null' || strncmp($d,"'",1) === 0) return $d; 02396 if ($this->isoDates) return "'$d'"; 02397 $d = ADOConnection::UnixDate($d); 02398 } 02399 02400 return adodb_date($this->fmtDate,$d); 02401 } 02402 02403 function BindDate($d) 02404 { 02405 $d = $this->DBDate($d); 02406 if (strncmp($d,"'",1)) return $d; 02407 02408 return substr($d,1,strlen($d)-2); 02409 } 02410 02411 function BindTimeStamp($d) 02412 { 02413 $d = $this->DBTimeStamp($d); 02414 if (strncmp($d,"'",1)) return $d; 02415 02416 return substr($d,1,strlen($d)-2); 02417 } 02418 02419 02427 function DBTimeStamp($ts) 02428 { 02429 if (empty($ts) && $ts !== 0) return 'null'; 02430 02431 # strlen(14) allows YYYYMMDDHHMMSS format 02432 if (!is_string($ts) || (is_numeric($ts) && strlen($ts)<14)) 02433 return adodb_date($this->fmtTimeStamp,$ts); 02434 02435 if ($ts === 'null') return $ts; 02436 if ($this->isoDates && strlen($ts) !== 14) return "'$ts'"; 02437 02438 $ts = ADOConnection::UnixTimeStamp($ts); 02439 return adodb_date($this->fmtTimeStamp,$ts); 02440 } 02441 02448 function UnixDate($v) 02449 { 02450 if (is_object($v)) { 02451 // odbtp support 02452 //( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 ) 02453 return adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year); 02454 } 02455 02456 if (is_numeric($v) && strlen($v) !== 8) return $v; 02457 if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|", 02458 ($v), $rr)) return false; 02459 02460 if ($rr[1] <= TIMESTAMP_FIRST_YEAR) return 0; 02461 // h-m-s-MM-DD-YY 02462 return @adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]); 02463 } 02464 02465 02472 function UnixTimeStamp($v) 02473 { 02474 if (is_object($v)) { 02475 // odbtp support 02476 //( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 ) 02477 return adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year); 02478 } 02479 02480 if (!preg_match( 02481 "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]*(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", 02482 ($v), $rr)) return false; 02483 02484 if ($rr[1] <= TIMESTAMP_FIRST_YEAR && $rr[2]<= 1) return 0; 02485 02486 // h-m-s-MM-DD-YY 02487 if (!isset($rr[5])) return adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]); 02488 return @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]); 02489 } 02490 02502 function UserDate($v,$fmt='Y-m-d',$gmt=false) 02503 { 02504 $tt = $this->UnixDate($v); 02505 02506 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR 02507 if (($tt === false || $tt == -1) && $v != false) return $v; 02508 else if ($tt == 0) return $this->emptyDate; 02509 else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR 02510 } 02511 02512 return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt); 02513 02514 } 02515 02523 function UserTimeStamp($v,$fmt='Y-m-d H:i:s',$gmt=false) 02524 { 02525 if (!isset($v)) return $this->emptyTimeStamp; 02526 # strlen(14) allows YYYYMMDDHHMMSS format 02527 if (is_numeric($v) && strlen($v)<14) return ($gmt) ? adodb_gmdate($fmt,$v) : adodb_date($fmt,$v); 02528 $tt = $this->UnixTimeStamp($v); 02529 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR 02530 if (($tt === false || $tt == -1) && $v != false) return $v; 02531 if ($tt == 0) return $this->emptyTimeStamp; 02532 return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt); 02533 } 02534 02535 function escape($s,$magic_quotes=false) 02536 { 02537 return $this->addq($s,$magic_quotes); 02538 } 02539 02543 function addq($s,$magic_quotes=false) 02544 { 02545 if (!$magic_quotes) { 02546 02547 if ($this->replaceQuote[0] == '\\'){ 02548 // only since php 4.0.5 02549 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s); 02550 //$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s)); 02551 } 02552 return str_replace("'",$this->replaceQuote,$s); 02553 } 02554 02555 // undo magic quotes for " 02556 $s = str_replace('\\"','"',$s); 02557 02558 if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything 02559 return $s; 02560 else {// change \' to '' for sybase/mssql 02561 $s = str_replace('\\\\','\\',$s); 02562 return str_replace("\\'",$this->replaceQuote,$s); 02563 } 02564 } 02565 02577 function qstr($s,$magic_quotes=false) 02578 { 02579 if (!$magic_quotes) { 02580 02581 if ($this->replaceQuote[0] == '\\'){ 02582 // only since php 4.0.5 02583 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s); 02584 //$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s)); 02585 } 02586 return "'".str_replace("'",$this->replaceQuote,$s)."'"; 02587 } 02588 02589 // undo magic quotes for " 02590 $s = str_replace('\\"','"',$s); 02591 02592 if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything 02593 return "'$s'"; 02594 else {// change \' to '' for sybase/mssql 02595 $s = str_replace('\\\\','\\',$s); 02596 return "'".str_replace("\\'",$this->replaceQuote,$s)."'"; 02597 } 02598 } 02599 02600 02618 function &PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) 02619 { 02620 global $ADODB_INCLUDED_LIB; 02621 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 02622 if ($this->pageExecuteCountRows) $rs =& _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache); 02623 else $rs =& _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache); 02624 return $rs; 02625 } 02626 02627 02640 function &CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) 02641 { 02642 /*switch($this->dataProvider) { 02643 case 'postgres': 02644 case 'mysql': 02645 break; 02646 default: $secs2cache = 0; break; 02647 }*/ 02648 $rs =& $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache); 02649 return $rs; 02650 } 02651 02652 } // end class ADOConnection 02653 02654 02655 02656 //============================================================================================== 02657 // CLASS ADOFetchObj 02658 //============================================================================================== 02659 02663 class ADOFetchObj { 02664 }; 02665 02666 //============================================================================================== 02667 // CLASS ADORecordSet_empty 02668 //============================================================================================== 02669 02673 class ADORecordSet_empty 02674 { 02675 var $dataProvider = 'empty'; 02676 var $databaseType = false; 02677 var $EOF = true; 02678 var $_numOfRows = 0; 02679 var $fields = false; 02680 var $connection = false; 02681 function RowCount() {return 0;} 02682 function RecordCount() {return 0;} 02683 function PO_RecordCount(){return 0;} 02684 function Close(){return true;} 02685 function FetchRow() {return false;} 02686 function FieldCount(){ return 0;} 02687 function Init() {} 02688 } 02689 02690 //============================================================================================== 02691 // DATE AND TIME FUNCTIONS 02692 //============================================================================================== 02693 if (!defined('ADODB_DATE_VERSION')) include(ADODB_DIR.'/adodb-time.inc.php'); 02694 02695 //============================================================================================== 02696 // CLASS ADORecordSet 02697 //============================================================================================== 02698 02699 if (PHP_VERSION < 5) include_once(ADODB_DIR.'/adodb-php4.inc.php'); 02700 else include_once(ADODB_DIR.'/adodb-iterator.inc.php'); 02707 class ADORecordSet extends ADODB_BASE_RS { 02708 /* 02709 * public variables 02710 */ 02711 var $dataProvider = "native"; 02712 var $fields = false; 02713 var $blobSize = 100; 02714 02715 var $canSeek = false; 02716 var $sql; 02717 var $EOF = false; 02718 02719 var $emptyTimeStamp = ' '; 02720 var $emptyDate = ' '; 02721 var $debug = false; 02722 var $timeCreated=0; 02723 02724 var $bind = false; 02725 var $fetchMode; 02726 var $connection = false; 02727 /* 02728 * private variables 02729 */ 02730 var $_numOfRows = -1; 02731 var $_numOfFields = -1; 02732 var $_queryID = -1; 02733 var $_currentRow = -1; 02734 var $_closed = false; 02735 var $_inited = false; 02736 var $_obj; 02737 var $_names; 02739 var $_currentPage = -1; 02740 var $_atFirstPage = false; 02741 var $_atLastPage = false; 02742 var $_lastPageNo = -1; 02743 var $_maxRecordCount = 0; 02744 var $datetime = false; 02745 02752 function ADORecordSet($queryID) 02753 { 02754 $this->_queryID = $queryID; 02755 } 02756 02757 02758 02759 function Init() 02760 { 02761 if ($this->_inited) return; 02762 $this->_inited = true; 02763 if ($this->_queryID) @$this->_initrs(); 02764 else { 02765 $this->_numOfRows = 0; 02766 $this->_numOfFields = 0; 02767 } 02768 if ($this->_numOfRows != 0 && $this->_numOfFields && $this->_currentRow == -1) { 02769 02770 $this->_currentRow = 0; 02771 if ($this->EOF = ($this->_fetch() === false)) { 02772 $this->_numOfRows = 0; // _numOfRows could be -1 02773 } 02774 } else { 02775 $this->EOF = true; 02776 } 02777 } 02778 02779 02800 function GetMenu($name,$defstr='',$blank1stItem=true,$multiple=false, 02801 $size=0, $selectAttr='',$compareFields0=true) 02802 { 02803 global $ADODB_INCLUDED_LIB; 02804 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 02805 return _adodb_getmenu($this, $name,$defstr,$blank1stItem,$multiple, 02806 $size, $selectAttr,$compareFields0); 02807 } 02808 02809 02810 02818 function GetMenu2($name,$defstr='',$blank1stItem=true,$multiple=false,$size=0, $selectAttr='') 02819 { 02820 return $this->GetMenu($name,$defstr,$blank1stItem,$multiple, 02821 $size, $selectAttr,false); 02822 } 02823 02824 /* 02825 Grouped Menu 02826 */ 02827 function GetMenu3($name,$defstr='',$blank1stItem=true,$multiple=false, 02828 $size=0, $selectAttr='') 02829 { 02830 global $ADODB_INCLUDED_LIB; 02831 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 02832 return _adodb_getmenu_gp($this, $name,$defstr,$blank1stItem,$multiple, 02833 $size, $selectAttr,false); 02834 } 02835 02843 function &GetArray($nRows = -1) 02844 { 02845 global $ADODB_EXTENSION; if ($ADODB_EXTENSION) { 02846 $results = adodb_getall($this,$nRows); 02847 return $results; 02848 } 02849 $results = array(); 02850 $cnt = 0; 02851 while (!$this->EOF && $nRows != $cnt) { 02852 $results[] = $this->fields; 02853 $this->MoveNext(); 02854 $cnt++; 02855 } 02856 return $results; 02857 } 02858 02859 function &GetAll($nRows = -1) 02860 { 02861 $arr =& $this->GetArray($nRows); 02862 return $arr; 02863 } 02864 02865 /* 02866 * Some databases allow multiple recordsets to be returned. This function 02867 * will return true if there is a next recordset, or false if no more. 02868 */ 02869 function NextRecordSet() 02870 { 02871 return false; 02872 } 02873 02883 function &GetArrayLimit($nrows,$offset=-1) 02884 { 02885 if ($offset <= 0) { 02886 $arr =& $this->GetArray($nrows); 02887 return $arr; 02888 } 02889 02890 $this->Move($offset); 02891 02892 $results = array(); 02893 $cnt = 0; 02894 while (!$this->EOF && $nrows != $cnt) { 02895 $results[$cnt++] = $this->fields; 02896 $this->MoveNext(); 02897 } 02898 02899 return $results; 02900 } 02901 02902 02910 function &GetRows($nRows = -1) 02911 { 02912 $arr =& $this->GetArray($nRows); 02913 return $arr; 02914 } 02915 02932 function &GetAssoc($force_array = false, $first2cols = false) 02933 { 02934 global $ADODB_EXTENSION; 02935 02936 $cols = $this->_numOfFields; 02937 if ($cols < 2) { 02938 $false = false; 02939 return $false; 02940 } 02941 $numIndex = isset($this->fields[0]); 02942 $results = array(); 02943 02944 if (!$first2cols && ($cols > 2 || $force_array)) { 02945 if ($ADODB_EXTENSION) { 02946 if ($numIndex) { 02947 while (!$this->EOF) { 02948 $results[trim($this->fields[0])] = array_slice($this->fields, 1); 02949 adodb_movenext($this); 02950 } 02951 } else { 02952 while (!$this->EOF) { 02953 // Fix for array_slice re-numbering numeric associative keys 02954 $keys = array_slice(array_keys($this->fields), 1); 02955 $sliced_array = array(); 02956 02957 foreach($keys as $key) { 02958 $sliced_array[$key] = $this->fields[$key]; 02959 } 02960 02961 $results[trim(reset($this->fields))] = $sliced_array; 02962 adodb_movenext($this); 02963 } 02964 } 02965 } else { 02966 if ($numIndex) { 02967 while (!$this->EOF) { 02968 $results[trim($this->fields[0])] = array_slice($this->fields, 1); 02969 $this->MoveNext(); 02970 } 02971 } else { 02972 while (!$this->EOF) { 02973 // Fix for array_slice re-numbering numeric associative keys 02974 $keys = array_slice(array_keys($this->fields), 1); 02975 $sliced_array = array(); 02976 02977 foreach($keys as $key) { 02978 $sliced_array[$key] = $this->fields[$key]; 02979 } 02980 02981 $results[trim(reset($this->fields))] = $sliced_array; 02982 $this->MoveNext(); 02983 } 02984 } 02985 } 02986 } else { 02987 if ($ADODB_EXTENSION) { 02988 // return scalar values 02989 if ($numIndex) { 02990 while (!$this->EOF) { 02991 // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string 02992 $results[trim(($this->fields[0]))] = $this->fields[1]; 02993 adodb_movenext($this); 02994 } 02995 } else { 02996 while (!$this->EOF) { 02997 // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string 02998 $v1 = trim(reset($this->fields)); 02999 $v2 = ''.next($this->fields); 03000 $results[$v1] = $v2; 03001 adodb_movenext($this); 03002 } 03003 } 03004 } else { 03005 if ($numIndex) { 03006 while (!$this->EOF) { 03007 // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string 03008 $results[trim(($this->fields[0]))] = $this->fields[1]; 03009 $this->MoveNext(); 03010 } 03011 } else { 03012 while (!$this->EOF) { 03013 // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string 03014 $v1 = trim(reset($this->fields)); 03015 $v2 = ''.next($this->fields); 03016 $results[$v1] = $v2; 03017 $this->MoveNext(); 03018 } 03019 } 03020 } 03021 } 03022 03023 $ref =& $results; # workaround accelerator incompat with PHP 4.4 :( 03024 return $ref; 03025 } 03026 03027 03035 function UserTimeStamp($v,$fmt='Y-m-d H:i:s') 03036 { 03037 if (is_numeric($v) && strlen($v)<14) return adodb_date($fmt,$v); 03038 $tt = $this->UnixTimeStamp($v); 03039 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR 03040 if (($tt === false || $tt == -1) && $v != false) return $v; 03041 if ($tt === 0) return $this->emptyTimeStamp; 03042 return adodb_date($fmt,$tt); 03043 } 03044 03045 03052 function UserDate($v,$fmt='Y-m-d') 03053 { 03054 $tt = $this->UnixDate($v); 03055 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR 03056 if (($tt === false || $tt == -1) && $v != false) return $v; 03057 else if ($tt == 0) return $this->emptyDate; 03058 else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR 03059 } 03060 return adodb_date($fmt,$tt); 03061 } 03062 03063 03069 function UnixDate($v) 03070 { 03071 return ADOConnection::UnixDate($v); 03072 } 03073 03074 03080 function UnixTimeStamp($v) 03081 { 03082 return ADOConnection::UnixTimeStamp($v); 03083 } 03084 03085 03089 function Free() 03090 { 03091 return $this->Close(); 03092 } 03093 03094 03098 function NumRows() 03099 { 03100 return $this->_numOfRows; 03101 } 03102 03103 03107 function NumCols() 03108 { 03109 return $this->_numOfFields; 03110 } 03111 03118 function &FetchRow() 03119 { 03120 if ($this->EOF) { 03121 $false = false; 03122 return $false; 03123 } 03124 $arr = $this->fields; 03125 $this->_currentRow++; 03126 if (!$this->_fetch()) $this->EOF = true; 03127 return $arr; 03128 } 03129 03130 03137 function FetchInto(&$arr) 03138 { 03139 if ($this->EOF) return (defined('PEAR_ERROR_RETURN')) ? new PEAR_Error('EOF',-1): false; 03140 $arr = $this->fields; 03141 $this->MoveNext(); 03142 return 1; // DB_OK 03143 } 03144 03145 03151 function MoveFirst() 03152 { 03153 if ($this->_currentRow == 0) return true; 03154 return $this->Move(0); 03155 } 03156 03157 03163 function MoveLast() 03164 { 03165 if ($this->_numOfRows >= 0) return $this->Move($this->_numOfRows-1); 03166 if ($this->EOF) return false; 03167 while (!$this->EOF) { 03168 $f = $this->fields; 03169 $this->MoveNext(); 03170 } 03171 $this->fields = $f; 03172 $this->EOF = false; 03173 return true; 03174 } 03175 03176 03182 function MoveNext() 03183 { 03184 if (!$this->EOF) { 03185 $this->_currentRow++; 03186 if ($this->_fetch()) return true; 03187 } 03188 $this->EOF = true; 03189 /* -- tested error handling when scrolling cursor -- seems useless. 03190 $conn = $this->connection; 03191 if ($conn && $conn->raiseErrorFn && ($errno = $conn->ErrorNo())) { 03192 $fn = $conn->raiseErrorFn; 03193 $fn($conn->databaseType,'MOVENEXT',$errno,$conn->ErrorMsg().' ('.$this->sql.')',$conn->host,$conn->database); 03194 } 03195 */ 03196 return false; 03197 } 03198 03199 03208 function Move($rowNumber = 0) 03209 { 03210 $this->EOF = false; 03211 if ($rowNumber == $this->_currentRow) return true; 03212 if ($rowNumber >= $this->_numOfRows) 03213 if ($this->_numOfRows != -1) $rowNumber = $this->_numOfRows-2; 03214 03215 if ($this->canSeek) { 03216 03217 if ($this->_seek($rowNumber)) { 03218 $this->_currentRow = $rowNumber; 03219 if ($this->_fetch()) { 03220 return true; 03221 } 03222 } else { 03223 $this->EOF = true; 03224 return false; 03225 } 03226 } else { 03227 if ($rowNumber < $this->_currentRow) return false; 03228 global $ADODB_EXTENSION; 03229 if ($ADODB_EXTENSION) { 03230 while (!$this->EOF && $this->_currentRow < $rowNumber) { 03231 adodb_movenext($this); 03232 } 03233 } else { 03234 03235 while (! $this->EOF && $this->_currentRow < $rowNumber) { 03236 $this->_currentRow++; 03237 03238 if (!$this->_fetch()) $this->EOF = true; 03239 } 03240 } 03241 return !($this->EOF); 03242 } 03243 03244 $this->fields = false; 03245 $this->EOF = true; 03246 return false; 03247 } 03248 03249 03258 function Fields($colname) 03259 { 03260 return $this->fields[$colname]; 03261 } 03262 03263 function GetAssocKeys($upper=true) 03264 { 03265 $this->bind = array(); 03266 for ($i=0; $i < $this->_numOfFields; $i++) { 03267 $o = $this->FetchField($i); 03268 if ($upper === 2) $this->bind[$o->name] = $i; 03269 else $this->bind[($upper) ? strtoupper($o->name) : strtolower($o->name)] = $i; 03270 } 03271 } 03272 03282 function &GetRowAssoc($upper=1) 03283 { 03284 $record = array(); 03285 // if (!$this->fields) return $record; 03286 03287 if (!$this->bind) { 03288 $this->GetAssocKeys($upper); 03289 } 03290 03291 foreach($this->bind as $k => $v) { 03292 $record[$k] = $this->fields[$v]; 03293 } 03294 03295 return $record; 03296 } 03297 03298 03304 function Close() 03305 { 03306 // free connection object - this seems to globally free the object 03307 // and not merely the reference, so don't do this... 03308 // $this->connection = false; 03309 if (!$this->_closed) { 03310 $this->_closed = true; 03311 return $this->_close(); 03312 } else 03313 return true; 03314 } 03315 03321 function RecordCount() {return $this->_numOfRows;} 03322 03323 03324 /* 03325 * If we are using PageExecute(), this will return the maximum possible rows 03326 * that can be returned when paging a recordset. 03327 */ 03328 function MaxRecordCount() 03329 { 03330 return ($this->_maxRecordCount) ? $this->_maxRecordCount : $this->RecordCount(); 03331 } 03332 03338 function RowCount() {return $this->_numOfRows;} 03339 03340 03349 function PO_RecordCount($table="", $condition="") { 03350 03351 $lnumrows = $this->_numOfRows; 03352 // the database doesn't support native recordcount, so we do a workaround 03353 if ($lnumrows == -1 && $this->connection) { 03354 IF ($table) { 03355 if ($condition) $condition = " WHERE " . $condition; 03356 $resultrows = &$this->connection->Execute("SELECT COUNT(*) FROM $table $condition"); 03357 if ($resultrows) $lnumrows = reset($resultrows->fields); 03358 } 03359 } 03360 return $lnumrows; 03361 } 03362 03363 03367 function CurrentRow() {return $this->_currentRow;} 03368 03374 function AbsolutePosition() {return $this->_currentRow;} 03375 03380 function FieldCount() {return $this->_numOfFields;} 03381 03382 03390 function &FetchField($fieldoffset) 03391 { 03392 // must be defined by child class 03393 } 03394 03399 function& FieldTypesArray() 03400 { 03401 $arr = array(); 03402 for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) 03403 $arr[] = $this->FetchField($i); 03404 return $arr; 03405 } 03406 03413 function &FetchObj() 03414 { 03415 $o =& $this->FetchObject(false); 03416 return $o; 03417 } 03418 03427 function &FetchObject($isupper=true) 03428 { 03429 if (empty($this->_obj)) { 03430 $this->_obj = new ADOFetchObj(); 03431 $this->_names = array(); 03432 for ($i=0; $i <$this->_numOfFields; $i++) { 03433 $f = $this->FetchField($i); 03434 $this->_names[] = $f->name; 03435 } 03436 } 03437 $i = 0; 03438 if (PHP_VERSION >= 5) $o = clone($this->_obj); 03439 else $o = $this->_obj; 03440 03441 for ($i=0; $i <$this->_numOfFields; $i++) { 03442 $name = $this->_names[$i]; 03443 if ($isupper) $n = strtoupper($name); 03444 else $n = $name; 03445 03446 $o->$n = $this->Fields($name); 03447 } 03448 return $o; 03449 } 03450 03460 function &FetchNextObj() 03461 { 03462 $o =& $this->FetchNextObject(false); 03463 return $o; 03464 } 03465 03466 03478 function &FetchNextObject($isupper=true) 03479 { 03480 $o = false; 03481 if ($this->_numOfRows != 0 && !$this->EOF) { 03482 $o = $this->FetchObject($isupper); 03483 $this->_currentRow++; 03484 if ($this->_fetch()) return $o; 03485 } 03486 $this->EOF = true; 03487 return $o; 03488 } 03489 03514 function MetaType($t,$len=-1,$fieldobj=false) 03515 { 03516 if (is_object($t)) { 03517 $fieldobj = $t; 03518 $t = $fieldobj->type; 03519 $len = $fieldobj->max_length; 03520 } 03521 // changed in 2.32 to hashing instead of switch stmt for speed... 03522 static $typeMap = array( 03523 'VARCHAR' => 'C', 03524 'VARCHAR2' => 'C', 03525 'CHAR' => 'C', 03526 'C' => 'C', 03527 'STRING' => 'C', 03528 'NCHAR' => 'C', 03529 'NVARCHAR' => 'C', 03530 'VARYING' => 'C', 03531 'BPCHAR' => 'C', 03532 'CHARACTER' => 'C', 03533 'INTERVAL' => 'C', # Postgres 03534 'MACADDR' => 'C', # postgres 03535 ## 03536 'LONGCHAR' => 'X', 03537 'TEXT' => 'X', 03538 'NTEXT' => 'X', 03539 'M' => 'X', 03540 'X' => 'X', 03541 'CLOB' => 'X', 03542 'NCLOB' => 'X', 03543 'LVARCHAR' => 'X', 03544 ## 03545 'BLOB' => 'B', 03546 'IMAGE' => 'B', 03547 'BINARY' => 'B', 03548 'VARBINARY' => 'B', 03549 'LONGBINARY' => 'B', 03550 'B' => 'B', 03551 ## 03552 'YEAR' => 'D', // mysql 03553 'DATE' => 'D', 03554 'D' => 'D', 03555 ## 03556 'UNIQUEIDENTIFIER' => 'C', # MS SQL Server 03557 ## 03558 'TIME' => 'T', 03559 'TIMESTAMP' => 'T', 03560 'DATETIME' => 'T', 03561 'TIMESTAMPTZ' => 'T', 03562 'T' => 'T', 03563 'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql 03564 ## 03565 'BOOL' => 'L', 03566 'BOOLEAN' => 'L', 03567 'BIT' => 'L', 03568 'L' => 'L', 03569 ## 03570 'COUNTER' => 'R', 03571 'R' => 'R', 03572 'SERIAL' => 'R', // ifx 03573 'INT IDENTITY' => 'R', 03574 ## 03575 'INT' => 'I', 03576 'INT2' => 'I', 03577 'INT4' => 'I', 03578 'INT8' => 'I', 03579 'INTEGER' => 'I', 03580 'INTEGER UNSIGNED' => 'I', 03581 'SHORT' => 'I', 03582 'TINYINT' => 'I', 03583 'SMALLINT' => 'I', 03584 'I' => 'I', 03585 ## 03586 'LONG' => 'N', // interbase is numeric, oci8 is blob 03587 'BIGINT' => 'N', // this is bigger than PHP 32-bit integers 03588 'DECIMAL' => 'N', 03589 'DEC' => 'N', 03590 'REAL' => 'N', 03591 'DOUBLE' => 'N', 03592 'DOUBLE PRECISION' => 'N', 03593 'SMALLFLOAT' => 'N', 03594 'FLOAT' => 'N', 03595 'NUMBER' => 'N', 03596 'NUM' => 'N', 03597 'NUMERIC' => 'N', 03598 'MONEY' => 'N', 03599 03600 ## informix 9.2 03601 'SQLINT' => 'I', 03602 'SQLSERIAL' => 'I', 03603 'SQLSMINT' => 'I', 03604 'SQLSMFLOAT' => 'N', 03605 'SQLFLOAT' => 'N', 03606 'SQLMONEY' => 'N', 03607 'SQLDECIMAL' => 'N', 03608 'SQLDATE' => 'D', 03609 'SQLVCHAR' => 'C', 03610 'SQLCHAR' => 'C', 03611 'SQLDTIME' => 'T', 03612 'SQLINTERVAL' => 'N', 03613 'SQLBYTES' => 'B', 03614 'SQLTEXT' => 'X', 03615 ## informix 10 03616 "SQLINT8" => 'I8', 03617 "SQLSERIAL8" => 'I8', 03618 "SQLNCHAR" => 'C', 03619 "SQLNVCHAR" => 'C', 03620 "SQLLVARCHAR" => 'X', 03621 "SQLBOOL" => 'L' 03622 ); 03623 03624 $tmap = false; 03625 $t = strtoupper($t); 03626 $tmap = (isset($typeMap[$t])) ? $typeMap[$t] : 'N'; 03627 switch ($tmap) { 03628 case 'C': 03629 03630 // is the char field is too long, return as text field... 03631 if ($this->blobSize >= 0) { 03632 if ($len > $this->blobSize) return 'X'; 03633 } else if ($len > 250) { 03634 return 'X'; 03635 } 03636 return 'C'; 03637 03638 case 'I': 03639 if (!empty($fieldobj->primary_key)) return 'R'; 03640 return 'I'; 03641 03642 case false: 03643 return 'N'; 03644 03645 case 'B': 03646 if (isset($fieldobj->binary)) 03647 return ($fieldobj->binary) ? 'B' : 'X'; 03648 return 'B'; 03649 03650 case 'D': 03651 if (!empty($this->connection) && !empty($this->connection->datetime)) return 'T'; 03652 return 'D'; 03653 03654 default: 03655 if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B'; 03656 return $tmap; 03657 } 03658 } 03659 03660 03661 function _close() {} 03662 03666 function AbsolutePage($page=-1) 03667 { 03668 if ($page != -1) $this->_currentPage = $page; 03669 return $this->_currentPage; 03670 } 03671 03675 function AtFirstPage($status=false) 03676 { 03677 if ($status != false) $this->_atFirstPage = $status; 03678 return $this->_atFirstPage; 03679 } 03680 03681 function LastPageNo($page = false) 03682 { 03683 if ($page != false) $this->_lastPageNo = $page; 03684 return $this->_lastPageNo; 03685 } 03686 03690 function AtLastPage($status=false) 03691 { 03692 if ($status != false) $this->_atLastPage = $status; 03693 return $this->_atLastPage; 03694 } 03695 03696 } // end class ADORecordSet 03697 03698 //============================================================================================== 03699 // CLASS ADORecordSet_array 03700 //============================================================================================== 03701 03709 class ADORecordSet_array extends ADORecordSet 03710 { 03711 var $databaseType = 'array'; 03712 03713 var $_array; // holds the 2-dimensional data array 03714 var $_types; // the array of types of each column (C B I L M) 03715 var $_colnames; // names of each column in array 03716 var $_skiprow1; // skip 1st row because it holds column names 03717 var $_fieldobjects; // holds array of field objects 03718 var $canSeek = true; 03719 var $affectedrows = false; 03720 var $insertid = false; 03721 var $sql = ''; 03722 var $compat = false; 03727 function ADORecordSet_array($fakeid=1) 03728 { 03729 global $ADODB_FETCH_MODE,$ADODB_COMPAT_FETCH; 03730 03731 // fetch() on EOF does not delete $this->fields 03732 $this->compat = !empty($ADODB_COMPAT_FETCH); 03733 $this->ADORecordSet($fakeid); // fake queryID 03734 $this->fetchMode = $ADODB_FETCH_MODE; 03735 } 03736 03737 function _transpose() 03738 { 03739 global $ADODB_INCLUDED_LIB; 03740 03741 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 03742 $hdr = true; 03743 03744 adodb_transpose($this->_array, $newarr, $hdr); 03745 //adodb_pr($newarr); 03746 03747 $this->_skiprow1 = false; 03748 $this->_array =& $newarr; 03749 $this->_colnames = $hdr; 03750 03751 adodb_probetypes($newarr,$this->_types); 03752 03753 $this->_fieldobjects = array(); 03754 03755 foreach($hdr as $k => $name) { 03756 $f = new ADOFieldObject(); 03757 $f->name = $name; 03758 $f->type = $this->_types[$k]; 03759 $f->max_length = -1; 03760 $this->_fieldobjects[] = $f; 03761 03762 } 03763 $this->fields = reset($this->_array); 03764 03765 $this->_initrs(); 03766 03767 } 03768 03780 function InitArray($array,$typearr,$colnames=false) 03781 { 03782 $this->_array = $array; 03783 $this->_types = $typearr; 03784 if ($colnames) { 03785 $this->_skiprow1 = false; 03786 $this->_colnames = $colnames; 03787 } else { 03788 $this->_skiprow1 = true; 03789 $this->_colnames = $array[0]; 03790 } 03791 $this->Init(); 03792 } 03801 function InitArrayFields(&$array,&$fieldarr) 03802 { 03803 $this->_array =& $array; 03804 $this->_skiprow1= false; 03805 if ($fieldarr) { 03806 $this->_fieldobjects =& $fieldarr; 03807 } 03808 $this->Init(); 03809 } 03810 03811 function &GetArray($nRows=-1) 03812 { 03813 if ($nRows == -1 && $this->_currentRow <= 0 && !$this->_skiprow1) { 03814 return $this->_array; 03815 } else { 03816 $arr =& ADORecordSet::GetArray($nRows); 03817 return $arr; 03818 } 03819 } 03820 03821 function _initrs() 03822 { 03823 $this->_numOfRows = sizeof($this->_array); 03824 if ($this->_skiprow1) $this->_numOfRows -= 1; 03825 03826 $this->_numOfFields =(isset($this->_fieldobjects)) ? 03827 sizeof($this->_fieldobjects):sizeof($this->_types); 03828 } 03829 03830 /* Use associative array to get fields array */ 03831 function Fields($colname) 03832 { 03833 $mode = isset($this->adodbFetchMode) ? $this->adodbFetchMode : $this->fetchMode; 03834 03835 if ($mode & ADODB_FETCH_ASSOC) { 03836 if (!isset($this->fields[$colname])) $colname = strtolower($colname); 03837 return $this->fields[$colname]; 03838 } 03839 if (!$this->bind) { 03840 $this->bind = array(); 03841 for ($i=0; $i < $this->_numOfFields; $i++) { 03842 $o = $this->FetchField($i); 03843 $this->bind[strtoupper($o->name)] = $i; 03844 } 03845 } 03846 return $this->fields[$this->bind[strtoupper($colname)]]; 03847 } 03848 03849 function &FetchField($fieldOffset = -1) 03850 { 03851 if (isset($this->_fieldobjects)) { 03852 return $this->_fieldobjects[$fieldOffset]; 03853 } 03854 $o = new ADOFieldObject(); 03855 $o->name = $this->_colnames[$fieldOffset]; 03856 $o->type = $this->_types[$fieldOffset]; 03857 $o->max_length = -1; // length not known 03858 03859 return $o; 03860 } 03861 03862 function _seek($row) 03863 { 03864 if (sizeof($this->_array) && 0 <= $row && $row < $this->_numOfRows) { 03865 $this->_currentRow = $row; 03866 if ($this->_skiprow1) $row += 1; 03867 $this->fields = $this->_array[$row]; 03868 return true; 03869 } 03870 return false; 03871 } 03872 03873 function MoveNext() 03874 { 03875 if (!$this->EOF) { 03876 $this->_currentRow++; 03877 03878 $pos = $this->_currentRow; 03879 03880 if ($this->_numOfRows <= $pos) { 03881 if (!$this->compat) $this->fields = false; 03882 } else { 03883 if ($this->_skiprow1) $pos += 1; 03884 $this->fields = $this->_array[$pos]; 03885 return true; 03886 } 03887 $this->EOF = true; 03888 } 03889 03890 return false; 03891 } 03892 03893 function _fetch() 03894 { 03895 $pos = $this->_currentRow; 03896 03897 if ($this->_numOfRows <= $pos) { 03898 if (!$this->compat) $this->fields = false; 03899 return false; 03900 } 03901 if ($this->_skiprow1) $pos += 1; 03902 $this->fields = $this->_array[$pos]; 03903 return true; 03904 } 03905 03906 function _close() 03907 { 03908 return true; 03909 } 03910 03911 } // ADORecordSet_array 03912 03913 //============================================================================================== 03914 // HELPER FUNCTIONS 03915 //============================================================================================== 03916 03922 function ADOLoadDB($dbType) 03923 { 03924 return ADOLoadCode($dbType); 03925 } 03926 03930 function ADOLoadCode($dbType) 03931 { 03932 global $ADODB_LASTDB; 03933 03934 if (!$dbType) return false; 03935 $db = strtolower($dbType); 03936 switch ($db) { 03937 case 'ado': 03938 if (PHP_VERSION >= 5) $db = 'ado5'; 03939 $class = 'ado'; 03940 break; 03941 case 'ifx': 03942 case 'maxsql': $class = $db = 'mysqlt'; break; 03943 case 'postgres': 03944 case 'postgres8': 03945 case 'pgsql': $class = $db = 'postgres7'; break; 03946 default: 03947 $class = $db; break; 03948 } 03949 03950 $file = ADODB_DIR."/drivers/adodb-".$db.".inc.php"; 03951 @include_once($file); 03952 $ADODB_LASTDB = $class; 03953 if (class_exists("ADODB_" . $class)) return $class; 03954 03955 //ADOConnection::outp(adodb_pr(get_declared_classes(),true)); 03956 if (!file_exists($file)) ADOConnection::outp("Missing file: $file"); 03957 else ADOConnection::outp("Syntax error in file: $file"); 03958 return false; 03959 } 03960 03964 function &NewADOConnection($db='') 03965 { 03966 $tmp =& ADONewConnection($db); 03967 return $tmp; 03968 } 03969 03978 function &ADONewConnection($db='') 03979 { 03980 GLOBAL $ADODB_NEWCONNECTION, $ADODB_LASTDB; 03981 03982 if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2); 03983 $errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false; 03984 $false = false; 03985 if ($at = strpos($db,'://')) { 03986 $origdsn = $db; 03987 if (PHP_VERSION < 5) $dsna = @parse_url($db); 03988 else { 03989 $fakedsn = 'fake'.substr($db,$at); 03990 $dsna = @parse_url($fakedsn); 03991 $dsna['scheme'] = substr($db,0,$at); 03992 03993 if (strncmp($db,'pdo',3) == 0) { 03994 $sch = explode('_',$dsna['scheme']); 03995 if (sizeof($sch)>1) { 03996 $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; 03997 $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host'])); 03998 $dsna['scheme'] = 'pdo'; 03999 } 04000 } 04001 } 04002 04003 if (!$dsna) { 04004 // special handling of oracle, which might not have host 04005 $db = str_replace('@/','@adodb-fakehost/',$db); 04006 $dsna = parse_url($db); 04007 if (!$dsna) return $false; 04008 $dsna['host'] = ''; 04009 } 04010 $db = @$dsna['scheme']; 04011 if (!$db) return $false; 04012 $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; 04013 $dsna['user'] = isset($dsna['user']) ? rawurldecode($dsna['user']) : ''; 04014 $dsna['pass'] = isset($dsna['pass']) ? rawurldecode($dsna['pass']) : ''; 04015 $dsna['path'] = isset($dsna['path']) ? rawurldecode(substr($dsna['path'],1)) : ''; # strip off initial / 04016 04017 if (isset($dsna['query'])) { 04018 $opt1 = explode('&',$dsna['query']); 04019 foreach($opt1 as $k => $v) { 04020 $arr = explode('=',$v); 04021 $opt[$arr[0]] = isset($arr[1]) ? rawurldecode($arr[1]) : 1; 04022 } 04023 } else $opt = array(); 04024 } 04025 /* 04026 * phptype: Database backend used in PHP (mysql, odbc etc.) 04027 * dbsyntax: Database used with regards to SQL syntax etc. 04028 * protocol: Communication protocol to use (tcp, unix etc.) 04029 * hostspec: Host specification (hostname[:port]) 04030 * database: Database to use on the DBMS server 04031 * username: User name for login 04032 * password: Password for login 04033 */ 04034 if (!empty($ADODB_NEWCONNECTION)) { 04035 $obj = $ADODB_NEWCONNECTION($db); 04036 04037 } else { 04038 04039 if (!isset($ADODB_LASTDB)) $ADODB_LASTDB = ''; 04040 if (empty($db)) $db = $ADODB_LASTDB; 04041 04042 if ($db != $ADODB_LASTDB) $db = ADOLoadCode($db); 04043 04044 if (!$db) { 04045 if (isset($origdsn)) $db = $origdsn; 04046 if ($errorfn) { 04047 // raise an error 04048 $ignore = false; 04049 $errorfn('ADONewConnection', 'ADONewConnection', -998, 04050 "could not load the database driver for '$db'", 04051 $db,false,$ignore); 04052 } else 04053 ADOConnection::outp( "<p>ADONewConnection: Unable to load database driver '$db'</p>",false); 04054 04055 return $false; 04056 } 04057 04058 $cls = 'ADODB_'.$db; 04059 if (!class_exists($cls)) { 04060 adodb_backtrace(); 04061 return $false; 04062 } 04063 04064 $obj = new $cls(); 04065 } 04066 04067 # constructor should not fail 04068 if ($obj) { 04069 if ($errorfn) $obj->raiseErrorFn = $errorfn; 04070 if (isset($dsna)) { 04071 if (isset($dsna['port'])) $obj->port = $dsna['port']; 04072 foreach($opt as $k => $v) { 04073 switch(strtolower($k)) { 04074 case 'new': 04075 $nconnect = true; $persist = true; break; 04076 case 'persist': 04077 case 'persistent': $persist = $v; break; 04078 case 'debug': $obj->debug = (integer) $v; break; 04079 #ibase 04080 case 'role': $obj->role = $v; break; 04081 case 'dialect': $obj->dialect = (integer) $v; break; 04082 case 'charset': $obj->charset = $v; $obj->charSet=$v; break; 04083 case 'buffers': $obj->buffers = $v; break; 04084 case 'fetchmode': $obj->SetFetchMode($v); break; 04085 #ado 04086 case 'charpage': $obj->charPage = $v; break; 04087 #mysql, mysqli 04088 case 'clientflags': $obj->clientFlags = $v; break; 04089 #mysql, mysqli, postgres 04090 case 'port': $obj->port = $v; break; 04091 #mysqli 04092 case 'socket': $obj->socket = $v; break; 04093 #oci8 04094 case 'nls_date_format': $obj->NLS_DATE_FORMAT = $v; break; 04095 } 04096 } 04097 if (empty($persist)) 04098 $ok = $obj->Connect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']); 04099 else if (empty($nconnect)) 04100 $ok = $obj->PConnect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']); 04101 else 04102 $ok = $obj->NConnect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']); 04103 04104 if (!$ok) return $false; 04105 } 04106 } 04107 return $obj; 04108 } 04109 04110 04111 04112 // $perf == true means called by NewPerfMonitor(), otherwise for data dictionary 04113 function _adodb_getdriver($provider,$drivername,$perf=false) 04114 { 04115 switch ($provider) { 04116 case 'odbtp': if (strncmp('odbtp_',$drivername,6)==0) return substr($drivername,6); 04117 case 'odbc' : if (strncmp('odbc_',$drivername,5)==0) return substr($drivername,5); 04118 case 'ado' : if (strncmp('ado_',$drivername,4)==0) return substr($drivername,4); 04119 case 'native': break; 04120 default: 04121 return $provider; 04122 } 04123 04124 switch($drivername) { 04125 case 'mysqlt': 04126 case 'mysqli': 04127 $drivername='mysql'; 04128 break; 04129 case 'postgres7': 04130 case 'postgres8': 04131 $drivername = 'postgres'; 04132 break; 04133 case 'firebird15': $drivername = 'firebird'; break; 04134 case 'oracle': $drivername = 'oci8'; break; 04135 case 'access': if ($perf) $drivername = ''; break; 04136 case 'db2' : break; 04137 case 'sapdb' : break; 04138 default: 04139 $drivername = 'generic'; 04140 break; 04141 } 04142 return $drivername; 04143 } 04144 04145 function &NewPerfMonitor(&$conn) 04146 { 04147 $false = false; 04148 $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType,true); 04149 if (!$drivername || $drivername == 'generic') return $false; 04150 include_once(ADODB_DIR.'/adodb-perf.inc.php'); 04151 @include_once(ADODB_DIR."/perf/perf-$drivername.inc.php"); 04152 $class = "Perf_$drivername"; 04153 if (!class_exists($class)) return $false; 04154 $perf = new $class($conn); 04155 04156 return $perf; 04157 } 04158 04159 function &NewDataDictionary(&$conn,$drivername=false) 04160 { 04161 $false = false; 04162 if (!$drivername) $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType); 04163 04164 include_once(ADODB_DIR.'/adodb-lib.inc.php'); 04165 include_once(ADODB_DIR.'/adodb-datadict.inc.php'); 04166 $path = ADODB_DIR."/datadict/datadict-$drivername.inc.php"; 04167 04168 if (!file_exists($path)) { 04169 ADOConnection::outp("Dictionary driver '$path' not available"); 04170 return $false; 04171 } 04172 include_once($path); 04173 $class = "ADODB2_$drivername"; 04174 $dict = new $class(); 04175 $dict->dataProvider = $conn->dataProvider; 04176 $dict->connection = &$conn; 04177 $dict->upperName = strtoupper($drivername); 04178 $dict->quote = $conn->nameQuote; 04179 if (!empty($conn->_connectionID)) 04180 $dict->serverInfo = $conn->ServerInfo(); 04181 04182 return $dict; 04183 } 04184 04185 04186 04187 /* 04188 Perform a print_r, with pre tags for better formatting. 04189 */ 04190 function adodb_pr($var,$as_string=false) 04191 { 04192 if ($as_string) ob_start(); 04193 04194 if (isset($_SERVER['HTTP_USER_AGENT'])) { 04195 echo " <pre>\n";print_r($var);echo "</pre>\n"; 04196 } else 04197 print_r($var); 04198 04199 if ($as_string) { 04200 $s = ob_get_contents(); 04201 ob_end_clean(); 04202 return $s; 04203 } 04204 } 04205 04206 /* 04207 Perform a stack-crawl and pretty print it. 04208 04209 @param printOrArr Pass in a boolean to indicate print, or an $exception->trace array (assumes that print is true then). 04210 @param levels Number of levels to display 04211 */ 04212 function adodb_backtrace($printOrArr=true,$levels=9999) 04213 { 04214 global $ADODB_INCLUDED_LIB; 04215 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php'); 04216 return _adodb_backtrace($printOrArr,$levels); 04217 } 04218 04219 04220 } 04221 ?>