3 // vim: expandtab sw=4 ts=4 sts=4:
6 * Interface to the improved MySQL extension (MySQLi)
10 if (!defined('PMA_MYSQL_CLIENT_API')) {
11 $client_api = explode('.', mysqli_get_client_info());
12 define('PMA_MYSQL_CLIENT_API', (int)sprintf('%d%02d%02d', $client_api[0], $client_api[1], intval($client_api[2])));
16 // Constants from mysql_com.h of MySQL 4.1.3
18 define('NOT_NULL_FLAG', 1);
19 define('PRI_KEY_FLAG', 2);
20 define('UNIQUE_KEY_FLAG', 4);
21 define('MULTIPLE_KEY_FLAG', 8);
22 define('BLOB_FLAG', 16);
23 define('UNSIGNED_FLAG', 32);
24 define('ZEROFILL_FLAG', 64);
25 define('BINARY_FLAG', 128);
26 define('ENUM_FLAG', 256);
27 define('AUTO_INCREMENT_FLAG', 512);
28 define('TIMESTAMP_FLAG', 1024);
29 define('SET_FLAG', 2048);
30 define('NUM_FLAG', 32768);
31 define('PART_KEY_FLAG', 16384);
32 define('UNIQUE_FLAG', 65536);
34 function PMA_DBI_connect($user, $password, $is_controluser = FALSE) {
35 global $cfg, $php_errormsg;
37 $server_port = (empty($cfg['Server']['port']))
39 : (int) $cfg['Server']['port'];
41 if (strtolower($cfg['Server']['connect_type']) == 'tcp') {
42 $cfg['Server']['socket'] = '';
45 // NULL enables connection to the default socket
46 $server_socket = (empty($cfg['Server']['socket']))
48 : $cfg['Server']['socket'];
50 $link = mysqli_init();
52 mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE
, TRUE);
54 $client_flags = $cfg['Server']['compress'] && defined('MYSQLI_CLIENT_COMPRESS') ? MYSQLI_CLIENT_COMPRESS
: 0;
56 $return_value = @mysqli_real_connect
($link, $cfg['Server']['host'], $user, $password, FALSE, $server_port, $server_socket, $client_flags);
58 if ($return_value == FALSE) {
62 PMA_DBI_postConnect($link, $is_controluser);
67 function PMA_DBI_select_db($dbname, $link = NULL) {
69 if (isset($GLOBALS['userlink'])) {
70 $link = $GLOBALS['userlink'];
75 if (PMA_MYSQL_INT_VERSION
< 40100) {
76 $dbname = PMA_convert_charset($dbname);
78 return mysqli_select_db($link, $dbname);
81 function PMA_DBI_try_query($query, $link = NULL, $options = 0) {
82 if ($options == ($options | PMA_DBI_QUERY_STORE
)) {
83 $method = MYSQLI_STORE_RESULT
;
84 } elseif ($options == ($options | PMA_DBI_QUERY_UNBUFFERED
)) {
85 $method = MYSQLI_USE_RESULT
;
87 $method = MYSQLI_USE_RESULT
;
91 if (isset($GLOBALS['userlink'])) {
92 $link = $GLOBALS['userlink'];
97 if (defined('PMA_MYSQL_INT_VERSION') && PMA_MYSQL_INT_VERSION
< 40100) {
98 $query = PMA_convert_charset($query);
100 return mysqli_query($link, $query, $method);
101 // From the PHP manual:
102 // "note: returns TRUE on success or FALSE on failure. For SELECT,
103 // SHOW, DESCRIBE or EXPLAIN, mysqli_query() will return a result object"
104 // so, do not use the return value to feed mysqli_num_rows() if it's
108 // The following function is meant for internal use only.
109 // Do not call it from outside this library!
110 function PMA_mysqli_fetch_array($result, $type = FALSE) {
111 global $cfg, $allow_recoding, $charset, $convcharset;
113 if ($type != FALSE) {
114 $data = @mysqli_fetch_array
($result, $type);
116 $data = @mysqli_fetch_array
($result);
119 /* No data returned => do not touch it */
120 if (! $data) return $data;
122 if (!defined('PMA_MYSQL_INT_VERSION') || PMA_MYSQL_INT_VERSION
>= 40100
123 ||
!(isset($cfg['AllowAnywhereRecoding']) && $cfg['AllowAnywhereRecoding'] && $allow_recoding)) {
124 /* No recoding -> return data as we got them */
128 $num = mysqli_num_fields($result);
130 $fields = PMA_DBI_get_fields_meta($result);
132 // sometimes, mysqli_fetch_fields() does not return results
133 // (as seen in PHP 5.1.0-dev), so for now, return $data unchanged
138 for ($i = 0; $i < $num; $i++
) {
139 if (!isset($fields[$i]->type
)) {
140 /* No meta information available -> we guess that it should be converted */
141 if (isset($data[$i])) {
142 $ret[$i] = PMA_convert_display_charset($data[$i]);
144 if (isset($fields[$i]->name
) && isset($data[$fields[$i]->name
])) {
145 $ret[PMA_convert_display_charset($fields[$i]->name
)] = PMA_convert_display_charset($data[$fields[$i]->name
]);
148 /* Meta information available -> check type of field and convert it according to the type */
149 if (stristr($fields[$i]->type
, 'BLOB') ||
stristr($fields[$i]->type
, 'BINARY')) {
150 if (isset($data[$i])) {
151 $ret[$i] = $data[$i];
153 if (isset($data[$fields[$i]->name
])) {
154 $ret[PMA_convert_display_charset($fields[$i]->name
)] = $data[$fields[$i]->name
];
157 if (isset($data[$i])) {
158 $ret[$i] = PMA_convert_display_charset($data[$i]);
160 if (isset($data[$fields[$i]->name
])) {
161 $ret[PMA_convert_display_charset($fields[$i]->name
)] = PMA_convert_display_charset($data[$fields[$i]->name
]);
170 function PMA_DBI_fetch_array($result) {
171 return PMA_mysqli_fetch_array($result, MYSQLI_BOTH
);
174 function PMA_DBI_fetch_assoc($result) {
175 return PMA_mysqli_fetch_array($result, MYSQLI_ASSOC
);
178 function PMA_DBI_fetch_row($result) {
179 return PMA_mysqli_fetch_array($result, MYSQLI_NUM
);
182 function PMA_DBI_free_result($result) {
183 if (!is_bool($result)) {
184 return mysqli_free_result($result);
191 * returns last error message or false if no errors occured
193 * @uses PMA_MYSQL_INT_VERSION
194 * @uses PMA_convert_display_charset()
195 * @uses PMA_DBI_convert_message()
196 * @uses $GLOBALS['errno']
197 * @uses $GLOBALS['userlink']
198 * @uses $GLOBALS['strServerNotResponding']
199 * @uses $GLOBALS['strSocketProblem']
200 * @uses mysqli_errno()
201 * @uses mysqli_error()
202 * @uses mysqli_connect_errno()
203 * @uses mysqli_connect_error()
205 * @param resource $link mysql link
206 * @return string|boolean $error or false
208 function PMA_DBI_getError( $link = NULL ) {
209 unset( $GLOBALS['errno'] );
211 if ( NULL === $link && isset( $GLOBALS['userlink'] ) ) {
212 $link =& $GLOBALS['userlink'];
213 // Do not stop now. We still can get the error code
214 // with mysqli_connect_errno()
219 if ( NULL !== $link ) {
220 $error_number = mysqli_errno( $link );
221 $error_message = mysqli_error( $link );
223 $error_number = mysqli_connect_errno();
224 $error_message = mysqli_connect_error();
226 if ( 0 == $error_number ) {
230 // keep the error number for further check after the call to PMA_DBI_getError()
231 $GLOBALS['errno'] = $error_number;
233 if ( ! empty( $error_message ) ) {
234 $error_message = PMA_DBI_convert_message( $error_message );
237 if ( $error_number == 2002 ) {
238 $error = '#' . ((string) $error_number) . ' - ' . $GLOBALS['strServerNotResponding'] . ' ' . $GLOBALS['strSocketProblem'];
239 } elseif ( defined( 'PMA_MYSQL_INT_VERSION' ) && PMA_MYSQL_INT_VERSION
>= 40100 ) {
240 $error = '#' . ((string) $error_number) . ' - ' . $error_message;
242 $error = '#' . ((string) $error_number) . ' - ' . PMA_convert_display_charset($error_message);
247 function PMA_DBI_close($link = NULL) {
249 if (isset($GLOBALS['userlink'])) {
250 $link = $GLOBALS['userlink'];
255 return @mysqli_close
($link);
258 function PMA_DBI_num_rows($result) {
259 // see the note for PMA_DBI_try_query();
260 if (!is_bool($result)) {
261 return @mysqli_num_rows
($result);
267 function PMA_DBI_insert_id($link = '') {
269 if (isset($GLOBALS['userlink'])) {
270 $link = $GLOBALS['userlink'];
275 return mysqli_insert_id($link);
278 function PMA_DBI_affected_rows($link = NULL) {
280 if (isset($GLOBALS['userlink'])) {
281 $link = $GLOBALS['userlink'];
286 return mysqli_affected_rows($link);
289 function PMA_DBI_get_fields_meta($result) {
290 // Build an associative array for a type look up
292 $typeAr[MYSQLI_TYPE_DECIMAL
] = 'real';
293 $typeAr[MYSQLI_TYPE_TINY
] = 'int';
294 $typeAr[MYSQLI_TYPE_SHORT
] = 'int';
295 $typeAr[MYSQLI_TYPE_LONG
] = 'int';
296 $typeAr[MYSQLI_TYPE_FLOAT
] = 'real';
297 $typeAr[MYSQLI_TYPE_DOUBLE
] = 'real';
298 $typeAr[MYSQLI_TYPE_NULL
] = 'null';
299 $typeAr[MYSQLI_TYPE_TIMESTAMP
] = 'timestamp';
300 $typeAr[MYSQLI_TYPE_LONGLONG
] = 'int';
301 $typeAr[MYSQLI_TYPE_INT24
] = 'int';
302 $typeAr[MYSQLI_TYPE_DATE
] = 'date';
303 $typeAr[MYSQLI_TYPE_TIME
] = 'time';
304 $typeAr[MYSQLI_TYPE_DATETIME
] = 'datetime';
305 $typeAr[MYSQLI_TYPE_YEAR
] = 'year';
306 $typeAr[MYSQLI_TYPE_NEWDATE
] = 'date';
307 $typeAr[MYSQLI_TYPE_ENUM
] = 'unknown';
308 $typeAr[MYSQLI_TYPE_SET
] = 'unknown';
309 $typeAr[MYSQLI_TYPE_TINY_BLOB
] = 'blob';
310 $typeAr[MYSQLI_TYPE_MEDIUM_BLOB
] = 'blob';
311 $typeAr[MYSQLI_TYPE_LONG_BLOB
] = 'blob';
312 $typeAr[MYSQLI_TYPE_BLOB
] = 'blob';
313 $typeAr[MYSQLI_TYPE_VAR_STRING
] = 'string';
314 $typeAr[MYSQLI_TYPE_STRING
] = 'string';
315 $typeAr[MYSQLI_TYPE_CHAR
] = 'string';
316 $typeAr[MYSQLI_TYPE_GEOMETRY
] = 'unknown';
318 $fields = mysqli_fetch_fields($result);
320 // this happens sometimes (seen under MySQL 4.0.25)
321 if (!is_array($fields)) {
325 foreach ($fields as $k => $field) {
326 $fields[$k]->type
= $typeAr[$fields[$k]->type
];
327 $fields[$k]->flags
= PMA_DBI_field_flags($result, $k);
329 // Enhance the field objects for mysql-extension compatibilty
330 $flags = explode(' ', $fields[$k]->flags
);
331 array_unshift($flags, 'dummy');
332 $fields[$k]->multiple_key
= (int)(array_search('multiple_key', $flags, true) > 0);
333 $fields[$k]->primary_key
= (int)(array_search('primary_key', $flags, true) > 0);
334 $fields[$k]->unique_key
= (int)(array_search('unique_key', $flags, true) > 0);
335 $fields[$k]->not_null
= (int)(array_search('not_null', $flags, true) > 0);
336 $fields[$k]->unsigned
= (int)(array_search('unsigned', $flags, true) > 0);
337 $fields[$k]->zerofill
= (int)(array_search('zerofill', $flags, true) > 0);
338 $fields[$k]->numeric = (int)(array_search('num', $flags, true) > 0);
339 $fields[$k]->blob
= (int)(array_search('blob', $flags, true) > 0);
344 function PMA_DBI_num_fields($result) {
345 return mysqli_num_fields($result);
348 function PMA_DBI_field_len($result, $i) {
349 $info = mysqli_fetch_field_direct($result, $i);
350 // stdClass::$length will be integrated in
351 // mysqli-ext when mysql4.1 has been released.
352 return @$info->length
;
355 function PMA_DBI_field_name($result, $i) {
356 $info = mysqli_fetch_field_direct($result, $i);
360 function PMA_DBI_field_flags($result, $i) {
361 $f = mysqli_fetch_field_direct($result, $i);
364 if ($f & UNIQUE_FLAG
) { $flags .= 'unique ';}
365 if ($f & NUM_FLAG
) { $flags .= 'num ';}
366 if ($f & PART_KEY_FLAG
) { $flags .= 'part_key ';}
367 if ($f & SET_FLAG
) { $flags .= 'set ';}
368 if ($f & TIMESTAMP_FLAG
) { $flags .= 'timestamp ';}
369 if ($f & AUTO_INCREMENT_FLAG
) { $flags .= 'auto_increment ';}
370 if ($f & ENUM_FLAG
) { $flags .= 'enum ';}
371 if ($f & BINARY_FLAG
) { $flags .= 'binary ';}
372 if ($f & ZEROFILL_FLAG
) { $flags .= 'zerofill ';}
373 if ($f & UNSIGNED_FLAG
) { $flags .= 'unsigned ';}
374 if ($f & BLOB_FLAG
) { $flags .= 'blob ';}
375 if ($f & MULTIPLE_KEY_FLAG
) { $flags .= 'multiple_key ';}
376 if ($f & UNIQUE_KEY_FLAG
) { $flags .= 'unique_key ';}
377 if ($f & PRI_KEY_FLAG
) { $flags .= 'primary_key ';}
378 if ($f & NOT_NULL_FLAG
) { $flags .= 'not_null ';}
379 return PMA_convert_display_charset(trim($flags));