]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/adodb/adodb-pear.inc.php
Reformat code
[SourceForge/phpwiki.git] / lib / WikiDB / adodb / adodb-pear.inc.php
1 <?php
2 /**
3  * @version V4.22 15 Apr 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
4  * Released under both BSD license and Lesser GPL library license.
5  * Whenever there is any discrepancy between the two licenses,
6  * the BSD license will take precedence.
7  *
8  * Set tabs to 4 for best viewing.
9  *
10  * PEAR DB Emulation Layer for ADODB.
11  *
12  * The following code is modelled on PEAR DB code by Stig Bakken <ssb@fast.no>                                   |
13  * and Tomas V.V.Cox <cox@idecnet.com>.    Portions (c)1997-2002 The PHP Group.
14  */
15
16 /*
17 We support:
18
19 DB_Common
20 ---------
21     query - returns PEAR_Error on error
22    limitQuery - return PEAR_Error on error
23    prepare - does not return PEAR_Error on error
24    execute - does not return PEAR_Error on error
25    setFetchMode - supports ASSOC and ORDERED
26    errorNative
27    quote
28    nextID
29    disconnect
30
31 DB_Result
32 ---------
33     numRows - returns -1 if not supported
34    numCols
35    fetchInto - does not support passing of fetchmode
36    fetchRows - does not support passing of fetchmode
37    free
38 */
39
40 define('ADODB_PEAR', dirname(__FILE__));
41 include_once 'PEAR.php';
42 include_once ADODB_PEAR . "/adodb-errorpear.inc.php";
43 include_once ADODB_PEAR . "/adodb.inc.php";
44
45 if (!defined('DB_OK')) {
46     define("DB_OK", 1);
47     define("DB_ERROR", -1);
48     /**
49      * This is a special constant that tells DB the user hasn't specified
50      * any particular get mode, so the default should be used.
51      */
52
53     define('DB_FETCHMODE_DEFAULT', 0);
54
55     /**
56      * Column data indexed by numbers, ordered from 0 and up
57      */
58
59     define('DB_FETCHMODE_ORDERED', 1);
60
61     /**
62      * Column data indexed by column names
63      */
64
65     define('DB_FETCHMODE_ASSOC', 2);
66
67     /* for compatibility */
68
69     define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
70     define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC);
71
72     /**
73      * these are constants for the tableInfo-function
74      * they are bitwised or'ed. so if there are more constants to be defined
75      * in the future, adjust DB_TABLEINFO_FULL accordingly
76      */
77
78     define('DB_TABLEINFO_ORDER', 1);
79     define('DB_TABLEINFO_ORDERTABLE', 2);
80     define('DB_TABLEINFO_FULL', 3);
81 }
82
83 /**
84  * The main "DB" class is simply a container class with some static
85  * methods for creating DB objects as well as some utility functions
86  * common to all parts of DB.
87  *
88  */
89
90 class DB
91 {
92     /**
93      * Create a new DB object for the specified database type
94      *
95      * @param $type string database type, for example "mysql"
96      *
97      * @return object a newly created DB object, or a DB error code on
98      * error
99      */
100
101     function &factory($type)
102     {
103         include_once(ADODB_DIR . "/drivers/adodb-$type.inc.php");
104         $obj = &NewADOConnection($type);
105         if (!is_object($obj)) $obj =& new PEAR_Error('Unknown Database Driver: ' . $dsninfo['phptype'], -1);
106         return $obj;
107     }
108
109     /**
110      * Create a new DB object and connect to the specified database
111      *
112      * @param $dsn mixed "data source name", see the DB::parseDSN
113      * method for a description of the dsn format.  Can also be
114      * specified as an array of the format returned by DB::parseDSN.
115      *
116      * @param $options mixed if boolean (or scalar), tells whether
117      * this connection should be persistent (for backends that support
118      * this).  This parameter can also be an array of options, see
119      * DB_common::setOption for more information on connection
120      * options.
121      *
122      * @return object a newly created DB connection object, or a DB
123      * error object on error
124      *
125      * @see DB::parseDSN
126      * @see DB::isError
127      */
128     function &connect($dsn, $options = false)
129     {
130         if (is_array($dsn)) {
131             $dsninfo = $dsn;
132         } else {
133             $dsninfo = DB::parseDSN($dsn);
134         }
135         switch ($dsninfo["phptype"]) {
136             case 'pgsql':
137                 $type = 'postgres7';
138                 break;
139             case 'ifx':
140                 $type = 'informix9';
141                 break;
142             default:
143                 $type = $dsninfo["phptype"];
144                 break;
145         }
146
147         if (is_array($options) && isset($options["debug"]) &&
148             $options["debug"] >= 2
149         ) {
150             // expose php errors with sufficient debug level
151             @include_once("adodb-$type.inc.php");
152         } else {
153             @include_once("adodb-$type.inc.php");
154         }
155
156         @$obj =& NewADOConnection($type);
157         if (!is_object($obj)) {
158             $obj =& new PEAR_Error('Unknown Database Driver: ' . $dsninfo['phptype'], -1);
159             return $obj;
160         }
161         if (is_array($options)) {
162             foreach ($options as $k => $v) {
163                 switch (strtolower($k)) {
164                     case 'persistent':
165                         $persist = $v;
166                         break;
167                     #ibase
168                     case 'dialect':
169                         $obj->dialect = $v;
170                         break;
171                     case 'charset':
172                         $obj->charset = $v;
173                         break;
174                     case 'buffers':
175                         $obj->buffers = $v;
176                         break;
177                     #ado
178                     case 'charpage':
179                         $obj->charPage = $v;
180                         break;
181                     #mysql
182                     case 'clientflags':
183                         $obj->clientFlags = $v;
184                         break;
185                 }
186             }
187         } else {
188             $persist = false;
189         }
190
191         if (isset($dsninfo['socket'])) $dsninfo['hostspec'] .= ':' . $dsninfo['socket'];
192         else if (isset($dsninfo['port'])) $dsninfo['hostspec'] .= ':' . $dsninfo['port'];
193
194         if ($persist) $ok = $obj->PConnect($dsninfo['hostspec'], $dsninfo['username'], $dsninfo['password'], $dsninfo['database']);
195         else  $ok = $obj->Connect($dsninfo['hostspec'], $dsninfo['username'], $dsninfo['password'], $dsninfo['database']);
196
197         if (!$ok) $obj = ADODB_PEAR_Error();
198         return $obj;
199     }
200
201     /**
202      * Return the DB API version
203      *
204      * @return int the DB API version number
205      */
206     function apiVersion()
207     {
208         return 2;
209     }
210
211     /**
212      * Tell whether a result code from a DB method is an error
213      *
214      * @param $value int result code
215      *
216      * @return bool whether $value is an error
217      */
218     function isError($value)
219     {
220         return (is_object($value) &&
221             (strtolower(get_class($value)) == 'db_error' ||
222                 is_subclass_of($value, 'db_error')));
223     }
224
225     /**
226      * Tell whether a result code from a DB method is a warning.
227      * Warnings differ from errors in that they are generated by DB,
228      * and are not fatal.
229      *
230      * @param $value mixed result value
231      *
232      * @return bool whether $value is a warning
233      */
234     function isWarning($value)
235     {
236         return is_object($value) &&
237             (strtolower(get_class($value)) == "db_warning" ||
238                 is_subclass_of($value, "db_warning"));
239     }
240
241     /**
242      * Parse a data source name
243      *
244      * @param $dsn string Data Source Name to be parsed
245      *
246      * @return array an associative array with the following keys:
247      *
248      *  phptype: Database backend used in PHP (mysql, odbc etc.)
249      *  dbsyntax: Database used with regards to SQL syntax etc.
250      *  protocol: Communication protocol to use (tcp, unix etc.)
251      *  hostspec: Host specification (hostname[:port])
252      *  database: Database to use on the DBMS server
253      *  username: User name for login
254      *  password: Password for login
255      *
256      * The format of the supplied DSN is in its fullest form:
257      *
258      *  phptype(dbsyntax)://username:password@protocol+hostspec/database
259      *
260      * Most variations are allowed:
261      *
262      *  phptype://username:password@protocol+hostspec:110//usr/db_file.db
263      *  phptype://username:password@hostspec/database_name
264      *  phptype://username:password@hostspec
265      *  phptype://username@hostspec
266      *  phptype://hostspec/database
267      *  phptype://hostspec
268      *  phptype(dbsyntax)
269      *  phptype
270      *
271      * @author Tomas V.V.Cox <cox@idecnet.com>
272      */
273     function parseDSN($dsn)
274     {
275         if (is_array($dsn)) {
276             return $dsn;
277         }
278
279         $parsed = array(
280             'phptype' => false,
281             'dbsyntax' => false,
282             'protocol' => false,
283             'hostspec' => false,
284             'database' => false,
285             'username' => false,
286             'password' => false
287         );
288
289         // Find phptype and dbsyntax
290         if (($pos = strpos($dsn, '://')) !== false) {
291             $str = substr($dsn, 0, $pos);
292             $dsn = substr($dsn, $pos + 3);
293         } else {
294             $str = $dsn;
295             $dsn = NULL;
296         }
297
298         // Get phptype and dbsyntax
299         // $str => phptype(dbsyntax)
300         if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
301             $parsed['phptype'] = $arr[1];
302             $parsed['dbsyntax'] = (empty($arr[2])) ? $arr[1] : $arr[2];
303         } else {
304             $parsed['phptype'] = $str;
305             $parsed['dbsyntax'] = $str;
306         }
307
308         if (empty($dsn)) {
309             return $parsed;
310         }
311
312         // Get (if found): username and password
313         // $dsn => username:password@protocol+hostspec/database
314         if (($at = strpos($dsn, '@')) !== false) {
315             $str = substr($dsn, 0, $at);
316             $dsn = substr($dsn, $at + 1);
317             if (($pos = strpos($str, ':')) !== false) {
318                 $parsed['username'] = urldecode(substr($str, 0, $pos));
319                 $parsed['password'] = urldecode(substr($str, $pos + 1));
320             } else {
321                 $parsed['username'] = urldecode($str);
322             }
323         }
324
325         // Find protocol and hostspec
326         // $dsn => protocol+hostspec/database
327         if (($pos = strpos($dsn, '/')) !== false) {
328             $str = substr($dsn, 0, $pos);
329             $dsn = substr($dsn, $pos + 1);
330         } else {
331             $str = $dsn;
332             $dsn = NULL;
333         }
334
335         // Get protocol + hostspec
336         // $str => protocol+hostspec
337         if (($pos = strpos($str, '+')) !== false) {
338             $parsed['protocol'] = substr($str, 0, $pos);
339             $parsed['hostspec'] = urldecode(substr($str, $pos + 1));
340         } else {
341             $parsed['hostspec'] = urldecode($str);
342         }
343
344         // Get dabase if any
345         // $dsn => database
346         if (!empty($dsn)) {
347             $parsed['database'] = $dsn;
348         }
349
350         return $parsed;
351     }
352
353     /**
354      * Load a PHP database extension if it is not loaded already.
355      *
356      * @access public
357      *
358      * @param $name the base name of the extension (without the .so or
359      * .dll suffix)
360      *
361      * @return bool true if the extension was already or successfully
362      * loaded, false if it could not be loaded
363      */
364     function assertExtension($name)
365     {
366         if (!extension_loaded($name)) {
367             $dlext = (strncmp(PHP_OS, 'WIN', 3) === 0) ? '.dll' : '.so';
368             @dl($name . $dlext);
369         }
370         if (!extension_loaded($name)) {
371             return false;
372         }
373         return true;
374     }
375 }