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 mysqli extension
6
 * The PEAR DB driver for PHP's mysqli extension
7
 * for interacting with MySQL databases
7
 * for interacting with MySQL databases
8
 *
8
 *
9
 * PHP versions 4 and 5
9
 * PHP version 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     Daniel Convissor <danielc@php.net>
19
 * @author     Daniel Convissor <danielc@php.net>
20
 * @copyright  1997-2005 The PHP Group
20
 * @copyright  1997-2007 The PHP Group
21
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
21
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
22
 * @version    CVS: $Id: mysqli.php,v 1.69 2005/03/04 23:12:36 danielc Exp $
22
 * @version    CVS: $Id$
23
 * @link       http://pear.php.net/package/DB
23
 * @link       http://pear.php.net/package/DB
24
 */
24
 */
25
 
25
 
26
/**
26
/**
27
 * Obtain the DB_common class so it can be extended from
27
 * Obtain the DB_common class so it can be extended from
28
 */
28
 */
29
require_once 'DB/common.php';
29
require_once 'DB/common.php';
30
 
30
 
31
/**
31
/**
32
 * The methods PEAR DB uses to interact with PHP's mysqli extension
32
 * The methods PEAR DB uses to interact with PHP's mysqli extension
33
 * for interacting with MySQL databases
33
 * for interacting with MySQL databases
34
 *
34
 *
35
 * This is for MySQL versions 4.1 and above.  Requires PHP 5.
35
 * This is for MySQL versions 4.1 and above.  Requires PHP 5.
36
 *
36
 *
37
 * Note that persistent connections no longer exist.
37
 * Note that persistent connections no longer exist.
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
 * @category   Database
41
 * @category   Database
42
 * @package    DB
42
 * @package    DB
43
 * @author     Daniel Convissor <danielc@php.net>
43
 * @author     Daniel Convissor <danielc@php.net>
44
 * @copyright  1997-2005 The PHP Group
44
 * @copyright  1997-2007 The PHP Group
45
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
45
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
46
 * @version    Release: 1.7.6
46
 * @version    Release: 1.9.2
47
 * @link       http://pear.php.net/package/DB
47
 * @link       http://pear.php.net/package/DB
48
 * @since      Class functional since Release 1.6.3
48
 * @since      Class functional since Release 1.6.3
49
 */
49
 */
50
class DB_mysqli extends DB_common
50
class DB_mysqli extends DB_common
51
{
51
{
52
    // {{{ properties
52
    // {{{ properties
53
 
53
 
54
    /**
54
    /**
55
     * The DB driver type (mysql, oci8, odbc, etc.)
55
     * The DB driver type (mysql, oci8, odbc, etc.)
56
     * @var string
56
     * @var string
57
     */
57
     */
58
    var $phptype = 'mysqli';
58
    var $phptype = 'mysqli';
59
 
59
 
60
    /**
60
    /**
61
     * The database syntax variant to be used (db2, access, etc.), if any
61
     * The database syntax variant to be used (db2, access, etc.), if any
62
     * @var string
62
     * @var string
63
     */
63
     */
64
    var $dbsyntax = 'mysqli';
64
    var $dbsyntax = 'mysqli';
65
 
65
 
66
    /**
66
    /**
67
     * The capabilities of this DB implementation
67
     * The capabilities of this DB implementation
68
     *
68
     *
69
     * The 'new_link' element contains the PHP version that first provided
69
     * The 'new_link' element contains the PHP version that first provided
70
     * new_link support for this DBMS.  Contains false if it's unsupported.
70
     * new_link support for this DBMS.  Contains false if it's unsupported.
71
     *
71
     *
72
     * Meaning of the 'limit' element:
72
     * Meaning of the 'limit' element:
73
     *   + 'emulate' = emulate with fetch row by number
73
     *   + 'emulate' = emulate with fetch row by number
74
     *   + 'alter'   = alter the query
74
     *   + 'alter'   = alter the query
75
     *   + false     = skip rows
75
     *   + false     = skip rows
76
     *
76
     *
77
     * @var array
77
     * @var array
78
     */
78
     */
79
    var $features = array(
79
    var $features = array(
80
        'limit'         => 'alter',
80
        'limit'         => 'alter',
81
        'new_link'      => false,
81
        'new_link'      => false,
82
        'numrows'       => true,
82
        'numrows'       => true,
83
        'pconnect'      => false,
83
        'pconnect'      => false,
84
        'prepare'       => false,
84
        'prepare'       => false,
85
        'ssl'           => true,
85
        'ssl'           => true,
86
        'transactions'  => true,
86
        'transactions'  => true,
87
    );
87
    );
88
 
88
 
89
    /**
89
    /**
90
     * A mapping of native error codes to DB error codes
90
     * A mapping of native error codes to DB error codes
91
     * @var array
91
     * @var array
92
     */
92
     */
93
    var $errorcode_map = array(
93
    var $errorcode_map = array(
94
        1004 => DB_ERROR_CANNOT_CREATE,
94
        1004 => DB_ERROR_CANNOT_CREATE,
95
        1005 => DB_ERROR_CANNOT_CREATE,
95
        1005 => DB_ERROR_CANNOT_CREATE,
96
        1006 => DB_ERROR_CANNOT_CREATE,
96
        1006 => DB_ERROR_CANNOT_CREATE,
97
        1007 => DB_ERROR_ALREADY_EXISTS,
97
        1007 => DB_ERROR_ALREADY_EXISTS,
98
        1008 => DB_ERROR_CANNOT_DROP,
98
        1008 => DB_ERROR_CANNOT_DROP,
99
        1022 => DB_ERROR_ALREADY_EXISTS,
99
        1022 => DB_ERROR_ALREADY_EXISTS,
100
        1044 => DB_ERROR_ACCESS_VIOLATION,
100
        1044 => DB_ERROR_ACCESS_VIOLATION,
101
        1046 => DB_ERROR_NODBSELECTED,
101
        1046 => DB_ERROR_NODBSELECTED,
102
        1048 => DB_ERROR_CONSTRAINT,
102
        1048 => DB_ERROR_CONSTRAINT,
103
        1049 => DB_ERROR_NOSUCHDB,
103
        1049 => DB_ERROR_NOSUCHDB,
104
        1050 => DB_ERROR_ALREADY_EXISTS,
104
        1050 => DB_ERROR_ALREADY_EXISTS,
105
        1051 => DB_ERROR_NOSUCHTABLE,
105
        1051 => DB_ERROR_NOSUCHTABLE,
106
        1054 => DB_ERROR_NOSUCHFIELD,
106
        1054 => DB_ERROR_NOSUCHFIELD,
107
        1061 => DB_ERROR_ALREADY_EXISTS,
107
        1061 => DB_ERROR_ALREADY_EXISTS,
108
        1062 => DB_ERROR_ALREADY_EXISTS,
108
        1062 => DB_ERROR_ALREADY_EXISTS,
109
        1064 => DB_ERROR_SYNTAX,
109
        1064 => DB_ERROR_SYNTAX,
110
        1091 => DB_ERROR_NOT_FOUND,
110
        1091 => DB_ERROR_NOT_FOUND,
111
        1100 => DB_ERROR_NOT_LOCKED,
111
        1100 => DB_ERROR_NOT_LOCKED,
112
        1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
112
        1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
113
        1142 => DB_ERROR_ACCESS_VIOLATION,
113
        1142 => DB_ERROR_ACCESS_VIOLATION,
114
        1146 => DB_ERROR_NOSUCHTABLE,
114
        1146 => DB_ERROR_NOSUCHTABLE,
115
        1216 => DB_ERROR_CONSTRAINT,
115
        1216 => DB_ERROR_CONSTRAINT,
116
        1217 => DB_ERROR_CONSTRAINT,
116
        1217 => DB_ERROR_CONSTRAINT,
-
 
117
        1356 => DB_ERROR_DIVZERO,
-
 
118
        1451 => DB_ERROR_CONSTRAINT,
-
 
119
        1452 => DB_ERROR_CONSTRAINT,
117
    );
120
    );
118
 
121
 
119
    /**
122
    /**
120
     * The raw database connection created by PHP
123
     * The raw database connection created by PHP
121
     * @var resource
124
     * @var resource
122
     */
125
     */
123
    var $connection;
126
    var $connection;
124
 
127
 
125
    /**
128
    /**
126
     * The DSN information for connecting to a database
129
     * The DSN information for connecting to a database
127
     * @var array
130
     * @var array
128
     */
131
     */
129
    var $dsn = array();
132
    var $dsn = array();
130
 
133
 
131
 
134
 
132
    /**
135
    /**
133
     * Should data manipulation queries be committed automatically?
136
     * Should data manipulation queries be committed automatically?
134
     * @var bool
137
     * @var bool
135
     * @access private
138
     * @access private
136
     */
139
     */
137
    var $autocommit = true;
140
    var $autocommit = true;
138
 
141
 
139
    /**
142
    /**
140
     * The quantity of transactions begun
143
     * The quantity of transactions begun
141
     *
144
     *
142
     * {@internal  While this is private, it can't actually be designated
145
     * {@internal  While this is private, it can't actually be designated
143
     * private in PHP 5 because it is directly accessed in the test suite.}}
146
     * private in PHP 5 because it is directly accessed in the test suite.}}
144
     *
147
     *
145
     * @var integer
148
     * @var integer
146
     * @access private
149
     * @access private
147
     */
150
     */
148
    var $transaction_opcount = 0;
151
    var $transaction_opcount = 0;
149
 
152
 
150
    /**
153
    /**
151
     * The database specified in the DSN
154
     * The database specified in the DSN
152
     *
155
     *
153
     * It's a fix to allow calls to different databases in the same script.
156
     * It's a fix to allow calls to different databases in the same script.
154
     *
157
     *
155
     * @var string
158
     * @var string
156
     * @access private
159
     * @access private
157
     */
160
     */
158
    var $_db = '';
161
    var $_db = '';
159
 
162
 
160
    /**
163
    /**
161
     * Array for converting MYSQLI_*_FLAG constants to text values
164
     * Array for converting MYSQLI_*_FLAG constants to text values
162
     * @var    array
165
     * @var    array
163
     * @access public
166
     * @access public
164
     * @since  Property available since Release 1.6.5
167
     * @since  Property available since Release 1.6.5
165
     */
168
     */
166
    var $mysqli_flags = array(
169
    var $mysqli_flags = array(
167
        MYSQLI_NOT_NULL_FLAG        => 'not_null',
170
        MYSQLI_NOT_NULL_FLAG        => 'not_null',
168
        MYSQLI_PRI_KEY_FLAG         => 'primary_key',
171
        MYSQLI_PRI_KEY_FLAG         => 'primary_key',
169
        MYSQLI_UNIQUE_KEY_FLAG      => 'unique_key',
172
        MYSQLI_UNIQUE_KEY_FLAG      => 'unique_key',
170
        MYSQLI_MULTIPLE_KEY_FLAG    => 'multiple_key',
173
        MYSQLI_MULTIPLE_KEY_FLAG    => 'multiple_key',
171
        MYSQLI_BLOB_FLAG            => 'blob',
174
        MYSQLI_BLOB_FLAG            => 'blob',
172
        MYSQLI_UNSIGNED_FLAG        => 'unsigned',
175
        MYSQLI_UNSIGNED_FLAG        => 'unsigned',
173
        MYSQLI_ZEROFILL_FLAG        => 'zerofill',
176
        MYSQLI_ZEROFILL_FLAG        => 'zerofill',
174
        MYSQLI_AUTO_INCREMENT_FLAG  => 'auto_increment',
177
        MYSQLI_AUTO_INCREMENT_FLAG  => 'auto_increment',
175
        MYSQLI_TIMESTAMP_FLAG       => 'timestamp',
178
        MYSQLI_TIMESTAMP_FLAG       => 'timestamp',
176
        MYSQLI_SET_FLAG             => 'set',
179
        MYSQLI_SET_FLAG             => 'set',
177
        // MYSQLI_NUM_FLAG             => 'numeric',  // unnecessary
180
        // MYSQLI_NUM_FLAG             => 'numeric',  // unnecessary
178
        // MYSQLI_PART_KEY_FLAG        => 'multiple_key',  // duplicatvie
181
        // MYSQLI_PART_KEY_FLAG        => 'multiple_key',  // duplicatvie
179
        MYSQLI_GROUP_FLAG           => 'group_by'
182
        MYSQLI_GROUP_FLAG           => 'group_by'
180
    );
183
    );
181
 
184
 
182
    /**
185
    /**
183
     * Array for converting MYSQLI_TYPE_* constants to text values
186
     * Array for converting MYSQLI_TYPE_* constants to text values
184
     * @var    array
187
     * @var    array
185
     * @access public
188
     * @access public
186
     * @since  Property available since Release 1.6.5
189
     * @since  Property available since Release 1.6.5
187
     */
190
     */
188
    var $mysqli_types = array(
191
    var $mysqli_types = array(
189
        MYSQLI_TYPE_DECIMAL     => 'decimal',
192
        MYSQLI_TYPE_DECIMAL     => 'decimal',
190
        MYSQLI_TYPE_TINY        => 'tinyint',
193
        MYSQLI_TYPE_TINY        => 'tinyint',
191
        MYSQLI_TYPE_SHORT       => 'int',
194
        MYSQLI_TYPE_SHORT       => 'int',
192
        MYSQLI_TYPE_LONG        => 'int',
195
        MYSQLI_TYPE_LONG        => 'int',
193
        MYSQLI_TYPE_FLOAT       => 'float',
196
        MYSQLI_TYPE_FLOAT       => 'float',
194
        MYSQLI_TYPE_DOUBLE      => 'double',
197
        MYSQLI_TYPE_DOUBLE      => 'double',
195
        // MYSQLI_TYPE_NULL        => 'DEFAULT NULL',  // let flags handle it
198
        // MYSQLI_TYPE_NULL        => 'DEFAULT NULL',  // let flags handle it
196
        MYSQLI_TYPE_TIMESTAMP   => 'timestamp',
199
        MYSQLI_TYPE_TIMESTAMP   => 'timestamp',
197
        MYSQLI_TYPE_LONGLONG    => 'bigint',
200
        MYSQLI_TYPE_LONGLONG    => 'bigint',
198
        MYSQLI_TYPE_INT24       => 'mediumint',
201
        MYSQLI_TYPE_INT24       => 'mediumint',
199
        MYSQLI_TYPE_DATE        => 'date',
202
        MYSQLI_TYPE_DATE        => 'date',
200
        MYSQLI_TYPE_TIME        => 'time',
203
        MYSQLI_TYPE_TIME        => 'time',
201
        MYSQLI_TYPE_DATETIME    => 'datetime',
204
        MYSQLI_TYPE_DATETIME    => 'datetime',
202
        MYSQLI_TYPE_YEAR        => 'year',
205
        MYSQLI_TYPE_YEAR        => 'year',
203
        MYSQLI_TYPE_NEWDATE     => 'date',
206
        MYSQLI_TYPE_NEWDATE     => 'date',
204
        MYSQLI_TYPE_ENUM        => 'enum',
207
        MYSQLI_TYPE_ENUM        => 'enum',
205
        MYSQLI_TYPE_SET         => 'set',
208
        MYSQLI_TYPE_SET         => 'set',
206
        MYSQLI_TYPE_TINY_BLOB   => 'tinyblob',
209
        MYSQLI_TYPE_TINY_BLOB   => 'tinyblob',
207
        MYSQLI_TYPE_MEDIUM_BLOB => 'mediumblob',
210
        MYSQLI_TYPE_MEDIUM_BLOB => 'mediumblob',
208
        MYSQLI_TYPE_LONG_BLOB   => 'longblob',
211
        MYSQLI_TYPE_LONG_BLOB   => 'longblob',
209
        MYSQLI_TYPE_BLOB        => 'blob',
212
        MYSQLI_TYPE_BLOB        => 'blob',
210
        MYSQLI_TYPE_VAR_STRING  => 'varchar',
213
        MYSQLI_TYPE_VAR_STRING  => 'varchar',
211
        MYSQLI_TYPE_STRING      => 'char',
214
        MYSQLI_TYPE_STRING      => 'char',
212
        MYSQLI_TYPE_GEOMETRY    => 'geometry',
215
        MYSQLI_TYPE_GEOMETRY    => 'geometry',
-
 
216
        /* These constants are conditionally compiled in ext/mysqli, so we'll
-
 
217
         * define them by number rather than constant. */
-
 
218
        16                      => 'bit',
-
 
219
        246                     => 'decimal',
213
    );
220
    );
214
 
221
 
215
 
222
 
216
    // }}}
223
    // }}}
217
    // {{{ constructor
224
    // {{{ constructor
218
 
225
 
219
    /**
226
    /**
220
     * This constructor calls <kbd>$this->DB_common()</kbd>
227
     * This constructor calls <kbd>parent::__construct()</kbd>
221
     *
228
     *
222
     * @return void
229
     * @return void
223
     */
230
     */
224
    function DB_mysqli()
231
    function __construct()
225
    {
232
    {
226
        $this->DB_common();
233
        parent::__construct();
227
    }
234
    }
228
 
235
 
229
    // }}}
236
    // }}}
230
    // {{{ connect()
237
    // {{{ connect()
231
 
238
 
232
    /**
239
    /**
233
     * Connect to the database server, log in and open the database
240
     * Connect to the database server, log in and open the database
234
     *
241
     *
235
     * Don't call this method directly.  Use DB::connect() instead.
242
     * Don't call this method directly.  Use DB::connect() instead.
236
     *
243
     *
237
     * PEAR DB's mysqli driver supports the following extra DSN options:
244
     * PEAR DB's mysqli driver supports the following extra DSN options:
238
     *   + When the 'ssl' $option passed to DB::connect() is true:
245
     *   + When the 'ssl' $option passed to DB::connect() is true:
239
     *     + key      The path to the key file.
246
     *     + key      The path to the key file.
240
     *     + cert     The path to the certificate file.
247
     *     + cert     The path to the certificate file.
241
     *     + ca       The path to the certificate authority file.
248
     *     + ca       The path to the certificate authority file.
242
     *     + capath   The path to a directory that contains trusted SSL
249
     *     + capath   The path to a directory that contains trusted SSL
243
     *                 CA certificates in pem format.
250
     *                 CA certificates in pem format.
244
     *     + cipher   The list of allowable ciphers for SSL encryption.
251
     *     + cipher   The list of allowable ciphers for SSL encryption.
245
     *
252
     *
246
     * Example of how to connect using SSL:
253
     * Example of how to connect using SSL:
247
     * <code>
254
     * <code>
248
     * require_once 'DB.php';
255
     * require_once 'DB.php';
249
     * 
256
     * 
250
     * $dsn = array(
257
     * $dsn = array(
251
     *     'phptype'  => 'mysqli',
258
     *     'phptype'  => 'mysqli',
252
     *     'username' => 'someuser',
259
     *     'username' => 'someuser',
253
     *     'password' => 'apasswd',
260
     *     'password' => 'apasswd',
254
     *     'hostspec' => 'localhost',
261
     *     'hostspec' => 'localhost',
255
     *     'database' => 'thedb',
262
     *     'database' => 'thedb',
256
     *     'key'      => 'client-key.pem',
263
     *     'key'      => 'client-key.pem',
257
     *     'cert'     => 'client-cert.pem',
264
     *     'cert'     => 'client-cert.pem',
258
     *     'ca'       => 'cacert.pem',
265
     *     'ca'       => 'cacert.pem',
259
     *     'capath'   => '/path/to/ca/dir',
266
     *     'capath'   => '/path/to/ca/dir',
260
     *     'cipher'   => 'AES',
267
     *     'cipher'   => 'AES',
261
     * );
268
     * );
262
     * 
269
     * 
263
     * $options = array(
270
     * $options = array(
264
     *     'ssl' => true,
271
     *     'ssl' => true,
265
     * );
272
     * );
266
     * 
273
     * 
267
     * $db =& DB::connect($dsn, $options);
274
     * $db = DB::connect($dsn, $options);
268
     * if (PEAR::isError($db)) {
275
     * if (PEAR::isError($db)) {
269
     *     die($db->getMessage());
276
     *     die($db->getMessage());
270
     * }
277
     * }
271
     * </code>
278
     * </code>
272
     *
279
     *
273
     * @param array $dsn         the data source name
280
     * @param array $dsn         the data source name
274
     * @param bool  $persistent  should the connection be persistent?
281
     * @param bool  $persistent  should the connection be persistent?
275
     *
282
     *
276
     * @return int  DB_OK on success. A DB_Error object on failure.
283
     * @return int  DB_OK on success. A DB_Error object on failure.
277
     */
284
     */
278
    function connect($dsn, $persistent = false)
285
    function connect($dsn, $persistent = false)
279
    {
286
    {
280
        if (!PEAR::loadExtension('mysqli')) {
287
        if (!PEAR::loadExtension('mysqli')) {
281
            return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
288
            return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
282
        }
289
        }
283
 
290
 
284
        $this->dsn = $dsn;
291
        $this->dsn = $dsn;
285
        if ($dsn['dbsyntax']) {
292
        if ($dsn['dbsyntax']) {
286
            $this->dbsyntax = $dsn['dbsyntax'];
293
            $this->dbsyntax = $dsn['dbsyntax'];
287
        }
294
        }
288
 
295
 
289
        $ini = ini_get('track_errors');
296
        $ini = ini_get('track_errors');
290
        ini_set('track_errors', 1);
297
        @ini_set('track_errors', 1);
291
        $php_errormsg = '';
298
        $php_errormsg = '';
292
 
299
 
293
        if ($this->getOption('ssl') === true) {
300
        if (((int) $this->getOption('ssl')) === 1) {
294
            $init = mysqli_init();
301
            $init = mysqli_init();
295
            mysqli_ssl_set(
302
            mysqli_ssl_set(
296
                $init,
303
                $init,
297
                empty($dsn['key'])    ? null : $dsn['key'],
304
                empty($dsn['key'])    ? null : $dsn['key'],
298
                empty($dsn['cert'])   ? null : $dsn['cert'],
305
                empty($dsn['cert'])   ? null : $dsn['cert'],
299
                empty($dsn['ca'])     ? null : $dsn['ca'],
306
                empty($dsn['ca'])     ? null : $dsn['ca'],
300
                empty($dsn['capath']) ? null : $dsn['capath'],
307
                empty($dsn['capath']) ? null : $dsn['capath'],
301
                empty($dsn['cipher']) ? null : $dsn['cipher']
308
                empty($dsn['cipher']) ? null : $dsn['cipher']
302
            );
309
            );
303
            if ($this->connection = @mysqli_real_connect(
310
            if ($this->connection = @mysqli_real_connect(
304
                    $init,
311
                    $init,
305
                    $dsn['hostspec'],
312
                    $dsn['hostspec'],
306
                    $dsn['username'],
313
                    $dsn['username'],
307
                    $dsn['password'],
314
                    $dsn['password'],
308
                    $dsn['database'],
315
                    $dsn['database'],
309
                    $dsn['port'],
316
                    $dsn['port'],
310
                    $dsn['socket']))
317
                    $dsn['socket']))
311
            {
318
            {
312
                $this->connection = $init;
319
                $this->connection = $init;
313
            }
320
            }
314
        } else {
321
        } else {
315
            $this->connection = @mysqli_connect(
322
            $this->connection = @mysqli_connect(
316
                $dsn['hostspec'],
323
                $dsn['hostspec'],
317
                $dsn['username'],
324
                $dsn['username'],
318
                $dsn['password'],
325
                $dsn['password'],
319
                $dsn['database'],
326
                $dsn['database'],
320
                $dsn['port'],
327
                $dsn['port'],
321
                $dsn['socket']
328
                $dsn['socket']
322
            );
329
            );
323
        }
330
        }
324
 
331
 
325
        ini_set('track_errors', $ini);
332
        @ini_set('track_errors', $ini);
326
 
333
 
327
        if (!$this->connection) {
334
        if (!$this->connection) {
328
            if (($err = @mysqli_connect_error()) != '') {
335
            if (($err = @mysqli_connect_error()) != '') {
329
                return $this->raiseError(DB_ERROR_CONNECT_FAILED,
336
                return $this->raiseError(DB_ERROR_CONNECT_FAILED,
330
                                         null, null, null,
337
                                         null, null, null,
331
                                         $err);
338
                                         $err);
332
            } else {
339
            } else {
333
                return $this->raiseError(DB_ERROR_CONNECT_FAILED,
340
                return $this->raiseError(DB_ERROR_CONNECT_FAILED,
334
                                         null, null, null,
341
                                         null, null, null,
335
                                         $php_errormsg);
342
                                         $php_errormsg);
336
            }
343
            }
337
        }
344
        }
338
 
345
 
339
        if ($dsn['database']) {
346
        if ($dsn['database']) {
340
            $this->_db = $dsn['database'];
347
            $this->_db = $dsn['database'];
341
        }
348
        }
342
 
349
 
343
        return DB_OK;
350
        return DB_OK;
344
    }
351
    }
345
 
352
 
346
    // }}}
353
    // }}}
347
    // {{{ disconnect()
354
    // {{{ disconnect()
348
 
355
 
349
    /**
356
    /**
350
     * Disconnects from the database server
357
     * Disconnects from the database server
351
     *
358
     *
352
     * @return bool  TRUE on success, FALSE on failure
359
     * @return bool  TRUE on success, FALSE on failure
353
     */
360
     */
354
    function disconnect()
361
    function disconnect()
355
    {
362
    {
356
        $ret = @mysqli_close($this->connection);
363
        $ret = @mysqli_close($this->connection);
357
        $this->connection = null;
364
        $this->connection = null;
358
        return $ret;
365
        return $ret;
359
    }
366
    }
360
 
367
 
361
    // }}}
368
    // }}}
362
    // {{{ simpleQuery()
369
    // {{{ simpleQuery()
363
 
370
 
364
    /**
371
    /**
365
     * Sends a query to the database server
372
     * Sends a query to the database server
366
     *
373
     *
367
     * @param string  the SQL query string
374
     * @param string  the SQL query string
368
     *
375
     *
369
     * @return mixed  + a PHP result resrouce for successful SELECT queries
376
     * @return mixed  + a PHP result resrouce for successful SELECT queries
370
     *                + the DB_OK constant for other successful queries
377
     *                + the DB_OK constant for other successful queries
371
     *                + a DB_Error object on failure
378
     *                + a DB_Error object on failure
372
     */
379
     */
373
    function simpleQuery($query)
380
    function simpleQuery($query)
374
    {
381
    {
375
        $ismanip = DB::isManip($query);
382
        $ismanip = $this->_checkManip($query);
376
        $this->last_query = $query;
383
        $this->last_query = $query;
377
        $query = $this->modifyQuery($query);
384
        $query = $this->modifyQuery($query);
378
        if ($this->_db) {
385
        if ($this->_db) {
379
            if (!@mysqli_select_db($this->connection, $this->_db)) {
386
            if (!@mysqli_select_db($this->connection, $this->_db)) {
380
                return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
387
                return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
381
            }
388
            }
382
        }
389
        }
383
        if (!$this->autocommit && $ismanip) {
390
        if (!$this->autocommit && $ismanip) {
384
            if ($this->transaction_opcount == 0) {
391
            if ($this->transaction_opcount == 0) {
385
                $result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=0');
392
                $result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=0');
386
                $result = @mysqli_query($this->connection, 'BEGIN');
393
                $result = @mysqli_query($this->connection, 'BEGIN');
387
                if (!$result) {
394
                if (!$result) {
388
                    return $this->mysqliRaiseError();
395
                    return $this->mysqliRaiseError();
389
                }
396
                }
390
            }
397
            }
391
            $this->transaction_opcount++;
398
            $this->transaction_opcount++;
392
        }
399
        }
393
        $result = @mysqli_query($this->connection, $query);
400
        $result = @mysqli_query($this->connection, $query);
394
        if (!$result) {
401
        if (!$result) {
395
            return $this->mysqliRaiseError();
402
            return $this->mysqliRaiseError();
396
        }
403
        }
397
        if (is_object($result)) {
404
        if (is_object($result)) {
398
            return $result;
405
            return $result;
399
        }
406
        }
400
        return DB_OK;
407
        return DB_OK;
401
    }
408
    }
402
 
409
 
403
    // }}}
410
    // }}}
404
    // {{{ nextResult()
411
    // {{{ nextResult()
405
 
412
 
406
    /**
413
    /**
407
     * Move the internal mysql result pointer to the next available result.
414
     * Move the internal mysql result pointer to the next available result.
408
     *
415
     *
409
     * This method has not been implemented yet.
416
     * This method has not been implemented yet.
410
     *
417
     *
411
     * @param resource $result a valid sql result resource
418
     * @param resource $result a valid sql result resource
412
     * @return false
419
     * @return false
413
     * @access public
420
     * @access public
414
     */
421
     */
415
    function nextResult($result)
422
    function nextResult($result)
416
    {
423
    {
417
        return false;
424
        return false;
418
    }
425
    }
419
 
426
 
420
    // }}}
427
    // }}}
421
    // {{{ fetchInto()
428
    // {{{ fetchInto()
422
 
429
 
423
    /**
430
    /**
424
     * Places a row from the result set into the given array
431
     * Places a row from the result set into the given array
425
     *
432
     *
426
     * Formating of the array and the data therein are configurable.
433
     * Formating of the array and the data therein are configurable.
427
     * See DB_result::fetchInto() for more information.
434
     * See DB_result::fetchInto() for more information.
428
     *
435
     *
429
     * This method is not meant to be called directly.  Use
436
     * This method is not meant to be called directly.  Use
430
     * DB_result::fetchInto() instead.  It can't be declared "protected"
437
     * DB_result::fetchInto() instead.  It can't be declared "protected"
431
     * because DB_result is a separate object.
438
     * because DB_result is a separate object.
432
     *
439
     *
433
     * @param resource $result    the query result resource
440
     * @param resource $result    the query result resource
434
     * @param array    $arr       the referenced array to put the data in
441
     * @param array    $arr       the referenced array to put the data in
435
     * @param int      $fetchmode how the resulting array should be indexed
442
     * @param int      $fetchmode how the resulting array should be indexed
436
     * @param int      $rownum    the row number to fetch (0 = first row)
443
     * @param int      $rownum    the row number to fetch (0 = first row)
437
     *
444
     *
438
     * @return mixed  DB_OK on success, NULL when the end of a result set is
445
     * @return mixed  DB_OK on success, NULL when the end of a result set is
439
     *                 reached or on failure
446
     *                 reached or on failure
440
     *
447
     *
441
     * @see DB_result::fetchInto()
448
     * @see DB_result::fetchInto()
442
     */
449
     */
443
    function fetchInto($result, &$arr, $fetchmode, $rownum = null)
450
    function fetchInto($result, &$arr, $fetchmode, $rownum = null)
444
    {
451
    {
445
        if ($rownum !== null) {
452
        if ($rownum !== null) {
446
            if (!@mysqli_data_seek($result, $rownum)) {
453
            if (!@mysqli_data_seek($result, $rownum)) {
447
                return null;
454
                return null;
448
            }
455
            }
449
        }
456
        }
450
        if ($fetchmode & DB_FETCHMODE_ASSOC) {
457
        if ($fetchmode & DB_FETCHMODE_ASSOC) {
451
            $arr = @mysqli_fetch_array($result, MYSQLI_ASSOC);
458
            $arr = @mysqli_fetch_array($result, MYSQLI_ASSOC);
452
            if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
459
            if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
453
                $arr = array_change_key_case($arr, CASE_LOWER);
460
                $arr = array_change_key_case($arr, CASE_LOWER);
454
            }
461
            }
455
        } else {
462
        } else {
456
            $arr = @mysqli_fetch_row($result);
463
            $arr = @mysqli_fetch_row($result);
457
        }
464
        }
458
        if (!$arr) {
465
        if (!$arr) {
459
            return null;
466
            return null;
460
        }
467
        }
461
        if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
468
        if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
462
            /*
469
            /*
463
             * Even though this DBMS already trims output, we do this because
470
             * Even though this DBMS already trims output, we do this because
464
             * a field might have intentional whitespace at the end that
471
             * a field might have intentional whitespace at the end that
465
             * gets removed by DB_PORTABILITY_RTRIM under another driver.
472
             * gets removed by DB_PORTABILITY_RTRIM under another driver.
466
             */
473
             */
467
            $this->_rtrimArrayValues($arr);
474
            $this->_rtrimArrayValues($arr);
468
        }
475
        }
469
        if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
476
        if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
470
            $this->_convertNullArrayValuesToEmpty($arr);
477
            $this->_convertNullArrayValuesToEmpty($arr);
471
        }
478
        }
472
        return DB_OK;
479
        return DB_OK;
473
    }
480
    }
474
 
481
 
475
    // }}}
482
    // }}}
476
    // {{{ freeResult()
483
    // {{{ freeResult()
477
 
484
 
478
    /**
485
    /**
479
     * Deletes the result set and frees the memory occupied by the result set
486
     * Deletes the result set and frees the memory occupied by the result set
480
     *
487
     *
481
     * This method is not meant to be called directly.  Use
488
     * This method is not meant to be called directly.  Use
482
     * DB_result::free() instead.  It can't be declared "protected"
489
     * DB_result::free() instead.  It can't be declared "protected"
483
     * because DB_result is a separate object.
490
     * because DB_result is a separate object.
484
     *
491
     *
485
     * @param resource $result  PHP's query result resource
492
     * @param resource $result  PHP's query result resource
486
     *
493
     *
487
     * @return bool  TRUE on success, FALSE if $result is invalid
494
     * @return bool  TRUE on success, FALSE if $result is invalid
488
     *
495
     *
489
     * @see DB_result::free()
496
     * @see DB_result::free()
490
     */
497
     */
491
    function freeResult($result)
498
    function freeResult($result)
492
    {
499
    {
-
 
500
        if (! $result instanceof mysqli_result) {
-
 
501
            return false;
-
 
502
        }
493
        return @mysqli_free_result($result);
503
        mysqli_free_result($result);
-
 
504
        return true;
494
    }
505
    }
495
 
506
 
496
    // }}}
507
    // }}}
497
    // {{{ numCols()
508
    // {{{ numCols()
498
 
509
 
499
    /**
510
    /**
500
     * Gets the number of columns in a result set
511
     * Gets the number of columns in a result set
501
     *
512
     *
502
     * This method is not meant to be called directly.  Use
513
     * This method is not meant to be called directly.  Use
503
     * DB_result::numCols() instead.  It can't be declared "protected"
514
     * DB_result::numCols() instead.  It can't be declared "protected"
504
     * because DB_result is a separate object.
515
     * because DB_result is a separate object.
505
     *
516
     *
506
     * @param resource $result  PHP's query result resource
517
     * @param resource $result  PHP's query result resource
507
     *
518
     *
508
     * @return int  the number of columns.  A DB_Error object on failure.
519
     * @return int  the number of columns.  A DB_Error object on failure.
509
     *
520
     *
510
     * @see DB_result::numCols()
521
     * @see DB_result::numCols()
511
     */
522
     */
512
    function numCols($result)
523
    function numCols($result)
513
    {
524
    {
514
        $cols = @mysqli_num_fields($result);
525
        $cols = @mysqli_num_fields($result);
515
        if (!$cols) {
526
        if (!$cols) {
516
            return $this->mysqliRaiseError();
527
            return $this->mysqliRaiseError();
517
        }
528
        }
518
        return $cols;
529
        return $cols;
519
    }
530
    }
520
 
531
 
521
    // }}}
532
    // }}}
522
    // {{{ numRows()
533
    // {{{ numRows()
523
 
534
 
524
    /**
535
    /**
525
     * Gets the number of rows in a result set
536
     * Gets the number of rows in a result set
526
     *
537
     *
527
     * This method is not meant to be called directly.  Use
538
     * This method is not meant to be called directly.  Use
528
     * DB_result::numRows() instead.  It can't be declared "protected"
539
     * DB_result::numRows() instead.  It can't be declared "protected"
529
     * because DB_result is a separate object.
540
     * because DB_result is a separate object.
530
     *
541
     *
531
     * @param resource $result  PHP's query result resource
542
     * @param resource $result  PHP's query result resource
532
     *
543
     *
533
     * @return int  the number of rows.  A DB_Error object on failure.
544
     * @return int  the number of rows.  A DB_Error object on failure.
534
     *
545
     *
535
     * @see DB_result::numRows()
546
     * @see DB_result::numRows()
536
     */
547
     */
537
    function numRows($result)
548
    function numRows($result)
538
    {
549
    {
539
        $rows = @mysqli_num_rows($result);
550
        $rows = @mysqli_num_rows($result);
540
        if ($rows === null) {
551
        if ($rows === null) {
541
            return $this->mysqliRaiseError();
552
            return $this->mysqliRaiseError();
542
        }
553
        }
543
        return $rows;
554
        return $rows;
544
    }
555
    }
545
 
556
 
546
    // }}}
557
    // }}}
547
    // {{{ autoCommit()
558
    // {{{ autoCommit()
548
 
559
 
549
    /**
560
    /**
550
     * Enables or disables automatic commits
561
     * Enables or disables automatic commits
551
     *
562
     *
552
     * @param bool $onoff  true turns it on, false turns it off
563
     * @param bool $onoff  true turns it on, false turns it off
553
     *
564
     *
554
     * @return int  DB_OK on success.  A DB_Error object if the driver
565
     * @return int  DB_OK on success.  A DB_Error object if the driver
555
     *               doesn't support auto-committing transactions.
566
     *               doesn't support auto-committing transactions.
556
     */
567
     */
557
    function autoCommit($onoff = false)
568
    function autoCommit($onoff = false)
558
    {
569
    {
559
        // XXX if $this->transaction_opcount > 0, we should probably
570
        // XXX if $this->transaction_opcount > 0, we should probably
560
        // issue a warning here.
571
        // issue a warning here.
561
        $this->autocommit = $onoff ? true : false;
572
        $this->autocommit = $onoff ? true : false;
562
        return DB_OK;
573
        return DB_OK;
563
    }
574
    }
564
 
575
 
565
    // }}}
576
    // }}}
566
    // {{{ commit()
577
    // {{{ commit()
567
 
578
 
568
    /**
579
    /**
569
     * Commits the current transaction
580
     * Commits the current transaction
570
     *
581
     *
571
     * @return int  DB_OK on success.  A DB_Error object on failure.
582
     * @return int  DB_OK on success.  A DB_Error object on failure.
572
     */
583
     */
573
    function commit()
584
    function commit()
574
    {
585
    {
575
        if ($this->transaction_opcount > 0) {
586
        if ($this->transaction_opcount > 0) {
576
            if ($this->_db) {
587
            if ($this->_db) {
577
                if (!@mysqli_select_db($this->connection, $this->_db)) {
588
                if (!@mysqli_select_db($this->connection, $this->_db)) {
578
                    return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
589
                    return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
579
                }
590
                }
580
            }
591
            }
581
            $result = @mysqli_query($this->connection, 'COMMIT');
592
            $result = @mysqli_query($this->connection, 'COMMIT');
582
            $result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=1');
593
            $result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=1');
583
            $this->transaction_opcount = 0;
594
            $this->transaction_opcount = 0;
584
            if (!$result) {
595
            if (!$result) {
585
                return $this->mysqliRaiseError();
596
                return $this->mysqliRaiseError();
586
            }
597
            }
587
        }
598
        }
588
        return DB_OK;
599
        return DB_OK;
589
    }
600
    }
590
 
601
 
591
    // }}}
602
    // }}}
592
    // {{{ rollback()
603
    // {{{ rollback()
593
 
604
 
594
    /**
605
    /**
595
     * Reverts the current transaction
606
     * Reverts the current transaction
596
     *
607
     *
597
     * @return int  DB_OK on success.  A DB_Error object on failure.
608
     * @return int  DB_OK on success.  A DB_Error object on failure.
598
     */
609
     */
599
    function rollback()
610
    function rollback()
600
    {
611
    {
601
        if ($this->transaction_opcount > 0) {
612
        if ($this->transaction_opcount > 0) {
602
            if ($this->_db) {
613
            if ($this->_db) {
603
                if (!@mysqli_select_db($this->connection, $this->_db)) {
614
                if (!@mysqli_select_db($this->connection, $this->_db)) {
604
                    return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
615
                    return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
605
                }
616
                }
606
            }
617
            }
607
            $result = @mysqli_query($this->connection, 'ROLLBACK');
618
            $result = @mysqli_query($this->connection, 'ROLLBACK');
608
            $result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=1');
619
            $result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=1');
609
            $this->transaction_opcount = 0;
620
            $this->transaction_opcount = 0;
610
            if (!$result) {
621
            if (!$result) {
611
                return $this->mysqliRaiseError();
622
                return $this->mysqliRaiseError();
612
            }
623
            }
613
        }
624
        }
614
        return DB_OK;
625
        return DB_OK;
615
    }
626
    }
616
 
627
 
617
    // }}}
628
    // }}}
618
    // {{{ affectedRows()
629
    // {{{ affectedRows()
619
 
630
 
620
    /**
631
    /**
621
     * Determines the number of rows affected by a data maniuplation query
632
     * Determines the number of rows affected by a data maniuplation query
622
     *
633
     *
623
     * 0 is returned for queries that don't manipulate data.
634
     * 0 is returned for queries that don't manipulate data.
624
     *
635
     *
625
     * @return int  the number of rows.  A DB_Error object on failure.
636
     * @return int  the number of rows.  A DB_Error object on failure.
626
     */
637
     */
627
    function affectedRows()
638
    function affectedRows()
628
    {
639
    {
629
        if (DB::isManip($this->last_query)) {
640
        if ($this->_last_query_manip) {
630
            return @mysqli_affected_rows($this->connection);
641
            return @mysqli_affected_rows($this->connection);
631
        } else {
642
        } else {
632
            return 0;
643
            return 0;
633
        }
644
        }
634
     }
645
     }
635
 
646
 
636
    // }}}
647
    // }}}
637
    // {{{ nextId()
648
    // {{{ nextId()
638
 
649
 
639
    /**
650
    /**
640
     * Returns the next free id in a sequence
651
     * Returns the next free id in a sequence
641
     *
652
     *
642
     * @param string  $seq_name  name of the sequence
653
     * @param string  $seq_name  name of the sequence
643
     * @param boolean $ondemand  when true, the seqence is automatically
654
     * @param boolean $ondemand  when true, the seqence is automatically
644
     *                            created if it does not exist
655
     *                            created if it does not exist
645
     *
656
     *
646
     * @return int  the next id number in the sequence.
657
     * @return int  the next id number in the sequence.
647
     *               A DB_Error object on failure.
658
     *               A DB_Error object on failure.
648
     *
659
     *
649
     * @see DB_common::nextID(), DB_common::getSequenceName(),
660
     * @see DB_common::nextID(), DB_common::getSequenceName(),
650
     *      DB_mysqli::createSequence(), DB_mysqli::dropSequence()
661
     *      DB_mysqli::createSequence(), DB_mysqli::dropSequence()
651
     */
662
     */
652
    function nextId($seq_name, $ondemand = true)
663
    function nextId($seq_name, $ondemand = true)
653
    {
664
    {
654
        $seqname = $this->getSequenceName($seq_name);
665
        $seqname = $this->getSequenceName($seq_name);
655
        do {
666
        do {
656
            $repeat = 0;
667
            $repeat = 0;
657
            $this->pushErrorHandling(PEAR_ERROR_RETURN);
668
            $this->pushErrorHandling(PEAR_ERROR_RETURN);
658
            $result = $this->query('UPDATE ' . $seqname
669
            $result = $this->query('UPDATE ' . $seqname
659
                                   . ' SET id = LAST_INSERT_ID(id + 1)');
670
                                   . ' SET id = LAST_INSERT_ID(id + 1)');
660
            $this->popErrorHandling();
671
            $this->popErrorHandling();
661
            if ($result === DB_OK) {
672
            if ($result === DB_OK) {
662
                // COMMON CASE
673
                // COMMON CASE
663
                $id = @mysqli_insert_id($this->connection);
674
                $id = @mysqli_insert_id($this->connection);
664
                if ($id != 0) {
675
                if ($id != 0) {
665
                    return $id;
676
                    return $id;
666
                }
677
                }
667
 
678
 
668
                // EMPTY SEQ TABLE
679
                // EMPTY SEQ TABLE
669
                // Sequence table must be empty for some reason,
680
                // Sequence table must be empty for some reason,
670
                // so fill it and return 1
681
                // so fill it and return 1
671
                // Obtain a user-level lock
682
                // Obtain a user-level lock
672
                $result = $this->getOne('SELECT GET_LOCK('
683
                $result = $this->getOne('SELECT GET_LOCK('
673
                                        . "'${seqname}_lock', 10)");
684
                                        . "'${seqname}_lock', 10)");
674
                if (DB::isError($result)) {
685
                if (DB::isError($result)) {
675
                    return $this->raiseError($result);
686
                    return $this->raiseError($result);
676
                }
687
                }
677
                if ($result == 0) {
688
                if ($result == 0) {
678
                    return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED);
689
                    return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED);
679
                }
690
                }
680
 
691
 
681
                // add the default value
692
                // add the default value
682
                $result = $this->query('REPLACE INTO ' . $seqname
693
                $result = $this->query('REPLACE INTO ' . $seqname
683
                                       . ' (id) VALUES (0)');
694
                                       . ' (id) VALUES (0)');
684
                if (DB::isError($result)) {
695
                if (DB::isError($result)) {
685
                    return $this->raiseError($result);
696
                    return $this->raiseError($result);
686
                }
697
                }
687
 
698
 
688
                // Release the lock
699
                // Release the lock
689
                $result = $this->getOne('SELECT RELEASE_LOCK('
700
                $result = $this->getOne('SELECT RELEASE_LOCK('
690
                                        . "'${seqname}_lock')");
701
                                        . "'${seqname}_lock')");
691
                if (DB::isError($result)) {
702
                if (DB::isError($result)) {
692
                    return $this->raiseError($result);
703
                    return $this->raiseError($result);
693
                }
704
                }
694
                // We know what the result will be, so no need to try again
705
                // We know what the result will be, so no need to try again
695
                return 1;
706
                return 1;
696
 
707
 
697
            } elseif ($ondemand && DB::isError($result) &&
708
            } elseif ($ondemand && DB::isError($result) &&
698
                $result->getCode() == DB_ERROR_NOSUCHTABLE)
709
                $result->getCode() == DB_ERROR_NOSUCHTABLE)
699
            {
710
            {
700
                // ONDEMAND TABLE CREATION
711
                // ONDEMAND TABLE CREATION
701
                $result = $this->createSequence($seq_name);
712
                $result = $this->createSequence($seq_name);
702
 
713
 
703
                // Since createSequence initializes the ID to be 1,
714
                // Since createSequence initializes the ID to be 1,
704
                // we do not need to retrieve the ID again (or we will get 2)
715
                // we do not need to retrieve the ID again (or we will get 2)
705
                if (DB::isError($result)) {
716
                if (DB::isError($result)) {
706
                    return $this->raiseError($result);
717
                    return $this->raiseError($result);
707
                } else {
718
                } else {
708
                    // First ID of a newly created sequence is 1
719
                    // First ID of a newly created sequence is 1
709
                    return 1;
720
                    return 1;
710
                }
721
                }
711
 
722
 
712
            } elseif (DB::isError($result) &&
723
            } elseif (DB::isError($result) &&
713
                      $result->getCode() == DB_ERROR_ALREADY_EXISTS)
724
                      $result->getCode() == DB_ERROR_ALREADY_EXISTS)
714
            {
725
            {
715
                // BACKWARDS COMPAT
726
                // BACKWARDS COMPAT
716
                // see _BCsequence() comment
727
                // see _BCsequence() comment
717
                $result = $this->_BCsequence($seqname);
728
                $result = $this->_BCsequence($seqname);
718
                if (DB::isError($result)) {
729
                if (DB::isError($result)) {
719
                    return $this->raiseError($result);
730
                    return $this->raiseError($result);
720
                }
731
                }
721
                $repeat = 1;
732
                $repeat = 1;
722
            }
733
            }
723
        } while ($repeat);
734
        } while ($repeat);
724
 
735
 
725
        return $this->raiseError($result);
736
        return $this->raiseError($result);
726
    }
737
    }
727
 
738
 
728
    /**
739
    /**
729
     * Creates a new sequence
740
     * Creates a new sequence
730
     *
741
     *
731
     * @param string $seq_name  name of the new sequence
742
     * @param string $seq_name  name of the new sequence
732
     *
743
     *
733
     * @return int  DB_OK on success.  A DB_Error object on failure.
744
     * @return int  DB_OK on success.  A DB_Error object on failure.
734
     *
745
     *
735
     * @see DB_common::createSequence(), DB_common::getSequenceName(),
746
     * @see DB_common::createSequence(), DB_common::getSequenceName(),
736
     *      DB_mysqli::nextID(), DB_mysqli::dropSequence()
747
     *      DB_mysqli::nextID(), DB_mysqli::dropSequence()
737
     */
748
     */
738
    function createSequence($seq_name)
749
    function createSequence($seq_name)
739
    {
750
    {
740
        $seqname = $this->getSequenceName($seq_name);
751
        $seqname = $this->getSequenceName($seq_name);
741
        $res = $this->query('CREATE TABLE ' . $seqname
752
        $res = $this->query('CREATE TABLE ' . $seqname
742
                            . ' (id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'
753
                            . ' (id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'
743
                            . ' PRIMARY KEY(id))');
754
                            . ' PRIMARY KEY(id))');
744
        if (DB::isError($res)) {
755
        if (DB::isError($res)) {
745
            return $res;
756
            return $res;
746
        }
757
        }
747
        // insert yields value 1, nextId call will generate ID 2
758
        // insert yields value 1, nextId call will generate ID 2
748
        return $this->query("INSERT INTO ${seqname} (id) VALUES (0)");
759
        return $this->query("INSERT INTO ${seqname} (id) VALUES (0)");
749
    }
760
    }
750
 
761
 
751
    // }}}
762
    // }}}
752
    // {{{ dropSequence()
763
    // {{{ dropSequence()
753
 
764
 
754
    /**
765
    /**
755
     * Deletes a sequence
766
     * Deletes a sequence
756
     *
767
     *
757
     * @param string $seq_name  name of the sequence to be deleted
768
     * @param string $seq_name  name of the sequence to be deleted
758
     *
769
     *
759
     * @return int  DB_OK on success.  A DB_Error object on failure.
770
     * @return int  DB_OK on success.  A DB_Error object on failure.
760
     *
771
     *
761
     * @see DB_common::dropSequence(), DB_common::getSequenceName(),
772
     * @see DB_common::dropSequence(), DB_common::getSequenceName(),
762
     *      DB_mysql::nextID(), DB_mysql::createSequence()
773
     *      DB_mysql::nextID(), DB_mysql::createSequence()
763
     */
774
     */
764
    function dropSequence($seq_name)
775
    function dropSequence($seq_name)
765
    {
776
    {
766
        return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
777
        return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
767
    }
778
    }
768
 
779
 
769
    // }}}
780
    // }}}
770
    // {{{ _BCsequence()
781
    // {{{ _BCsequence()
771
 
782
 
772
    /**
783
    /**
773
     * Backwards compatibility with old sequence emulation implementation
784
     * Backwards compatibility with old sequence emulation implementation
774
     * (clean up the dupes)
785
     * (clean up the dupes)
775
     *
786
     *
776
     * @param string $seqname  the sequence name to clean up
787
     * @param string $seqname  the sequence name to clean up
777
     *
788
     *
778
     * @return bool  true on success.  A DB_Error object on failure.
789
     * @return bool  true on success.  A DB_Error object on failure.
779
     *
790
     *
780
     * @access private
791
     * @access private
781
     */
792
     */
782
    function _BCsequence($seqname)
793
    function _BCsequence($seqname)
783
    {
794
    {
784
        // Obtain a user-level lock... this will release any previous
795
        // Obtain a user-level lock... this will release any previous
785
        // application locks, but unlike LOCK TABLES, it does not abort
796
        // application locks, but unlike LOCK TABLES, it does not abort
786
        // the current transaction and is much less frequently used.
797
        // the current transaction and is much less frequently used.
787
        $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)");
798
        $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)");
788
        if (DB::isError($result)) {
799
        if (DB::isError($result)) {
789
            return $result;
800
            return $result;
790
        }
801
        }
791
        if ($result == 0) {
802
        if ($result == 0) {
792
            // Failed to get the lock, can't do the conversion, bail
803
            // Failed to get the lock, can't do the conversion, bail
793
            // with a DB_ERROR_NOT_LOCKED error
804
            // with a DB_ERROR_NOT_LOCKED error
794
            return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED);
805
            return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED);
795
        }
806
        }
796
 
807
 
797
        $highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}");
808
        $highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}");
798
        if (DB::isError($highest_id)) {
809
        if (DB::isError($highest_id)) {
799
            return $highest_id;
810
            return $highest_id;
800
        }
811
        }
801
 
812
 
802
        // This should kill all rows except the highest
813
        // This should kill all rows except the highest
803
        // We should probably do something if $highest_id isn't
814
        // We should probably do something if $highest_id isn't
804
        // numeric, but I'm at a loss as how to handle that...
815
        // numeric, but I'm at a loss as how to handle that...
805
        $result = $this->query('DELETE FROM ' . $seqname
816
        $result = $this->query('DELETE FROM ' . $seqname
806
                               . " WHERE id <> $highest_id");
817
                               . " WHERE id <> $highest_id");
807
        if (DB::isError($result)) {
818
        if (DB::isError($result)) {
808
            return $result;
819
            return $result;
809
        }
820
        }
810
 
821
 
811
        // If another thread has been waiting for this lock,
822
        // If another thread has been waiting for this lock,
812
        // it will go thru the above procedure, but will have no
823
        // it will go thru the above procedure, but will have no
813
        // real effect
824
        // real effect
814
        $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')");
825
        $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')");
815
        if (DB::isError($result)) {
826
        if (DB::isError($result)) {
816
            return $result;
827
            return $result;
817
        }
828
        }
818
        return true;
829
        return true;
819
    }
830
    }
820
 
831
 
821
    // }}}
832
    // }}}
822
    // {{{ quoteIdentifier()
833
    // {{{ quoteIdentifier()
823
 
834
 
824
    /**
835
    /**
825
     * Quotes a string so it can be safely used as a table or column name
836
     * Quotes a string so it can be safely used as a table or column name
-
 
837
     * (WARNING: using names that require this is a REALLY BAD IDEA)
826
     *
838
     *
827
     * MySQL can't handle the backtick character (<kbd>`</kbd>) in
839
     * WARNING:  Older versions of MySQL can't handle the backtick
828
     * table or column names.
840
     * character (<kbd>`</kbd>) in table or column names.
829
     *
841
     *
830
     * @param string $str  identifier name to be quoted
842
     * @param string $str  identifier name to be quoted
831
     *
843
     *
832
     * @return string  quoted identifier string
844
     * @return string  quoted identifier string
833
     *
845
     *
834
     * @see DB_common::quoteIdentifier()
846
     * @see DB_common::quoteIdentifier()
835
     * @since Method available since Release 1.6.0
847
     * @since Method available since Release 1.6.0
836
     */
848
     */
837
    function quoteIdentifier($str)
849
    function quoteIdentifier($str)
838
    {
850
    {
839
        return '`' . $str . '`';
851
        return '`' . str_replace('`', '``', $str) . '`';
840
    }
852
    }
841
 
853
 
842
    // }}}
854
    // }}}
843
    // {{{ escapeSimple()
855
    // {{{ escapeSimple()
844
 
856
 
845
    /**
857
    /**
846
     * Escapes a string according to the current DBMS's standards
858
     * Escapes a string according to the current DBMS's standards
847
     *
859
     *
848
     * @param string $str  the string to be escaped
860
     * @param string $str  the string to be escaped
849
     *
861
     *
850
     * @return string  the escaped string
862
     * @return string  the escaped string
851
     *
863
     *
852
     * @see DB_common::quoteSmart()
864
     * @see DB_common::quoteSmart()
853
     * @since Method available since Release 1.6.0
865
     * @since Method available since Release 1.6.0
854
     */
866
     */
855
    function escapeSimple($str)
867
    function escapeSimple($str)
856
    {
868
    {
857
        return @mysqli_real_escape_string($this->connection, $str);
869
        return @mysqli_real_escape_string($this->connection, $str);
858
    }
870
    }
859
 
871
 
860
    // }}}
872
    // }}}
861
    // {{{ modifyLimitQuery()
873
    // {{{ modifyLimitQuery()
862
 
874
 
863
    /**
875
    /**
864
     * Adds LIMIT clauses to a query string according to current DBMS standards
876
     * Adds LIMIT clauses to a query string according to current DBMS standards
865
     *
877
     *
866
     * @param string $query   the query to modify
878
     * @param string $query   the query to modify
867
     * @param int    $from    the row to start to fetching (0 = the first row)
879
     * @param int    $from    the row to start to fetching (0 = the first row)
868
     * @param int    $count   the numbers of rows to fetch
880
     * @param int    $count   the numbers of rows to fetch
869
     * @param mixed  $params  array, string or numeric data to be used in
881
     * @param mixed  $params  array, string or numeric data to be used in
870
     *                         execution of the statement.  Quantity of items
882
     *                         execution of the statement.  Quantity of items
871
     *                         passed must match quantity of placeholders in
883
     *                         passed must match quantity of placeholders in
872
     *                         query:  meaning 1 placeholder for non-array
884
     *                         query:  meaning 1 placeholder for non-array
873
     *                         parameters or 1 placeholder per array element.
885
     *                         parameters or 1 placeholder per array element.
874
     *
886
     *
875
     * @return string  the query string with LIMIT clauses added
887
     * @return string  the query string with LIMIT clauses added
876
     *
888
     *
877
     * @access protected
889
     * @access protected
878
     */
890
     */
879
    function modifyLimitQuery($query, $from, $count, $params = array())
891
    function modifyLimitQuery($query, $from, $count, $params = array())
880
    {
892
    {
881
        if (DB::isManip($query)) {
893
        if (DB::isManip($query) || $this->_next_query_manip) {
882
            return $query . " LIMIT $count";
894
            return $query . " LIMIT $count";
883
        } else {
895
        } else {
884
            return $query . " LIMIT $from, $count";
896
            return $query . " LIMIT $from, $count";
885
        }
897
        }
886
    }
898
    }
887
 
899
 
888
    // }}}
900
    // }}}
889
    // {{{ mysqliRaiseError()
901
    // {{{ mysqliRaiseError()
890
 
902
 
891
    /**
903
    /**
892
     * Produces a DB_Error object regarding the current problem
904
     * Produces a DB_Error object regarding the current problem
893
     *
905
     *
894
     * @param int $errno  if the error is being manually raised pass a
906
     * @param int $errno  if the error is being manually raised pass a
895
     *                     DB_ERROR* constant here.  If this isn't passed
907
     *                     DB_ERROR* constant here.  If this isn't passed
896
     *                     the error information gathered from the DBMS.
908
     *                     the error information gathered from the DBMS.
897
     *
909
     *
898
     * @return object  the DB_Error object
910
     * @return object  the DB_Error object
899
     *
911
     *
900
     * @see DB_common::raiseError(),
912
     * @see DB_common::raiseError(),
901
     *      DB_mysqli::errorNative(), DB_common::errorCode()
913
     *      DB_mysqli::errorNative(), DB_common::errorCode()
902
     */
914
     */
903
    function mysqliRaiseError($errno = null)
915
    function mysqliRaiseError($errno = null)
904
    {
916
    {
905
        if ($errno === null) {
917
        if ($errno === null) {
906
            if ($this->options['portability'] & DB_PORTABILITY_ERRORS) {
918
            if ($this->options['portability'] & DB_PORTABILITY_ERRORS) {
907
                $this->errorcode_map[1022] = DB_ERROR_CONSTRAINT;
919
                $this->errorcode_map[1022] = DB_ERROR_CONSTRAINT;
908
                $this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL;
920
                $this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL;
909
                $this->errorcode_map[1062] = DB_ERROR_CONSTRAINT;
921
                $this->errorcode_map[1062] = DB_ERROR_CONSTRAINT;
910
            } else {
922
            } else {
911
                // Doing this in case mode changes during runtime.
923
                // Doing this in case mode changes during runtime.
912
                $this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS;
924
                $this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS;
913
                $this->errorcode_map[1048] = DB_ERROR_CONSTRAINT;
925
                $this->errorcode_map[1048] = DB_ERROR_CONSTRAINT;
914
                $this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS;
926
                $this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS;
915
            }
927
            }
916
            $errno = $this->errorCode(mysqli_errno($this->connection));
928
            $errno = $this->errorCode(mysqli_errno($this->connection));
917
        }
929
        }
918
        return $this->raiseError($errno, null, null, null,
930
        return $this->raiseError($errno, null, null, null,
919
                                 @mysqli_errno($this->connection) . ' ** ' .
931
                                 @mysqli_errno($this->connection) . ' ** ' .
920
                                 @mysqli_error($this->connection));
932
                                 @mysqli_error($this->connection));
921
    }
933
    }
922
 
934
 
923
    // }}}
935
    // }}}
924
    // {{{ errorNative()
936
    // {{{ errorNative()
925
 
937
 
926
    /**
938
    /**
927
     * Gets the DBMS' native error code produced by the last query
939
     * Gets the DBMS' native error code produced by the last query
928
     *
940
     *
929
     * @return int  the DBMS' error code
941
     * @return int  the DBMS' error code
930
     */
942
     */
931
    function errorNative()
943
    function errorNative()
932
    {
944
    {
933
        return @mysqli_errno($this->connection);
945
        return @mysqli_errno($this->connection);
934
    }
946
    }
935
 
947
 
936
    // }}}
948
    // }}}
937
    // {{{ tableInfo()
949
    // {{{ tableInfo()
938
 
950
 
939
    /**
951
    /**
940
     * Returns information about a table or a result set
952
     * Returns information about a table or a result set
941
     *
953
     *
942
     * @param object|string  $result  DB_result object from a query or a
954
     * @param object|string  $result  DB_result object from a query or a
943
     *                                 string containing the name of a table.
955
     *                                 string containing the name of a table.
944
     *                                 While this also accepts a query result
956
     *                                 While this also accepts a query result
945
     *                                 resource identifier, this behavior is
957
     *                                 resource identifier, this behavior is
946
     *                                 deprecated.
958
     *                                 deprecated.
947
     * @param int            $mode    a valid tableInfo mode
959
     * @param int            $mode    a valid tableInfo mode
948
     *
960
     *
949
     * @return array  an associative array with the information requested.
961
     * @return array  an associative array with the information requested.
950
     *                 A DB_Error object on failure.
962
     *                 A DB_Error object on failure.
951
     *
963
     *
952
     * @see DB_common::setOption()
964
     * @see DB_common::setOption()
953
     */
965
     */
954
    function tableInfo($result, $mode = null)
966
    function tableInfo($result, $mode = null)
955
    {
967
    {
956
        if (is_string($result)) {
968
        if (is_string($result)) {
-
 
969
            // Fix for bug #11580.
-
 
970
            if ($this->_db) {
-
 
971
                if (!@mysqli_select_db($this->connection, $this->_db)) {
-
 
972
                    return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
-
 
973
                }
-
 
974
            }
-
 
975
 
957
            /*
976
            /*
958
             * Probably received a table name.
977
             * Probably received a table name.
959
             * Create a result resource identifier.
978
             * Create a result resource identifier.
960
             */
979
             */
961
            $id = @mysqli_query($this->connection,
980
            $id = @mysqli_query($this->connection,
962
                                "SELECT * FROM $result LIMIT 0");
981
                                "SELECT * FROM $result LIMIT 0");
963
            $got_string = true;
982
            $got_string = true;
964
        } elseif (isset($result->result)) {
983
        } elseif (isset($result->result)) {
965
            /*
984
            /*
966
             * Probably received a result object.
985
             * Probably received a result object.
967
             * Extract the result resource identifier.
986
             * Extract the result resource identifier.
968
             */
987
             */
969
            $id = $result->result;
988
            $id = $result->result;
970
            $got_string = false;
989
            $got_string = false;
971
        } else {
990
        } else {
972
            /*
991
            /*
973
             * Probably received a result resource identifier.
992
             * Probably received a result resource identifier.
974
             * Copy it.
993
             * Copy it.
975
             * Deprecated.  Here for compatibility only.
994
             * Deprecated.  Here for compatibility only.
976
             */
995
             */
977
            $id = $result;
996
            $id = $result;
978
            $got_string = false;
997
            $got_string = false;
979
        }
998
        }
980
 
999
 
981
        if (!is_a($id, 'mysqli_result')) {
1000
        if (!is_object($id) || !is_a($id, 'mysqli_result')) {
982
            return $this->mysqliRaiseError(DB_ERROR_NEED_MORE_DATA);
1001
            return $this->mysqliRaiseError(DB_ERROR_NEED_MORE_DATA);
983
        }
1002
        }
984
 
1003
 
985
        if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
1004
        if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
986
            $case_func = 'strtolower';
1005
            $case_func = 'strtolower';
987
        } else {
1006
        } else {
988
            $case_func = 'strval';
1007
            $case_func = 'strval';
989
        }
1008
        }
990
 
1009
 
991
        $count = @mysqli_num_fields($id);
1010
        $count = @mysqli_num_fields($id);
992
        $res   = array();
1011
        $res   = array();
993
 
1012
 
994
        if ($mode) {
1013
        if ($mode) {
995
            $res['num_fields'] = $count;
1014
            $res['num_fields'] = $count;
996
        }
1015
        }
997
 
1016
 
998
        for ($i = 0; $i < $count; $i++) {
1017
        for ($i = 0; $i < $count; $i++) {
999
            $tmp = @mysqli_fetch_field($id);
1018
            $tmp = @mysqli_fetch_field($id);
1000
 
1019
 
1001
            $flags = '';
1020
            $flags = '';
1002
            foreach ($this->mysqli_flags as $const => $means) {
1021
            foreach ($this->mysqli_flags as $const => $means) {
1003
                if ($tmp->flags & $const) {
1022
                if ($tmp->flags & $const) {
1004
                    $flags .= $means . ' ';
1023
                    $flags .= $means . ' ';
1005
                }
1024
                }
1006
            }
1025
            }
1007
            if ($tmp->def) {
1026
            if ($tmp->def) {
1008
                $flags .= 'default_' . rawurlencode($tmp->def);
1027
                $flags .= 'default_' . rawurlencode($tmp->def);
1009
            }
1028
            }
1010
            $flags = trim($flags);
1029
            $flags = trim($flags);
1011
 
1030
 
1012
            $res[$i] = array(
1031
            $res[$i] = array(
1013
                'table' => $case_func($tmp->table),
1032
                'table' => $case_func($tmp->table),
1014
                'name'  => $case_func($tmp->name),
1033
                'name'  => $case_func($tmp->name),
1015
                'type'  => isset($this->mysqli_types[$tmp->type])
1034
                'type'  => isset($this->mysqli_types[$tmp->type])
1016
                                    ? $this->mysqli_types[$tmp->type]
1035
                                    ? $this->mysqli_types[$tmp->type]
1017
                                    : 'unknown',
1036
                                    : 'unknown',
-
 
1037
                // http://bugs.php.net/?id=36579
-
 
1038
                //  Doc Bug #36579: mysqli_fetch_field length handling
-
 
1039
                // https://bugs.php.net/bug.php?id=62426
-
 
1040
                //  Bug #62426: mysqli_fetch_field_direct returns incorrect
-
 
1041
                //  length on UTF8 fields
1018
                'len'   => $tmp->max_length,
1042
                'len'   => $tmp->length,
1019
                'flags' => $flags,
1043
                'flags' => $flags,
1020
            );
1044
            );
1021
 
1045
 
1022
            if ($mode & DB_TABLEINFO_ORDER) {
1046
            if ($mode & DB_TABLEINFO_ORDER) {
1023
                $res['order'][$res[$i]['name']] = $i;
1047
                $res['order'][$res[$i]['name']] = $i;
1024
            }
1048
            }
1025
            if ($mode & DB_TABLEINFO_ORDERTABLE) {
1049
            if ($mode & DB_TABLEINFO_ORDERTABLE) {
1026
                $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
1050
                $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
1027
            }
1051
            }
1028
        }
1052
        }
1029
 
1053
 
1030
        // free the result only if we were called on a table
1054
        // free the result only if we were called on a table
1031
        if ($got_string) {
1055
        if ($got_string) {
1032
            @mysqli_free_result($id);
1056
            @mysqli_free_result($id);
1033
        }
1057
        }
1034
        return $res;
1058
        return $res;
1035
    }
1059
    }
1036
 
1060
 
1037
    // }}}
1061
    // }}}
1038
    // {{{ getSpecialQuery()
1062
    // {{{ getSpecialQuery()
1039
 
1063
 
1040
    /**
1064
    /**
1041
     * Obtains the query string needed for listing a given type of objects
1065
     * Obtains the query string needed for listing a given type of objects
1042
     *
1066
     *
1043
     * @param string $type  the kind of objects you want to retrieve
1067
     * @param string $type  the kind of objects you want to retrieve
1044
     *
1068
     *
1045
     * @return string  the SQL query string or null if the driver doesn't
1069
     * @return string  the SQL query string or null if the driver doesn't
1046
     *                  support the object type requested
1070
     *                  support the object type requested
1047
     *
1071
     *
1048
     * @access protected
1072
     * @access protected
1049
     * @see DB_common::getListOf()
1073
     * @see DB_common::getListOf()
1050
     */
1074
     */
1051
    function getSpecialQuery($type)
1075
    function getSpecialQuery($type)
1052
    {
1076
    {
1053
        switch ($type) {
1077
        switch ($type) {
1054
            case 'tables':
1078
            case 'tables':
1055
                return 'SHOW TABLES';
1079
                return 'SHOW TABLES';
1056
            case 'users':
1080
            case 'users':
1057
                return 'SELECT DISTINCT User FROM mysql.user';
1081
                return 'SELECT DISTINCT User FROM mysql.user';
1058
            case 'databases':
1082
            case 'databases':
1059
                return 'SHOW DATABASES';
1083
                return 'SHOW DATABASES';
1060
            default:
1084
            default:
1061
                return null;
1085
                return null;
1062
        }
1086
        }
1063
    }
1087
    }
1064
 
1088
 
1065
    // }}}
1089
    // }}}
1066
 
1090
 
1067
}
1091
}
1068
 
1092
 
1069
/*
1093
/*
1070
 * Local variables:
1094
 * Local variables:
1071
 * tab-width: 4
1095
 * tab-width: 4
1072
 * c-basic-offset: 4
1096
 * c-basic-offset: 4
1073
 * End:
1097
 * End:
1074
 */
1098
 */
1075
 
1099
 
1076
?>
1100
?>