"TYPO3 4.0.1: typo3_src-4.0.1/typo3/sysext/adodb/adodb/adodb.inc.php Source File", "datetime" => "Sat Dec 2 19:22:24 2006", "date" => "2 Dec 2006", "doxygenversion" => "1.4.6", "projectname" => "TYPO3 4.0.1", "projectnumber" => "4.0.1" ); get_header($doxygen_vars); ?>

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                 $ADODB_COUNTRECS = $savec;
01365                 if (!$rs) 
01366                         if (defined('ADODB_PEAR')) {
01367                                 $cls = ADODB_PEAR_Error();
01368                                 return $cls;
01369                         } else {
01370                                 $false = false;
01371                                 return $false;
01372                         }
01373                 $arr =& $rs->GetArray();
01374                 $rs->Close();
01375                 return $arr;
01376         }
01377         
01378         function &CacheGetAll($secs2cache,$sql=false,$inputarr=false)
01379         {
01380                 return $this->CacheGetArray($secs2cache,$sql,$inputarr);
01381         }
01382         
01383         function &CacheGetArray($secs2cache,$sql=false,$inputarr=false)
01384         {
01385         global $ADODB_COUNTRECS;
01386                 
01387                 $savec = $ADODB_COUNTRECS;
01388                 $ADODB_COUNTRECS = false;
01389                 $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr);
01390                 $ADODB_COUNTRECS = $savec;
01391                 
01392                 if (!$rs) 
01393                         if (defined('ADODB_PEAR')) {
01394                                 $cls = ADODB_PEAR_Error();
01395                                 return $cls;
01396                         } else {
01397                                 $false = false;
01398                                 return $false;
01399                         }
01400                 $arr =& $rs->GetArray();
01401                 $rs->Close();
01402                 return $arr;
01403         }
01404         
01405         
01406         
01413         function &GetRow($sql,$inputarr=false)
01414         {
01415         global $ADODB_COUNTRECS;
01416                 $crecs = $ADODB_COUNTRECS;
01417                 $ADODB_COUNTRECS = false;
01418                 
01419                 $rs =& $this->Execute($sql,$inputarr);
01420                 
01421                 $ADODB_COUNTRECS = $crecs;
01422                 if ($rs) {
01423                         if (!$rs->EOF) $arr = $rs->fields;
01424                         else $arr = array();
01425                         $rs->Close();
01426                         return $arr;
01427                 }
01428                 
01429                 $false = false;
01430                 return $false;
01431         }
01432         
01433         function &CacheGetRow($secs2cache,$sql=false,$inputarr=false)
01434         {
01435                 $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr);
01436                 if ($rs) {
01437                         $arr = false;
01438                         if (!$rs->EOF) $arr = $rs->fields;
01439                         $rs->Close();
01440                         return $arr;
01441                 }
01442                 $false = false;
01443                 return $false;
01444         }
01445         
01466         function Replace($table, $fieldArray, $keyCol, $autoQuote=false, $has_autoinc=false)
01467         {
01468                 global $ADODB_INCLUDED_LIB;
01469                 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
01470                 
01471                 return _adodb_replace($this, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc);
01472         }
01473         
01474         
01493         function &CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false)
01494         {       
01495                 if (!is_numeric($secs2cache)) {
01496                         if ($sql === false) $sql = -1;
01497                         if ($offset == -1) $offset = false;
01498                                                                           // sql,       nrows, offset,inputarr
01499                         $rs =& $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs);
01500                 } else {
01501                         if ($sql === false) ADOConnection::outp( "Warning: \$sql missing from CacheSelectLimit()");
01502                         $rs =& $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
01503                 }
01504                 return $rs;
01505         }
01506         
01507         
01517         function CacheFlush($sql=false,$inputarr=false)
01518         {
01519         global $ADODB_CACHE_DIR;
01520         
01521                 if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) {
01522          /*if (strncmp(PHP_OS,'WIN',3) === 0)
01523             $dir = str_replace('/', '\\', $ADODB_CACHE_DIR);
01524          else */
01525             $dir = $ADODB_CACHE_DIR;
01526             
01527          if ($this->debug) {
01528             ADOConnection::outp( "CacheFlush: $dir<br><pre>\n", $this->_dirFlush($dir),"</pre>");
01529          } else {
01530             $this->_dirFlush($dir);
01531          }
01532          return;
01533       } 
01534       
01535       global $ADODB_INCLUDED_CSV;
01536       if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php');
01537       
01538       $f = $this->_gencachename($sql.serialize($inputarr),false);
01539       adodb_write_file($f,''); // is adodb_write_file needed?
01540       if (!@unlink($f)) {
01541          if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f");
01542       }
01543    }
01544    
01551    function _dirFlush($dir, $kill_top_level = false) {
01552       if(!$dh = @opendir($dir)) return;
01553       
01554       while (($obj = readdir($dh))) {
01555          if($obj=='.' || $obj=='..')
01556             continue;
01557                         
01558          if (!@unlink($dir.'/'.$obj))
01559                           $this->_dirFlush($dir.'/'.$obj, true);
01560       }
01561       if ($kill_top_level === true)
01562          @rmdir($dir);
01563       return true;
01564    }
01565    
01566    
01567         function xCacheFlush($sql=false,$inputarr=false)
01568         {
01569         global $ADODB_CACHE_DIR;
01570         
01571                 if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) {
01572                         if (strncmp(PHP_OS,'WIN',3) === 0) {
01573                                 $cmd = 'del /s '.str_replace('/','\\',$ADODB_CACHE_DIR).'\adodb_*.cache';
01574                         } else {
01575                                 //$cmd = 'find "'.$ADODB_CACHE_DIR.'" -type f -maxdepth 1 -print0 | xargs -0 rm -f';
01576                                 $cmd = 'rm -rf '.$ADODB_CACHE_DIR.'/[0-9a-f][0-9a-f]/'; 
01577                                 // old version 'rm -f `find '.$ADODB_CACHE_DIR.' -name adodb_*.cache`';
01578                         }
01579                         if ($this->debug) {
01580                                 ADOConnection::outp( "CacheFlush: $cmd<br><pre>\n", system($cmd),"</pre>");
01581                         } else {
01582                                 exec($cmd);
01583                         }
01584                         return;
01585                 } 
01586                 
01587                 global $ADODB_INCLUDED_CSV;
01588                 if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php');
01589                 
01590                 $f = $this->_gencachename($sql.serialize($inputarr),false);
01591                 adodb_write_file($f,''); // is adodb_write_file needed?
01592                 if (!@unlink($f)) {
01593                         if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f");
01594                 }
01595         }
01596         
01611         function _gencachename($sql,$createdir)
01612         {
01613         global $ADODB_CACHE_DIR;
01614         static $notSafeMode;
01615                 
01616                 if ($this->fetchMode === false) { 
01617                 global $ADODB_FETCH_MODE;
01618                         $mode = $ADODB_FETCH_MODE;
01619                 } else {
01620                         $mode = $this->fetchMode;
01621                 }
01622                 $m = md5($sql.$this->databaseType.$this->database.$this->user.$mode);
01623                 
01624                 if (!isset($notSafeMode)) $notSafeMode = !ini_get('safe_mode');
01625                 $dir = ($notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($m,0,2) : $ADODB_CACHE_DIR;
01626                         
01627                 if ($createdir && $notSafeMode && !file_exists($dir)) {
01628                         $oldu = umask(0);
01629                         if (!mkdir($dir,0771)) 
01630                                 if ($this->debug) ADOConnection::outp( "Unable to mkdir $dir for $sql");
01631                         umask($oldu);
01632                 }
01633                 return $dir.'/adodb_'.$m.'.cache';
01634         }
01635         
01636         
01646         function &CacheExecute($secs2cache,$sql=false,$inputarr=false)
01647         {
01648 
01649                         
01650                 if (!is_numeric($secs2cache)) {
01651                         $inputarr = $sql;
01652                         $sql = $secs2cache;
01653                         $secs2cache = $this->cacheSecs;
01654                 }
01655                 
01656                 if (is_array($sql)) {
01657                         $sqlparam = $sql;
01658                         $sql = $sql[0];
01659                 } else
01660                         $sqlparam = $sql;
01661                         
01662                 global $ADODB_INCLUDED_CSV;
01663                 if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php');
01664                 
01665                 $md5file = $this->_gencachename($sql.serialize($inputarr),true);
01666                 $err = '';
01667                 
01668                 if ($secs2cache > 0){
01669                         $rs = &csv2rs($md5file,$err,$secs2cache,$this->arrayClass);
01670                         $this->numCacheHits += 1;
01671                 } else {
01672                         $err='Timeout 1';
01673                         $rs = false;
01674                         $this->numCacheMisses += 1;
01675                 }
01676                 if (!$rs) {
01677                 // no cached rs found
01678                         if ($this->debug) {
01679                                 if (get_magic_quotes_runtime()) {
01680                                         ADOConnection::outp("Please disable magic_quotes_runtime - it corrupts cache files :(");
01681                                 }
01682                                 if ($this->debug !== -1) ADOConnection::outp( " $md5file cache failure: $err (see sql below)");
01683                         }
01684                         
01685                         $rs = &$this->Execute($sqlparam,$inputarr);
01686 
01687                         if ($rs) {
01688                                 $eof = $rs->EOF;
01689                                 $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately
01690                                 $txt = _rs2serialize($rs,false,$sql); // serialize
01691                 
01692                                 if (!adodb_write_file($md5file,$txt,$this->debug)) {
01693                                         if ($fn = $this->raiseErrorFn) {
01694                                                 $fn($this->databaseType,'CacheExecute',-32000,"Cache write error",$md5file,$sql,$this);
01695                                         }
01696                                         if ($this->debug) ADOConnection::outp( " Cache write error");
01697                                 }
01698                                 if ($rs->EOF && !$eof) {
01699                                         $rs->MoveFirst();
01700                                         //$rs = &csv2rs($md5file,$err);         
01701                                         $rs->connection = &$this; // Pablo suggestion
01702                                 }  
01703                                 
01704                         } else
01705                                 @unlink($md5file);
01706                 } else {
01707                         $this->_errorMsg = '';
01708                         $this->_errorCode = 0;
01709                         
01710                         if ($this->fnCacheExecute) {
01711                                 $fn = $this->fnCacheExecute;
01712                                 $fn($this, $secs2cache, $sql, $inputarr);
01713                         }
01714                 // ok, set cached object found
01715                         $rs->connection = &$this; // Pablo suggestion
01716                         if ($this->debug){ 
01717                                         
01718                                 $inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
01719                                 $ttl = $rs->timeCreated + $secs2cache - time();
01720                                 $s = is_array($sql) ? $sql[0] : $sql;
01721                                 if ($inBrowser) $s = '<i>'.htmlspecialchars($s).'</i>';
01722                                 
01723                                 ADOConnection::outp( " $md5file reloaded, ttl=$ttl [ $s ]");
01724                         }
01725                 }
01726                 return $rs;
01727         }
01728         
01729         
01730         /* 
01731                 Similar to PEAR DB's autoExecute(), except that 
01732                 $mode can be 'INSERT' or 'UPDATE' or DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
01733                 If $mode == 'UPDATE', then $where is compulsory as a safety measure.
01734                 
01735                 $forceUpdate means that even if the data has not changed, perform update.
01736          */
01737         function& AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false) 
01738         {
01739                 $false = false;
01740                 $sql = 'SELECT * FROM '.$table;  
01741                 if ($where!==FALSE) $sql .= ' WHERE '.$where;
01742                 else if ($mode == 'UPDATE' || $mode == 2 /* DB_AUTOQUERY_UPDATE */) {
01743                         ADOConnection::outp('AutoExecute: Illegal mode=UPDATE with empty WHERE clause');
01744                         return $false;
01745                 }
01746 
01747                 $rs =& $this->SelectLimit($sql,1);
01748                 if (!$rs) return $false; // table does not exist
01749                 $rs->tableName = $table;
01750                 
01751                 switch((string) $mode) {
01752                 case 'UPDATE':
01753                 case '2':
01754                         $sql = $this->GetUpdateSQL($rs, $fields_values, $forceUpdate, $magicq);
01755                         break;
01756                 case 'INSERT':
01757                 case '1':
01758                         $sql = $this->GetInsertSQL($rs, $fields_values, $magicq);
01759                         break;
01760                 default:
01761                         ADOConnection::outp("AutoExecute: Unknown mode=$mode");
01762                         return $false;
01763                 }
01764                 $ret = false;
01765                 if ($sql) $ret = $this->Execute($sql);
01766                 if ($ret) $ret = true;
01767                 return $ret;
01768         }
01769         
01770         
01782         function GetUpdateSQL(&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=null)
01783         {
01784                 global $ADODB_INCLUDED_LIB;
01785 
01786         //********************************************************//
01787         //This is here to maintain compatibility
01788         //with older adodb versions. Sets force type to force nulls if $forcenulls is set.
01789                 if (!isset($force)) {
01790                                 global $ADODB_FORCE_TYPE;
01791                             $force = $ADODB_FORCE_TYPE;
01792                 }
01793                 //********************************************************//
01794 
01795                 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
01796                 return _adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq,$force);
01797         }
01798 
01807         function GetInsertSQL(&$rs, $arrFields,$magicq=false,$force=null)
01808         {       
01809                 global $ADODB_INCLUDED_LIB;
01810                 if (!isset($force)) {
01811                         global $ADODB_FORCE_TYPE;
01812                         $force = $ADODB_FORCE_TYPE;
01813                         
01814                 }
01815                 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
01816                 return _adodb_getinsertsql($this,$rs,$arrFields,$magicq,$force);
01817         }
01818         
01819 
01839         function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
01840         {
01841                 return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false;
01842         }
01843 
01853         function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
01854         {
01855                 $fd = fopen($path,'rb');
01856                 if ($fd === false) return false;
01857                 $val = fread($fd,filesize($path));
01858                 fclose($fd);
01859                 return $this->UpdateBlob($table,$column,$val,$where,$blobtype);
01860         }
01861         
01862         function BlobDecode($blob)
01863         {
01864                 return $blob;
01865         }
01866         
01867         function BlobEncode($blob)
01868         {
01869                 return $blob;
01870         }
01871         
01872         function SetCharSet($charset)
01873         {
01874                 return false;
01875         }
01876         
01877         function IfNull( $field, $ifNull ) 
01878         {
01879                 return " CASE WHEN $field is null THEN $ifNull ELSE $field END ";
01880         }
01881         
01882         function LogSQL($enable=true)
01883         {
01884                 include_once(ADODB_DIR.'/adodb-perf.inc.php');
01885                 
01886                 if ($enable) $this->fnExecute = 'adodb_log_sql';
01887                 else $this->fnExecute = false;
01888                 
01889                 $old = $this->_logsql;  
01890                 $this->_logsql = $enable;
01891                 if ($enable && !$old) $this->_affected = false;
01892                 return $old;
01893         }
01894         
01895         function GetCharSet()
01896         {
01897                 return false;
01898         }
01899         
01907         function UpdateClob($table,$column,$val,$where)
01908         {
01909                 return $this->UpdateBlob($table,$column,$val,$where,'CLOB');
01910         }
01911         
01912         // not the fastest implementation - quick and dirty - jlim
01913         // for best performance, use the actual $rs->MetaType().
01914         function MetaType($t,$len=-1,$fieldobj=false)
01915         {
01916                 
01917                 if (empty($this->_metars)) {
01918                         $rsclass = $this->rsPrefix.$this->databaseType;
01919                         $this->_metars =& new $rsclass(false,$this->fetchMode); 
01920                         $this->_metars->connection =& $this;
01921                 }
01922                 return $this->_metars->MetaType($t,$len,$fieldobj);
01923         }
01924         
01925         
01930         function SetDateLocale($locale = 'En')
01931         {
01932                 $this->locale = $locale;
01933                 switch (strtoupper($locale))
01934                 {
01935                         case 'EN':
01936                                 $this->fmtDate="'Y-m-d'";
01937                                 $this->fmtTimeStamp = "'Y-m-d H:i:s'";
01938                                 break;
01939                                 
01940                         case 'US':
01941                                 $this->fmtDate = "'m-d-Y'";
01942                                 $this->fmtTimeStamp = "'m-d-Y H:i:s'";
01943                                 break;
01944                                 
01945                         case 'NL':
01946                         case 'FR':
01947                         case 'RO':
01948                         case 'IT':
01949                                 $this->fmtDate="'d-m-Y'";
01950                                 $this->fmtTimeStamp = "'d-m-Y H:i:s'";
01951                                 break;
01952                                 
01953                         case 'GE':
01954                                 $this->fmtDate="'d.m.Y'";
01955                                 $this->fmtTimeStamp = "'d.m.Y H:i:s'";
01956                                 break;
01957                                 
01958                         default:
01959                                 $this->fmtDate="'Y-m-d'";
01960                                 $this->fmtTimeStamp = "'Y-m-d H:i:s'";
01961                                 break;
01962                 }
01963         }
01964 
01965         function &GetActiveRecordsClass($class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false)
01966         {
01967         global $_ADODB_ACTIVE_DBS;
01968         
01969                 $save = $this->SetFetchMode(ADODB_FETCH_NUM);
01970                 if (empty($whereOrderBy)) $whereOrderBy = '1=1';
01971                 $rows = $this->GetAll("select * from ".$table.' WHERE '.$whereOrderBy,$bindarr);
01972                 $this->SetFetchMode($save);
01973                 
01974                 $false = false;
01975                 
01976                 if ($rows === false) {  
01977                         return $false;
01978                 }
01979                 
01980                 
01981                 if (!isset($_ADODB_ACTIVE_DBS)) {
01982                         include(ADODB_DIR.'/adodb-active-record.inc.php');
01983                 }       
01984                 if (!class_exists($class)) {
01985                         ADOConnection::outp("Unknown class $class in GetActiveRcordsClass()");
01986                         return $false;
01987                 }
01988                 $arr = array();
01989                 foreach($rows as $row) {
01990                 
01991                         $obj =& new $class($table,$primkeyArr,$this);
01992                         if ($obj->ErrorMsg()){
01993                                 $this->_errorMsg = $obj->ErrorMsg();
01994                                 return $false;
01995                         }
01996                         $obj->Set($row);
01997                         $arr[] =& $obj;
01998                 }
01999                 return $arr;
02000         }
02001         
02002         function &GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false)
02003         {
02004                 $arr =& $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr);
02005                 return $arr;
02006         }
02007         
02011         function Close()
02012         {
02013                 $rez = $this->_close();
02014                 $this->_connectionID = false;
02015                 return $rez;
02016         }
02017         
02023         function BeginTrans() {return false;}
02024         
02025         /* set transaction mode */
02026         function SetTransactionMode( $transaction_mode ) 
02027         {
02028                 $transaction_mode = $this->MetaTransaction($transaction_mode, $this->dataProvider);
02029                 $this->_transmode  = $transaction_mode;
02030         }
02031 /*
02032 http://msdn2.microsoft.com/en-US/ms173763.aspx
02033 http://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-isolation.html
02034 http://www.postgresql.org/docs/8.1/interactive/sql-set-transaction.html
02035 http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_10005.htm
02036 */
02037         function MetaTransaction($mode,$db)
02038         {
02039                 $mode = strtoupper($mode);
02040                 $mode = str_replace('ISOLATION LEVEL ','',$mode);
02041                 
02042                 switch($mode) {
02043 
02044                 case 'READ UNCOMMITTED':
02045                         switch($db) { 
02046                         case 'oci8':
02047                         case 'oracle':
02048                                 return 'ISOLATION LEVEL READ COMMITTED';
02049                         default:
02050                                 return 'ISOLATION LEVEL READ UNCOMMITTED';
02051                         }
02052                         break;
02053                                         
02054                 case 'READ COMMITTED':
02055                                 return 'ISOLATION LEVEL READ COMMITTED';
02056                         break;
02057                         
02058                 case 'REPEATABLE READ':
02059                         switch($db) {
02060                         case 'oci8':
02061                         case 'oracle':
02062                                 return 'ISOLATION LEVEL SERIALIZABLE';
02063                         default:
02064                                 return 'ISOLATION LEVEL REPEATABLE READ';
02065                         }
02066                         break;
02067                         
02068                 case 'SERIALIZABLE':
02069                                 return 'ISOLATION LEVEL SERIALIZABLE';
02070                         break;
02071                         
02072                 default:
02073                         return $mode;
02074                 }
02075         }
02076         
02084         function CommitTrans($ok=true) 
02085         { return true;}
02086         
02087         
02093         function RollbackTrans() 
02094         { return false;}
02095 
02096 
02103                 function MetaDatabases() 
02104                 {
02105                 global $ADODB_FETCH_MODE;
02106                 
02107                         if ($this->metaDatabasesSQL) {
02108                                 $save = $ADODB_FETCH_MODE; 
02109                                 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 
02110                                 
02111                                 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
02112                                 
02113                                 $arr = $this->GetCol($this->metaDatabasesSQL);
02114                                 if (isset($savem)) $this->SetFetchMode($savem);
02115                                 $ADODB_FETCH_MODE = $save; 
02116                         
02117                                 return $arr;
02118                         }
02119                         
02120                         return false;
02121                 }
02122         
02123                 
02134         function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
02135         {
02136         global $ADODB_FETCH_MODE;
02137         
02138                 
02139                 $false = false;
02140                 if ($mask) {
02141                         return $false;
02142                 }
02143                 if ($this->metaTablesSQL) {
02144                         $save = $ADODB_FETCH_MODE; 
02145                         $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 
02146                         
02147                         if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
02148                         
02149                         $rs = $this->Execute($this->metaTablesSQL);
02150                         if (isset($savem)) $this->SetFetchMode($savem);
02151                         $ADODB_FETCH_MODE = $save; 
02152                         
02153                         if ($rs === false) return $false;
02154                         $arr =& $rs->GetArray();
02155                         $arr2 = array();
02156                         
02157                         if ($hast = ($ttype && isset($arr[0][1]))) { 
02158                                 $showt = strncmp($ttype,'T',1);
02159                         }
02160                         
02161                         for ($i=0; $i < sizeof($arr); $i++) {
02162                                 if ($hast) {
02163                                         if ($showt == 0) {
02164                                                 if (strncmp($arr[$i][1],'T',1) == 0) $arr2[] = trim($arr[$i][0]);
02165                                         } else {
02166                                                 if (strncmp($arr[$i][1],'V',1) == 0) $arr2[] = trim($arr[$i][0]);
02167                                         }
02168                                 } else
02169                                         $arr2[] = trim($arr[$i][0]);
02170                         }
02171                         $rs->Close();
02172                         return $arr2;
02173                 }
02174                 return $false;
02175         }
02176         
02177         
02178         function _findschema(&$table,&$schema)
02179         {
02180                 if (!$schema && ($at = strpos($table,'.')) !== false) {
02181                         $schema = substr($table,0,$at);
02182                         $table = substr($table,$at+1);
02183                 }
02184         }
02185         
02196         function &MetaColumns($table,$normalize=true) 
02197         {
02198         global $ADODB_FETCH_MODE;
02199                 
02200                 $false = false;
02201                 
02202                 if (!empty($this->metaColumnsSQL)) {
02203                 
02204                         $schema = false;
02205                         $this->_findschema($table,$schema);
02206                 
02207                         $save = $ADODB_FETCH_MODE;
02208                         $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
02209                         if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
02210                         $rs = $this->Execute(sprintf($this->metaColumnsSQL,($normalize)?strtoupper($table):$table));
02211                         if (isset($savem)) $this->SetFetchMode($savem);
02212                         $ADODB_FETCH_MODE = $save;
02213                         if ($rs === false || $rs->EOF) return $false;
02214 
02215                         $retarr = array();
02216                         while (!$rs->EOF) { //print_r($rs->fields);
02217                                 $fld = new ADOFieldObject();
02218                                 $fld->name = $rs->fields[0];
02219                                 $fld->type = $rs->fields[1];
02220                                 if (isset($rs->fields[3]) && $rs->fields[3]) {
02221                                         if ($rs->fields[3]>0) $fld->max_length = $rs->fields[3];
02222                                         $fld->scale = $rs->fields[4];
02223                                         if ($fld->scale>0) $fld->max_length += 1;
02224                                 } else
02225                                         $fld->max_length = $rs->fields[2];
02226                                         
02227                                 if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;     
02228                                 else $retarr[strtoupper($fld->name)] = $fld;
02229                                 $rs->MoveNext();
02230                         }
02231                         $rs->Close();
02232                         return $retarr; 
02233                 }
02234                 return $false;
02235         }
02236         
02255      function &MetaIndexes($table, $primary = false, $owner = false)
02256      {
02257                         $false = false;
02258             return $false;
02259      }
02260 
02267         function &MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */) 
02268         {
02269                 $objarr =& $this->MetaColumns($table);
02270                 if (!is_array($objarr)) {
02271                         $false = false;
02272                         return $false;
02273                 }
02274                 $arr = array();
02275                 if ($numIndexes) {
02276                         $i = 0;
02277                         if ($useattnum) {
02278                                 foreach($objarr as $v) 
02279                                         $arr[$v->attnum] = $v->name;
02280                                 
02281                         } else
02282                                 foreach($objarr as $v) $arr[$i++] = $v->name;
02283                 } else
02284                         foreach($objarr as $v) $arr[strtoupper($v->name)] = $v->name;
02285                 
02286                 return $arr;
02287         }
02288                         
02299         function Concat()
02300         {       
02301                 $arr = func_get_args();
02302                 return implode($this->concat_operator, $arr);
02303         }
02304         
02305         
02313         function DBDate($d)
02314         {
02315                 if (empty($d) && $d !== 0) return 'null';
02316 
02317                 if (is_string($d) && !is_numeric($d)) {
02318                         if ($d === 'null' || strncmp($d,"'",1) === 0) return $d;
02319                         if ($this->isoDates) return "'$d'";
02320                         $d = ADOConnection::UnixDate($d);
02321                 }
02322 
02323                 return adodb_date($this->fmtDate,$d);
02324         }
02325         
02326         function BindDate($d)
02327         {
02328                 $d = $this->DBDate($d);
02329                 if (strncmp($d,"'",1)) return $d;
02330                 
02331                 return substr($d,1,strlen($d)-2);
02332         }
02333         
02334         function BindTimeStamp($d)
02335         {
02336                 $d = $this->DBTimeStamp($d);
02337                 if (strncmp($d,"'",1)) return $d;
02338                 
02339                 return substr($d,1,strlen($d)-2);
02340         }
02341         
02342         
02350         function DBTimeStamp($ts)
02351         {
02352                 if (empty($ts) && $ts !== 0) return 'null';
02353 
02354                 # strlen(14) allows YYYYMMDDHHMMSS format
02355                 if (!is_string($ts) || (is_numeric($ts) && strlen($ts)<14)) 
02356                         return adodb_date($this->fmtTimeStamp,$ts);
02357                 
02358                 if ($ts === 'null') return $ts;
02359                 if ($this->isoDates && strlen($ts) !== 14) return "'$ts'";
02360                 
02361                 $ts = ADOConnection::UnixTimeStamp($ts);
02362                 return adodb_date($this->fmtTimeStamp,$ts);
02363         }
02364         
02371         function UnixDate($v)
02372         {
02373                 if (is_object($v)) {
02374                 // odbtp support
02375                 //( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 )
02376                         return adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year);
02377                 }
02378         
02379                 if (is_numeric($v) && strlen($v) !== 8) return $v;
02380                 if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|", 
02381                         ($v), $rr)) return false;
02382 
02383                 if ($rr[1] <= TIMESTAMP_FIRST_YEAR) return 0;
02384                 // h-m-s-MM-DD-YY
02385                 return @adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]);
02386         }
02387         
02388 
02395         function UnixTimeStamp($v)
02396         {
02397                 if (is_object($v)) {
02398                 // odbtp support
02399                 //( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 )
02400                         return adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year);
02401                 }
02402                 
02403                 if (!preg_match( 
02404                         "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]*(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", 
02405                         ($v), $rr)) return false;
02406                         
02407                 if ($rr[1] <= TIMESTAMP_FIRST_YEAR && $rr[2]<= 1) return 0;
02408         
02409                 // h-m-s-MM-DD-YY
02410                 if (!isset($rr[5])) return  adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]);
02411                 return  @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]);
02412         }
02413         
02425         function UserDate($v,$fmt='Y-m-d',$gmt=false)
02426         {
02427                 $tt = $this->UnixDate($v);
02428 
02429                 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR
02430                 if (($tt === false || $tt == -1) && $v != false) return $v;
02431                 else if ($tt == 0) return $this->emptyDate;
02432                 else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR
02433                 }
02434                 
02435                 return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt);
02436         
02437         }
02438         
02446         function UserTimeStamp($v,$fmt='Y-m-d H:i:s',$gmt=false)
02447         {
02448                 if (!isset($v)) return $this->emptyTimeStamp;
02449                 # strlen(14) allows YYYYMMDDHHMMSS format
02450                 if (is_numeric($v) && strlen($v)<14) return ($gmt) ? adodb_gmdate($fmt,$v) : adodb_date($fmt,$v);
02451                 $tt = $this->UnixTimeStamp($v);
02452                 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR
02453                 if (($tt === false || $tt == -1) && $v != false) return $v;
02454                 if ($tt == 0) return $this->emptyTimeStamp;
02455                 return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt);
02456         }
02457         
02458         function escape($s,$magic_quotes=false)
02459         {
02460                 return $this->addq($s,$magic_quotes);
02461         }
02462         
02466         function addq($s,$magic_quotes=false)
02467         {
02468                 if (!$magic_quotes) {
02469                 
02470                         if ($this->replaceQuote[0] == '\\'){
02471                                 // only since php 4.0.5
02472                                 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
02473                                 //$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s));
02474                         }
02475                         return  str_replace("'",$this->replaceQuote,$s);
02476                 }
02477                 
02478                 // undo magic quotes for "
02479                 $s = str_replace('\\"','"',$s);
02480                 
02481                 if ($this->replaceQuote == "\\'")  // ' already quoted, no need to change anything
02482                         return $s;
02483                 else {// change \' to '' for sybase/mssql
02484                         $s = str_replace('\\\\','\\',$s);
02485                         return str_replace("\\'",$this->replaceQuote,$s);
02486                 }
02487         }
02488         
02500         function qstr($s,$magic_quotes=false)
02501         {       
02502                 if (!$magic_quotes) {
02503                 
02504                         if ($this->replaceQuote[0] == '\\'){
02505                                 // only since php 4.0.5
02506                                 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
02507                                 //$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s));
02508                         }
02509                         return  "'".str_replace("'",$this->replaceQuote,$s)."'";
02510                 }
02511                 
02512                 // undo magic quotes for "
02513                 $s = str_replace('\\"','"',$s);
02514                 
02515                 if ($this->replaceQuote == "\\'")  // ' already quoted, no need to change anything
02516                         return "'$s'";
02517                 else {// change \' to '' for sybase/mssql
02518                         $s = str_replace('\\\\','\\',$s);
02519                         return "'".str_replace("\\'",$this->replaceQuote,$s)."'";
02520                 }
02521         }
02522         
02523         
02541         function &PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) 
02542         {
02543                 global $ADODB_INCLUDED_LIB;
02544                 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
02545                 if ($this->pageExecuteCountRows) $rs =& _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache);
02546                 else $rs =& _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache);
02547                 return $rs;
02548         }
02549         
02550                 
02563         function &CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) 
02564         {
02565                 /*switch($this->dataProvider) {
02566                 case 'postgres':
02567                 case 'mysql': 
02568                         break;
02569                 default: $secs2cache = 0; break;
02570                 }*/
02571                 $rs =& $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache);
02572                 return $rs;
02573         }
02574 
02575 } // end class ADOConnection
02576         
02577         
02578         
02579         //==============================================================================================        
02580         // CLASS ADOFetchObj
02581         //==============================================================================================        
02582                 
02586         class ADOFetchObj {
02587         };
02588         
02589         //==============================================================================================        
02590         // CLASS ADORecordSet_empty
02591         //==============================================================================================        
02592         
02596         class ADORecordSet_empty
02597         {
02598                 var $dataProvider = 'empty';
02599                 var $databaseType = false;
02600                 var $EOF = true;
02601                 var $_numOfRows = 0;
02602                 var $fields = false;
02603                 var $connection = false;
02604                 function RowCount() {return 0;}
02605                 function RecordCount() {return 0;}
02606                 function PO_RecordCount(){return 0;}
02607                 function Close(){return true;}
02608                 function FetchRow() {return false;}
02609                 function FieldCount(){ return 0;}
02610                 function Init() {}
02611         }
02612         
02613         //==============================================================================================        
02614         // DATE AND TIME FUNCTIONS
02615         //==============================================================================================        
02616         if (!defined('ADODB_DATE_VERSION')) include(ADODB_DIR.'/adodb-time.inc.php');
02617         
02618         //==============================================================================================        
02619         // CLASS ADORecordSet
02620         //==============================================================================================        
02621 
02622         if (PHP_VERSION < 5) include_once(ADODB_DIR.'/adodb-php4.inc.php');
02623         else include_once(ADODB_DIR.'/adodb-iterator.inc.php');
02630         class ADORecordSet extends ADODB_BASE_RS {
02631         /*
02632          * public variables     
02633          */
02634         var $dataProvider = "native";
02635         var $fields = false;    
02636         var $blobSize = 100;    
02637 
02638         var $canSeek = false;   
02639         var $sql;                               
02640         var $EOF = false;               
02641         
02642         var $emptyTimeStamp = '&nbsp;'; 
02643         var $emptyDate = '&nbsp;'; 
02644         var $debug = false;
02645         var $timeCreated=0;     
02646 
02647         var $bind = false;              
02648         var $fetchMode;                 
02649         var $connection = false; 
02650         /*
02651          *      private variables       
02652          */
02653         var $_numOfRows = -1;   
02654         var $_numOfFields = -1; 
02655         var $_queryID = -1;             
02656         var $_currentRow = -1;  
02657         var $_closed = false;   
02658         var $_inited = false;   
02659         var $_obj;                              
02660         var $_names;                    
02662         var $_currentPage = -1; 
02663         var $_atFirstPage = false;      
02664         var $_atLastPage = false;       
02665         var $_lastPageNo = -1; 
02666         var $_maxRecordCount = 0;
02667         var $datetime = false;
02668         
02675         function ADORecordSet($queryID) 
02676         {
02677                 $this->_queryID = $queryID;
02678         }
02679         
02680         
02681         
02682         function Init()
02683         {
02684                 if ($this->_inited) return;
02685                 $this->_inited = true;
02686                 if ($this->_queryID) @$this->_initrs();
02687                 else {
02688                         $this->_numOfRows = 0;
02689                         $this->_numOfFields = 0;
02690                 }
02691                 if ($this->_numOfRows != 0 && $this->_numOfFields && $this->_currentRow == -1) {
02692                         
02693                         $this->_currentRow = 0;
02694                         if ($this->EOF = ($this->_fetch() === false)) {
02695                                 $this->_numOfRows = 0; // _numOfRows could be -1
02696                         }
02697                 } else {
02698                         $this->EOF = true;
02699                 }
02700         }
02701         
02702         
02723         function GetMenu($name,$defstr='',$blank1stItem=true,$multiple=false,
02724                         $size=0, $selectAttr='',$compareFields0=true)
02725         {
02726                 global $ADODB_INCLUDED_LIB;
02727                 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
02728                 return _adodb_getmenu($this, $name,$defstr,$blank1stItem,$multiple,
02729                         $size, $selectAttr,$compareFields0);
02730         }
02731         
02732 
02733         
02741         function GetMenu2($name,$defstr='',$blank1stItem=true,$multiple=false,$size=0, $selectAttr='')  
02742         {
02743                 return $this->GetMenu($name,$defstr,$blank1stItem,$multiple,
02744                         $size, $selectAttr,false);
02745         }
02746         
02747         /*
02748                 Grouped Menu
02749         */
02750         function GetMenu3($name,$defstr='',$blank1stItem=true,$multiple=false,
02751                         $size=0, $selectAttr='')
02752         {
02753                 global $ADODB_INCLUDED_LIB;
02754                 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
02755                 return _adodb_getmenu_gp($this, $name,$defstr,$blank1stItem,$multiple,
02756                         $size, $selectAttr,false);
02757         }
02758 
02766         function &GetArray($nRows = -1) 
02767         {
02768         global $ADODB_EXTENSION; if ($ADODB_EXTENSION) {
02769                 $results = adodb_getall($this,$nRows);
02770                 return $results;
02771         }
02772                 $results = array();
02773                 $cnt = 0;
02774                 while (!$this->EOF && $nRows != $cnt) {
02775                         $results[] = $this->fields;
02776                         $this->MoveNext();
02777                         $cnt++;
02778                 }
02779                 return $results;
02780         }
02781         
02782         function &GetAll($nRows = -1)
02783         {
02784                 $arr =& $this->GetArray($nRows);
02785                 return $arr;
02786         }
02787         
02788         /*
02789         * Some databases allow multiple recordsets to be returned. This function
02790         * will return true if there is a next recordset, or false if no more.
02791         */
02792         function NextRecordSet()
02793         {
02794                 return false;
02795         }
02796         
02806         function &GetArrayLimit($nrows,$offset=-1) 
02807         {       
02808                 if ($offset <= 0) {
02809                         $arr =& $this->GetArray($nrows);
02810                         return $arr;
02811                 } 
02812                 
02813                 $this->Move($offset);
02814                 
02815                 $results = array();
02816                 $cnt = 0;
02817                 while (!$this->EOF && $nrows != $cnt) {
02818                         $results[$cnt++] = $this->fields;
02819                         $this->MoveNext();
02820                 }
02821                 
02822                 return $results;
02823         }
02824         
02825         
02833         function &GetRows($nRows = -1) 
02834         {
02835                 $arr =& $this->GetArray($nRows);
02836                 return $arr;
02837         }
02838         
02855         function &GetAssoc($force_array = false, $first2cols = false) 
02856         {
02857         global $ADODB_EXTENSION;
02858         
02859                 $cols = $this->_numOfFields;
02860                 if ($cols < 2) {
02861                         $false = false;
02862                         return $false;
02863                 }
02864                 $numIndex = isset($this->fields[0]);
02865                 $results = array();
02866                 
02867                 if (!$first2cols && ($cols > 2 || $force_array)) {
02868                         if ($ADODB_EXTENSION) {
02869                                 if ($numIndex) {
02870                                         while (!$this->EOF) {
02871                                                 $results[trim($this->fields[0])] = array_slice($this->fields, 1);
02872                                                 adodb_movenext($this);
02873                                         }
02874                                 } else {
02875                                         while (!$this->EOF) {
02876                                                 $results[trim(reset($this->fields))] = array_slice($this->fields, 1);
02877                                                 adodb_movenext($this);
02878                                         }
02879                                 }
02880                         } else {
02881                                 if ($numIndex) {
02882                                         while (!$this->EOF) {
02883                                                 $results[trim($this->fields[0])] = array_slice($this->fields, 1);
02884                                                 $this->MoveNext();
02885                                         }
02886                                 } else {
02887                                         while (!$this->EOF) {
02888                                                 $results[trim(reset($this->fields))] = array_slice($this->fields, 1);
02889                                                 $this->MoveNext();
02890                                         }
02891                                 }
02892                         }
02893                 } else {
02894                         if ($ADODB_EXTENSION) {
02895                                 // return scalar values
02896                                 if ($numIndex) {
02897                                         while (!$this->EOF) {
02898                                         // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
02899                                                 $results[trim(($this->fields[0]))] = $this->fields[1];
02900                                                 adodb_movenext($this);
02901                                         }
02902                                 } else {
02903                                         while (!$this->EOF) {
02904                                         // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
02905                                                 $v1 = trim(reset($this->fields));
02906                                                 $v2 = ''.next($this->fields); 
02907                                                 $results[$v1] = $v2;
02908                                                 adodb_movenext($this);
02909                                         }
02910                                 }
02911                         } else {
02912                                 if ($numIndex) {
02913                                         while (!$this->EOF) {
02914                                         // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
02915                                                 $results[trim(($this->fields[0]))] = $this->fields[1];
02916                                                 $this->MoveNext();
02917                                         }
02918                                 } else {
02919                                         while (!$this->EOF) {
02920                                         // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
02921                                                 $v1 = trim(reset($this->fields));
02922                                                 $v2 = ''.next($this->fields); 
02923                                                 $results[$v1] = $v2;
02924                                                 $this->MoveNext();
02925                                         }
02926                                 }
02927                         }
02928                 }
02929                 
02930                 $ref =& $results; # workaround accelerator incompat with PHP 4.4 :(
02931                 return $ref; 
02932         }
02933         
02934         
02942         function UserTimeStamp($v,$fmt='Y-m-d H:i:s')
02943         {
02944                 if (is_numeric($v) && strlen($v)<14) return adodb_date($fmt,$v);
02945                 $tt = $this->UnixTimeStamp($v);
02946                 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR
02947                 if (($tt === false || $tt == -1) && $v != false) return $v;
02948                 if ($tt === 0) return $this->emptyTimeStamp;
02949                 return adodb_date($fmt,$tt);
02950         }
02951         
02952         
02959         function UserDate($v,$fmt='Y-m-d')
02960         {
02961                 $tt = $this->UnixDate($v);
02962                 // $tt == -1 if pre TIMESTAMP_FIRST_YEAR
02963                 if (($tt === false || $tt == -1) && $v != false) return $v;
02964                 else if ($tt == 0) return $this->emptyDate;
02965                 else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR
02966                 }
02967                 return adodb_date($fmt,$tt);
02968         }
02969         
02970         
02976         function UnixDate($v)
02977         {
02978                 return ADOConnection::UnixDate($v);
02979         }
02980         
02981 
02987         function UnixTimeStamp($v)
02988         {
02989                 return ADOConnection::UnixTimeStamp($v);
02990         }
02991         
02992         
02996         function Free()
02997         {
02998                 return $this->Close();
02999         }
03000         
03001         
03005         function NumRows()
03006         {
03007                 return $this->_numOfRows;
03008         }
03009         
03010         
03014         function NumCols()
03015         {
03016                 return $this->_numOfFields;
03017         }
03018         
03025         function &FetchRow()
03026         {
03027                 if ($this->EOF) {
03028                         $false = false;
03029                         return $false;
03030                 }
03031                 $arr = $this->fields;
03032                 $this->_currentRow++;
03033                 if (!$this->_fetch()) $this->EOF = true;
03034                 return $arr;
03035         }
03036         
03037         
03044         function FetchInto(&$arr)
03045         {
03046                 if ($this->EOF) return (defined('PEAR_ERROR_RETURN')) ? new PEAR_Error('EOF',-1): false;
03047                 $arr = $this->fields;
03048                 $this->MoveNext();
03049                 return 1; // DB_OK
03050         }
03051         
03052         
03058         function MoveFirst() 
03059         {
03060                 if ($this->_currentRow == 0) return true;
03061                 return $this->Move(0);                  
03062         }                       
03063 
03064         
03070         function MoveLast() 
03071         {
03072                 if ($this->_numOfRows >= 0) return $this->Move($this->_numOfRows-1);
03073                 if ($this->EOF) return false;
03074                 while (!$this->EOF) {
03075                         $f = $this->fields;
03076                         $this->MoveNext();
03077                 }
03078                 $this->fields = $f;
03079                 $this->EOF = false;
03080                 return true;
03081         }
03082         
03083         
03089         function MoveNext() 
03090         {
03091                 if (!$this->EOF) {
03092                         $this->_currentRow++;
03093                         if ($this->_fetch()) return true;
03094                 }
03095                 $this->EOF = true;
03096                 /* -- tested error handling when scrolling cursor -- seems useless.
03097                 $conn = $this->connection;
03098                 if ($conn && $conn->raiseErrorFn && ($errno = $conn->ErrorNo())) {
03099                         $fn = $conn->raiseErrorFn;
03100                         $fn($conn->databaseType,'MOVENEXT',$errno,$conn->ErrorMsg().' ('.$this->sql.')',$conn->host,$conn->database);
03101                 }
03102                 */
03103                 return false;
03104         }
03105         
03106         
03115         function Move($rowNumber = 0) 
03116         {
03117                 $this->EOF = false;
03118                 if ($rowNumber == $this->_currentRow) return true;
03119                 if ($rowNumber >= $this->_numOfRows)
03120                         if ($this->_numOfRows != -1) $rowNumber = $this->_numOfRows-2;
03121                                 
03122                 if ($this->canSeek) { 
03123         
03124                         if ($this->_seek($rowNumber)) {
03125                                 $this->_currentRow = $rowNumber;
03126                                 if ($this->_fetch()) {
03127                                         return true;
03128                                 }
03129                         } else {
03130                                 $this->EOF = true;
03131                                 return false;
03132                         }
03133                 } else {
03134                         if ($rowNumber < $this->_currentRow) return false;
03135                         global $ADODB_EXTENSION;
03136                         if ($ADODB_EXTENSION) {
03137                                 while (!$this->EOF && $this->_currentRow < $rowNumber) {
03138                                         adodb_movenext($this);
03139                                 }
03140                         } else {
03141                         
03142                                 while (! $this->EOF && $this->_currentRow < $rowNumber) {
03143                                         $this->_currentRow++;
03144                                         
03145                                         if (!$this->_fetch()) $this->EOF = true;
03146                                 }
03147                         }
03148                         return !($this->EOF);
03149                 }
03150                 
03151                 $this->fields = false;  
03152                 $this->EOF = true;
03153                 return false;
03154         }
03155         
03156                 
03165         function Fields($colname)
03166         {
03167                 return $this->fields[$colname];
03168         }
03169         
03170         function GetAssocKeys($upper=true)
03171         {
03172                 $this->bind = array();
03173                 for ($i=0; $i < $this->_numOfFields; $i++) {
03174                         $o = $this->FetchField($i);
03175                         if ($upper === 2) $this->bind[$o->name] = $i;
03176                         else $this->bind[($upper) ? strtoupper($o->name) : strtolower($o->name)] = $i;
03177                 }
03178         }
03179         
03189         function &GetRowAssoc($upper=1)
03190         {
03191                 $record = array();
03192          //     if (!$this->fields) return $record;
03193                 
03194                 if (!$this->bind) {
03195                         $this->GetAssocKeys($upper);
03196                 }
03197                 
03198                 foreach($this->bind as $k => $v) {
03199                         $record[$k] = $this->fields[$v];
03200                 }
03201 
03202                 return $record;
03203         }
03204         
03205         
03211         function Close() 
03212         {
03213                 // free connection object - this seems to globally free the object
03214                 // and not merely the reference, so don't do this...
03215                 // $this->connection = false; 
03216                 if (!$this->_closed) {
03217                         $this->_closed = true;
03218                         return $this->_close();         
03219                 } else
03220                         return true;
03221         }
03222         
03228         function RecordCount() {return $this->_numOfRows;}
03229         
03230         
03231         /*
03232         * If we are using PageExecute(), this will return the maximum possible rows
03233         * that can be returned when paging a recordset.
03234         */
03235         function MaxRecordCount()
03236         {
03237                 return ($this->_maxRecordCount) ? $this->_maxRecordCount : $this->RecordCount();
03238         }
03239         
03245         function RowCount() {return $this->_numOfRows;} 
03246         
03247 
03256         function PO_RecordCount($table="", $condition="") {
03257                 
03258                 $lnumrows = $this->_numOfRows;
03259                 // the database doesn't support native recordcount, so we do a workaround
03260                 if ($lnumrows == -1 && $this->connection) {
03261                         IF ($table) {
03262                                 if ($condition) $condition = " WHERE " . $condition; 
03263                                 $resultrows = &$this->connection->Execute("SELECT COUNT(*) FROM $table $condition");
03264                                 if ($resultrows) $lnumrows = reset($resultrows->fields);
03265                         }
03266                 }
03267                 return $lnumrows;
03268         }
03269         
03270         
03274         function CurrentRow() {return $this->_currentRow;}
03275         
03281         function AbsolutePosition() {return $this->_currentRow;}
03282         
03287         function FieldCount() {return $this->_numOfFields;}   
03288 
03289 
03297         function &FetchField($fieldoffset) 
03298         {
03299                 // must be defined by child class
03300         }       
03301         
03306         function& FieldTypesArray()
03307         {
03308                 $arr = array();
03309                 for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) 
03310                         $arr[] = $this->FetchField($i);
03311                 return $arr;
03312         }
03313         
03320         function &FetchObj()
03321         {
03322                 $o =& $this->FetchObject(false);
03323                 return $o;
03324         }
03325         
03334         function &FetchObject($isupper=true)
03335         {
03336                 if (empty($this->_obj)) {
03337                         $this->_obj = new ADOFetchObj();
03338                         $this->_names = array();
03339                         for ($i=0; $i <$this->_numOfFields; $i++) {
03340                                 $f = $this->FetchField($i);
03341                                 $this->_names[] = $f->name;
03342                         }
03343                 }
03344                 $i = 0;
03345                 if (PHP_VERSION >= 5) $o = clone($this->_obj);
03346                 else $o = $this->_obj;
03347         
03348                 for ($i=0; $i <$this->_numOfFields; $i++) {
03349                         $name = $this->_names[$i];
03350                         if ($isupper) $n = strtoupper($name);
03351                         else $n = $name;
03352                         
03353                         $o->$n = $this->Fields($name);
03354                 }
03355                 return $o;
03356         }
03357         
03367         function &FetchNextObj()
03368         {
03369                 $o =& $this->FetchNextObject(false);
03370                 return $o;
03371         }
03372         
03373         
03385         function &FetchNextObject($isupper=true)
03386         {
03387                 $o = false;
03388                 if ($this->_numOfRows != 0 && !$this->EOF) {
03389                         $o = $this->FetchObject($isupper);      
03390                         $this->_currentRow++;
03391                         if ($this->_fetch()) return $o;
03392                 }
03393                 $this->EOF = true;
03394                 return $o;
03395         }
03396         
03421         function MetaType($t,$len=-1,$fieldobj=false)
03422         {
03423                 if (is_object($t)) {
03424                         $fieldobj = $t;
03425                         $t = $fieldobj->type;
03426                         $len = $fieldobj->max_length;
03427                 }
03428         // changed in 2.32 to hashing instead of switch stmt for speed...
03429         static $typeMap = array(
03430                 'VARCHAR' => 'C',
03431                 'VARCHAR2' => 'C',
03432                 'CHAR' => 'C',
03433                 'C' => 'C',
03434                 'STRING' => 'C',
03435                 'NCHAR' => 'C',
03436                 'NVARCHAR' => 'C',
03437                 'VARYING' => 'C',
03438                 'BPCHAR' => 'C',
03439                 'CHARACTER' => 'C',
03440                 'INTERVAL' => 'C',  # Postgres
03441                 'MACADDR' => 'C', # postgres
03442                 ##
03443                 'LONGCHAR' => 'X',
03444                 'TEXT' => 'X',
03445                 'NTEXT' => 'X',
03446                 'M' => 'X',
03447                 'X' => 'X',
03448                 'CLOB' => 'X',
03449                 'NCLOB' => 'X',
03450                 'LVARCHAR' => 'X',
03451                 ##
03452                 'BLOB' => 'B',
03453                 'IMAGE' => 'B',
03454                 'BINARY' => 'B',
03455                 'VARBINARY' => 'B',
03456                 'LONGBINARY' => 'B',
03457                 'B' => 'B',
03458                 ##
03459                 'YEAR' => 'D', // mysql
03460                 'DATE' => 'D',
03461                 'D' => 'D',
03462                 ##
03463                 'TIME' => 'T',
03464                 'TIMESTAMP' => 'T',
03465                 'DATETIME' => 'T',
03466                 'TIMESTAMPTZ' => 'T',
03467                 'T' => 'T',
03468                 'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql
03469                 ##
03470                 'BOOL' => 'L',
03471                 'BOOLEAN' => 'L', 
03472                 'BIT' => 'L',
03473                 'L' => 'L',
03474                 ##
03475                 'COUNTER' => 'R',
03476                 'R' => 'R',
03477                 'SERIAL' => 'R', // ifx
03478                 'INT IDENTITY' => 'R',
03479                 ##
03480                 'INT' => 'I',
03481                 'INT2' => 'I',
03482                 'INT4' => 'I',
03483                 'INT8' => 'I',
03484                 'INTEGER' => 'I',
03485                 'INTEGER UNSIGNED' => 'I',
03486                 'SHORT' => 'I',
03487                 'TINYINT' => 'I',
03488                 'SMALLINT' => 'I',
03489                 'I' => 'I',
03490                 ##
03491                 'LONG' => 'N', // interbase is numeric, oci8 is blob
03492                 'BIGINT' => 'N', // this is bigger than PHP 32-bit integers
03493                 'DECIMAL' => 'N',
03494                 'DEC' => 'N',
03495                 'REAL' => 'N',
03496                 'DOUBLE' => 'N',
03497                 'DOUBLE PRECISION' => 'N',
03498                 'SMALLFLOAT' => 'N',
03499                 'FLOAT' => 'N',
03500                 'NUMBER' => 'N',
03501                 'NUM' => 'N',
03502                 'NUMERIC' => 'N',
03503                 'MONEY' => 'N',
03504                 
03505                 ## informix 9.2
03506                 'SQLINT' => 'I', 
03507                 'SQLSERIAL' => 'I', 
03508                 'SQLSMINT' => 'I', 
03509                 'SQLSMFLOAT' => 'N', 
03510                 'SQLFLOAT' => 'N', 
03511                 'SQLMONEY' => 'N', 
03512                 'SQLDECIMAL' => 'N', 
03513                 'SQLDATE' => 'D', 
03514                 'SQLVCHAR' => 'C', 
03515                 'SQLCHAR' => 'C', 
03516                 'SQLDTIME' => 'T', 
03517                 'SQLINTERVAL' => 'N', 
03518                 'SQLBYTES' => 'B', 
03519                 'SQLTEXT' => 'X' 
03520                 );
03521                 
03522                 $tmap = false;
03523                 $t = strtoupper($t);
03524                 $tmap = (isset($typeMap[$t])) ? $typeMap[$t] : 'N';
03525                 switch ($tmap) {
03526                 case 'C':
03527                 
03528                         // is the char field is too long, return as text field... 
03529                         if ($this->blobSize >= 0) {
03530                                 if ($len > $this->blobSize) return 'X';
03531                         } else if ($len > 250) {
03532                                 return 'X';
03533                         }
03534                         return 'C';
03535                         
03536                 case 'I':
03537                         if (!empty($fieldobj->primary_key)) return 'R';
03538                         return 'I';
03539                 
03540                 case false:
03541                         return 'N';
03542                         
03543                 case 'B':
03544                          if (isset($fieldobj->binary)) 
03545                                  return ($fieldobj->binary) ? 'B' : 'X';
03546                         return 'B';
03547                 
03548                 case 'D':
03549                         if (!empty($this->connection) && !empty($this->connection->datetime)) return 'T';
03550                         return 'D';
03551                         
03552                 default: 
03553                         if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
03554                         return $tmap;
03555                 }
03556         }
03557         
03558         function _close() {}
03559         
03563         function AbsolutePage($page=-1)
03564         {
03565                 if ($page != -1) $this->_currentPage = $page;
03566                 return $this->_currentPage;
03567         }
03568         
03572         function AtFirstPage($status=false)
03573         {
03574                 if ($status != false) $this->_atFirstPage = $status;
03575                 return $this->_atFirstPage;
03576         }
03577         
03578         function LastPageNo($page = false)
03579         {
03580                 if ($page != false) $this->_lastPageNo = $page;
03581                 return $this->_lastPageNo;
03582         }
03583         
03587         function AtLastPage($status=false)
03588         {
03589                 if ($status != false) $this->_atLastPage = $status;
03590                 return $this->_atLastPage;
03591         }
03592         
03593 } // end class ADORecordSet
03594         
03595         //==============================================================================================        
03596         // CLASS ADORecordSet_array
03597         //==============================================================================================        
03598         
03606         class ADORecordSet_array extends ADORecordSet
03607         {
03608                 var $databaseType = 'array';
03609 
03610                 var $_array;    // holds the 2-dimensional data array
03611                 var $_types;    // the array of types of each column (C B I L M)
03612                 var $_colnames; // names of each column in array
03613                 var $_skiprow1; // skip 1st row because it holds column names
03614                 var $_fieldarr; // holds array of field objects
03615                 var $canSeek = true;
03616                 var $affectedrows = false;
03617                 var $insertid = false;
03618                 var $sql = '';
03619                 var $compat = false;
03624                 function ADORecordSet_array($fakeid=1)
03625                 {
03626                 global $ADODB_FETCH_MODE,$ADODB_COMPAT_FETCH;
03627                 
03628                         // fetch() on EOF does not delete $this->fields
03629                         $this->compat = !empty($ADODB_COMPAT_FETCH);
03630                         $this->ADORecordSet($fakeid); // fake queryID           
03631                         $this->fetchMode = $ADODB_FETCH_MODE;
03632                 }
03633                 
03634                 
03646                 function InitArray($array,$typearr,$colnames=false)
03647                 {
03648                         $this->_array = $array;
03649                         $this->_types = $typearr;       
03650                         if ($colnames) {
03651                                 $this->_skiprow1 = false;
03652                                 $this->_colnames = $colnames;
03653                         } else  {
03654                                 $this->_skiprow1 = true;
03655                                 $this->_colnames = $array[0];
03656                         }
03657                         $this->Init();
03658                 }
03667                 function InitArrayFields(&$array,&$fieldarr)
03668                 {
03669                         $this->_array =& $array;
03670                         $this->_skiprow1= false;
03671                         if ($fieldarr) {
03672                                 $this->_fieldobjects =& $fieldarr;
03673                         } 
03674                         $this->Init();
03675                 }
03676                 
03677                 function &GetArray($nRows=-1)
03678                 {
03679                         if ($nRows == -1 && $this->_currentRow <= 0 && !$this->_skiprow1) {
03680                                 return $this->_array;
03681                         } else {
03682                                 $arr =& ADORecordSet::GetArray($nRows);
03683                                 return $arr;
03684                         }
03685                 }
03686                 
03687                 function _initrs()
03688                 {
03689                         $this->_numOfRows =  sizeof($this->_array);
03690                         if ($this->_skiprow1) $this->_numOfRows -= 1;
03691                 
03692                         $this->_numOfFields =(isset($this->_fieldobjects)) ?
03693                                  sizeof($this->_fieldobjects):sizeof($this->_types);
03694                 }
03695                 
03696                 /* Use associative array to get fields array */
03697                 function Fields($colname)
03698                 {
03699                         $mode = isset($this->adodbFetchMode) ? $this->adodbFetchMode : $this->fetchMode;
03700                         
03701                         if ($mode & ADODB_FETCH_ASSOC) {
03702                                 if (!isset($this->fields[$colname])) $colname = strtolower($colname);
03703                                 return $this->fields[$colname];
03704                         }
03705                         if (!$this->bind) {
03706                                 $this->bind = array();
03707                                 for ($i=0; $i < $this->_numOfFields; $i++) {
03708                                         $o = $this->FetchField($i);
03709                                         $this->bind[strtoupper($o->name)] = $i;
03710                                 }
03711                         }
03712                         return $this->fields[$this->bind[strtoupper($colname)]];
03713                 }
03714                 
03715                 function &FetchField($fieldOffset = -1) 
03716                 {
03717                         if (isset($this->_fieldobjects)) {
03718                                 return $this->_fieldobjects[$fieldOffset];
03719                         }
03720                         $o =  new ADOFieldObject();
03721                         $o->name = $this->_colnames[$fieldOffset];
03722                         $o->type =  $this->_types[$fieldOffset];
03723                         $o->max_length = -1; // length not known
03724                         
03725                         return $o;
03726                 }
03727                         
03728                 function _seek($row)
03729                 {
03730                         if (sizeof($this->_array) && 0 <= $row && $row < $this->_numOfRows) {
03731                                 $this->_currentRow = $row;
03732                                 if ($this->_skiprow1) $row += 1;
03733                                 $this->fields = $this->_array[$row];
03734                                 return true;
03735                         }
03736                         return false;
03737                 }
03738                 
03739                 function MoveNext() 
03740                 {
03741                         if (!$this->EOF) {              
03742                                 $this->_currentRow++;
03743                                 
03744                                 $pos = $this->_currentRow;
03745                                 
03746                                 if ($this->_numOfRows <= $pos) {
03747                                         if (!$this->compat) $this->fields = false;
03748                                 } else {
03749                                         if ($this->_skiprow1) $pos += 1;
03750                                         $this->fields = $this->_array[$pos];
03751                                         return true;
03752                                 }               
03753                                 $this->EOF = true;
03754                         }
03755                         
03756                         return false;
03757                 }       
03758         
03759                 function _fetch()
03760                 {
03761                         $pos = $this->_currentRow;
03762                         
03763                         if ($this->_numOfRows <= $pos) {
03764                                 if (!$this->compat) $this->fields = false;
03765                                 return false;
03766                         }
03767                         if ($this->_skiprow1) $pos += 1;
03768                         $this->fields = $this->_array[$pos];
03769                         return true;
03770                 }
03771                 
03772                 function _close() 
03773                 {
03774                         return true;    
03775                 }
03776         
03777         } // ADORecordSet_array
03778 
03779         //==============================================================================================        
03780         // HELPER FUNCTIONS
03781         //==============================================================================================                        
03782         
03788         function ADOLoadDB($dbType) 
03789         { 
03790                 return ADOLoadCode($dbType);
03791         }
03792                 
03796         function ADOLoadCode($dbType) 
03797         {
03798         global $ADODB_LASTDB;
03799         
03800                 if (!$dbType) return false;
03801                 $db = strtolower($dbType);
03802                 switch ($db) {
03803                         case 'ado': 
03804                                 if (PHP_VERSION >= 5) $db = 'ado5';
03805                                 $class = 'ado'; 
03806                                 break;
03807                         case 'ifx':
03808                         case 'maxsql': $class = $db = 'mysqlt'; break;
03809                         case 'postgres':
03810                         case 'postgres8':
03811                         case 'pgsql': $class = $db = 'postgres7'; break;
03812                         default:
03813                                 $class = $db; break;
03814                 }
03815                 
03816                 $file = ADODB_DIR."/drivers/adodb-".$db.".inc.php";
03817                 @include_once($file);
03818                 $ADODB_LASTDB = $class;
03819                 if (class_exists("ADODB_" . $class)) return $class;
03820                 
03821                 //ADOConnection::outp(adodb_pr(get_declared_classes(),true));
03822                 if (!file_exists($file)) ADOConnection::outp("Missing file: $file");
03823                 else ADOConnection::outp("Syntax error in file: $file");
03824                 return false;
03825         }
03826 
03830         function &NewADOConnection($db='')
03831         {
03832                 $tmp =& ADONewConnection($db);
03833                 return $tmp;
03834         }
03835         
03844         function &ADONewConnection($db='')
03845         {
03846         GLOBAL $ADODB_NEWCONNECTION, $ADODB_LASTDB;
03847                 
03848                 if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
03849                 $errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false;
03850                 $false = false;
03851                 if ($at = strpos($db,'://')) {
03852                         $origdsn = $db;
03853                         if (PHP_VERSION < 5) $dsna = @parse_url($db);
03854                         else {
03855                                 $fakedsn = 'fake'.substr($db,$at);
03856                                 $dsna = @parse_url($fakedsn);
03857                                 $dsna['scheme'] = substr($db,0,$at);
03858                         
03859                                 if (strncmp($db,'pdo',3) == 0) {
03860                                         $sch = explode('_',$dsna['scheme']);
03861                                         if (sizeof($sch)>1) {
03862                                                 $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
03863                                                 $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host']));
03864                                                 $dsna['scheme'] = 'pdo';
03865                                         }
03866                                 }
03867                         }
03868                         
03869                         if (!$dsna) {
03870                                 // special handling of oracle, which might not have host
03871                                 $db = str_replace('@/','@adodb-fakehost/',$db);
03872                                 $dsna = parse_url($db);
03873                                 if (!$dsna) return $false;
03874                                 $dsna['host'] = '';
03875                         }
03876                         $db = @$dsna['scheme'];
03877                         if (!$db) return $false;
03878                         $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
03879                         $dsna['user'] = isset($dsna['user']) ? rawurldecode($dsna['user']) : '';
03880                         $dsna['pass'] = isset($dsna['pass']) ? rawurldecode($dsna['pass']) : '';
03881                         $dsna['path'] = isset($dsna['path']) ? rawurldecode(substr($dsna['path'],1)) : ''; # strip off initial /
03882                         
03883                         if (isset($dsna['query'])) {
03884                                 $opt1 = explode('&',$dsna['query']);
03885                                 foreach($opt1 as $k => $v) {
03886                                         $arr = explode('=',$v);
03887                                         $opt[$arr[0]] = isset($arr[1]) ? rawurldecode($arr[1]) : 1;
03888                                 }
03889                         } else $opt = array();
03890                 }
03891         /*
03892          *  phptype: Database backend used in PHP (mysql, odbc etc.)
03893          *  dbsyntax: Database used with regards to SQL syntax etc.
03894          *  protocol: Communication protocol to use (tcp, unix etc.)
03895          *  hostspec: Host specification (hostname[:port])
03896          *  database: Database to use on the DBMS server
03897          *  username: User name for login
03898          *  password: Password for login
03899          */
03900                 if (!empty($ADODB_NEWCONNECTION)) {
03901                         $obj = $ADODB_NEWCONNECTION($db);
03902 
03903                 } else {
03904                 
03905                         if (!isset($ADODB_LASTDB)) $ADODB_LASTDB = '';
03906                         if (empty($db)) $db = $ADODB_LASTDB;
03907                         
03908                         if ($db != $ADODB_LASTDB) $db = ADOLoadCode($db);
03909                         
03910                         if (!$db) {
03911                                 if (isset($origdsn)) $db = $origdsn;
03912                                 if ($errorfn) {
03913                                         // raise an error
03914                                         $ignore = false;
03915                                         $errorfn('ADONewConnection', 'ADONewConnection', -998,
03916                                                          "could not load the database driver for '$db'",
03917                                                          $db,false,$ignore);
03918                                 } else
03919                                          ADOConnection::outp( "<p>ADONewConnection: Unable to load database driver '$db'</p>",false);
03920                                         
03921                                 return $false;
03922                         }
03923                         
03924                         $cls = 'ADODB_'.$db;
03925                         if (!class_exists($cls)) {
03926                                 adodb_backtrace();
03927                                 return $false;
03928                         }
03929                         
03930                         $obj = new $cls();
03931                 }
03932                 
03933                 # constructor should not fail
03934                 if ($obj) {
03935                         if ($errorfn)  $obj->raiseErrorFn = $errorfn;
03936                         if (isset($dsna)) {
03937                                 if (isset($dsna['port'])) $obj->port = $dsna['port'];
03938                                 foreach($opt as $k => $v) {
03939                                         switch(strtolower($k)) {
03940                                         case 'new':
03941                                                                                 $nconnect = true; $persist = true; break;
03942                                         case 'persist':
03943                                         case 'persistent':      $persist = $v; break;
03944                                         case 'debug':           $obj->debug = (integer) $v; break;
03945                                         #ibase
03946                                         case 'role':            $obj->role = $v; break;
03947                                         case 'dialect':         $obj->dialect = (integer) $v; break;
03948                                         case 'charset':         $obj->charset = $v; $obj->charSet=$v; break;
03949                                         case 'buffers':         $obj->buffers = $v; break;
03950                                         case 'fetchmode':   $obj->SetFetchMode($v); break;
03951                                         #ado
03952                                         case 'charpage':        $obj->charPage = $v; break;
03953                                         #mysql, mysqli
03954                                         case 'clientflags': $obj->clientFlags = $v; break;
03955                                         #mysql, mysqli, postgres
03956                                         case 'port': $obj->port = $v; break;
03957                                         #mysqli
03958                                         case 'socket': $obj->socket = $v; break;
03959                                         #oci8
03960                                         case 'nls_date_format': $obj->NLS_DATE_FORMAT = $v; break;
03961                                         }
03962                                 }
03963                                 if (empty($persist))
03964                                         $ok = $obj->Connect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']);
03965                                 else if (empty($nconnect))
03966                                         $ok = $obj->PConnect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']);
03967                                 else
03968                                         $ok = $obj->NConnect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']);
03969                                         
03970                                 if (!$ok) return $false;
03971                         }
03972                 }
03973                 return $obj;
03974         }
03975         
03976         
03977         
03978         // $perf == true means called by NewPerfMonitor(), otherwise for data dictionary
03979         function _adodb_getdriver($provider,$drivername,$perf=false)
03980         {
03981                 switch ($provider) {
03982                 case 'odbtp':   if (strncmp('odbtp_',$drivername,6)==0) return substr($drivername,6); 
03983                 case 'odbc' :   if (strncmp('odbc_',$drivername,5)==0) return substr($drivername,5); 
03984                 case 'ado'  :   if (strncmp('ado_',$drivername,4)==0) return substr($drivername,4);
03985                 case 'native':  break;
03986                 default:
03987                         return $provider;
03988                 }
03989                 
03990                 switch($drivername) {
03991                 case 'mysqlt':
03992                 case 'mysqli': 
03993                                 $drivername='mysql'; 
03994                                 break;
03995                 case 'postgres7':
03996                 case 'postgres8':
03997                                 $drivername = 'postgres'; 
03998                                 break;  
03999                 case 'firebird15': $drivername = 'firebird'; break;
04000                 case 'oracle': $drivername = 'oci8'; break;
04001                 case 'access': if ($perf) $drivername = ''; break;
04002                 case 'db2'   : break;
04003                 case 'sapdb' : break;
04004                 default:
04005                         $drivername = 'generic';
04006                         break;
04007                 }
04008                 return $drivername;
04009         }
04010         
04011         function &NewPerfMonitor(&$conn)
04012         {
04013                 $false = false;
04014                 $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType,true);
04015                 if (!$drivername || $drivername == 'generic') return $false;
04016                 include_once(ADODB_DIR.'/adodb-perf.inc.php');
04017                 @include_once(ADODB_DIR."/perf/perf-$drivername.inc.php");
04018                 $class = "Perf_$drivername";
04019                 if (!class_exists($class)) return $false;
04020                 $perf = new $class($conn);
04021                 
04022                 return $perf;
04023         }
04024         
04025         function &NewDataDictionary(&$conn,$drivername=false)
04026         {
04027                 $false = false;
04028                 if (!$drivername) $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType);
04029 
04030                 include_once(ADODB_DIR.'/adodb-lib.inc.php');
04031                 include_once(ADODB_DIR.'/adodb-datadict.inc.php');
04032                 $path = ADODB_DIR."/datadict/datadict-$drivername.inc.php";
04033 
04034                 if (!file_exists($path)) {
04035                         ADOConnection::outp("Dictionary driver '$path' not available");
04036                         return $false;
04037                 }
04038                 include_once($path);
04039                 $class = "ADODB2_$drivername";
04040                 $dict = new $class();
04041                 $dict->dataProvider = $conn->dataProvider;
04042                 $dict->connection = &$conn;
04043                 $dict->upperName = strtoupper($drivername);
04044                 $dict->quote = $conn->nameQuote;
04045                 if (!empty($conn->_connectionID))
04046                         $dict->serverInfo = $conn->ServerInfo();
04047                 
04048                 return $dict;
04049         }
04050 
04051 
04052         
04053         /*
04054                 Perform a print_r, with pre tags for better formatting.
04055         */
04056         function adodb_pr($var,$as_string=false)
04057         {
04058                 if ($as_string) ob_start();
04059                 
04060                 if (isset($_SERVER['HTTP_USER_AGENT'])) { 
04061                         echo " <pre>\n";print_r($var);echo "</pre>\n";
04062                 } else
04063                         print_r($var);
04064                         
04065                 if ($as_string) {
04066                         $s = ob_get_contents();
04067                         ob_end_clean();
04068                         return $s;
04069                 }
04070         }
04071         
04072         /*
04073                 Perform a stack-crawl and pretty print it.
04074                 
04075                 @param printOrArr  Pass in a boolean to indicate print, or an $exception->trace array (assumes that print is true then).
04076                 @param levels Number of levels to display
04077         */
04078         function adodb_backtrace($printOrArr=true,$levels=9999)
04079         {
04080                 global $ADODB_INCLUDED_LIB;
04081                 if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
04082                 return _adodb_backtrace($printOrArr,$levels);
04083         }
04084 
04085 
04086 }
04087 ?>