root/releases/elgg0.8rc2/lib/adodb/adodb.inc.php

Revision 725, 117.7 kB (checked in by misja, 2 years ago)

Updated ADODB library.

  • Property svn:eol-style set to native
Line 
1 <?php
2 /*
3  * Set tabs to 4 for best viewing.
4  *
5  * Latest version is available at http://adodb.sourceforge.net
6  *
7  * This is the main include file for ADOdb.
8  * Database specific drivers are stored in the adodb/drivers/adodb-*.inc.php
9  *
10  * The ADOdb files are formatted so that doxygen can be used to generate documentation.
11  * Doxygen is a documentation generation tool and can be downloaded from http://doxygen.org/
12  */
13
14 /**
15     \mainpage     
16     
17      @version V4.93 10 Oct 2006  (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved.
18
19     Released under both BSD license and Lesser GPL library license. You can choose which license
20     you prefer.
21     
22     PHP's database access functions are not standardised. This creates a need for a database
23     class library to hide the differences between the different database API's (encapsulate
24     the differences) so we can easily switch databases.
25
26     We currently support MySQL, Oracle, Microsoft SQL Server, Sybase, Sybase SQL Anywhere, DB2,
27     Informix, PostgreSQL, FrontBase, Interbase (Firebird and Borland variants), Foxpro, Access,
28     ADO, SAP DB, SQLite and ODBC. We have had successful reports of connecting to Progress and
29     other databases via ODBC.
30
31     Latest Download at http://adodb.sourceforge.net/
32       
33  */
34  
35  if (!defined('_ADODB_LAYER')) {
36      define('_ADODB_LAYER',1);
37     
38     //==============================================================================================   
39     // CONSTANT DEFINITIONS
40     //==============================================================================================   
41
42
43     /**
44      * Set ADODB_DIR to the directory where this file resides...
45      * This constant was formerly called $ADODB_RootPath
46      */
47     if (!defined('ADODB_DIR')) define('ADODB_DIR',dirname(__FILE__));
48     
49     //==============================================================================================   
50     // GLOBAL VARIABLES
51     //==============================================================================================   
52
53     GLOBAL
54         $ADODB_vers,         // database version
55         $ADODB_COUNTRECS,    // count number of records returned - slows down query
56         $ADODB_CACHE_DIR,    // directory to cache recordsets
57         $ADODB_EXTENSION,   // ADODB extension installed
58         $ADODB_COMPAT_FETCH, // If $ADODB_COUNTRECS and this is true, $rs->fields is available on EOF
59          $ADODB_FETCH_MODE;    // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default...
60     
61     //==============================================================================================   
62     // GLOBAL SETUP
63     //==============================================================================================   
64     
65     $ADODB_EXTENSION = defined('ADODB_EXTENSION');
66     
67     //********************************************************//
68     /*
69     Controls $ADODB_FORCE_TYPE mode. Default is ADODB_FORCE_VALUE (3).
70     Used in GetUpdateSql and GetInsertSql functions. Thx to Niko, nuko#mbnet.fi
71
72          0 = ignore empty fields. All empty fields in array are ignored.
73         1 = force null. All empty, php null and string 'null' fields are changed to sql NULL values.
74         2 = force empty. All empty, php null and string 'null' fields are changed to sql empty '' or 0 values.
75         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.
76     */
77         define('ADODB_FORCE_IGNORE',0);
78         define('ADODB_FORCE_NULL',1);
79         define('ADODB_FORCE_EMPTY',2);
80         define('ADODB_FORCE_VALUE',3);
81     //********************************************************//
82
83
84     if (!$ADODB_EXTENSION || ADODB_EXTENSION < 4.0) {
85         
86         define('ADODB_BAD_RS','<p>Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;</p>');
87     
88     // allow [ ] @ ` " and . in table names
89         define('ADODB_TABLE_REGEX','([]0-9a-z_\:\"\`\.\@\[-]*)');
90     
91     // prefetching used by oracle
92         if (!defined('ADODB_PREFETCH_ROWS')) define('ADODB_PREFETCH_ROWS',10);
93     
94     
95     /*
96     Controls ADODB_FETCH_ASSOC field-name case. Default is 2, use native case-names.
97     This currently works only with mssql, odbc, oci8po and ibase derived drivers.
98     
99          0 = assoc lowercase field names. $rs->fields['orderid']
100         1 = assoc uppercase field names. $rs->fields['ORDERID']
101         2 = use native-case field names. $rs->fields['OrderID']
102     */
103     
104         define('ADODB_FETCH_DEFAULT',0);
105         define('ADODB_FETCH_NUM',1);
106         define('ADODB_FETCH_ASSOC',2);
107         define('ADODB_FETCH_BOTH',3);
108         
109         if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
110     
111         // PHP's version scheme makes converting to numbers difficult - workaround
112         $_adodb_ver = (float) PHP_VERSION;
113         if ($_adodb_ver >= 5.2) {
114             define('ADODB_PHPVER',0x5200);
115         } else if ($_adodb_ver >= 5.0) {
116             define('ADODB_PHPVER',0x5000);
117         } else if ($_adodb_ver > 4.299999) { # 4.3
118             define('ADODB_PHPVER',0x4300);
119         } else if ($_adodb_ver > 4.199999) { # 4.2
120             define('ADODB_PHPVER',0x4200);
121         } else if (strnatcmp(PHP_VERSION,'4.0.5')>=0) {
122             define('ADODB_PHPVER',0x4050);
123         } else {
124             define('ADODB_PHPVER',0x4000);
125         }
126     }
127     
128     //if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
129
130     
131     /**
132          Accepts $src and $dest arrays, replacing string $data
133     */
134     function ADODB_str_replace($src, $dest, $data)
135     {
136         if (ADODB_PHPVER >= 0x4050) return str_replace($src,$dest,$data);
137         
138         $s = reset($src);
139         $d = reset($dest);
140         while ($s !== false) {
141             $data = str_replace($s,$d,$data);
142             $s = next($src);
143             $d = next($dest);
144         }
145         return $data;
146     }
147     
148     function ADODB_Setup()
149     {
150     GLOBAL
151         $ADODB_vers,         // database version
152         $ADODB_COUNTRECS,    // count number of records returned - slows down query
153         $ADODB_CACHE_DIR,    // directory to cache recordsets
154          $ADODB_FETCH_MODE,
155         $ADODB_FORCE_TYPE;
156         
157         $ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT;
158         $ADODB_FORCE_TYPE = ADODB_FORCE_VALUE;
159
160
161         if (!isset($ADODB_CACHE_DIR)) {
162             $ADODB_CACHE_DIR = '/tmp'; //(isset($_ENV['TMP'])) ? $_ENV['TMP'] : '/tmp';
163         } else {
164             // do not accept url based paths, eg. http:/ or ftp:/
165             if (strpos($ADODB_CACHE_DIR,'://') !== false)
166                 die("Illegal path http:// or ftp://");
167         }
168         
169             
170         // Initialize random number generator for randomizing cache flushes
171         // -- note Since PHP 4.2.0, the seed  becomes optional and defaults to a random value if omitted.
172          srand(((double)microtime())*1000000);
173         
174         /**
175          * ADODB version as a string.
176          */
177         $ADODB_vers = 'V4.93 10 Oct 2006 (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.';
178     
179         /**
180          * Determines whether recordset->RecordCount() is used.
181          * Set to false for highest performance -- RecordCount() will always return -1 then
182          * for databases that provide "virtual" recordcounts...
183          */
184         if (!isset($ADODB_COUNTRECS)) $ADODB_COUNTRECS = true;
185     }
186     
187     
188     //==============================================================================================   
189     // CHANGE NOTHING BELOW UNLESS YOU ARE DESIGNING ADODB
190     //==============================================================================================   
191     
192     ADODB_Setup();
193
194     //==============================================================================================   
195     // CLASS ADOFieldObject
196     //==============================================================================================   
197     /**
198      * Helper class for FetchFields -- holds info on a column
199      */
200     class ADOFieldObject {
201         var $name = '';
202         var $max_length=0;
203         var $type="";
204 /*
205         // additional fields by dannym... (danny_milo@yahoo.com)
206         var $not_null = false;
207         // actually, this has already been built-in in the postgres, fbsql AND mysql module? ^-^
208         // so we can as well make not_null standard (leaving it at "false" does not harm anyways)
209
210         var $has_default = false; // this one I have done only in mysql and postgres for now ...
211             // others to come (dannym)
212         var $default_value; // default, if any, and supported. Check has_default first.
213 */
214     }
215     
216
217     
218     function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection)
219     {
220         //print "Errorno ($fn errno=$errno m=$errmsg) ";
221         $thisConnection->_transOK = false;
222         if ($thisConnection->_oldRaiseFn) {
223             $fn = $thisConnection->_oldRaiseFn;
224             $fn($dbms, $fn, $errno, $errmsg, $p1, $p2,$thisConnection);
225         }
226     }
227     
228     //==============================================================================================   
229     // CLASS ADOConnection
230     //==============================================================================================   
231     
232     /**
233      * Connection object. For connecting to databases, and executing queries.
234      */
235     class ADOConnection {
236     //
237     // PUBLIC VARS
238     //
239     var $dataProvider = 'native';
240     var $databaseType = '';        /// RDBMS currently in use, eg. odbc, mysql, mssql                   
241     var $database = '';            /// Name of database to be used.   
242     var $host = '';             /// The hostname of the database server   
243     var $user = '';             /// The username which is used to connect to the database server.
244     var $password = '';         /// Password for the username. For security, we no longer store it.
245     var $debug = false;         /// if set to true will output sql statements
246     var $maxblobsize = 262144;     /// maximum size of blobs or large text fields (262144 = 256K)-- some db's die otherwise like foxpro
247     var $concat_operator = '+'; /// default concat operator -- change to || for Oracle/Interbase   
248     var $substr = 'substr';        /// substring operator
249     var $length = 'length';        /// string length ofperator
250     var $random = 'rand()';        /// random function
251     var $upperCase = 'upper';        /// uppercase function
252     var $fmtDate = "'Y-m-d'";    /// used by DBDate() as the default date format used by the database
253     var $fmtTimeStamp = "'Y-m-d, h:i:s A'"; /// used by DBTimeStamp as the default timestamp fmt.
254     var $true = '1';             /// string that represents TRUE for a database
255     var $false = '0';             /// string that represents FALSE for a database
256     var $replaceQuote = "\\'";     /// string to use to replace quotes
257     var $nameQuote = '"';        /// string to use to quote identifiers and names
258     var $charSet=false;         /// character set to use - only for interbase, postgres and oci8
259     var $metaDatabasesSQL = '';
260     var $metaTablesSQL = '';
261     var $uniqueOrderBy = false; /// All order by columns have to be unique
262     var $emptyDate = '&nbsp;';
263     var $emptyTimeStamp = '&nbsp;';
264     var $lastInsID = false;
265     //--
266     var $hasInsertID = false;         /// supports autoincrement ID?
267     var $hasAffectedRows = false;     /// supports affected rows for update/delete?
268     var $hasTop = false;            /// support mssql/access SELECT TOP 10 * FROM TABLE
269     var $hasLimit = false;            /// support pgsql/mysql SELECT * FROM TABLE LIMIT 10
270     var $readOnly = false;             /// this is a readonly database - used by phpLens
271     var $hasMoveFirst = false/// has ability to run MoveFirst(), scrolling backwards
272     var $hasGenID = false;         /// can generate sequences using GenID();
273     var $hasTransactions = true; /// has transactions
274     //--
275     var $genID = 0;             /// sequence id used by GenID();
276     var $raiseErrorFn = false;     /// error function to call
277     var $isoDates = false; /// accepts dates in ISO format
278     var $cacheSecs = 3600; /// cache for 1 hour
279
280     // memcache
281     var $memCache = false; /// should we use memCache instead of caching in files
282     var $memCacheHost; /// memCache host
283     var $memCachePort = 11211; /// memCache port
284     var $memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib)
285
286     var $sysDate = false; /// name of function that returns the current date
287     var $sysTimeStamp = false; /// name of function that returns the current timestamp
288     var $arrayClass = 'ADORecordSet_array'; /// name of class used to generate array recordsets, which are pre-downloaded recordsets
289     
290     var $noNullStrings = false; /// oracle specific stuff - if true ensures that '' is converted to ' '
291     var $numCacheHits = 0;
292     var $numCacheMisses = 0;
293     var $pageExecuteCountRows = true;
294     var $uniqueSort = false; /// indicates that all fields in order by must be unique
295     var $leftOuter = false; /// operator to use for left outer join in WHERE clause
296     var $rightOuter = false; /// operator to use for right outer join in WHERE clause
297     var $ansiOuter = false; /// whether ansi outer join syntax supported
298     var $autoRollback = false; // autoRollback on PConnect().
299     var $poorAffectedRows = false; // affectedRows not working or unreliable
300     
301     var $fnExecute = false;
302     var $fnCacheExecute = false;
303     var $blobEncodeType = false; // false=not required, 'I'=encode to integer, 'C'=encode to char
304     var $rsPrefix = "ADORecordSet_";
305     
306     var $autoCommit = true;     /// do not modify this yourself - actually private
307     var $transOff = 0;             /// temporarily disable transactions
308     var $transCnt = 0;             /// count of nested transactions
309     
310     var $fetchMode=false;
311     
312     var $null2null = 'null'; // in autoexecute/getinsertsql/getupdatesql, this value will be converted to a null
313      //
314      // PRIVATE VARS
315      //
316     var $_oldRaiseFn false;
317     var $_transOK = null;
318     var $_connectionID    = false;    /// The returned link identifier whenever a successful database connection is made.   
319     var $_errorMsg = false;        /// A variable which was used to keep the returned last error message.  The value will
320                                 /// then returned by the errorMsg() function   
321     var $_errorCode = false;    /// Last error code, not guaranteed to be used - only by oci8                   
322     var $_queryID = false;        /// This variable keeps the last created result link identifier
323     
324     var $_isPersistentConnection = false;    /// A boolean variable to state whether its a persistent connection or normal connection.    */
325     var $_bindInputArray = false; /// set to true if ADOConnection.Execute() permits binding of array parameters.
326     var $_evalAll = false;
327     var $_affected = false;
328     var $_logsql = false;
329     var $_transmode = ''; // transaction mode
330     
331
332     
333     /**
334      * Constructor
335      */
336     function ADOConnection()           
337     {
338         die('Virtual Class -- cannot instantiate');
339     }
340     
341     function Version()
342     {
343     global $ADODB_vers;
344     
345         return (float) substr($ADODB_vers,1);
346     }
347     
348     /**
349         Get server version info...
350         
351         @returns An array with 2 elements: $arr['string'] is the description string,
352             and $arr[version] is the version (also a string).
353     */
354     function ServerInfo()
355     {
356         return array('description' => '', 'version' => '');
357     }
358     
359     function IsConnected()
360     {
361         return !empty($this->_connectionID);
362     }
363     
364     function _findvers($str)
365     {
366         if (preg_match('/([0-9]+\.([0-9\.])+)/',$str, $arr)) return $arr[1];
367         else return '';
368     }
369     
370     /**
371     * All error messages go through this bottleneck function.
372     * You can define your own handler by defining the function name in ADODB_OUTP.
373     */
374     function outp($msg,$newline=true)
375     {
376     global $ADODB_FLUSH,$ADODB_OUTP;
377     
378         if (defined('ADODB_OUTP')) {
379             $fn = ADODB_OUTP;
380             $fn($msg,$newline);
381             return;
382         } else if (isset($ADODB_OUTP)) {
383             $fn = $ADODB_OUTP;
384             $fn($msg,$newline);
385             return;
386         }
387         
388         if ($newline) $msg .= "<br>\n";
389         
390         if (isset($_SERVER['HTTP_USER_AGENT']) || !$newline) echo $msg;
391         else echo strip_tags($msg);
392     
393         
394         if (!empty($ADODB_FLUSH) && ob_get_length() !== false) flush(); //  do not flush if output buffering enabled - useless - thx to Jesse Mullan
395         
396     }
397     
398     function Time()
399     {
400         $rs =& $this->_Execute("select $this->sysTimeStamp");
401         if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
402         
403         return false;
404     }
405     
406     /**
407      * Connect to database
408      *
409      * @param [argHostname]        Host to connect to
410      * @param [argUsername]        Userid to login
411      * @param [argPassword]        Associated password
412      * @param [argDatabaseName]    database
413      * @param [forceNew]        force new connection
414      *
415      * @return true or false
416      */     
417     function Connect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "", $forceNew = false)
418     {
419         if ($argHostname != "") $this->host = $argHostname;
420         if ($argUsername != "") $this->user = $argUsername;
421         if ($argPassword != "") $this->password = $argPassword; // not stored for security reasons
422         if ($argDatabaseName != "") $this->database = $argDatabaseName;       
423         
424         $this->_isPersistentConnection = false;   
425         if ($forceNew) {
426             if ($rez=$this->_nconnect($this->host, $this->user, $this->password, $this->database)) return true;
427         } else {
428              if ($rez=$this->_connect($this->host, $this->user, $this->password, $this->database)) return true;
429         }
430         if (isset($rez)) {
431             $err = $this->ErrorMsg();
432             if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'";
433             $ret = false;
434         } else {
435             $err = "Missing extension for ".$this->dataProvider;
436             $ret = 0;
437         }
438         if ($fn = $this->raiseErrorFn)
439             $fn($this->databaseType,'CONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this);
440         
441         
442         $this->_connectionID = false;
443         if ($this->debug) ADOConnection::outp( $this->host.': '.$err);
444         return $ret;
445     }   
446     
447     function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName)
448     {
449         return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName);
450     }
451     
452     
453     /**
454      * Always force a new connection to database - currently only works with oracle
455      *
456      * @param [argHostname]        Host to connect to
457      * @param [argUsername]        Userid to login
458      * @param [argPassword]        Associated password
459      * @param [argDatabaseName]    database
460      *
461      * @return true or false
462      */     
463     function NConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "")
464     {
465         return $this->Connect($argHostname, $argUsername, $argPassword, $argDatabaseName, true);
466     }
467     
468     /**
469      * Establish persistent connect to database
470      *
471      * @param [argHostname]        Host to connect to
472      * @param [argUsername]        Userid to login
473      * @param [argPassword]        Associated password
474      * @param [argDatabaseName]    database
475      *
476      * @return return true or false
477      */   
478     function PConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "")
479     {
480         if (defined('ADODB_NEVER_PERSIST'))
481             return $this->Connect($argHostname,$argUsername,$argPassword,$argDatabaseName);
482         
483         if ($argHostname != "") $this->host = $argHostname;
484         if ($argUsername != "") $this->user = $argUsername;
485         if ($argPassword != "") $this->password = $argPassword;
486         if ($argDatabaseName != "") $this->database = $argDatabaseName;       
487             
488         $this->_isPersistentConnection = true;   
489         if ($rez = $this->_pconnect($this->host, $this->user, $this->password, $this->database)) return true;
490         if (isset($rez)) {
491             $err = $this->ErrorMsg();
492             if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'";
493             $ret = false;
494         } else {
495             $err = "Missing extension for ".$this->dataProvider;
496             $ret = 0;
497         }
498         if ($fn = $this->raiseErrorFn) {
499             $fn($this->databaseType,'PCONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this);
500         }
501         
502         $this->_connectionID = false;
503         if (