3 // +----------------------------------------------------------------------+
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 // +----------------------------------------------------------------------+
19 // $Id: ifx.php,v 1.1 2002-09-12 11:47:07 rurban Exp $
21 // Database independent query interface definition for PHP's Informix
26 // For more info on Informix errors see:
27 // http://www.informix.com/answers/english/ierrors.htm
30 // - set needed env Informix vars on connect
31 // - implement native prepare/execute
33 // Based on DB 1.3 from the pear.php.net repository.
34 // The only modifications made have been modification of the include paths.
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');
39 require_once 'lib/pear/DB/common.php';
41 class DB_ifx extends DB_common
46 var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */
50 $this->phptype = 'ifx';
51 $this->dbsyntax = 'ifx';
52 $this->features = array(
55 'transactions' => false,
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
73 * Connect to a database and log in as the specified user.
75 * @param $dsn the data source name (see DB::parseDSN for syntax)
76 * @param $persistent (optional) whether the connection should
79 * @return int DB_OK on success, a DB error code on failure
81 function connect(&$dsninfo, $persistent = false)
83 if (!DB::assertExtension('informix') || !DB::assertExtension('Informix')) {
84 return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
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'] : '';
92 $connect_function = $persistent ? 'ifx_pconnect' : 'ifx_connect';
94 $this->connection = @$connect_function($dbname, $user, $pw);
95 if (!is_resource($this->connection)) {
96 return $this->ifxraiseError(DB_ERROR_CONNECT_FAILED);
102 * Log out and disconnect from the database.
104 * @return bool TRUE on success, FALSE if not connected.
106 function disconnect()
108 $ret = @ifx_close($this->connection);
109 $this->connection = null;
114 * Send a query to Informix and return the results as a
115 * Informix resource identifier.
117 * @param $query the SQL query
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.
123 function simpleQuery($query)
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);
131 $result = @ifx_query($query, $this->connection);
134 return $this->ifxraiseError();
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)) {
148 * Move the internal ifx result pointer to the next available result
150 * @param a valid fbsql result resource
154 * @return true if a result is available otherwise return false
156 function nextResult($result)
164 * Gets the number of rows affected by the last query.
165 * if the last query was a select, returns an _estimate_ value.
167 * @return number of rows affected by the last query
169 function affectedRows()
171 return $this->affected;
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
180 * @return array a row of data, or false on error
182 function fetchRow($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
184 if ($fetchmode == DB_FETCHMODE_DEFAULT) {
185 $fetchmode = $this->fetchmode;
187 $res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
188 if ($res !== DB_OK) {
195 * Fetch a row and return as array.
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
202 * @return int an array on success, a DB error code on failure, NULL
203 * if there is no more data
205 function fetchInto($result, &$row, $fetchmode, $rownum=null)
207 if (($rownum !== null) && ($rownum < 0)) {
210 // if $rownum is null, fetch row will return the next row
211 if (!$row = @ifx_fetch_row($result, $rownum)) {
214 if ($fetchmode !== DB_FETCHMODE_ASSOC) {
217 foreach ($row as $key => $val) {
225 function numRows($result)
227 return $this->raiseError(DB_ERROR_NOT_CAPABLE);
231 * Get the number of columns in a result set.
233 * @param $result Informix result identifier
235 * @return int the number of columns per row in $result
237 function numCols($result)
239 if (!$cols = @ifx_num_fields($result)) {
240 return $this->ifxraiseError();
246 * Free the internal resources associated with $result.
248 * @param $result Informix result identifier
250 * @return bool TRUE on success, DB_error on error
252 function freeResult($result)
254 if (is_resource($result)) {
255 if (!@ifx_free_result($result)) {
256 return $this->ifxraiseError();
260 if (!isset($this->prepare_tokens[(int)$result])) {
263 unset($this->prepare_tokens[(int)$result]);
264 unset($this->prepare_types[(int)$result]);
268 function ifxraiseError($errno = null)
270 if ($errno === null) {
271 $errno = $this->errorCode(ifx_error());
274 return $this->raiseError($errno, null, null, null,
275 $this->errorNative());
279 * Map native error codes to DB's portable ones. Requires that
280 * the DB implementation's constructor fills in the $errorcode_map
283 * @return int a portable DB error code, or DB_ERROR if this DB
284 * implementation has no mapping for the given error code.
287 function errorCode($nativecode)
289 if (ereg('SQLCODE=(.*)]', $nativecode, $match)) {
291 if (isset($this->errorcode_map[$code])) {
292 return $this->errorcode_map[$code];
299 * Get the native error message of the last error (if any) that
300 * occured on the current connection.
302 * @return int native Informix error code
304 function errorNative()
306 return ifx_error() . ' ' . ifx_errormsg();
309 // {{{ getSpecialQuery()
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
316 function getSpecialQuery($type)