]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/pear/DB/ifx.php
new PEAR DB 1.3 backends plus the experimental PEAR DB_Pager
[SourceForge/phpwiki.git] / lib / pear / DB / ifx.php
1 <?php
2 //
3 // +----------------------------------------------------------------------+
4 // | PHP Version 4                                                        |
5 // +----------------------------------------------------------------------+
6 // | Copyright (c) 1997-2002 The PHP Group                                |
7 // +----------------------------------------------------------------------+
8 // | This source file is subject to version 2.02 of the PHP license,      |
9 // | that is bundled with this package in the file LICENSE, and is        |
10 // | available at through the world-wide-web at                           |
11 // | http://www.php.net/license/2_02.txt.                                 |
12 // | If you did not receive a copy of the PHP license and are unable to   |
13 // | obtain it through the world-wide-web, please send a note to          |
14 // | license@php.net so we can mail you a copy immediately.               |
15 // +----------------------------------------------------------------------+
16 // | Author: Tomas V.V.Cox <cox@idecnet.com>                              |
17 // +----------------------------------------------------------------------+
18 //
19 // $Id: ifx.php,v 1.1 2002-09-12 11:47:07 rurban Exp $
20 //
21 // Database independent query interface definition for PHP's Informix
22 // extension.
23 //
24
25 // Legend:
26 // For more info on Informix errors see:
27 // http://www.informix.com/answers/english/ierrors.htm
28 //
29 // TODO:
30 //  - set needed env Informix vars on connect
31 //  - implement native prepare/execute
32
33 // Based on DB 1.3 from the pear.php.net repository. 
34 // The only modifications made have been modification of the include paths. 
35 //
36 rcs_id('$Id: ifx.php,v 1.1 2002-09-12 11:47:07 rurban Exp $');
37 rcs_id('From Pear CVS: Id: ifx.php,v 1.4 2002/05/26 14:41:27 cox Exp');
38
39 require_once 'lib/pear/DB/common.php';
40
41 class DB_ifx extends DB_common
42 {
43     var $connection;
44     var $affected = 0;
45     var $dsn = array();
46     var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */
47
48     function DB_ifx()
49     {
50         $this->phptype = 'ifx';
51         $this->dbsyntax = 'ifx';
52         $this->features = array(
53             'prepare' => false,
54             'pconnect' => true,
55             'transactions' => false,
56             'limit' => 'emulate'
57         );
58         $this->errorcode_map = array(
59             '-201'    => DB_ERROR_SYNTAX,
60             '-206'    => DB_ERROR_NOSUCHTABLE,
61             '-217'    => DB_ERROR_NOSUCHFIELD,
62             '-329'    => DB_ERROR_NODBSELECTED,
63             '-1204'   => DB_ERROR_INVALID_DATE,
64             '-1205'   => DB_ERROR_INVALID_DATE,
65             '-1206'   => DB_ERROR_INVALID_DATE,
66             '-1209'   => DB_ERROR_INVALID_DATE,
67             '-1210'   => DB_ERROR_INVALID_DATE,
68             '-1212'   => DB_ERROR_INVALID_DATE
69        );
70     }
71
72     /**
73      * Connect to a database and log in as the specified user.
74      *
75      * @param $dsn the data source name (see DB::parseDSN for syntax)
76      * @param $persistent (optional) whether the connection should
77      *        be persistent
78      *
79      * @return int DB_OK on success, a DB error code on failure
80      */
81     function connect(&$dsninfo, $persistent = false)
82     {
83         if (!DB::assertExtension('informix') || !DB::assertExtension('Informix')) {
84             return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
85         }
86         $this->dsn = $dsninfo;
87         $dbhost = $dsninfo['hostspec'] ? '@' . $dsninfo['hostspec'] : '';
88         $dbname = $dsninfo['database'] ? $dsninfo['database'] . $dbhost : '';
89         $user = $dsninfo['username'] ? $dsninfo['username'] : '';
90         $pw = $dsninfo['password'] ? $dsninfo['password'] : '';
91
92         $connect_function = $persistent ? 'ifx_pconnect' : 'ifx_connect';
93
94         $this->connection = @$connect_function($dbname, $user, $pw);
95         if (!is_resource($this->connection)) {
96             return $this->ifxraiseError(DB_ERROR_CONNECT_FAILED);
97         }
98         return DB_OK;
99     }
100
101     /**
102      * Log out and disconnect from the database.
103      *
104      * @return bool TRUE on success, FALSE if not connected.
105      */
106     function disconnect()
107     {
108         $ret = @ifx_close($this->connection);
109         $this->connection = null;
110         return $ret;
111     }
112
113     /**
114      * Send a query to Informix and return the results as a
115      * Informix resource identifier.
116      *
117      * @param $query the SQL query
118      *
119      * @return int returns a valid Informix result for successful SELECT
120      * queries, DB_OK for other successful queries.  A DB error code
121      * is returned on failure.
122      */
123     function simpleQuery($query)
124     {
125         $this->last_query = $query;
126         if (preg_match('/(SELECT)/i', $query)) {    //TESTME: Use !DB::isManip()?
127             // the scroll is needed for fetching absolute row numbers
128             // in a select query result
129             $result = @ifx_query($query, $this->connection, IFX_SCROLL);
130         } else {
131             $result = @ifx_query($query, $this->connection);
132         }
133         if (!$result) {
134             return $this->ifxraiseError();
135         }
136         $this->affected = ifx_affected_rows ($result);
137         // Determine which queries that should return data, and which
138         // should return an error code only.
139         if (preg_match('/(SELECT)/i', $query)) {
140             return $result;
141         }
142         return DB_OK;
143     }
144
145     // {{{ nextResult()
146
147     /**
148      * Move the internal ifx result pointer to the next available result
149      *
150      * @param a valid fbsql result resource
151      *
152      * @access public
153      *
154      * @return true if a result is available otherwise return false
155      */
156     function nextResult($result)
157     {
158         return false;
159     }
160
161     // }}}
162
163     /**
164      * Gets the number of rows affected by the last query.
165      * if the last query was a select, returns an _estimate_ value.
166      *
167      * @return number of rows affected by the last query
168      */
169     function affectedRows()
170     {
171         return $this->affected;
172     }
173
174     /**
175      * Fetch and return a row of data (it uses fetchInto for that)
176      * @param   $result             Informix result identifier
177      * @param   $fetchmode     format of fetched row array
178      * @param   $rownum        the absolute row number to fetch
179      *
180      * @return  array   a row of data, or false on error
181      */
182     function fetchRow($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
183     {
184         if ($fetchmode == DB_FETCHMODE_DEFAULT) {
185             $fetchmode = $this->fetchmode;
186         }
187         $res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
188         if ($res !== DB_OK) {
189             return $res;
190         }
191         return $arr;
192     }
193
194     /**
195      * Fetch a row and return as array.
196      *
197      * @param   $result     Informix result identifier
198      * @param   $row         (reference) array where data from the row is stored
199      * @param   $fetchmode      how the resulting array should be indexed
200      * @param   $rownum     the row number to fetch
201      *
202      * @return int an array on success, a DB error code on failure, NULL
203      *             if there is no more data
204      */
205     function fetchInto($result, &$row, $fetchmode, $rownum=null)
206     {
207         if (($rownum !== null) && ($rownum < 0)) {
208             return null;
209         }
210         // if $rownum is null, fetch row will return the next row
211         if (!$row = @ifx_fetch_row($result, $rownum)) {
212             return null;
213         }
214         if ($fetchmode !== DB_FETCHMODE_ASSOC) {
215             $i=0;
216             $order = array();
217             foreach ($row as $key => $val) {
218                 $order[$i++] = $val;
219             }
220             $row = $order;
221         }
222         return DB_OK;
223     }
224
225     function numRows($result)
226     {
227         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
228     }
229
230     /**
231      * Get the number of columns in a result set.
232      *
233      * @param $result Informix result identifier
234      *
235      * @return int the number of columns per row in $result
236      */
237     function numCols($result)
238     {
239         if (!$cols = @ifx_num_fields($result)) {
240             return $this->ifxraiseError();
241         }
242         return $cols;
243     }
244
245     /**
246      * Free the internal resources associated with $result.
247      *
248      * @param $result Informix result identifier
249      *
250      * @return bool TRUE on success, DB_error on error
251      */
252     function freeResult($result)
253     {
254         if (is_resource($result)) {
255             if (!@ifx_free_result($result)) {
256                 return $this->ifxraiseError();
257             }
258             return true;
259         }
260         if (!isset($this->prepare_tokens[(int)$result])) {
261             return false;
262         }
263         unset($this->prepare_tokens[(int)$result]);
264         unset($this->prepare_types[(int)$result]);
265         return true;
266     }
267
268     function ifxraiseError($errno = null)
269     {
270         if ($errno === null) {
271             $errno = $this->errorCode(ifx_error());
272         }
273
274         return $this->raiseError($errno, null, null, null,
275                             $this->errorNative());
276     }
277
278     /**
279      * Map native error codes to DB's portable ones.  Requires that
280      * the DB implementation's constructor fills in the $errorcode_map
281      * property.
282      *
283      * @return int a portable DB error code, or DB_ERROR if this DB
284      * implementation has no mapping for the given error code.
285      */
286
287     function errorCode($nativecode)
288     {
289         if (ereg('SQLCODE=(.*)]', $nativecode, $match)) {
290             $code = $match[1];
291             if (isset($this->errorcode_map[$code])) {
292                 return $this->errorcode_map[$code];
293             }
294         }
295         return DB_ERROR;
296     }
297
298     /**
299      * Get the native error message of the last error (if any) that
300      * occured on the current connection.
301      *
302      * @return int native Informix error code
303      */
304     function errorNative()
305     {
306         return ifx_error() . ' ' . ifx_errormsg();
307     }
308
309     // {{{ getSpecialQuery()
310
311     /**
312     * Returns the query needed to get some backend info
313     * @param string $type What kind of info you want to retrieve
314     * @return string The SQL query string
315     */
316     function getSpecialQuery($type)
317     {
318         switch ($type) {
319             case 'tables':
320             default:
321                 return null;
322         }
323         return $sql;
324     }
325
326     // }}}
327 }
328
329 ?>