Documentation TYPO3 par Ameos

adodb.inc.php

00001 <?php 
00002 /*
00003  * Set tabs to 4 for best viewing.
00004  * 
00005  * Latest version is available at http://adodb.sourceforge.net
00006  * 
00007  * This is the main include file for ADOdb.
00008  * Database specific drivers are stored in the adodb/drivers/adodb-*.inc.php
00009  *
00010  * The ADOdb files are formatted so that doxygen can be used to generate documentation.
00011  * Doxygen is a documentation generation tool and can be downloaded from http://doxygen.org/
00012  */
00013 
00035  if (!defined('_ADODB_LAYER')) {
00036         define('_ADODB_LAYER',1);
00037         
00038         //==============================================================================================        
00039         // CONSTANT DEFINITIONS
00040         //==============================================================================================        
00041 
00042 
00047         if (!defined('ADODB_DIR')) define('ADODB_DIR',dirname(__FILE__));
00048         
00049         //==============================================================================================        
00050         // GLOBAL VARIABLES
00051         //==============================================================================================        
00052 
00053         GLOBAL 
00054                 $ADODB_vers,            // database version
00055                 $ADODB_COUNTRECS,       // count number of records returned - slows down query
00056                 $ADODB_CACHE_DIR,       // directory to cache recordsets
00057                 $ADODB_EXTENSION,   // ADODB extension installed
00058                 $ADODB_COMPAT_FETCH, // If $ADODB_COUNTRECS and this is true, $rs->fields is available on EOF
00059                 $ADODB_FETCH_MODE;      // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default...
00060         
00061         //==============================================================================================        
00062         // GLOBAL SETUP
00063         //==============================================================================================        
00064         
00065         $ADODB_EXTENSION = defined('ADODB_EXTENSION');
00066         
00067         //********************************************************//
00068         /*
00069         Controls $ADODB_FORCE_TYPE mode. Default is ADODB_FORCE_VALUE (3).
00070         Used in GetUpdateSql and GetInsertSql functions. Thx to Niko, nuko#mbnet.fi
00071 
00072                 0 = ignore empty fields. All empty fields in array are ignored.
00073                 1 = force null. All empty, php null and string 'null' fields are changed to sql NULL values.
00074                 2 = force empty. All empty, php null and string 'null' fields are changed to sql empty '' or 0 values.
00075                 3 = force value. Value is left as it is. Php null and string 'null' are set to sql NULL values and empty fields '' are set to empty '' sql values.
00076         */
00077         define('ADODB_FORCE_IGNORE',0);
00078         define('ADODB_FORCE_NULL',1);
00079         define('ADODB_FORCE_EMPTY',2);
00080         define('ADODB_FORCE_VALUE',3);
00081     //********************************************************//
00082 
00083 
00084         if (!$ADODB_EXTENSION || ADODB_EXTENSION < 4.0) {
00085                 
00086                 define('ADODB_BAD_RS','<p>Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;</p>');
00087         
00088         // allow [ ] @ ` " and . in table names
00089                 define('ADODB_TABLE_REGEX','([]0-9a-z_\:\"\`\.\@\[-]*)');
00090         
00091         // prefetching used by oracle
00092                 if (!defined('ADODB_PREFETCH_ROWS')) define('ADODB_PREFETCH_ROWS',10);
00093         
00094         
00095         /*
00096         Controls ADODB_FETCH_ASSOC field-name case. Default is 2, use native case-names.
00097         This currently works only with mssql, odbc, oci8po and ibase derived drivers.
00098         
00099                 0 = assoc lowercase field names. $rs->fields['orderid']
00100                 1 = assoc uppercase field names. $rs->fields['ORDERID']
00101                 2 = use native-case field names. $rs->fields['OrderID']
00102         */
00103         
00104                 define('ADODB_FETCH_DEFAULT',0);
00105                 define('ADODB_FETCH_NUM',1);
00106                 define('ADODB_FETCH_ASSOC',2);
00107                 define('ADODB_FETCH_BOTH',3);
00108                 
00109                 if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
00110         
00111                 // PHP's version scheme makes converting to numbers difficult - workaround
00112                 $_adodb_ver = (float) PHP_VERSION;
00113                 if ($_adodb_ver >= 5.0) {
00114                         define('ADODB_PHPVER',0x5000);
00115                 } else if ($_adodb_ver > 4.299999) { # 4.3
00116                         define('ADODB_PHPVER',0x4300);
00117                 } else if ($_adodb_ver > 4.199999) { # 4.2
00118                         define('ADODB_PHPVER',0x4200);
00119                 } else if (strnatcmp(PHP_VERSION,'4.0.5')>=0) {
00120                         define('ADODB_PHPVER',0x4050);
00121                 } else {
00122                         define('ADODB_PHPVER',0x4000);
00123                 }
00124         }
00125         
00126         //if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
00127 
00128         
00132         function ADODB_str_replace($src, $dest, $data)
00133         {
00134                 if (ADODB_PHPVER >= 0x4050) return str_replace($src,$dest,$data);
00135                 
00136                 $s = reset($src);
00137                 $d = reset($dest);
00138                 while ($s !== false) {
00139                         $data = str_replace($s,$d,$data);
00140                         $s = next($src);
00141                         $d = next($dest);
00142                 }
00143                 return $data;
00144         }
00145         
00146         function ADODB_Setup()
00147         {
00148         GLOBAL 
00149                 $ADODB_vers,            // database version
00150                 $ADODB_COUNTRECS,       // count number of records returned - slows down query
00151                 $ADODB_CACHE_DIR,       // directory to cache recordsets
00152                 $ADODB_FETCH_MODE,
00153                 $ADODB_FORCE_TYPE;
00154                 
00155                 $ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT;
00156                 $ADODB_FORCE_TYPE = ADODB_FORCE_VALUE;
00157 
00158 
00159                 if (!isset($ADODB_CACHE_DIR)) {
00160                         $ADODB_CACHE_DIR = '/tmp'; //(isset($_ENV['TMP'])) ? $_ENV['TMP'] : '/tmp';
00161                 } else {
00162                         // do not accept url based paths, eg. http:/ or ftp:/
00163                         if (strpos($ADODB_CACHE_DIR,'://') !== false) 
00164                                 die("Illegal path http:// or ftp://");
00165                 }
00166                 
00167                         
00168                 // Initialize random number generator for randomizing cache flushes
00169                 srand(((double)microtime())*1000000);
00170                 
00174                 $ADODB_vers = 'V4.90 8 June 2006  (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.';
00175         
00181                 if (!isset($ADODB_COUNTRECS)) $ADODB_COUNTRECS = true; 
00182         }
00183         
00184         
00185         //==============================================================================================        
00186         // CHANGE NOTHING BELOW UNLESS YOU ARE DESIGNING ADODB
00187         //==============================================================================================        
00188         
00189         ADODB_Setup();
00190 
00191         //==============================================================================================        
00192         // CLASS ADOFieldObject
00193         //==============================================================================================        
00197         class ADOFieldObject { 
00198                 var $name = '';
00199                 var $max_length=0;
00200                 var $type="";
00201 /*
00202                 // additional fields by dannym... (danny_milo@yahoo.com)
00203                 var $not_null = false; 
00204                 // actually, this has already been built-in in the postgres, fbsql AND mysql module? ^-^
00205                 // so we can as well make not_null standard (leaving it at "false" does not harm anyways)
00206 
00207                 var $has_default = false; // this one I have done only in mysql and postgres for now ... 
00208                         // others to come (dannym)
00209                 var $default_value; // default, if any, and supported. Check has_default first.
00210 */
00211         }
00212         
00213 
00214         
00215         function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection)
00216         {
00217                 //print "Errorno ($fn errno=$errno m=$errmsg) ";
00218                 $thisConnection->_transOK = false;
00219                 if ($thisConnection->_oldRaiseFn) {
00220                         $fn = $thisConnection->_oldRaiseFn;
00221                         $fn($dbms, $fn, $errno, $errmsg, $p1, $p2,$thisConnection);
00222                 }
00223         }
00224         
00225         //==============================================================================================        
00226         // CLASS ADOConnection
00227         //==============================================================================================        
00228         
00232         class ADOConnection {
00233         //
00234         // PUBLIC VARS 
00235         //
00236         var $dataProvider = 'native';
00237         var $databaseType = '';         
00238         var $database = '';                     
00239         var $host = '';                         
00240         var $user = '';                         
00241         var $password = '';             
00242         var $debug = false;             
00243         var $maxblobsize = 262144;      
00244         var $concat_operator = '+'; 
00245         var $substr = 'substr';         
00246         var $length = 'length';         
00247         var $random = 'rand()';         
00248         var $upperCase = 'upper';               
00249         var $fmtDate = "'Y-m-d'";       
00250         var $fmtTimeStamp = "'Y-m-d, h:i:s A'"; 
00251         var $true = '1';                        
00252         var $false = '0';                       
00253         var $replaceQuote = "\\'";      
00254         var $nameQuote = '"';           
00255         var $charSet=false;             
00256         var $metaDatabasesSQL = '';
00257         var $metaTablesSQL = '';
00258         var $uniqueOrderBy = false; 
00259         var $emptyDate = '&nbsp;';
00260         var $emptyTimeStamp = '&nbsp;';
00261         var $lastInsID = false;
00262         //--
00263         var $hasInsertID = false;               
00264         var $hasAffectedRows = false;   
00265         var $hasTop = false;                    
00266         var $hasLimit = false;                  
00267         var $readOnly = false;                  
00268         var $hasMoveFirst = false;  
00269         var $hasGenID = false;          
00270         var $hasTransactions = true; 
00271         //--
00272         var $genID = 0;                         
00273         var $raiseErrorFn = false;      
00274         var $isoDates = false; 
00275         var $cacheSecs = 3600; 
00276         var $sysDate = false; 
00277         var $sysTimeStamp = false; 
00278         var $arrayClass = 'ADORecordSet_array'; 
00279         
00280         var $noNullStrings = false; 
00281         var $numCacheHits = 0; 
00282         var $numCacheMisses = 0;
00283         var $pageExecuteCountRows = true;
00284         var $uniqueSort = false; 
00285         var $leftOuter = false; 
00286         var $rightOuter = false; 
00287         var $ansiOuter = false; 
00288         var $autoRollback = false; // autoRollback on PConnect().
00289         var $poorAffectedRows = false; // affectedRows not working or unreliable
00290         
00291         var $fnExecute = false;
00292         var $fnCacheExecute = false;
00293         var $blobEncodeType = false; // false=not required, 'I'=encode to integer, 'C'=encode to char
00294         var $rsPrefix = "ADORecordSet_";
00295         
00296         var $autoCommit = true;         
00297         var $transOff = 0;                      
00298         var $transCnt = 0;                      
00299         
00300         var $fetchMode=false;
00301          //
00302          // PRIVATE VARS
00303          //
00304         var $_oldRaiseFn =  false;
00305         var $_transOK = null;
00306         var $_connectionID      = false;        
00307         var $_errorMsg = false;         
00308 
00309         var $_errorCode = false;        
00310         var $_queryID = false;          
00311         
00312         var $_isPersistentConnection = false;   
00313         var $_bindInputArray = false; 
00314         var $_evalAll = false;
00315         var $_affected = false;
00316         var $_logsql = false;
00317         var $_transmode = ''; // transaction mode
00318         
00322         function ADOConnection()                        
00323         {
00324                 die('Virtual Class -- cannot instantiate');
00325         }
00326         
00327         function Version()
00328         {
00329         global $ADODB_vers;
00330         
00331                 return (float) substr($ADODB_vers,1);
00332         }
00333         
00340         function ServerInfo()
00341         {
00342                 return array('description' => '', 'version' => '');
00343         }
00344         
00345         function IsConnected()
00346         {
00347         return !empty($this->_connectionID);
00348         }
00349         
00350         function _findvers($str)
00351         {
00352                 if (preg_match('/([0-9]+\.([0-9\.])+)/',$str, $arr)) return $arr[1];
00353                 else return '';
00354         }
00355         
00360         function outp($msg,$newline=true)
00361         {
00362         global $ADODB_FLUSH,$ADODB_OUTP;
00363         
00364                 if (defined('ADODB_OUTP')) {
00365                         $fn = ADODB_OUTP;
00366                         $fn($msg,$newline);
00367                         return;
00368                 } else if (isset($ADODB_OUTP)) {
00369                         $fn = $ADODB_OUTP;
00370                         $fn($msg,$newline);
00371                         return;
00372                 }
00373                 
00374                 if ($newline) $msg .= "<br>\n";
00375                 
00376                 if (isset($_SERVER['HTTP_USER_AGENT']) || !$newline) echo $msg;
00377                 else echo strip_tags($msg);
00378         
00379                 
00380                 if (!empty($ADODB_FLUSH) && ob_get_length() !== false) flush(); //  do not flush if output buffering enabled - useless - thx to Jesse Mullan 
00381                 
00382         }
00383         
00384         function Time()
00385         {
00386                 $rs =& $this->_Execute("select $this->sysTimeStamp");
00387                 if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
00388                 
00389                 return false;
00390         }
00391         
00403         function Connect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "", $forceNew = false) 
00404         {
00405                 if ($argHostname != "") $this->host = $argHostname;
00406                 if ($argUsername != "") $this->user = $argUsername;
00407                 if ($argPassword != "") $this->password = $argPassword; // not stored for security reasons
00408                 if ($argDatabaseName != "") $this->database = $argDatabaseName;         
00409                 
00410                 $this->_isPersistentConnection = false; 
00411                 if ($forceNew) {
00412                         if ($rez=$this->_nconnect($this->host, $this->user, $this->password, $this->database)) return true;
00413                 } else {
00414                          if ($rez=$this->_connect($this->host, $this->user, $this->password, $this->database)) return true;
00415                 }
00416                 if (isset($rez)) {
00417                         $err = $this->ErrorMsg();
00418                         if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'";
00419                         $ret = false;
00420                 } else {
00421                         $err = "Missing extension for ".$this->dataProvider;
00422                         $ret = 0;
00423                 }
00424                 if ($fn = $this->raiseErrorFn) 
00425                         $fn($this->databaseType,'CONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this);
00426                 
00427                 
00428                 $this->_connectionID = false;
00429                 if ($this->debug) ADOConnection::outp( $this->host.': '.$err);
00430                 return $ret;
00431         }       
00432         
00433         function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName)
00434         {
00435                 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName);
00436         }
00437         
00438         
00449         function NConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") 
00450         {
00451                 return $this->Connect($argHostname, $argUsername, $argPassword, $argDatabaseName, true);
00452         }
00453         
00464         function PConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "")
00465         {
00466                 if (defined('ADODB_NEVER_PERSIST')) 
00467                         return $this->Connect($argHostname,$argUsername,$argPassword,$argDatabaseName);
00468                 
00469                 if ($argHostname != "") $this->host = $argHostname;
00470                 if ($argUsername != "") $this->user = $argUsername;
00471                 if ($argPassword != "") $this->password = $argPassword;
00472                 if ($argDatabaseName != "") $this->database = $argDatabaseName;         
00473                         
00474                 $this->_isPersistentConnection = true;  
00475                 if ($rez = $this->_pconnect($this->host, $this->user, $this->password, $this->database)) return true;
00476                 if (isset($rez)) {
00477                         $err = $this->ErrorMsg();
00478                         if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'";
00479                         $ret = false;
00480                 } else {
00481                         $err = "Missing extension for ".$this->dataProvider;
00482                         $ret = 0;
00483                 }
00484                 if ($fn = $this->raiseErrorFn) {
00485                         $fn($this->databaseType,'PCONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this);
00486                 }
00487                 
00488                 $this->_connectionID = false;
00489                 if ($this->debug) ADOConnection::outp( $this->host.': '.$err);
00490                 return $ret;
00491         }
00492 
00493         // Format date column in sql string given an input format that understands Y M D
00494         function SQLDate($fmt, $col=false)
00495         {       
00496                 if (!$col) $col = $this->sysDate;
00497                 return $col; // child class implement
00498         }
00499         
00515         function Prepare($sql)
00516         {
00517                 return $sql;
00518         }
00519         
00534         function PrepareSP($sql,$param=true)
00535         {
00536                 return $this->Prepare($sql,$param);
00537         }
00538         
00542         function Quote($s)
00543         {
00544                 return $this->qstr($s,false);
00545         }
00546         
00550         function QMagic($s)
00551         {
00552                 return $this->qstr($s,get_magic_quotes_gpc());
00553         }
00554 
00555         function q(&$s)
00556         {
00557                 #if (!empty($this->qNull)) if ($s == 'null') return $s;
00558                 $s = $this->qstr($s,false);
00559         }
00560         
00564         function ErrorNative()
00565         {
00566                 return $this->ErrorNo();
00567         }
00568 
00569         
00573         function nextId($seq_name)
00574         {
00575                 return $this->GenID($seq_name);
00576         }
00577 
00585         function RowLock($table,$where)
00586         {
00587                 return false;
00588         }
00589         
00590         function CommitLock($table)
00591         {
00592                 return $this->CommitTrans();
00593         }
00594         
00595         function RollbackLock($table)
00596         {
00597                 return $this->RollbackTrans();
00598         }
00599         
00609         function SetFetchMode($mode)
00610         {       
00611                 $old = $this->fetchMode;
00612                 $this->fetchMode = $mode;
00613                 
00614                 if ($old === false) {
00615                 global $ADODB_FETCH_MODE;
00616                         return $ADODB_FETCH_MODE;
00617                 }
00618                 return $old;
00619         }
00620         
00621 
00625         function &Query($sql, $inputarr=false)
00626         {
00627                 $rs = &$this->Execute($sql, $inputarr);
00628                 if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error();
00629                 return $rs;
00630         }
00631 
00632         
00636         function &LimitQuery($sql, $offset, $count, $params=false)
00637         {
00638                 $rs = &$this->SelectLimit($sql, $count, $offset, $params); 
00639                 if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error();
00640                 return $rs;
00641         }
00642 
00643         
00647         function Disconnect()
00648         {
00649                 return $this->Close();
00650         }
00651         
00652         /*
00653                  Returns placeholder for parameter, eg.
00654                  $DB->Param('a')
00655                  
00656                  will return ':a' for Oracle, and '?' for most other databases...
00657                  
00658                  For databases that require positioned params, eg $1, $2, $3 for postgresql,
00659                         pass in Param(false) before setting the first parameter.
00660         */
00661         function Param($name,$type='C')
00662         {
00663                 return '?';
00664         }
00665         
00666         /*
00667                 InParameter and OutParameter are self-documenting versions of Parameter().
00668         */
00669         function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false)
00670         {
00671                 return $this->Parameter($stmt,$var,$name,false,$maxLen,$type);
00672         }
00673         
00674         /*
00675         */
00676         function OutParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false)
00677         {
00678                 return $this->Parameter($stmt,$var,$name,true,$maxLen,$type);
00679         
00680         }
00681         
00682         /* 
00683         Usage in oracle
00684                 $stmt = $db->Prepare('select * from table where id =:myid and group=:group');
00685                 $db->Parameter($stmt,$id,'myid');
00686                 $db->Parameter($stmt,$group,'group',64);
00687                 $db->Execute();
00688                 
00689                 @param $stmt Statement returned by Prepare() or PrepareSP().
00690                 @param $var PHP variable to bind to
00691                 @param $name Name of stored procedure variable name to bind to.
00692                 @param [$isOutput] Indicates direction of parameter 0/false=IN  1=OUT  2= IN/OUT. This is ignored in oci8.
00693                 @param [$maxLen] Holds an maximum length of the variable.
00694                 @param [$type] The data type of $var. Legal values depend on driver.
00695 
00696         */
00697         function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false)
00698         {
00699                 return false;
00700         }
00701         
00712         function StartTrans($errfn = 'ADODB_TransMonitor')
00713         {
00714                 if ($this->transOff > 0) {
00715                         $this->transOff += 1;
00716                         return;
00717                 }
00718                 
00719                 $this->_oldRaiseFn = $this->raiseErrorFn;
00720                 $this->raiseErrorFn = $errfn;
00721                 $this->_transOK = true;
00722                 
00723                 if ($this->debug && $this->transCnt > 0) ADOConnection::outp("Bad Transaction: StartTrans called within BeginTrans");
00724                 $this->BeginTrans();
00725                 $this->transOff = 1;
00726         }
00727         
00728         
00737         function CompleteTrans($autoComplete = true)
00738         {
00739                 if ($this->transOff > 1) {
00740                         $this->transOff -= 1;
00741                         return true;
00742                 }
00743                 $this->raiseErrorFn = $this->_oldRaiseFn;
00744                 
00745                 $this->transOff = 0;
00746                 if ($this->_transOK && $autoComplete) {
00747                         if (!$this->CommitTrans()) {
00748                                 $this->_transOK = false;
00749                                 if ($this->debug) ADOConnection::outp("Smart Commit failed");
00750                         } else
00751                                 if ($this->debug) ADOConnection::outp("Smart Commit occurred");
00752                 } else {
00753                         $this->_transOK = false;
00754                         $this->RollbackTrans();
00755                         if ($this->debug) ADOCOnnection::outp("Smart Rollback occurred");
00756                 }
00757                 
00758                 return $this->_transOK;
00759         }
00760         
00761         /*
00762                 At the end of a StartTrans/CompleteTrans block, perform a rollback.
00763         */
00764         function FailTrans()
00765         {
00766                 if ($this->debug) 
00767                         if ($this->transOff == 0) {
00768                                 ADOConnection::outp("FailTrans outside StartTrans/CompleteTrans");
00769                         } else {
00770                                 ADOConnection::outp("FailTrans was called");
00771                                 adodb_backtrace();
00772                         }
00773                 $this->_transOK = false;
00774         }
00775         
00779         function HasFailedTrans()
00780         {
00781                 if ($this->transOff > 0) return $this->_transOK == false;
00782                 return false;
00783         }
00784         
00792         function &Execute($sql,$inputarr=false) 
00793         {
00794                 if ($this->fnExecute) {
00795                         $fn = $this->fnExecute;
00796                         $ret =& $fn($this,$sql,$inputarr);
00797                         if (isset($ret)) return $ret;
00798                 }
00799                 if ($inputarr) {
00800                         if (!is_array($inputarr)) $inputarr = array($inputarr);
00801                         
00802                         $element0 = reset($inputarr);
00803                         # is_object check because oci8 descriptors can be passed in
00804                         $array_2d = is_array($element0) && !is_object(reset($element0));
00805                         //remove extra memory copy of input -mikefedyk
00806                         unset($element0);
00807                         
00808                         if (!is_array($sql) && !$this->_bindInputArray) {
00809                                 $sqlarr = explode('?',$sql);
00810                                         
00811                                 if (!$array_2d) $inputarr = array($inputarr);
00812                                 foreach($inputarr as $arr) {
00813                                         $sql = ''; $i = 0;
00814                                         //Use each() instead of foreach to reduce memory usage -mikefedyk
00815                                         while(list(, $v) = each($arr)) {
00816                                                 $sql .= $sqlarr[$i];
00817                                                 // from Ron Baldwin <ron.baldwin#sourceprose.com>
00818                                                 // Only quote string types      
00819                                                 $typ = gettype($v);
00820                                                 if ($typ == 'string')
00821                                                         //New memory copy of input created here -mikefedyk
00822                                                         $sql .= $this->qstr($v);
00823                                                 else if ($typ == 'double')
00824                                                         $sql .= str_replace(',','.',$v); // locales fix so 1.1 does not get converted to 1,1
00825                                                 else if ($typ == 'boolean')
00826                                                         $sql .= $v ? $this->true : $this->false;
00827                                                 else if ($typ == 'object') {
00828                                                         if (method_exists($v, '__toString')) $sql .= $this->qstr($v->__toString());
00829                                                         else $sql .= $this->qstr((string) $v);
00830                                                 } else if ($v === null)
00831                                                         $sql .= 'NULL';
00832                                                 else
00833                                                         $sql .= $v;
00834                                                 $i += 1;
00835                                         }
00836                                         if (isset($sqlarr[$i])) {
00837                                                 $sql .= $sqlarr[$i];
00838                                                 if ($i+1 != sizeof($sqlarr)) ADOConnection::outp( "Input Array does not match ?: ".htmlspecialchars($sql));
00839                                         } else if ($i != sizeof($sqlarr))       
00840                                                 ADOConnection::outp( "Input array does not match ?: ".htmlspecialchars($sql));
00841                 
00842                                         $ret =& $this->_Execute($sql);
00843                                         if (!$ret) return $ret;
00844                                 }       
00845                         } else {
00846                                 if ($array_2d) {
00847                                         if (is_string($sql))
00848                                                 $stmt = $this->Prepare($sql);
00849                                         else
00850                                                 $stmt = $sql;
00851                                                 
00852                                         foreach($inputarr as $arr) {
00853                                                 $ret =& $this->_Execute($stmt,$arr);
00854                                                 if (!$ret) return $ret;
00855                                         }
00856                                 } else {
00857                                         $ret =& $this->_Execute($sql,$inputarr);
00858                                 }
00859                         }
00860                 } else {
00861                         $ret =& $this->_Execute($sql,false);
00862                 }
00863 
00864                 return $ret;
00865         }
00866         
00867         
00868         function &_Execute($sql,$inputarr=false)
00869         {
00870                 if ($this->debug) {
00871                         global $ADODB_INCLUDED_LIB;
00872                         if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
00873                         $this->_queryID = _adodb_debug_execute($this, $sql,$inputarr);
00874                 } else {
00875                         $this->_queryID = @$this->_query($sql,$inputarr);
00876                 }
00877                 
00878                 /************************
00879                 // OK, query executed
00880                 *************************/
00881 
00882                 if ($this->_queryID === false) { // error handling if query fails
00883                         if ($this->debug == 99) adodb_backtrace(true,5);        
00884                         $fn = $this->raiseErrorFn;
00885                         if ($fn) {
00886                                 $fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,$inputarr,$this);
00887                         } 
00888                         $false = false;
00889                         return $false;
00890                 } 
00891                 
00892                 if ($this->_queryID === true) { // return simplified recordset for inserts/updates/deletes with lower overhead
00893                         $rs =& new ADORecordSet_empty();
00894                         return $rs;
00895                 }
00896                 
00897                 // return real recordset from select statement
00898                 $rsclass = $this->rsPrefix.$this->databaseType;
00899                 $rs = new $rsclass($this->_queryID,$this->fetchMode);
00900                 $rs->connection = &$this; // Pablo suggestion
00901                 $rs->Init();
00902                 if (is_array($sql)) $rs->sql = $sql[0];
00903                 else $rs->sql = $sql;
00904                 if ($rs->_numOfRows <= 0) {
00905                 global $ADODB_COUNTRECS;
00906                         if ($ADODB_COUNTRECS) {
00907                                 if (!$rs->EOF) { 
00908                                         $rs = &$this->_rs2rs($rs,-1,-1,!is_array($sql));
00909                                         $rs->_queryID = $this->_queryID;
00910                                 } else
00911                                         $rs->_numOfRows = 0;
00912                         }
00913                 }
00914                 return $rs;
00915         }
00916 
00917         function CreateSequence($seqname='adodbseq',$startID=1)
00918         {
00919                 if (empty($this->_genSeqSQL)) return false;
00920                 return $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID));
00921         }
00922 
00923         function DropSequence($seqname='adodbseq')
00924         {
00925                 if (empty($this->_dropSeqSQL)) return false;
00926                 return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
00927         }
00928 
00937         function GenID($seqname='adodbseq',$startID=1)
00938         {
00939                 if (!$this->hasGenID) {
00940                         return 0; // formerly returns false pre 1.60
00941                 }
00942                 
00943                 $getnext = sprintf($this->_genIDSQL,$seqname);
00944                 
00945                 $holdtransOK = $this->_transOK;
00946                 
00947                 $save_handler = $this->raiseErrorFn;
00948                 $this->raiseErrorFn = '';
00949                 @($rs = $this->Execute($getnext));
00950                 $this->raiseErrorFn = $save_handler;
00951                 
00952                 if (!$rs) {
00953                         $this->_transOK = $holdtransOK; //if the status was ok before reset
00954                         $createseq = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID));
00955                         $rs = $this->Execute($getnext);
00956                 }
00957                 if ($rs && !$rs->EOF) $this->genID = reset($rs->fields);
00958                 else $this->genID = 0; // false
00959         
00960                 if ($rs) $rs->Close();
00961 
00962                 return $this->genID;
00963         }       
00964 
00970         function Insert_ID($table='',$column='')
00971         {
00972                 if ($this->_logsql && $this->lastInsID) return $this->lastInsID;
00973                 if ($this->hasInsertID) return $this->_insertid($table,$column);
00974                 if ($this->debug) {
00975                         ADOConnection::outp( '<p>Insert_ID error</p>');
00976                         adodb_backtrace();
00977                 }
00978                 return false;
00979         }
00980 
00981 
00988         function PO_Insert_ID($table="", $id="") 
00989         {
00990            if ($this->hasInsertID){
00991                    return $this->Insert_ID($table,$id);
00992            } else {
00993                    return $this->GetOne("SELECT MAX($id) FROM $table");
00994            }
00995         }
00996 
01000         function Affected_Rows()
01001         {
01002                 if ($this->hasAffectedRows) {
01003                         if ($this->fnExecute === 'adodb_log_sql') {
01004                                 if ($this->_logsql && $this->_affected !== false) return $this->_affected;
01005                         }
01006                         $val = $this->_affectedrows();
01007                         return ($val < 0) ? false : $val;
01008                 }
01009                                   
01010                 if ($this->debug) ADOConnection::outp( '<p>Affected_Rows error</p>',false);
01011                 return false;
01012         }
01013         
01014         
01018         function ErrorMsg()
01019         {
01020                 if ($this->_errorMsg) return '!! '.strtoupper($this->dataProvider.' '.$this->databaseType).': '.$this->_errorMsg;
01021                 else return '';
01022         }
01023         
01024         
01028         function ErrorNo() 
01029         {
01030                 return ($this->_errorMsg) ? -1 : 0;
01031         }
01032         
01033         function MetaError($err=false)
01034         {
01035                 include_once(ADODB_DIR."/adodb-error.inc.php");
01036                 if ($err === false) $err = $this->ErrorNo();
01037                 return adodb_error($this->dataProvider,$this->databaseType,$err);
01038         }
01039         
01040         function MetaErrorMsg($errno)
01041         {
01042                 include_once(ADODB_DIR."/adodb-error.inc.php");
01043                 return adodb_errormsg($errno);
01044         }
01045         
01049         function MetaPrimaryKeys($table, $owner=false)
01050         {
01051         // owner not used in base class - see oci8
01052                 $p = array();
01053                 $objs =& $this->MetaColumns($table);
01054                 if ($objs) {
01055                         foreach($objs as $v) {
01056                                 if (!empty($v->primary_key))
01057                                         $p[] = $v->name;
01058                         }
01059                 }
01060                 if (sizeof($p)) return $p;
01061                 if (function_exists('ADODB_VIEW_PRIMARYKEYS'))
01062                         return ADODB_VIEW_PRIMARYKEYS($this->databaseType, $this->database, $table, $owner);
01063                 return false;
01064         }
01065         
01069         function MetaForeignKeys($table, $owner=false, $upper=false)
01070         {
01071                 return false;
01072         }
01079         function SelectDB($dbName) 
01080         {return false;}
01081         
01082         
01102         function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
01103         {
01104                 if ($this->hasTop && $nrows > 0) {
01105                 // suggested by Reinhard Balling. Access requires top after distinct 
01106                  // Informix requires first before distinct - F Riosa
01107                         $ismssql = (strpos($this->databaseType,'mssql') !== false);
01108                         if ($ismssql) $isaccess = false;
01109                         else $isaccess = (strpos($this->databaseType,'access') !== false);
01110                         
01111                         if ($offset <= 0) {
01112                                 
01113                                         // access includes ties in result
01114                                         if ($isaccess) {
01115                                                 $sql = preg_replace(
01116                                                 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql);
01117 
01118                                                 if ($secs2cache>0) {
01119                                                         $ret =& $this->CacheExecute($secs2cache, $sql,$inputarr);
01120                                                 } else {
01121                                                         $ret =& $this->Execute($sql,$inputarr);
01122                                                 }
01123                                                 return $ret; // PHP5 fix
01124                                         } else if ($ismssql){
01125                                                 $sql = preg_replace(
01126                                                 '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql);
01127                                         } else {
01128                                                 $sql = preg_replace(
01129                                                 '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql);
01130                                         }
01131                         } else {
01132                                 $nn = $nrows + $offset;
01133                                 if ($isaccess || $ismssql) {
01134                                         $sql = preg_replace(
01135                                         '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.$nn.' ',$sql);
01136                                 } else {
01137                                         $sql = preg_replace(
01138                                         '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.$nn.' ',$sql);
01139                                 }
01140                         }
01141                 }
01142                 
01143                 // if $offset>0, we want to skip rows, and $ADODB_COUNTRECS is set, we buffer  rows
01144                 // 0 to offset-1 which will be discarded anyway. So we disable $ADODB_COUNTRECS.
01145                 global $ADODB_COUNTRECS;
01146                 
01147                 $savec = $ADODB_COUNTRECS;
01148                 $ADODB_COUNTRECS = false;
01149                         
01150                 if ($offset>0){
01151                         if ($secs2cache>0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
01152                         else $rs = &$this->Execute($sql,$inputarr);
01153                 } else {
01154                         if ($secs2cache>0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
01155                         else $rs = &$this->Execute($sql,$inputarr);
01156                 }
01157                 $ADODB_COUNTRECS = $savec;
01158                 if ($rs && !$rs->EOF) {
01159                         $rs =& $this->_rs2rs($rs,$nrows,$offset);
01160                 }
01161                 //print_r($rs);
01162                 return $rs;
01163         }
01164         
01170         function &SerializableRS(&$rs)
01171         {
01172                 $rs2 =& $this->_rs2rs($rs);
01173                 $ignore = false;
01174                 $rs2->connection =& $ignore;
01175                 
01176                 return $rs2;
01177         }
01178         
01189         function &_rs2rs(&$rs,$nrows=-1,$offset=-1,$close=true)
01190         {
01191                 if (! $rs) {
01192                         $false = false;
01193                         return $false;
01194                 }
01195                 $dbtype = $rs->databaseType;
01196                 if (!$dbtype) {
01197                         $rs = &$rs;  // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ?
01198                         return $rs;
01199                 }
01200                 if (($dbtype == 'array' || $dbtype == 'csv') && $nrows == -1 && $offset == -1) {
01201                         $rs->MoveFirst();
01202                         $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ?
01203                         return $rs;
01204                 }
01205                 $flds = array();
01206                 for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
01207                         $flds[] = $rs->FetchField($i);
01208                 }
01209 
01210                 $arr =& $rs->GetArrayLimit($nrows,$offset);
01211                 //print_r($arr);
01212                 if ($close) $rs->Close();
01213                 
01214                 $arrayClass = $this->arrayClass;
01215                 
01216                 $rs2 = new $arrayClass();
01217                 $rs2->connection = &$this;
01218                 $rs2->sql = $rs->sql;
01219                 $rs2->dataProvider = $this->dataProvider;
01220                 $rs2->InitArrayFields($arr,$flds);
01221                 $rs2->fetchMode = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode;
01222                 return $rs2;
01223         }
01224         
01225         /*
01226         * Return all rows. Compat with PEAR DB
01227         */
01228         function &GetAll($sql, $inputarr=false)
01229         {
01230                 $arr =& $this->GetArray($sql,$inputarr);
01231                 return $arr;
01232         }
01233         
01234         function &GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false)
01235         {
01236                 $rs =& $this->Execute($sql, $inputarr);
01237                 if (!$rs) {
01238                         $false = false;
01239                         return $false;
01240                 }
01241                 $arr =& $rs->GetAssoc($force_array,$first2cols);
01242                 return $arr;
01243         }
01244         
01245         function &CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false)
01246         {
01247                 if (!is_numeric($secs2cache)) {
01248                         $first2cols = $force_array;
01249                         $force_array = $inputarr;
01250                 }
01251                 $rs =& $this->CacheExecute($secs2cache, $sql, $inputarr);
01252                 if (!$rs) {
01253                         $false = false;
01254                         return $false;
01255                 }
01256                 $arr =& $rs->GetAssoc($force_array,$first2cols);
01257                 return $arr;
01258         }
01259         
01267         function GetOne($sql,$inputarr=false)
01268         {
01269         global $ADODB_COUNTRECS;
01270                 $crecs = $ADODB_COUNTRECS;
01271                 $ADODB_COUNTRECS = false;
01272                 
01273                 $ret = false;
01274                 $rs = &$this->Execute($sql,$inputarr);
01275                 if ($rs) {      
01276                         if (!$rs->EOF) $ret = reset($rs->fields);
01277                         $rs->Close();
01278                 }
01279                 $ADODB_COUNTRECS = $crecs;
01280                 return $ret;
01281         }
01282         
01283         function CacheGetOne($secs2cache,$sql=false,$inputarr=false)
01284         {
01285                 $ret = false;
01286                 $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
01287                 if ($rs) {              
01288                         if (!$rs->EOF) $ret = reset($rs->fields);
01289                         $rs->Close();
01290                 } 
01291                 
01292                 return $ret;
01293         }
01294         
01295         function GetCol($sql, $inputarr = false, $trim = false)
01296         {
01297                 $rv = false;
01298                 $rs = &$this->Execute($sql, $inputarr);
01299                 if ($rs) {
01300                         $rv = array();
01301                         if ($trim) {
01302                                 while (!$rs->EOF) {
01303                                         $rv[] = trim(reset($rs->fields));
01304                                         $rs->MoveNext();
01305                                 }
01306                         } else {
01307                                 while (!$rs->EOF) {
01308                                         $rv[] = reset($rs->fields);
01309                                         $rs->MoveNext();
01310                                 }
01311                         }
01312                         $rs->Close();
01313                 }
01314                 return $rv;
01315         }
01316         
01317         function CacheGetCol($secs, $sql = false, $inputarr = false,$trim=false)
01318         {
01319                 $rv = false;
01320                 $rs = &$this->CacheExecute($secs, $sql, $inputarr);
01321                 if ($rs) {
01322                         if ($trim) {
01323                                 while (!$rs->EOF) {
01324                                         $rv[] = trim(reset($rs->fields));
01325                                         $rs->MoveNext();
01326                                 }
01327                         } else {
01328                                 while (!$rs->EOF) {
01329                                         $rv[] = reset($rs->fields);
01330                                         $rs->MoveNext();
01331                                 }
01332                         }
01333                         $rs->Close();
01334                 }
01335                 return $rv;
01336         }
01337  
01338         /*
01339                 Calculate the offset of a date for a particular database and generate
01340                         appropriate SQL. Useful for calculating future/past dates and storing
01341                         in a database.
01342                         
01343                 If dayFraction=1.5 means 1.5 days from now, 1.0/24 for 1 hour.
01344         */
01345         function OffsetDate($dayFraction,$date=false)
01346         {               
01347                 if (!$date) $date = $this->sysDate;
01348                 return  '('.$date.'+'.$dayFraction.')';
01349         }
01350         
01351         
01357         function &GetArray($sql,$inputarr=false)
01358         {
01359         global $ADODB_COUNTRECS;
01360                 
01361                 $savec = $ADODB_COUNTRECS;
01362                 $ADODB_COUNTRECS = false;
01363                 $rs =& $this->Execute($sql,$inputarr);
01364