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.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 = '&nbsp;';
00263         var $emptyTimeStamp = '&nbsp;';
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-