Subversion Repositories Applications.gtt

Rev

Rev 94 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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