Subversion Repositories Applications.papyrus

Rev

Rev 320 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 320 Rev 443
1
<?php
1
<?php
2
 
2
 
3
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
 
4
 
5
/**
5
/**
6
 * The PEAR DB driver for PHP's oci8 extension
6
 * The PEAR DB driver for PHP's oci8 extension
7
 * for interacting with Oracle databases
7
 * for interacting with Oracle databases
8
 *
8
 *
9
 * PHP versions 4 and 5
9
 * PHP versions 4 and 5
10
 *
10
 *
11
 * LICENSE: This source file is subject to version 3.0 of the PHP license
11
 * LICENSE: This source file is subject to version 3.0 of the PHP license
12
 * that is available through the world-wide-web at the following URI:
12
 * that is available through the world-wide-web at the following URI:
13
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
13
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
14
 * the PHP License and are unable to obtain it through the web, please
14
 * the PHP License and are unable to obtain it through the web, please
15
 * send a note to license@php.net so we can mail you a copy immediately.
15
 * send a note to license@php.net so we can mail you a copy immediately.
16
 *
16
 *
17
 * @category   Database
17
 * @category   Database
18
 * @package    DB
18
 * @package    DB
19
 * @author     James L. Pine <jlp@valinux.com>
19
 * @author     James L. Pine <jlp@valinux.com>
20
 * @author     Daniel Convissor <danielc@php.net>
20
 * @author     Daniel Convissor <danielc@php.net>
21
 * @copyright  1997-2005 The PHP Group
21
 * @copyright  1997-2005 The PHP Group
22
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
22
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
23
 * @version    CVS: $Id: oci8.php,v 1.1 2005-03-30 08:50:33 jpm Exp $
23
 * @version    CVS: $Id: oci8.php,v 1.2 2005-09-20 17:01:22 ddelon Exp $
24
 * @link       http://pear.php.net/package/DB
24
 * @link       http://pear.php.net/package/DB
25
 */
25
 */
26
 
26
 
27
/**
27
/**
28
 * Obtain the DB_common class so it can be extended from
28
 * Obtain the DB_common class so it can be extended from
29
 */
29
 */
30
require_once 'DB/common.php';
30
require_once 'DB/common.php';
31
 
31
 
32
/**
32
/**
33
 * The methods PEAR DB uses to interact with PHP's oci8 extension
33
 * The methods PEAR DB uses to interact with PHP's oci8 extension
34
 * for interacting with Oracle databases
34
 * for interacting with Oracle databases
35
 *
35
 *
36
 * Definitely works with versions 8 and 9 of Oracle.
36
 * Definitely works with versions 8 and 9 of Oracle.
37
 *
37
 *
38
 * These methods overload the ones declared in DB_common.
38
 * These methods overload the ones declared in DB_common.
39
 *
39
 *
40
 * Be aware...  OCIError() only appears to return anything when given a
40
 * Be aware...  OCIError() only appears to return anything when given a
41
 * statement, so functions return the generic DB_ERROR instead of more
41
 * statement, so functions return the generic DB_ERROR instead of more
42
 * useful errors that have to do with feedback from the database.
42
 * useful errors that have to do with feedback from the database.
43
 *
43
 *
44
 * @category   Database
44
 * @category   Database
45
 * @package    DB
45
 * @package    DB
46
 * @author     James L. Pine <jlp@valinux.com>
46
 * @author     James L. Pine <jlp@valinux.com>
47
 * @author     Daniel Convissor <danielc@php.net>
47
 * @author     Daniel Convissor <danielc@php.net>
48
 * @copyright  1997-2005 The PHP Group
48
 * @copyright  1997-2005 The PHP Group
49
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
49
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
50
 * @version    Release: 1.7.5
50
 * @version    Release: @package_version@
51
 * @link       http://pear.php.net/package/DB
51
 * @link       http://pear.php.net/package/DB
52
 */
52
 */
53
class DB_oci8 extends DB_common
53
class DB_oci8 extends DB_common
54
{
54
{
55
    // {{{ properties
55
    // {{{ properties
56
 
56
 
57
    /**
57
    /**
58
     * The DB driver type (mysql, oci8, odbc, etc.)
58
     * The DB driver type (mysql, oci8, odbc, etc.)
59
     * @var string
59
     * @var string
60
     */
60
     */
61
    var $phptype = 'oci8';
61
    var $phptype = 'oci8';
62
 
62
 
63
    /**
63
    /**
64
     * The database syntax variant to be used (db2, access, etc.), if any
64
     * The database syntax variant to be used (db2, access, etc.), if any
65
     * @var string
65
     * @var string
66
     */
66
     */
67
    var $dbsyntax = 'oci8';
67
    var $dbsyntax = 'oci8';
68
 
68
 
69
    /**
69
    /**
70
     * The capabilities of this DB implementation
70
     * The capabilities of this DB implementation
71
     *
71
     *
72
     * The 'new_link' element contains the PHP version that first provided
72
     * The 'new_link' element contains the PHP version that first provided
73
     * new_link support for this DBMS.  Contains false if it's unsupported.
73
     * new_link support for this DBMS.  Contains false if it's unsupported.
74
     *
74
     *
75
     * Meaning of the 'limit' element:
75
     * Meaning of the 'limit' element:
76
     *   + 'emulate' = emulate with fetch row by number
76
     *   + 'emulate' = emulate with fetch row by number
77
     *   + 'alter'   = alter the query
77
     *   + 'alter'   = alter the query
78
     *   + false     = skip rows
78
     *   + false     = skip rows
79
     *
79
     *
80
     * @var array
80
     * @var array
81
     */
81
     */
82
    var $features = array(
82
    var $features = array(
83
        'limit'         => 'alter',
83
        'limit'         => 'alter',
84
        'new_link'      => '5.0.0',
84
        'new_link'      => '5.0.0',
85
        'numrows'       => 'subquery',
85
        'numrows'       => 'subquery',
86
        'pconnect'      => true,
86
        'pconnect'      => true,
87
        'prepare'       => true,
87
        'prepare'       => true,
88
        'ssl'           => false,
88
        'ssl'           => false,
89
        'transactions'  => true,
89
        'transactions'  => true,
90
    );
90
    );
91
 
91
 
92
    /**
92
    /**
93
     * A mapping of native error codes to DB error codes
93
     * A mapping of native error codes to DB error codes
94
     * @var array
94
     * @var array
95
     */
95
     */
96
    var $errorcode_map = array(
96
    var $errorcode_map = array(
97
        1    => DB_ERROR_CONSTRAINT,
97
        1    => DB_ERROR_CONSTRAINT,
98
        900  => DB_ERROR_SYNTAX,
98
        900  => DB_ERROR_SYNTAX,
99
        904  => DB_ERROR_NOSUCHFIELD,
99
        904  => DB_ERROR_NOSUCHFIELD,
100
        913  => DB_ERROR_VALUE_COUNT_ON_ROW,
100
        913  => DB_ERROR_VALUE_COUNT_ON_ROW,
101
        921  => DB_ERROR_SYNTAX,
101
        921  => DB_ERROR_SYNTAX,
102
        923  => DB_ERROR_SYNTAX,
102
        923  => DB_ERROR_SYNTAX,
103
        942  => DB_ERROR_NOSUCHTABLE,
103
        942  => DB_ERROR_NOSUCHTABLE,
104
        955  => DB_ERROR_ALREADY_EXISTS,
104
        955  => DB_ERROR_ALREADY_EXISTS,
105
        1400 => DB_ERROR_CONSTRAINT_NOT_NULL,
105
        1400 => DB_ERROR_CONSTRAINT_NOT_NULL,
106
        1401 => DB_ERROR_INVALID,
106
        1401 => DB_ERROR_INVALID,
107
        1407 => DB_ERROR_CONSTRAINT_NOT_NULL,
107
        1407 => DB_ERROR_CONSTRAINT_NOT_NULL,
108
        1418 => DB_ERROR_NOT_FOUND,
108
        1418 => DB_ERROR_NOT_FOUND,
109
        1476 => DB_ERROR_DIVZERO,
109
        1476 => DB_ERROR_DIVZERO,
110
        1722 => DB_ERROR_INVALID_NUMBER,
110
        1722 => DB_ERROR_INVALID_NUMBER,
111
        2289 => DB_ERROR_NOSUCHTABLE,
111
        2289 => DB_ERROR_NOSUCHTABLE,
112
        2291 => DB_ERROR_CONSTRAINT,
112
        2291 => DB_ERROR_CONSTRAINT,
113
        2292 => DB_ERROR_CONSTRAINT,
113
        2292 => DB_ERROR_CONSTRAINT,
114
        2449 => DB_ERROR_CONSTRAINT,
114
        2449 => DB_ERROR_CONSTRAINT,
115
    );
115
    );
116
 
116
 
117
    /**
117
    /**
118
     * The raw database connection created by PHP
118
     * The raw database connection created by PHP
119
     * @var resource
119
     * @var resource
120
     */
120
     */
121
    var $connection;
121
    var $connection;
122
 
122
 
123
    /**
123
    /**
124
     * The DSN information for connecting to a database
124
     * The DSN information for connecting to a database
125
     * @var array
125
     * @var array
126
     */
126
     */
127
    var $dsn = array();
127
    var $dsn = array();
128
 
128
 
129
 
129
 
130
    /**
130
    /**
131
     * Should data manipulation queries be committed automatically?
131
     * Should data manipulation queries be committed automatically?
132
     * @var bool
132
     * @var bool
133
     * @access private
133
     * @access private
134
     */
134
     */
135
    var $autocommit = true;
135
    var $autocommit = true;
136
 
136
 
137
    /**
137
    /**
138
     * Stores the $data passed to execute() in the oci8 driver
138
     * Stores the $data passed to execute() in the oci8 driver
139
     *
139
     *
140
     * Gets reset to array() when simpleQuery() is run.
140
     * Gets reset to array() when simpleQuery() is run.
141
     *
141
     *
142
     * Needed in case user wants to call numRows() after prepare/execute
142
     * Needed in case user wants to call numRows() after prepare/execute
143
     * was used.
143
     * was used.
144
     *
144
     *
145
     * @var array
145
     * @var array
146
     * @access private
146
     * @access private
147
     */
147
     */
148
    var $_data = array();
148
    var $_data = array();
149
 
149
 
150
    /**
150
    /**
151
     * The result or statement handle from the most recently executed query
151
     * The result or statement handle from the most recently executed query
152
     * @var resource
152
     * @var resource
153
     */
153
     */
154
    var $last_stmt;
154
    var $last_stmt;
155
 
155
 
156
    /**
156
    /**
157
     * Is the given prepared statement a data manipulation query?
157
     * Is the given prepared statement a data manipulation query?
158
     * @var array
158
     * @var array
159
     * @access private
159
     * @access private
160
     */
160
     */
161
    var $manip_query = array();
161
    var $manip_query = array();
162
 
162
 
163
 
163
 
164
    // }}}
164
    // }}}
165
    // {{{ constructor
165
    // {{{ constructor
166
 
166
 
167
    /**
167
    /**
168
     * This constructor calls <kbd>$this->DB_common()</kbd>
168
     * This constructor calls <kbd>$this->DB_common()</kbd>
169
     *
169
     *
170
     * @return void
170
     * @return void
171
     */
171
     */
172
    function DB_oci8()
172
    function DB_oci8()
173
    {
173
    {
174
        $this->DB_common();
174
        $this->DB_common();
175
    }
175
    }
176
 
176
 
177
    // }}}
177
    // }}}
178
    // {{{ connect()
178
    // {{{ connect()
179
 
179
 
180
    /**
180
    /**
181
     * Connect to the database server, log in and open the database
181
     * Connect to the database server, log in and open the database
182
     *
182
     *
183
     * Don't call this method directly.  Use DB::connect() instead.
183
     * Don't call this method directly.  Use DB::connect() instead.
184
     *
184
     *
185
     * If PHP is at version 5.0.0 or greater:
185
     * If PHP is at version 5.0.0 or greater:
186
     *   + Generally, oci_connect() or oci_pconnect() are used.
186
     *   + Generally, oci_connect() or oci_pconnect() are used.
187
     *   + But if the new_link DSN option is set to true, oci_new_connect()
187
     *   + But if the new_link DSN option is set to true, oci_new_connect()
188
     *     is used.
188
     *     is used.
189
     *
189
     *
190
     * When using PHP version 4.x, OCILogon() or OCIPLogon() are used.
190
     * When using PHP version 4.x, OCILogon() or OCIPLogon() are used.
191
     *
191
     *
192
     * PEAR DB's oci8 driver supports the following extra DSN options:
192
     * PEAR DB's oci8 driver supports the following extra DSN options:
193
     *   + charset       The character set to be used on the connection.
193
     *   + charset       The character set to be used on the connection.
194
     *                    Only used if PHP is at version 5.0.0 or greater
194
     *                    Only used if PHP is at version 5.0.0 or greater
195
     *                    and the Oracle server is at 9.2 or greater.
195
     *                    and the Oracle server is at 9.2 or greater.
196
     *                    Available since PEAR DB 1.7.0.
196
     *                    Available since PEAR DB 1.7.0.
197
     *   + new_link      If set to true, causes subsequent calls to
197
     *   + new_link      If set to true, causes subsequent calls to
198
     *                    connect() to return a new connection link
198
     *                    connect() to return a new connection link
199
     *                    instead of the existing one.  WARNING: this is
199
     *                    instead of the existing one.  WARNING: this is
200
     *                    not portable to other DBMS's.
200
     *                    not portable to other DBMS's.
201
     *                    Available since PEAR DB 1.7.0.
201
     *                    Available since PEAR DB 1.7.0.
202
     *
202
     *
203
     * @param array $dsn         the data source name
203
     * @param array $dsn         the data source name
204
     * @param bool  $persistent  should the connection be persistent?
204
     * @param bool  $persistent  should the connection be persistent?
205
     *
205
     *
206
     * @return int  DB_OK on success. A DB_Error object on failure.
206
     * @return int  DB_OK on success. A DB_Error object on failure.
207
     */
207
     */
208
    function connect($dsn, $persistent = false)
208
    function connect($dsn, $persistent = false)
209
    {
209
    {
210
        if (!PEAR::loadExtension('oci8')) {
210
        if (!PEAR::loadExtension('oci8')) {
211
            return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
211
            return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
212
        }
212
        }
213
 
213
 
214
        $this->dsn = $dsn;
214
        $this->dsn = $dsn;
215
        if ($dsn['dbsyntax']) {
215
        if ($dsn['dbsyntax']) {
216
            $this->dbsyntax = $dsn['dbsyntax'];
216
            $this->dbsyntax = $dsn['dbsyntax'];
217
        }
217
        }
218
 
218
 
219
        if (function_exists('oci_connect')) {
219
        if (function_exists('oci_connect')) {
220
            if (isset($dsn['new_link'])
220
            if (isset($dsn['new_link'])
221
                && ($dsn['new_link'] == 'true' || $dsn['new_link'] === true))
221
                && ($dsn['new_link'] == 'true' || $dsn['new_link'] === true))
222
            {
222
            {
223
                $connect_function = 'oci_new_connect';
223
                $connect_function = 'oci_new_connect';
224
            } else {
224
            } else {
225
                $connect_function = $persistent ? 'oci_pconnect'
225
                $connect_function = $persistent ? 'oci_pconnect'
226
                                    : 'oci_connect';
226
                                    : 'oci_connect';
227
            }
227
            }
-
 
228
 
-
 
229
            // Backwards compatibility with DB < 1.7.0
-
 
230
            if (empty($dsn['database']) && !empty($dsn['hostspec'])) {
-
 
231
                $db = $dsn['hostspec'];
-
 
232
            } else {
-
 
233
                $db = $dsn['database'];
-
 
234
            }
-
 
235
 
228
            $char = empty($dsn['charset']) ? null : $dsn['charset'];
236
            $char = empty($dsn['charset']) ? null : $dsn['charset'];
229
            $this->connection = @$connect_function($dsn['username'],
237
            $this->connection = @$connect_function($dsn['username'],
230
                                                   $dsn['password'],
238
                                                   $dsn['password'],
231
                                                   $dsn['database'],
239
                                                   $db,
232
                                                   $char);
240
                                                   $char);
233
            $error = OCIError();
241
            $error = OCIError();
234
            if (!empty($error) && $error['code'] == 12541) {
242
            if (!empty($error) && $error['code'] == 12541) {
235
                // Couldn't find TNS listener.  Try direct connection.
243
                // Couldn't find TNS listener.  Try direct connection.
236
                $this->connection = @$connect_function($dsn['username'],
244
                $this->connection = @$connect_function($dsn['username'],
237
                                                       $dsn['password'],
245
                                                       $dsn['password'],
238
                                                       null,
246
                                                       null,
239
                                                       $char);
247
                                                       $char);
240
            }
248
            }
241
        } else {
249
        } else {
242
            $connect_function = $persistent ? 'OCIPLogon' : 'OCILogon';
250
            $connect_function = $persistent ? 'OCIPLogon' : 'OCILogon';
243
            if ($dsn['hostspec']) {
251
            if ($dsn['hostspec']) {
244
                $this->connection = @$connect_function($dsn['username'],
252
                $this->connection = @$connect_function($dsn['username'],
245
                                                       $dsn['password'],
253
                                                       $dsn['password'],
246
                                                       $dsn['hostspec']);
254
                                                       $dsn['hostspec']);
247
            } elseif ($dsn['username'] || $dsn['password']) {
255
            } elseif ($dsn['username'] || $dsn['password']) {
248
                $this->connection = @$connect_function($dsn['username'],
256
                $this->connection = @$connect_function($dsn['username'],
249
                                                       $dsn['password']);
257
                                                       $dsn['password']);
250
            }
258
            }
251
        }
259
        }
252
 
260
 
253
        if (!$this->connection) {
261
        if (!$this->connection) {
254
            $error = OCIError();
262
            $error = OCIError();
255
            $error = (is_array($error)) ? $error['message'] : null;
263
            $error = (is_array($error)) ? $error['message'] : null;
256
            return $this->raiseError(DB_ERROR_CONNECT_FAILED,
264
            return $this->raiseError(DB_ERROR_CONNECT_FAILED,
257
                                     null, null, null,
265
                                     null, null, null,
258
                                     $error);
266
                                     $error);
259
        }
267
        }
260
        return DB_OK;
268
        return DB_OK;
261
    }
269
    }
262
 
270
 
263
    // }}}
271
    // }}}
264
    // {{{ disconnect()
272
    // {{{ disconnect()
265
 
273
 
266
    /**
274
    /**
267
     * Disconnects from the database server
275
     * Disconnects from the database server
268
     *
276
     *
269
     * @return bool  TRUE on success, FALSE on failure
277
     * @return bool  TRUE on success, FALSE on failure
270
     */
278
     */
271
    function disconnect()
279
    function disconnect()
272
    {
280
    {
273
        if (function_exists('oci_close')) {
281
        if (function_exists('oci_close')) {
274
            $ret = @oci_close($this->connection);
282
            $ret = @oci_close($this->connection);
275
        } else {
283
        } else {
276
            $ret = @OCILogOff($this->connection);
284
            $ret = @OCILogOff($this->connection);
277
        }
285
        }
278
        $this->connection = null;
286
        $this->connection = null;
279
        return $ret;
287
        return $ret;
280
    }
288
    }
281
 
289
 
282
    // }}}
290
    // }}}
283
    // {{{ simpleQuery()
291
    // {{{ simpleQuery()
284
 
292
 
285
    /**
293
    /**
286
     * Sends a query to the database server
294
     * Sends a query to the database server
287
     *
295
     *
288
     * To determine how many rows of a result set get buffered using
296
     * To determine how many rows of a result set get buffered using
289
     * ocisetprefetch(), see the "result_buffering" option in setOptions().
297
     * ocisetprefetch(), see the "result_buffering" option in setOptions().
290
     * This option was added in Release 1.7.0.
298
     * This option was added in Release 1.7.0.
291
     *
299
     *
292
     * @param string  the SQL query string
300
     * @param string  the SQL query string
293
     *
301
     *
294
     * @return mixed  + a PHP result resrouce for successful SELECT queries
302
     * @return mixed  + a PHP result resrouce for successful SELECT queries
295
     *                + the DB_OK constant for other successful queries
303
     *                + the DB_OK constant for other successful queries
296
     *                + a DB_Error object on failure
304
     *                + a DB_Error object on failure
297
     */
305
     */
298
    function simpleQuery($query)
306
    function simpleQuery($query)
299
    {
307
    {
300
        $this->_data = array();
308
        $this->_data = array();
301
        $this->last_parameters = array();
309
        $this->last_parameters = array();
302
        $this->last_query = $query;
310
        $this->last_query = $query;
303
        $query = $this->modifyQuery($query);
311
        $query = $this->modifyQuery($query);
304
        $result = @OCIParse($this->connection, $query);
312
        $result = @OCIParse($this->connection, $query);
305
        if (!$result) {
313
        if (!$result) {
306
            return $this->oci8RaiseError();
314
            return $this->oci8RaiseError();
307
        }
315
        }
308
        if ($this->autocommit) {
316
        if ($this->autocommit) {
309
            $success = @OCIExecute($result,OCI_COMMIT_ON_SUCCESS);
317
            $success = @OCIExecute($result,OCI_COMMIT_ON_SUCCESS);
310
        } else {
318
        } else {
311
            $success = @OCIExecute($result,OCI_DEFAULT);
319
            $success = @OCIExecute($result,OCI_DEFAULT);
312
        }
320
        }
313
        if (!$success) {
321
        if (!$success) {
314
            return $this->oci8RaiseError($result);
322
            return $this->oci8RaiseError($result);
315
        }
323
        }
316
        $this->last_stmt = $result;
324
        $this->last_stmt = $result;
317
        if (DB::isManip($query)) {
325
        if (DB::isManip($query)) {
318
            return DB_OK;
326
            return DB_OK;
319
        } else {
327
        } else {
320
            @ocisetprefetch($result, $this->options['result_buffering']);
328
            @ocisetprefetch($result, $this->options['result_buffering']);
321
            return $result;
329
            return $result;
322
        }
330
        }
323
    }
331
    }
324
 
332
 
325
    // }}}
333
    // }}}
326
    // {{{ nextResult()
334
    // {{{ nextResult()
327
 
335
 
328
    /**
336
    /**
329
     * Move the internal oracle result pointer to the next available result
337
     * Move the internal oracle result pointer to the next available result
330
     *
338
     *
331
     * @param a valid oci8 result resource
339
     * @param a valid oci8 result resource
332
     *
340
     *
333
     * @access public
341
     * @access public
334
     *
342
     *
335
     * @return true if a result is available otherwise return false
343
     * @return true if a result is available otherwise return false
336
     */
344
     */
337
    function nextResult($result)
345
    function nextResult($result)
338
    {
346
    {
339
        return false;
347
        return false;
340
    }
348
    }
341
 
349
 
342
    // }}}
350
    // }}}
343
    // {{{ fetchInto()
351
    // {{{ fetchInto()
344
 
352
 
345
    /**
353
    /**
346
     * Places a row from the result set into the given array
354
     * Places a row from the result set into the given array
347
     *
355
     *
348
     * Formating of the array and the data therein are configurable.
356
     * Formating of the array and the data therein are configurable.
349
     * See DB_result::fetchInto() for more information.
357
     * See DB_result::fetchInto() for more information.
350
     *
358
     *
351
     * This method is not meant to be called directly.  Use
359
     * This method is not meant to be called directly.  Use
352
     * DB_result::fetchInto() instead.  It can't be declared "protected"
360
     * DB_result::fetchInto() instead.  It can't be declared "protected"
353
     * because DB_result is a separate object.
361
     * because DB_result is a separate object.
354
     *
362
     *
355
     * @param resource $result    the query result resource
363
     * @param resource $result    the query result resource
356
     * @param array    $arr       the referenced array to put the data in
364
     * @param array    $arr       the referenced array to put the data in
357
     * @param int      $fetchmode how the resulting array should be indexed
365
     * @param int      $fetchmode how the resulting array should be indexed
358
     * @param int      $rownum    the row number to fetch (0 = first row)
366
     * @param int      $rownum    the row number to fetch (0 = first row)
359
     *
367
     *
360
     * @return mixed  DB_OK on success, NULL when the end of a result set is
368
     * @return mixed  DB_OK on success, NULL when the end of a result set is
361
     *                 reached or on failure
369
     *                 reached or on failure
362
     *
370
     *
363
     * @see DB_result::fetchInto()
371
     * @see DB_result::fetchInto()
364
     */
372
     */
365
    function fetchInto($result, &$arr, $fetchmode, $rownum = null)
373
    function fetchInto($result, &$arr, $fetchmode, $rownum = null)
366
    {
374
    {
367
        if ($rownum !== null) {
375
        if ($rownum !== null) {
368
            return $this->raiseError(DB_ERROR_NOT_CAPABLE);
376
            return $this->raiseError(DB_ERROR_NOT_CAPABLE);
369
        }
377
        }
370
        if ($fetchmode & DB_FETCHMODE_ASSOC) {
378
        if ($fetchmode & DB_FETCHMODE_ASSOC) {
371
            $moredata = @OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS);
379
            $moredata = @OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS);
372
            if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE &&
380
            if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE &&
373
                $moredata)
381
                $moredata)
374
            {
382
            {
375
                $arr = array_change_key_case($arr, CASE_LOWER);
383
                $arr = array_change_key_case($arr, CASE_LOWER);
376
            }
384
            }
377
        } else {
385
        } else {
378
            $moredata = OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS);
386
            $moredata = OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS);
379
        }
387
        }
380
        if (!$moredata) {
388
        if (!$moredata) {
381
            return null;
389
            return null;
382
        }
390
        }
383
        if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
391
        if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
384
            $this->_rtrimArrayValues($arr);
392
            $this->_rtrimArrayValues($arr);
385
        }
393
        }
386
        if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
394
        if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
387
            $this->_convertNullArrayValuesToEmpty($arr);
395
            $this->_convertNullArrayValuesToEmpty($arr);
388
        }
396
        }
389
        return DB_OK;
397
        return DB_OK;
390
    }
398
    }
391
 
399
 
392
    // }}}
400
    // }}}
393
    // {{{ freeResult()
401
    // {{{ freeResult()
394
 
402
 
395
    /**
403
    /**
396
     * Deletes the result set and frees the memory occupied by the result set
404
     * Deletes the result set and frees the memory occupied by the result set
397
     *
405
     *
398
     * This method is not meant to be called directly.  Use
406
     * This method is not meant to be called directly.  Use
399
     * DB_result::free() instead.  It can't be declared "protected"
407
     * DB_result::free() instead.  It can't be declared "protected"
400
     * because DB_result is a separate object.
408
     * because DB_result is a separate object.
401
     *
409
     *
402
     * @param resource $result  PHP's query result resource
410
     * @param resource $result  PHP's query result resource
403
     *
411
     *
404
     * @return bool  TRUE on success, FALSE if $result is invalid
412
     * @return bool  TRUE on success, FALSE if $result is invalid
405
     *
413
     *
406
     * @see DB_result::free()
414
     * @see DB_result::free()
407
     */
415
     */
408
    function freeResult($result)
416
    function freeResult($result)
409
    {
417
    {
410
        return @OCIFreeStatement($result);
418
        return @OCIFreeStatement($result);
411
    }
419
    }
412
 
420
 
413
    /**
421
    /**
414
     * Frees the internal resources associated with a prepared query
422
     * Frees the internal resources associated with a prepared query
415
     *
423
     *
416
     * @param resource $stmt           the prepared statement's resource
424
     * @param resource $stmt           the prepared statement's resource
417
     * @param bool     $free_resource  should the PHP resource be freed too?
425
     * @param bool     $free_resource  should the PHP resource be freed too?
418
     *                                  Use false if you need to get data
426
     *                                  Use false if you need to get data
419
     *                                  from the result set later.
427
     *                                  from the result set later.
420
     *
428
     *
421
     * @return bool  TRUE on success, FALSE if $result is invalid
429
     * @return bool  TRUE on success, FALSE if $result is invalid
422
     *
430
     *
423
     * @see DB_oci8::prepare()
431
     * @see DB_oci8::prepare()
424
     */
432
     */
425
    function freePrepared($stmt, $free_resource = true)
433
    function freePrepared($stmt, $free_resource = true)
426
    {
434
    {
427
        if (!is_resource($stmt)) {
435
        if (!is_resource($stmt)) {
428
            return false;
436
            return false;
429
        }
437
        }
430
        if ($free_resource) {
438
        if ($free_resource) {
431
            @ocifreestatement($stmt);
439
            @ocifreestatement($stmt);
432
        }
440
        }
433
        if (isset($this->prepare_types[(int)$stmt])) {
441
        if (isset($this->prepare_types[(int)$stmt])) {
434
            unset($this->prepare_types[(int)$stmt]);
442
            unset($this->prepare_types[(int)$stmt]);
435
            unset($this->manip_query[(int)$stmt]);
443
            unset($this->manip_query[(int)$stmt]);
436
        } else {
444
        } else {
437
            return false;
445
            return false;
438
        }
446
        }
439
        return true;
447
        return true;
440
    }
448
    }
441
 
449
 
442
    // }}}
450
    // }}}
443
    // {{{ numRows()
451
    // {{{ numRows()
444
 
452
 
445
    /**
453
    /**
446
     * Gets the number of rows in a result set
454
     * Gets the number of rows in a result set
447
     *
455
     *
448
     * Only works if the DB_PORTABILITY_NUMROWS portability option
456
     * Only works if the DB_PORTABILITY_NUMROWS portability option
449
     * is turned on.
457
     * is turned on.
450
     *
458
     *
451
     * This method is not meant to be called directly.  Use
459
     * This method is not meant to be called directly.  Use
452
     * DB_result::numRows() instead.  It can't be declared "protected"
460
     * DB_result::numRows() instead.  It can't be declared "protected"
453
     * because DB_result is a separate object.
461
     * because DB_result is a separate object.
454
     *
462
     *
455
     * @param resource $result  PHP's query result resource
463
     * @param resource $result  PHP's query result resource
456
     *
464
     *
457
     * @return int  the number of rows.  A DB_Error object on failure.
465
     * @return int  the number of rows.  A DB_Error object on failure.
458
     *
466
     *
459
     * @see DB_result::numRows(), DB_common::setOption()
467
     * @see DB_result::numRows(), DB_common::setOption()
460
     */
468
     */
461
    function numRows($result)
469
    function numRows($result)
462
    {
470
    {
463
        // emulate numRows for Oracle.  yuck.
471
        // emulate numRows for Oracle.  yuck.
464
        if ($this->options['portability'] & DB_PORTABILITY_NUMROWS &&
472
        if ($this->options['portability'] & DB_PORTABILITY_NUMROWS &&
465
            $result === $this->last_stmt)
473
            $result === $this->last_stmt)
466
        {
474
        {
467
            $countquery = 'SELECT COUNT(*) FROM ('.$this->last_query.')';
475
            $countquery = 'SELECT COUNT(*) FROM ('.$this->last_query.')';
468
            $save_query = $this->last_query;
476
            $save_query = $this->last_query;
469
            $save_stmt = $this->last_stmt;
477
            $save_stmt = $this->last_stmt;
470
 
478
 
471
            if (count($this->_data)) {
479
            if (count($this->_data)) {
472
                $smt = $this->prepare('SELECT COUNT(*) FROM ('.$this->last_query.')');
480
                $smt = $this->prepare('SELECT COUNT(*) FROM ('.$this->last_query.')');
473
                $count = $this->execute($smt, $this->_data);
481
                $count = $this->execute($smt, $this->_data);
474
            } else {
482
            } else {
475
                $count =& $this->query($countquery);
483
                $count =& $this->query($countquery);
476
            }
484
            }
477
 
485
 
478
            if (DB::isError($count) ||
486
            if (DB::isError($count) ||
479
                DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED)))
487
                DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED)))
480
            {
488
            {
481
                $this->last_query = $save_query;
489
                $this->last_query = $save_query;
482
                $this->last_stmt = $save_stmt;
490
                $this->last_stmt = $save_stmt;
483
                return $this->raiseError(DB_ERROR_NOT_CAPABLE);
491
                return $this->raiseError(DB_ERROR_NOT_CAPABLE);
484
            }
492
            }
485
            return $row[0];
493
            return $row[0];
486
        }
494
        }
487
        return $this->raiseError(DB_ERROR_NOT_CAPABLE);
495
        return $this->raiseError(DB_ERROR_NOT_CAPABLE);
488
    }
496
    }
489
 
497
 
490
    // }}}
498
    // }}}
491
    // {{{ numCols()
499
    // {{{ numCols()
492
 
500
 
493
    /**
501
    /**
494
     * Gets the number of columns in a result set
502
     * Gets the number of columns in a result set
495
     *
503
     *
496
     * This method is not meant to be called directly.  Use
504
     * This method is not meant to be called directly.  Use
497
     * DB_result::numCols() instead.  It can't be declared "protected"
505
     * DB_result::numCols() instead.  It can't be declared "protected"
498
     * because DB_result is a separate object.
506
     * because DB_result is a separate object.
499
     *
507
     *
500
     * @param resource $result  PHP's query result resource
508
     * @param resource $result  PHP's query result resource
501
     *
509
     *
502
     * @return int  the number of columns.  A DB_Error object on failure.
510
     * @return int  the number of columns.  A DB_Error object on failure.
503
     *
511
     *
504
     * @see DB_result::numCols()
512
     * @see DB_result::numCols()
505
     */
513
     */
506
    function numCols($result)
514
    function numCols($result)
507
    {
515
    {
508
        $cols = @OCINumCols($result);
516
        $cols = @OCINumCols($result);
509
        if (!$cols) {
517
        if (!$cols) {
510
            return $this->oci8RaiseError($result);
518
            return $this->oci8RaiseError($result);
511
        }
519
        }
512
        return $cols;
520
        return $cols;
513
    }
521
    }
514
 
522
 
515
    // }}}
523
    // }}}
516
    // {{{ prepare()
524
    // {{{ prepare()
517
 
525
 
518
    /**
526
    /**
519
     * Prepares a query for multiple execution with execute().
527
     * Prepares a query for multiple execution with execute().
520
     *
528
     *
521
     * With oci8, this is emulated.
529
     * With oci8, this is emulated.
522
     *
530
     *
523
     * prepare() requires a generic query as string like <code>
531
     * prepare() requires a generic query as string like <code>
524
     *    INSERT INTO numbers VALUES (?, ?, ?)
532
     *    INSERT INTO numbers VALUES (?, ?, ?)
525
     * </code>.  The <kbd>?</kbd> characters are placeholders.
533
     * </code>.  The <kbd>?</kbd> characters are placeholders.
526
     *
534
     *
527
     * Three types of placeholders can be used:
535
     * Three types of placeholders can be used:
528
     *   + <kbd>?</kbd>  a quoted scalar value, i.e. strings, integers
536
     *   + <kbd>?</kbd>  a quoted scalar value, i.e. strings, integers
529
     *   + <kbd>!</kbd>  value is inserted 'as is'
537
     *   + <kbd>!</kbd>  value is inserted 'as is'
530
     *   + <kbd>&</kbd>  requires a file name.  The file's contents get
538
     *   + <kbd>&</kbd>  requires a file name.  The file's contents get
531
     *                     inserted into the query (i.e. saving binary
539
     *                     inserted into the query (i.e. saving binary
532
     *                     data in a db)
540
     *                     data in a db)
533
     *
541
     *
534
     * Use backslashes to escape placeholder characters if you don't want
542
     * Use backslashes to escape placeholder characters if you don't want
535
     * them to be interpreted as placeholders.  Example: <code>
543
     * them to be interpreted as placeholders.  Example: <code>
536
     *    "UPDATE foo SET col=? WHERE col='over \& under'"
544
     *    "UPDATE foo SET col=? WHERE col='over \& under'"
537
     * </code>
545
     * </code>
538
     *
546
     *
539
     * @param string $query  the query to be prepared
547
     * @param string $query  the query to be prepared
540
     *
548
     *
541
     * @return mixed  DB statement resource on success. DB_Error on failure.
549
     * @return mixed  DB statement resource on success. DB_Error on failure.
542
     *
550
     *
543
     * @see DB_oci8::execute()
551
     * @see DB_oci8::execute()
544
     */
552
     */
545
    function prepare($query)
553
    function prepare($query)
546
    {
554
    {
547
        $tokens   = preg_split('/((?<!\\\)[&?!])/', $query, -1,
555
        $tokens   = preg_split('/((?<!\\\)[&?!])/', $query, -1,
548
                               PREG_SPLIT_DELIM_CAPTURE);
556
                               PREG_SPLIT_DELIM_CAPTURE);
549
        $binds    = count($tokens) - 1;
557
        $binds    = count($tokens) - 1;
550
        $token    = 0;
558
        $token    = 0;
551
        $types    = array();
559
        $types    = array();
552
        $newquery = '';
560
        $newquery = '';
553
 
561
 
554
        foreach ($tokens as $key => $val) {
562
        foreach ($tokens as $key => $val) {
555
            switch ($val) {
563
            switch ($val) {
556
                case '?':
564
                case '?':
557
                    $types[$token++] = DB_PARAM_SCALAR;
565
                    $types[$token++] = DB_PARAM_SCALAR;
558
                    unset($tokens[$key]);
566
                    unset($tokens[$key]);
559
                    break;
567
                    break;
560
                case '&':
568
                case '&':
561
                    $types[$token++] = DB_PARAM_OPAQUE;
569
                    $types[$token++] = DB_PARAM_OPAQUE;
562
                    unset($tokens[$key]);
570
                    unset($tokens[$key]);
563
                    break;
571
                    break;
564
                case '!':
572
                case '!':
565
                    $types[$token++] = DB_PARAM_MISC;
573
                    $types[$token++] = DB_PARAM_MISC;
566
                    unset($tokens[$key]);
574
                    unset($tokens[$key]);
567
                    break;
575
                    break;
568
                default:
576
                default:
569
                    $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val);
577
                    $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val);
570
                    if ($key != $binds) {
578
                    if ($key != $binds) {
571
                        $newquery .= $tokens[$key] . ':bind' . $token;
579
                        $newquery .= $tokens[$key] . ':bind' . $token;
572
                    } else {
580
                    } else {
573
                        $newquery .= $tokens[$key];
581
                        $newquery .= $tokens[$key];
574
                    }
582
                    }
575
            }
583
            }
576
        }
584
        }
577
 
585
 
578
        $this->last_query = $query;
586
        $this->last_query = $query;
579
        $newquery = $this->modifyQuery($newquery);
587
        $newquery = $this->modifyQuery($newquery);
580
        if (!$stmt = @OCIParse($this->connection, $newquery)) {
588
        if (!$stmt = @OCIParse($this->connection, $newquery)) {
581
            return $this->oci8RaiseError();
589
            return $this->oci8RaiseError();
582
        }
590
        }
583
        $this->prepare_types[(int)$stmt] = $types;
591
        $this->prepare_types[(int)$stmt] = $types;
584
        $this->manip_query[(int)$stmt] = DB::isManip($query);
592
        $this->manip_query[(int)$stmt] = DB::isManip($query);
585
        return $stmt;
593
        return $stmt;
586
    }
594
    }
587
 
595
 
588
    // }}}
596
    // }}}
589
    // {{{ execute()
597
    // {{{ execute()
590
 
598
 
591
    /**
599
    /**
592
     * Executes a DB statement prepared with prepare().
600
     * Executes a DB statement prepared with prepare().
593
     *
601
     *
594
     * To determine how many rows of a result set get buffered using
602
     * To determine how many rows of a result set get buffered using
595
     * ocisetprefetch(), see the "result_buffering" option in setOptions().
603
     * ocisetprefetch(), see the "result_buffering" option in setOptions().
596
     * This option was added in Release 1.7.0.
604
     * This option was added in Release 1.7.0.
597
     *
605
     *
598
     * @param resource  $stmt  a DB statement resource returned from prepare()
606
     * @param resource  $stmt  a DB statement resource returned from prepare()
599
     * @param mixed  $data  array, string or numeric data to be used in
607
     * @param mixed  $data  array, string or numeric data to be used in
600
     *                      execution of the statement.  Quantity of items
608
     *                      execution of the statement.  Quantity of items
601
     *                      passed must match quantity of placeholders in
609
     *                      passed must match quantity of placeholders in
602
     *                      query:  meaning 1 for non-array items or the
610
     *                      query:  meaning 1 for non-array items or the
603
     *                      quantity of elements in the array.
611
     *                      quantity of elements in the array.
604
     *
612
     *
605
     * @return mixed  returns an oic8 result resource for successful SELECT
613
     * @return mixed  returns an oic8 result resource for successful SELECT
606
     *                queries, DB_OK for other successful queries.
614
     *                queries, DB_OK for other successful queries.
607
     *                A DB error object is returned on failure.
615
     *                A DB error object is returned on failure.
608
     *
616
     *
609
     * @see DB_oci8::prepare()
617
     * @see DB_oci8::prepare()
610
     */
618
     */
611
    function &execute($stmt, $data = array())
619
    function &execute($stmt, $data = array())
612
    {
620
    {
613
        $data = (array)$data;
621
        $data = (array)$data;
614
        $this->last_parameters = $data;
622
        $this->last_parameters = $data;
615
        $this->_data = $data;
623
        $this->_data = $data;
616
 
624
 
617
        $types =& $this->prepare_types[(int)$stmt];
625
        $types =& $this->prepare_types[(int)$stmt];
618
        if (count($types) != count($data)) {
626
        if (count($types) != count($data)) {
619
            $tmp =& $this->raiseError(DB_ERROR_MISMATCH);
627
            $tmp =& $this->raiseError(DB_ERROR_MISMATCH);
620
            return $tmp;
628
            return $tmp;
621
        }
629
        }
622
 
630
 
623
        $i = 0;
631
        $i = 0;
624
        foreach ($data as $key => $value) {
632
        foreach ($data as $key => $value) {
625
            if ($types[$i] == DB_PARAM_MISC) {
633
            if ($types[$i] == DB_PARAM_MISC) {
626
                /*
634
                /*
627
                 * Oracle doesn't seem to have the ability to pass a
635
                 * Oracle doesn't seem to have the ability to pass a
628
                 * parameter along unchanged, so strip off quotes from start
636
                 * parameter along unchanged, so strip off quotes from start
629
                 * and end, plus turn two single quotes to one single quote,
637
                 * and end, plus turn two single quotes to one single quote,
630
                 * in order to avoid the quotes getting escaped by
638
                 * in order to avoid the quotes getting escaped by
631
                 * Oracle and ending up in the database.
639
                 * Oracle and ending up in the database.
632
                 */
640
                 */
633
                $data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]);
641
                $data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]);
634
                $data[$key] = str_replace("''", "'", $data[$key]);
642
                $data[$key] = str_replace("''", "'", $data[$key]);
635
            } elseif ($types[$i] == DB_PARAM_OPAQUE) {
643
            } elseif ($types[$i] == DB_PARAM_OPAQUE) {
636
                $fp = @fopen($data[$key], 'rb');
644
                $fp = @fopen($data[$key], 'rb');
637
                if (!$fp) {
645
                if (!$fp) {
638
                    $tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
646
                    $tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
639
                    return $tmp;
647
                    return $tmp;
640
                }
648
                }
641
                $data[$key] = fread($fp, filesize($data[$key]));
649
                $data[$key] = fread($fp, filesize($data[$key]));
642
                fclose($fp);
650
                fclose($fp);
643
            }
651
            }
644
            if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) {
652
            if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) {
645
                $tmp = $this->oci8RaiseError($stmt);
653
                $tmp = $this->oci8RaiseError($stmt);
646
                return $tmp;
654
                return $tmp;
647
            }
655
            }
648
            $i++;
656
            $i++;
649
        }
657
        }
650
        if ($this->autocommit) {
658
        if ($this->autocommit) {
651
            $success = @OCIExecute($stmt, OCI_COMMIT_ON_SUCCESS);
659
            $success = @OCIExecute($stmt, OCI_COMMIT_ON_SUCCESS);
652
        } else {
660
        } else {
653
            $success = @OCIExecute($stmt, OCI_DEFAULT);
661
            $success = @OCIExecute($stmt, OCI_DEFAULT);
654
        }
662
        }
655
        if (!$success) {
663
        if (!$success) {
656
            $tmp = $this->oci8RaiseError($stmt);
664
            $tmp = $this->oci8RaiseError($stmt);
657
            return $tmp;
665
            return $tmp;
658
        }
666
        }
659
        $this->last_stmt = $stmt;
667
        $this->last_stmt = $stmt;
660
        if ($this->manip_query[(int)$stmt]) {
668
        if ($this->manip_query[(int)$stmt]) {
661
            $tmp = DB_OK;
669
            $tmp = DB_OK;
662
        } else {
670
        } else {
663
            @ocisetprefetch($stmt, $this->options['result_buffering']);
671
            @ocisetprefetch($stmt, $this->options['result_buffering']);
664
            $tmp =& new DB_result($this, $stmt);
672
            $tmp =& new DB_result($this, $stmt);
665
        }
673
        }
666
        return $tmp;
674
        return $tmp;
667
    }
675
    }
668
 
676
 
669
    // }}}
677
    // }}}
670
    // {{{ autoCommit()
678
    // {{{ autoCommit()
671
 
679
 
672
    /**
680
    /**
673
     * Enables or disables automatic commits
681
     * Enables or disables automatic commits
674
     *
682
     *
675
     * @param bool $onoff  true turns it on, false turns it off
683
     * @param bool $onoff  true turns it on, false turns it off
676
     *
684
     *
677
     * @return int  DB_OK on success.  A DB_Error object if the driver
685
     * @return int  DB_OK on success.  A DB_Error object if the driver
678
     *               doesn't support auto-committing transactions.
686
     *               doesn't support auto-committing transactions.
679
     */
687
     */
680
    function autoCommit($onoff = false)
688
    function autoCommit($onoff = false)
681
    {
689
    {
682
        $this->autocommit = (bool)$onoff;;
690
        $this->autocommit = (bool)$onoff;;
683
        return DB_OK;
691
        return DB_OK;
684
    }
692
    }
685
 
693
 
686
    // }}}
694
    // }}}
687
    // {{{ commit()
695
    // {{{ commit()
688
 
696
 
689
    /**
697
    /**
690
     * Commits the current transaction
698
     * Commits the current transaction
691
     *
699
     *
692
     * @return int  DB_OK on success.  A DB_Error object on failure.
700
     * @return int  DB_OK on success.  A DB_Error object on failure.
693
     */
701
     */
694
    function commit()
702
    function commit()
695
    {
703
    {
696
        $result = @OCICommit($this->connection);
704
        $result = @OCICommit($this->connection);
697
        if (!$result) {
705
        if (!$result) {
698
            return $this->oci8RaiseError();
706
            return $this->oci8RaiseError();
699
        }
707
        }
700
        return DB_OK;
708
        return DB_OK;
701
    }
709
    }
702
 
710
 
703
    // }}}
711
    // }}}
704
    // {{{ rollback()
712
    // {{{ rollback()
705
 
713
 
706
    /**
714
    /**
707
     * Reverts the current transaction
715
     * Reverts the current transaction
708
     *
716
     *
709
     * @return int  DB_OK on success.  A DB_Error object on failure.
717
     * @return int  DB_OK on success.  A DB_Error object on failure.
710
     */
718
     */
711
    function rollback()
719
    function rollback()
712
    {
720
    {
713
        $result = @OCIRollback($this->connection);
721
        $result = @OCIRollback($this->connection);
714
        if (!$result) {
722
        if (!$result) {
715
            return $this->oci8RaiseError();
723
            return $this->oci8RaiseError();
716
        }
724
        }
717
        return DB_OK;
725
        return DB_OK;
718
    }
726
    }
719
 
727
 
720
    // }}}
728
    // }}}
721
    // {{{ affectedRows()
729
    // {{{ affectedRows()
722
 
730
 
723
    /**
731
    /**
724
     * Determines the number of rows affected by a data maniuplation query
732
     * Determines the number of rows affected by a data maniuplation query
725
     *
733
     *
726
     * 0 is returned for queries that don't manipulate data.
734
     * 0 is returned for queries that don't manipulate data.
727
     *
735
     *
728
     * @return int  the number of rows.  A DB_Error object on failure.
736
     * @return int  the number of rows.  A DB_Error object on failure.
729
     */
737
     */
730
    function affectedRows()
738
    function affectedRows()
731
    {
739
    {
732
        if ($this->last_stmt === false) {
740
        if ($this->last_stmt === false) {
733
            return $this->oci8RaiseError();
741
            return $this->oci8RaiseError();
734
        }
742
        }
735
        $result = @OCIRowCount($this->last_stmt);
743
        $result = @OCIRowCount($this->last_stmt);
736
        if ($result === false) {
744
        if ($result === false) {
737
            return $this->oci8RaiseError($this->last_stmt);
745
            return $this->oci8RaiseError($this->last_stmt);
738
        }
746
        }
739
        return $result;
747
        return $result;
740
    }
748
    }
741
 
749
 
742
    // }}}
750
    // }}}
743
    // {{{ modifyQuery()
751
    // {{{ modifyQuery()
744
 
752
 
745
    /**
753
    /**
746
     * Changes a query string for various DBMS specific reasons
754
     * Changes a query string for various DBMS specific reasons
747
     *
755
     *
748
     * "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle.
756
     * "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle.
749
     *
757
     *
750
     * @param string $query  the query string to modify
758
     * @param string $query  the query string to modify
751
     *
759
     *
752
     * @return string  the modified query string
760
     * @return string  the modified query string
753
     *
761
     *
754
     * @access protected
762
     * @access protected
755
     */
763
     */
756
    function modifyQuery($query)
764
    function modifyQuery($query)
757
    {
765
    {
758
        if (preg_match('/^\s*SELECT/i', $query) &&
766
        if (preg_match('/^\s*SELECT/i', $query) &&
759
            !preg_match('/\sFROM\s/i', $query)) {
767
            !preg_match('/\sFROM\s/i', $query)) {
760
            $query .= ' FROM dual';
768
            $query .= ' FROM dual';
761
        }
769
        }
762
        return $query;
770
        return $query;
763
    }
771
    }
764
 
772
 
765
    // }}}
773
    // }}}
766
    // {{{ modifyLimitQuery()
774
    // {{{ modifyLimitQuery()
767
 
775
 
768
    /**
776
    /**
769
     * Adds LIMIT clauses to a query string according to current DBMS standards
777
     * Adds LIMIT clauses to a query string according to current DBMS standards
770
     *
778
     *
771
     * @param string $query   the query to modify
779
     * @param string $query   the query to modify
772
     * @param int    $from    the row to start to fetching (0 = the first row)
780
     * @param int    $from    the row to start to fetching (0 = the first row)
773
     * @param int    $count   the numbers of rows to fetch
781
     * @param int    $count   the numbers of rows to fetch
774
     * @param mixed  $params  array, string or numeric data to be used in
782
     * @param mixed  $params  array, string or numeric data to be used in
775
     *                         execution of the statement.  Quantity of items
783
     *                         execution of the statement.  Quantity of items
776
     *                         passed must match quantity of placeholders in
784
     *                         passed must match quantity of placeholders in
777
     *                         query:  meaning 1 placeholder for non-array
785
     *                         query:  meaning 1 placeholder for non-array
778
     *                         parameters or 1 placeholder per array element.
786
     *                         parameters or 1 placeholder per array element.
779
     *
787
     *
780
     * @return string  the query string with LIMIT clauses added
788
     * @return string  the query string with LIMIT clauses added
781
     *
789
     *
782
     * @access protected
790
     * @access protected
783
     */
791
     */
784
    function modifyLimitQuery($query, $from, $count, $params = array())
792
    function modifyLimitQuery($query, $from, $count, $params = array())
785
    {
793
    {
786
        // Let Oracle return the name of the columns instead of
794
        // Let Oracle return the name of the columns instead of
787
        // coding a "home" SQL parser
795
        // coding a "home" SQL parser
788
 
796
 
789
        if (count($params)) {
797
        if (count($params)) {
790
            $result = $this->prepare("SELECT * FROM ($query) "
798
            $result = $this->prepare("SELECT * FROM ($query) "
791
                                     . 'WHERE NULL = NULL');
799
                                     . 'WHERE NULL = NULL');
792
            $tmp =& $this->execute($result, $params);
800
            $tmp =& $this->execute($result, $params);
793
        } else {
801
        } else {
794
            $q_fields = "SELECT * FROM ($query) WHERE NULL = NULL";
802
            $q_fields = "SELECT * FROM ($query) WHERE NULL = NULL";
795
 
803
 
796
            if (!$result = @OCIParse($this->connection, $q_fields)) {
804
            if (!$result = @OCIParse($this->connection, $q_fields)) {
797
                $this->last_query = $q_fields;
805
                $this->last_query = $q_fields;
798
                return $this->oci8RaiseError();
806
                return $this->oci8RaiseError();
799
            }
807
            }
800
            if (!@OCIExecute($result, OCI_DEFAULT)) {
808
            if (!@OCIExecute($result, OCI_DEFAULT)) {
801
                $this->last_query = $q_fields;
809
                $this->last_query = $q_fields;
802
                return $this->oci8RaiseError($result);
810
                return $this->oci8RaiseError($result);
803
            }
811
            }
804
        }
812
        }
805
 
813
 
806
        $ncols = OCINumCols($result);
814
        $ncols = OCINumCols($result);
807
        $cols  = array();
815
        $cols  = array();
808
        for ( $i = 1; $i <= $ncols; $i++ ) {
816
        for ( $i = 1; $i <= $ncols; $i++ ) {
809
            $cols[] = '"' . OCIColumnName($result, $i) . '"';
817
            $cols[] = '"' . OCIColumnName($result, $i) . '"';
810
        }
818
        }
811
        $fields = implode(', ', $cols);
819
        $fields = implode(', ', $cols);
812
        // XXX Test that (tip by John Lim)
820
        // XXX Test that (tip by John Lim)
813
        //if (preg_match('/^\s*SELECT\s+/is', $query, $match)) {
821
        //if (preg_match('/^\s*SELECT\s+/is', $query, $match)) {
814
        //    // Introduce the FIRST_ROWS Oracle query optimizer
822
        //    // Introduce the FIRST_ROWS Oracle query optimizer
815
        //    $query = substr($query, strlen($match[0]), strlen($query));
823
        //    $query = substr($query, strlen($match[0]), strlen($query));
816
        //    $query = "SELECT /* +FIRST_ROWS */ " . $query;
824
        //    $query = "SELECT /* +FIRST_ROWS */ " . $query;
817
        //}
825
        //}
818
 
826
 
819
        // Construct the query
827
        // Construct the query
820
        // more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2
828
        // more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2
821
        // Perhaps this could be optimized with the use of Unions
829
        // Perhaps this could be optimized with the use of Unions
822
        $query = "SELECT $fields FROM".
830
        $query = "SELECT $fields FROM".
823
                 "  (SELECT rownum as linenum, $fields FROM".
831
                 "  (SELECT rownum as linenum, $fields FROM".
824
                 "      ($query)".
832
                 "      ($query)".
825
                 '  WHERE rownum <= '. ($from + $count) .
833
                 '  WHERE rownum <= '. ($from + $count) .
826
                 ') WHERE linenum >= ' . ++$from;
834
                 ') WHERE linenum >= ' . ++$from;
827
        return $query;
835
        return $query;
828
    }
836
    }
829
 
837
 
830
    // }}}
838
    // }}}
831
    // {{{ nextId()
839
    // {{{ nextId()
832
 
840
 
833
    /**
841
    /**
834
     * Returns the next free id in a sequence
842
     * Returns the next free id in a sequence
835
     *
843
     *
836
     * @param string  $seq_name  name of the sequence
844
     * @param string  $seq_name  name of the sequence
837
     * @param boolean $ondemand  when true, the seqence is automatically
845
     * @param boolean $ondemand  when true, the seqence is automatically
838
     *                            created if it does not exist
846
     *                            created if it does not exist
839
     *
847
     *
840
     * @return int  the next id number in the sequence.
848
     * @return int  the next id number in the sequence.
841
     *               A DB_Error object on failure.
849
     *               A DB_Error object on failure.
842
     *
850
     *
843
     * @see DB_common::nextID(), DB_common::getSequenceName(),
851
     * @see DB_common::nextID(), DB_common::getSequenceName(),
844
     *      DB_oci8::createSequence(), DB_oci8::dropSequence()
852
     *      DB_oci8::createSequence(), DB_oci8::dropSequence()
845
     */
853
     */
846
    function nextId($seq_name, $ondemand = true)
854
    function nextId($seq_name, $ondemand = true)
847
    {
855
    {
848
        $seqname = $this->getSequenceName($seq_name);
856
        $seqname = $this->getSequenceName($seq_name);
849
        $repeat = 0;
857
        $repeat = 0;
850
        do {
858
        do {
851
            $this->expectError(DB_ERROR_NOSUCHTABLE);
859
            $this->expectError(DB_ERROR_NOSUCHTABLE);
852
            $result =& $this->query("SELECT ${seqname}.nextval FROM dual");
860
            $result =& $this->query("SELECT ${seqname}.nextval FROM dual");
853
            $this->popExpect();
861
            $this->popExpect();
854
            if ($ondemand && DB::isError($result) &&
862
            if ($ondemand && DB::isError($result) &&
855
                $result->getCode() == DB_ERROR_NOSUCHTABLE) {
863
                $result->getCode() == DB_ERROR_NOSUCHTABLE) {
856
                $repeat = 1;
864
                $repeat = 1;
857
                $result = $this->createSequence($seq_name);
865
                $result = $this->createSequence($seq_name);
858
                if (DB::isError($result)) {
866
                if (DB::isError($result)) {
859
                    return $this->raiseError($result);
867
                    return $this->raiseError($result);
860
                }
868
                }
861
            } else {
869
            } else {
862
                $repeat = 0;
870
                $repeat = 0;
863
            }
871
            }
864
        } while ($repeat);
872
        } while ($repeat);
865
        if (DB::isError($result)) {
873
        if (DB::isError($result)) {
866
            return $this->raiseError($result);
874
            return $this->raiseError($result);
867
        }
875
        }
868
        $arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
876
        $arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
869
        return $arr[0];
877
        return $arr[0];
870
    }
878
    }
871
 
879
 
872
    /**
880
    /**
873
     * Creates a new sequence
881
     * Creates a new sequence
874
     *
882
     *
875
     * @param string $seq_name  name of the new sequence
883
     * @param string $seq_name  name of the new sequence
876
     *
884
     *
877
     * @return int  DB_OK on success.  A DB_Error object on failure.
885
     * @return int  DB_OK on success.  A DB_Error object on failure.
878
     *
886
     *
879
     * @see DB_common::createSequence(), DB_common::getSequenceName(),
887
     * @see DB_common::createSequence(), DB_common::getSequenceName(),
880
     *      DB_oci8::nextID(), DB_oci8::dropSequence()
888
     *      DB_oci8::nextID(), DB_oci8::dropSequence()
881
     */
889
     */
882
    function createSequence($seq_name)
890
    function createSequence($seq_name)
883
    {
891
    {
884
        return $this->query('CREATE SEQUENCE '
892
        return $this->query('CREATE SEQUENCE '
885
                            . $this->getSequenceName($seq_name));
893
                            . $this->getSequenceName($seq_name));
886
    }
894
    }
887
 
895
 
888
    // }}}
896
    // }}}
889
    // {{{ dropSequence()
897
    // {{{ dropSequence()
890
 
898
 
891
    /**
899
    /**
892
     * Deletes a sequence
900
     * Deletes a sequence
893
     *
901
     *
894
     * @param string $seq_name  name of the sequence to be deleted
902
     * @param string $seq_name  name of the sequence to be deleted
895
     *
903
     *
896
     * @return int  DB_OK on success.  A DB_Error object on failure.
904
     * @return int  DB_OK on success.  A DB_Error object on failure.
897
     *
905
     *
898
     * @see DB_common::dropSequence(), DB_common::getSequenceName(),
906
     * @see DB_common::dropSequence(), DB_common::getSequenceName(),
899
     *      DB_oci8::nextID(), DB_oci8::createSequence()
907
     *      DB_oci8::nextID(), DB_oci8::createSequence()
900
     */
908
     */
901
    function dropSequence($seq_name)
909
    function dropSequence($seq_name)
902
    {
910
    {
903
        return $this->query('DROP SEQUENCE '
911
        return $this->query('DROP SEQUENCE '
904
                            . $this->getSequenceName($seq_name));
912
                            . $this->getSequenceName($seq_name));
905
    }
913
    }
906
 
914
 
907
    // }}}
915
    // }}}
908
    // {{{ oci8RaiseError()
916
    // {{{ oci8RaiseError()
909
 
917
 
910
    /**
918
    /**
911
     * Produces a DB_Error object regarding the current problem
919
     * Produces a DB_Error object regarding the current problem
912
     *
920
     *
913
     * @param int $errno  if the error is being manually raised pass a
921
     * @param int $errno  if the error is being manually raised pass a
914
     *                     DB_ERROR* constant here.  If this isn't passed
922
     *                     DB_ERROR* constant here.  If this isn't passed
915
     *                     the error information gathered from the DBMS.
923
     *                     the error information gathered from the DBMS.
916
     *
924
     *
917
     * @return object  the DB_Error object
925
     * @return object  the DB_Error object
918
     *
926
     *
919
     * @see DB_common::raiseError(),
927
     * @see DB_common::raiseError(),
920
     *      DB_oci8::errorNative(), DB_oci8::errorCode()
928
     *      DB_oci8::errorNative(), DB_oci8::errorCode()
921
     */
929
     */
922
    function oci8RaiseError($errno = null)
930
    function oci8RaiseError($errno = null)
923
    {
931
    {
924
        if ($errno === null) {
932
        if ($errno === null) {
925
            $error = @OCIError($this->connection);
933
            $error = @OCIError($this->connection);
926
            return $this->raiseError($this->errorCode($error['code']),
934
            return $this->raiseError($this->errorCode($error['code']),
927
                                     null, null, null, $error['message']);
935
                                     null, null, null, $error['message']);
928
        } elseif (is_resource($errno)) {
936
        } elseif (is_resource($errno)) {
929
            $error = @OCIError($errno);
937
            $error = @OCIError($errno);
930
            return $this->raiseError($this->errorCode($error['code']),
938
            return $this->raiseError($this->errorCode($error['code']),
931
                                     null, null, null, $error['message']);
939
                                     null, null, null, $error['message']);
932
        }
940
        }
933
        return $this->raiseError($this->errorCode($errno));
941
        return $this->raiseError($this->errorCode($errno));
934
    }
942
    }
935
 
943
 
936
    // }}}
944
    // }}}
937
    // {{{ errorNative()
945
    // {{{ errorNative()
938
 
946
 
939
    /**
947
    /**
940
     * Gets the DBMS' native error code produced by the last query
948
     * Gets the DBMS' native error code produced by the last query
941
     *
949
     *
942
     * @return int  the DBMS' error code.  FALSE if the code could not be
950
     * @return int  the DBMS' error code.  FALSE if the code could not be
943
     *               determined
951
     *               determined
944
     */
952
     */
945
    function errorNative()
953
    function errorNative()
946
    {
954
    {
947
        if (is_resource($this->last_stmt)) {
955
        if (is_resource($this->last_stmt)) {
948
            $error = @OCIError($this->last_stmt);
956
            $error = @OCIError($this->last_stmt);
949
        } else {
957
        } else {
950
            $error = @OCIError($this->connection);
958
            $error = @OCIError($this->connection);
951
        }
959
        }
952
        if (is_array($error)) {
960
        if (is_array($error)) {
953
            return $error['code'];
961
            return $error['code'];
954
        }
962
        }
955
        return false;
963
        return false;
956
    }
964
    }
957
 
965
 
958
    // }}}
966
    // }}}
959
    // {{{ tableInfo()
967
    // {{{ tableInfo()
960
 
968
 
961
    /**
969
    /**
962
     * Returns information about a table or a result set
970
     * Returns information about a table or a result set
963
     *
971
     *
964
     * NOTE: only supports 'table' and 'flags' if <var>$result</var>
972
     * NOTE: only supports 'table' and 'flags' if <var>$result</var>
965
     * is a table name.
973
     * is a table name.
966
     *
974
     *
967
     * NOTE: flags won't contain index information.
975
     * NOTE: flags won't contain index information.
968
     *
976
     *
969
     * @param object|string  $result  DB_result object from a query or a
977
     * @param object|string  $result  DB_result object from a query or a
970
     *                                 string containing the name of a table.
978
     *                                 string containing the name of a table.
971
     *                                 While this also accepts a query result
979
     *                                 While this also accepts a query result
972
     *                                 resource identifier, this behavior is
980
     *                                 resource identifier, this behavior is
973
     *                                 deprecated.
981
     *                                 deprecated.
974
     * @param int            $mode    a valid tableInfo mode
982
     * @param int            $mode    a valid tableInfo mode
975
     *
983
     *
976
     * @return array  an associative array with the information requested.
984
     * @return array  an associative array with the information requested.
977
     *                 A DB_Error object on failure.
985
     *                 A DB_Error object on failure.
978
     *
986
     *
979
     * @see DB_common::tableInfo()
987
     * @see DB_common::tableInfo()
980
     */
988
     */
981
    function tableInfo($result, $mode = null)
989
    function tableInfo($result, $mode = null)
982
    {
990
    {
983
        if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
991
        if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
984
            $case_func = 'strtolower';
992
            $case_func = 'strtolower';
985
        } else {
993
        } else {
986
            $case_func = 'strval';
994
            $case_func = 'strval';
987
        }
995
        }
988
 
996
 
989
        $res = array();
997
        $res = array();
990
 
998
 
991
        if (is_string($result)) {
999
        if (is_string($result)) {
992
            /*
1000
            /*
993
             * Probably received a table name.
1001
             * Probably received a table name.
994
             * Create a result resource identifier.
1002
             * Create a result resource identifier.
995
             */
1003
             */
996
            $result = strtoupper($result);
1004
            $result = strtoupper($result);
997
            $q_fields = 'SELECT column_name, data_type, data_length, '
1005
            $q_fields = 'SELECT column_name, data_type, data_length, '
998
                        . 'nullable '
1006
                        . 'nullable '
999
                        . 'FROM user_tab_columns '
1007
                        . 'FROM user_tab_columns '
1000
                        . "WHERE table_name='$result' ORDER BY column_id";
1008
                        . "WHERE table_name='$result' ORDER BY column_id";
1001
 
1009
 
1002
            $this->last_query = $q_fields;
1010
            $this->last_query = $q_fields;
1003
 
1011
 
1004
            if (!$stmt = @OCIParse($this->connection, $q_fields)) {
1012
            if (!$stmt = @OCIParse($this->connection, $q_fields)) {
1005
                return $this->oci8RaiseError(DB_ERROR_NEED_MORE_DATA);
1013
                return $this->oci8RaiseError(DB_ERROR_NEED_MORE_DATA);
1006
            }
1014
            }
1007
            if (!@OCIExecute($stmt, OCI_DEFAULT)) {
1015
            if (!@OCIExecute($stmt, OCI_DEFAULT)) {
1008
                return $this->oci8RaiseError($stmt);
1016
                return $this->oci8RaiseError($stmt);
1009
            }
1017
            }
1010
 
1018
 
1011
            $i = 0;
1019
            $i = 0;
1012
            while (@OCIFetch($stmt)) {
1020
            while (@OCIFetch($stmt)) {
1013
                $res[$i] = array(
1021
                $res[$i] = array(
1014
                    'table' => $case_func($result),
1022
                    'table' => $case_func($result),
1015
                    'name'  => $case_func(@OCIResult($stmt, 1)),
1023
                    'name'  => $case_func(@OCIResult($stmt, 1)),
1016
                    'type'  => @OCIResult($stmt, 2),
1024
                    'type'  => @OCIResult($stmt, 2),
1017
                    'len'   => @OCIResult($stmt, 3),
1025
                    'len'   => @OCIResult($stmt, 3),
1018
                    'flags' => (@OCIResult($stmt, 4) == 'N') ? 'not_null' : '',
1026
                    'flags' => (@OCIResult($stmt, 4) == 'N') ? 'not_null' : '',
1019
                );
1027
                );
1020
                if ($mode & DB_TABLEINFO_ORDER) {
1028
                if ($mode & DB_TABLEINFO_ORDER) {
1021
                    $res['order'][$res[$i]['name']] = $i;
1029
                    $res['order'][$res[$i]['name']] = $i;
1022
                }
1030
                }
1023
                if ($mode & DB_TABLEINFO_ORDERTABLE) {
1031
                if ($mode & DB_TABLEINFO_ORDERTABLE) {
1024
                    $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
1032
                    $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
1025
                }
1033
                }
1026
                $i++;
1034
                $i++;
1027
            }
1035
            }
1028
 
1036
 
1029
            if ($mode) {
1037
            if ($mode) {
1030
                $res['num_fields'] = $i;
1038
                $res['num_fields'] = $i;
1031
            }
1039
            }
1032
            @OCIFreeStatement($stmt);
1040
            @OCIFreeStatement($stmt);
1033
 
1041
 
1034
        } else {
1042
        } else {
1035
            if (isset($result->result)) {
1043
            if (isset($result->result)) {
1036
                /*
1044
                /*
1037
                 * Probably received a result object.
1045
                 * Probably received a result object.
1038
                 * Extract the result resource identifier.
1046
                 * Extract the result resource identifier.
1039
                 */
1047
                 */
1040
                $result = $result->result;
1048
                $result = $result->result;
1041
            }
1049
            }
1042
 
1050
 
1043
            $res = array();
1051
            $res = array();
1044
 
1052
 
1045
            if ($result === $this->last_stmt) {
1053
            if ($result === $this->last_stmt) {
1046
                $count = @OCINumCols($result);
1054
                $count = @OCINumCols($result);
1047
                if ($mode) {
1055
                if ($mode) {
1048
                    $res['num_fields'] = $count;
1056
                    $res['num_fields'] = $count;
1049
                }
1057
                }
1050
                for ($i = 0; $i < $count; $i++) {
1058
                for ($i = 0; $i < $count; $i++) {
1051
                    $res[$i] = array(
1059
                    $res[$i] = array(
1052
                        'table' => '',
1060
                        'table' => '',
1053
                        'name'  => $case_func(@OCIColumnName($result, $i+1)),
1061
                        'name'  => $case_func(@OCIColumnName($result, $i+1)),
1054
                        'type'  => @OCIColumnType($result, $i+1),
1062
                        'type'  => @OCIColumnType($result, $i+1),
1055
                        'len'   => @OCIColumnSize($result, $i+1),
1063
                        'len'   => @OCIColumnSize($result, $i+1),
1056
                        'flags' => '',
1064
                        'flags' => '',
1057
                    );
1065
                    );
1058
                    if ($mode & DB_TABLEINFO_ORDER) {
1066
                    if ($mode & DB_TABLEINFO_ORDER) {
1059
                        $res['order'][$res[$i]['name']] = $i;
1067
                        $res['order'][$res[$i]['name']] = $i;
1060
                    }
1068
                    }
1061
                    if ($mode & DB_TABLEINFO_ORDERTABLE) {
1069
                    if ($mode & DB_TABLEINFO_ORDERTABLE) {
1062
                        $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
1070
                        $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
1063
                    }
1071
                    }
1064
                }
1072
                }
1065
            } else {
1073
            } else {
1066
                return $this->raiseError(DB_ERROR_NOT_CAPABLE);
1074
                return $this->raiseError(DB_ERROR_NOT_CAPABLE);
1067
            }
1075
            }
1068
        }
1076
        }
1069
        return $res;
1077
        return $res;
1070
    }
1078
    }
1071
 
1079
 
1072
    // }}}
1080
    // }}}
1073
    // {{{ getSpecialQuery()
1081
    // {{{ getSpecialQuery()
1074
 
1082
 
1075
    /**
1083
    /**
1076
     * Obtains the query string needed for listing a given type of objects
1084
     * Obtains the query string needed for listing a given type of objects
1077
     *
1085
     *
1078
     * @param string $type  the kind of objects you want to retrieve
1086
     * @param string $type  the kind of objects you want to retrieve
1079
     *
1087
     *
1080
     * @return string  the SQL query string or null if the driver doesn't
1088
     * @return string  the SQL query string or null if the driver doesn't
1081
     *                  support the object type requested
1089
     *                  support the object type requested
1082
     *
1090
     *
1083
     * @access protected
1091
     * @access protected
1084
     * @see DB_common::getListOf()
1092
     * @see DB_common::getListOf()
1085
     */
1093
     */
1086
    function getSpecialQuery($type)
1094
    function getSpecialQuery($type)
1087
    {
1095
    {
1088
        switch ($type) {
1096
        switch ($type) {
1089
            case 'tables':
1097
            case 'tables':
1090
                return 'SELECT table_name FROM user_tables';
1098
                return 'SELECT table_name FROM user_tables';
1091
            case 'synonyms':
1099
            case 'synonyms':
1092
                return 'SELECT synonym_name FROM user_synonyms';
1100
                return 'SELECT synonym_name FROM user_synonyms';
1093
            default:
1101
            default:
1094
                return null;
1102
                return null;
1095
        }
1103
        }
1096
    }
1104
    }
1097
 
1105
 
1098
    // }}}
1106
    // }}}
1099
 
1107
 
1100
}
1108
}
1101
 
1109
 
1102
/*
1110
/*
1103
 * Local variables:
1111
 * Local variables:
1104
 * tab-width: 4
1112
 * tab-width: 4
1105
 * c-basic-offset: 4
1113
 * c-basic-offset: 4
1106
 * End:
1114
 * End:
1107
 */
1115
 */
1108
 
1116
 
1109
?>
1117
?>