Upgraded phpmyadmin to 4.0.4 (All Languages) - No modifications yet
[openemr.git] / phpmyadmin / libraries / dbi / drizzle.dbi.lib.php
blob093e5d624b50bcb0a4fae925431f312bf5e4cb6f
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Interface to the Drizzle extension
6 * WARNING - EXPERIMENTAL, never use in production,
7 * drizzle module segfaults often and when you least expect it to
9 * TODO: This file and drizzle-wrappers.lib.php should be devoid
10 * of any segault related hacks.
11 * TODO: Crashing versions of drizzle module and/or libdrizzle
12 * should be blacklisted
14 * @package PhpMyAdmin-DBI
15 * @subpackage Drizzle
17 if (! defined('PHPMYADMIN')) {
18 exit;
21 require_once './libraries/logging.lib.php';
22 require_once './libraries/dbi/drizzle-wrappers.lib.php';
24 /**
25 * MySQL client API
27 if (!defined('PMA_MYSQL_CLIENT_API')) {
28 define('PMA_MYSQL_CLIENT_API', (int)drizzle_version());
31 /**
32 * Helper function for connecting to the database server
34 * @param PMA_Drizzle $drizzle connection handle
35 * @param string $host Drizzle host
36 * @param integer $port Drizzle port
37 * @param string $uds server socket
38 * @param string $user username
39 * @param string $password password
40 * @param string $db database name
41 * @param integer $options connection options
43 * @return PMA_DrizzleCon
45 function PMA_DBI_real_connect($drizzle, $host, $port, $uds, $user, $password,
46 $db = null, $options = DRIZZLE_CON_NONE
47 ) {
48 if ($uds) {
49 $con = $drizzle->addUds($uds, $user, $password, $db, $options);
50 } else {
51 $con = $drizzle->addTcp($host, $port, $user, $password, $db, $options);
54 return $con;
57 /**
58 * connects to the database server
60 * @param string $user drizzle user name
61 * @param string $password drizzle user password
62 * @param bool $is_controluser whether this is a control user connection
63 * @param array $server host/port/socket/persistent
64 * @param bool $auxiliary_connection (when true, don't go back to login if
65 * connection fails)
67 * @return mixed false on error or a mysqli object on success
69 function PMA_DBI_connect($user, $password, $is_controluser = false,
70 $server = null, $auxiliary_connection = false
71 ) {
72 global $cfg;
74 if ($server) {
75 $server_port = (empty($server['port']))
76 ? false
77 : (int)$server['port'];
78 $server_socket = (empty($server['socket']))
79 ? ''
80 : $server['socket'];
81 $server['host'] = (empty($server['host']))
82 ? 'localhost'
83 : $server['host'];
84 } else {
85 $server_port = (empty($cfg['Server']['port']))
86 ? false
87 : (int) $cfg['Server']['port'];
88 $server_socket = (empty($cfg['Server']['socket']))
89 ? null
90 : $cfg['Server']['socket'];
93 if (strtolower($GLOBALS['cfg']['Server']['connect_type']) == 'tcp') {
94 $GLOBALS['cfg']['Server']['socket'] = '';
97 $drizzle = new PMA_Drizzle();
99 $client_flags = 0;
101 /* Optionally compress connection */
102 if ($GLOBALS['cfg']['Server']['compress']) {
103 $client_flags |= DRIZZLE_CAPABILITIES_COMPRESS;
106 /* Optionally enable SSL */
107 if ($GLOBALS['cfg']['Server']['ssl']) {
108 $client_flags |= DRIZZLE_CAPABILITIES_SSL;
111 if (!$server) {
112 $link = @PMA_DBI_real_connect(
113 $drizzle, $cfg['Server']['host'], $server_port, $server_socket, $user,
114 $password, false, $client_flags
116 // Retry with empty password if we're allowed to
117 if ($link == false && isset($cfg['Server']['nopassword'])
118 && $cfg['Server']['nopassword'] && !$is_controluser
120 $link = @PMA_DBI_real_connect(
121 $drizzle, $cfg['Server']['host'], $server_port, $server_socket,
122 $user, null, false, $client_flags
125 } else {
126 $link = @PMA_DBI_real_connect(
127 $drizzle, $server['host'], $server_port, $server_socket,
128 $user, $password
132 if ($link == false) {
133 if ($is_controluser) {
134 trigger_error(
136 'Connection for controluser as defined'
137 . ' in your configuration failed.'
139 E_USER_WARNING
141 return false;
143 // we could be calling PMA_DBI_connect() to connect to another
144 // server, for example in the Synchronize feature, so do not
145 // go back to main login if it fails
146 if (! $auxiliary_connection) {
147 PMA_log_user($user, 'drizzle-denied');
148 global $auth_plugin;
149 $auth_plugin->authFails();
150 } else {
151 return false;
153 } else {
154 PMA_DBI_postConnect($link, $is_controluser);
157 return $link;
161 * selects given database
163 * @param string $dbname database name to select
164 * @param PMA_DrizzleCom $link connection object
166 * @return bool
168 function PMA_DBI_select_db($dbname, $link = null)
170 if (empty($link)) {
171 if (isset($GLOBALS['userlink'])) {
172 $link = $GLOBALS['userlink'];
173 } else {
174 return false;
177 return $link->selectDb($dbname);
181 * runs a query and returns the result
183 * @param string $query query to execute
184 * @param PMA_DrizzleCon $link connection object
185 * @param int $options query options
187 * @return PMA_DrizzleResult
189 function PMA_DBI_real_query($query, $link, $options)
191 $buffer_mode = $options & PMA_DBI_QUERY_UNBUFFERED
192 ? PMA_Drizzle::BUFFER_ROW
193 : PMA_Drizzle::BUFFER_RESULT;
194 $res = $link->query($query, $buffer_mode);
195 return $res;
199 * returns array of rows with associative and numeric keys from $result
201 * @param PMA_DrizzleResult $result Drizzle result object
203 * @return array
205 function PMA_DBI_fetch_array($result)
207 return $result->fetchRow(PMA_Drizzle::FETCH_BOTH);
211 * returns array of rows with associative keys from $result
213 * @param PMA_DrizzleResult $result Drizzle result object
215 * @return array
217 function PMA_DBI_fetch_assoc($result)
219 return $result->fetchRow(PMA_Drizzle::FETCH_ASSOC);
223 * returns array of rows with numeric keys from $result
225 * @param PMA_DrizzleResult $result Drizzle result object
227 * @return array
229 function PMA_DBI_fetch_row($result)
231 return $result->fetchRow(PMA_Drizzle::FETCH_NUM);
235 * Adjusts the result pointer to an arbitrary row in the result
237 * @param PMA_DrizzleResult $result Drizzle result object
238 * @param int $offset offset to seek
240 * @return boolean true on success, false on failure
242 function PMA_DBI_data_seek($result, $offset)
244 return $result->seek($offset);
248 * Frees memory associated with the result
250 * @param PMA_DrizzleResult $result database result
252 * @return void
254 function PMA_DBI_free_result($result)
256 if ($result instanceof PMA_DrizzleResult) {
257 $result->free();
262 * Check if there are any more query results from a multi query
264 * @return bool false
266 function PMA_DBI_more_results()
268 // N.B.: PHP's 'mysql' extension does not support
269 // multi_queries so this function will always
270 // return false. Use the 'mysqli' extension, if
271 // you need support for multi_queries.
272 return false;
276 * Prepare next result from multi_query
278 * @return bool false
280 function PMA_DBI_next_result()
282 // N.B.: PHP's 'mysql' extension does not support
283 // multi_queries so this function will always
284 // return false. Use the 'mysqli' extension, if
285 // you need support for multi_queries.
286 return false;
290 * Returns a string representing the type of connection used
292 * @param PMA_DrizzleCon $link connection object
294 * @return string type of connection used
296 function PMA_DBI_get_host_info($link = null)
298 if (null === $link) {
299 if (isset($GLOBALS['userlink'])) {
300 $link = $GLOBALS['userlink'];
301 } else {
302 return false;
306 $str = $link->port()
307 ? $link->host() . ':' . $link->port() . ' via TCP/IP'
308 : 'Localhost via UNIX socket';
309 return $str;
313 * Returns the version of the Drizzle protocol used
315 * @param PMA_DrizzleCon $link connection object
317 * @return int version of the Drizzle protocol used
319 function PMA_DBI_get_proto_info($link = null)
321 if (null === $link) {
322 if (isset($GLOBALS['userlink'])) {
323 $link = $GLOBALS['userlink'];
324 } else {
325 return false;
329 return $link->protocolVersion();
333 * returns a string that represents the client library version
335 * @return string Drizzle client library version
337 function PMA_DBI_get_client_info()
339 return 'libdrizzle (Drizzle ' . drizzle_version() . ')';
343 * returns last error message or false if no errors occured
345 * @param PMA_DrizzleCon $link connection object
347 * @return string|bool $error or false
349 function PMA_DBI_getError($link = null)
351 $GLOBALS['errno'] = 0;
353 /* Treat false same as null because of controllink */
354 if ($link === false) {
355 $link = null;
358 if (null === $link && isset($GLOBALS['userlink'])) {
359 $link =& $GLOBALS['userlink'];
360 // Do not stop now. We still can get the error code
361 // with mysqli_connect_errno()
362 // } else {
363 // return false;
366 if (null !== $link) {
367 $error_number = drizzle_con_errno($link->getConnectionObject());
368 $error_message = drizzle_con_error($link->getConnectionObject());
369 } else {
370 $error_number = drizzle_errno();
371 $error_message = drizzle_error();
373 if (0 == $error_number) {
374 return false;
377 // keep the error number for further check after the call to PMA_DBI_getError()
378 $GLOBALS['errno'] = $error_number;
380 return PMA_DBI_formatError($error_number, $error_message);
384 * returns the number of rows returned by last query
386 * @param PMA_DrizzleResult $result Drizzle result object
388 * @return string|int
390 function PMA_DBI_num_rows($result)
392 // see the note for PMA_DBI_try_query();
393 if (!is_bool($result)) {
394 return @$result->numRows();
395 } else {
396 return 0;
401 * returns last inserted auto_increment id for given $link or $GLOBALS['userlink']
403 * @param PMA_DrizzleCon $link connection object
405 * @return string|int
407 function PMA_DBI_insert_id($link = null)
409 if (empty($link)) {
410 if (isset($GLOBALS['userlink'])) {
411 $link = $GLOBALS['userlink'];
412 } else {
413 return false;
417 // copied from mysql and mysqli
419 // When no controluser is defined, using mysqli_insert_id($link)
420 // does not always return the last insert id due to a mixup with
421 // the tracking mechanism, but this works:
422 return PMA_DBI_fetch_value('SELECT LAST_INSERT_ID();', 0, 0, $link);
423 // Curiously, this problem does not happen with the mysql extension but
424 // there is another problem with BIGINT primary keys so PMA_DBI_insert_id()
425 // in the mysql extension also uses this logic.
429 * returns the number of rows affected by last query
431 * @param PMA_DrizzleResult $link connection object
432 * @param bool $get_from_cache whether to retrieve from cache
434 * @return string|int
436 function PMA_DBI_affected_rows($link = null, $get_from_cache = true)
438 if (empty($link)) {
439 if (isset($GLOBALS['userlink'])) {
440 $link = $GLOBALS['userlink'];
441 } else {
442 return false;
445 if ($get_from_cache) {
446 return $GLOBALS['cached_affected_rows'];
447 } else {
448 return $link->affectedRows();
453 * returns metainfo for fields in $result
455 * @param PMA_DrizzleResult $result Drizzle result object
457 * @return array meta info for fields in $result
459 function PMA_DBI_get_fields_meta($result)
461 // Build an associative array for a type look up
462 $typeAr = array();
463 /*$typeAr[DRIZZLE_COLUMN_TYPE_DECIMAL] = 'real';
464 $typeAr[DRIZZLE_COLUMN_TYPE_NEWDECIMAL] = 'real';
465 $typeAr[DRIZZLE_COLUMN_TYPE_BIT] = 'int';
466 $typeAr[DRIZZLE_COLUMN_TYPE_TINY] = 'int';
467 $typeAr[DRIZZLE_COLUMN_TYPE_SHORT] = 'int';
468 $typeAr[DRIZZLE_COLUMN_TYPE_LONG] = 'int';
469 $typeAr[DRIZZLE_COLUMN_TYPE_FLOAT] = 'real';
470 $typeAr[DRIZZLE_COLUMN_TYPE_DOUBLE] = 'real';
471 $typeAr[DRIZZLE_COLUMN_TYPE_NULL] = 'null';
472 $typeAr[DRIZZLE_COLUMN_TYPE_TIMESTAMP] = 'timestamp';
473 $typeAr[DRIZZLE_COLUMN_TYPE_LONGLONG] = 'int';
474 $typeAr[DRIZZLE_COLUMN_TYPE_INT24] = 'int';
475 $typeAr[DRIZZLE_COLUMN_TYPE_DATE] = 'date';
476 $typeAr[DRIZZLE_COLUMN_TYPE_TIME] = 'date';
477 $typeAr[DRIZZLE_COLUMN_TYPE_DATETIME] = 'datetime';
478 $typeAr[DRIZZLE_COLUMN_TYPE_YEAR] = 'year';
479 $typeAr[DRIZZLE_COLUMN_TYPE_NEWDATE] = 'date';
480 $typeAr[DRIZZLE_COLUMN_TYPE_ENUM] = 'unknown';
481 $typeAr[DRIZZLE_COLUMN_TYPE_SET] = 'unknown';
482 $typeAr[DRIZZLE_COLUMN_TYPE_VIRTUAL] = 'unknown';
483 $typeAr[DRIZZLE_COLUMN_TYPE_TINY_BLOB] = 'blob';
484 $typeAr[DRIZZLE_COLUMN_TYPE_MEDIUM_BLOB] = 'blob';
485 $typeAr[DRIZZLE_COLUMN_TYPE_LONG_BLOB] = 'blob';
486 $typeAr[DRIZZLE_COLUMN_TYPE_BLOB] = 'blob';
487 $typeAr[DRIZZLE_COLUMN_TYPE_VAR_STRING] = 'string';
488 $typeAr[DRIZZLE_COLUMN_TYPE_VARCHAR] = 'string';
489 $typeAr[DRIZZLE_COLUMN_TYPE_STRING] = 'string';
490 $typeAr[DRIZZLE_COLUMN_TYPE_GEOMETRY] = 'geometry';*/
492 $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_BLOB] = 'blob';
493 $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DATE] = 'date';
494 $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DATETIME] = 'datetime';
495 $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DOUBLE] = 'real';
496 $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_ENUM] = 'unknown';
497 $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_LONG] = 'int';
498 $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_LONGLONG] = 'int';
499 $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_MAX] = 'unknown';
500 $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_NULL] = 'null';
501 $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_TIMESTAMP] = 'timestamp';
502 $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_TINY] = 'int';
503 $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_VARCHAR] = 'string';
505 // array of DrizzleColumn
506 $columns = $result->getColumns();
507 // columns in a standarized format
508 $std_columns = array();
510 foreach ($columns as $k => $column) {
511 $c = new stdClass();
512 $c->name = $column->name();
513 $c->orgname = $column->origName();
514 $c->table = $column->table();
515 $c->orgtable = $column->origTable();
516 $c->def = $column->defaultValue();
517 $c->db = $column->db();
518 $c->catalog = $column->catalog();
519 // $column->maxSize() returns always 0 while size() seems
520 // to return a correct value (drizzle extension v.0.5, API v.7)
521 $c->max_length = $column->size();
522 $c->decimals = $column->decimals();
523 $c->charsetnr = $column->charset();
524 $c->type = $typeAr[$column->typeDrizzle()];
525 $c->_type = $column->type();
526 $c->flags = PMA_DBI_field_flags($result, $k);
527 $c->_flags = $column->flags();
529 $c->multiple_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_MULTIPLE_KEY);
530 $c->primary_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_PRI_KEY);
531 $c->unique_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY);
532 $c->not_null = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_NOT_NULL);
533 $c->unsigned = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_UNSIGNED);
534 $c->zerofill = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_ZEROFILL);
535 $c->numeric = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_NUM);
536 $c->blob = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_BLOB);
538 $std_columns[] = $c;
541 return $std_columns;
545 * return number of fields in given $result
547 * @param PMA_DrizzleResult $result Drizzle result object
549 * @return int field count
551 function PMA_DBI_num_fields($result)
553 return $result->numColumns();
557 * returns the length of the given field $i in $result
559 * @param PMA_DrizzleResult $result Drizzle result object
560 * @param int $i field
562 * @return int length of field
564 function PMA_DBI_field_len($result, $i)
566 $colums = $result->getColumns();
567 return $colums[$i]->size();
571 * returns name of $i. field in $result
573 * @param PMA_DrizzleResult $result Drizzle result object
574 * @param int $i field
576 * @return string name of $i. field in $result
578 function PMA_DBI_field_name($result, $i)
580 $colums = $result->getColumns();
581 return $colums[$i]->name();
585 * returns concatenated string of human readable field flags
587 * @param PMA_DrizzleResult $result Drizzle result object
588 * @param int $i field
590 * @return string field flags
592 function PMA_DBI_field_flags($result, $i)
594 $columns = $result->getColumns();
595 $f = $columns[$i];
596 $type = $f->typeDrizzle();
597 $charsetnr = $f->charset();
598 $f = $f->flags();
599 $flags = '';
600 if ($f & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY) {
601 $flags .= 'unique ';
603 if ($f & DRIZZLE_COLUMN_FLAGS_NUM) {
604 $flags .= 'num ';
606 if ($f & DRIZZLE_COLUMN_FLAGS_PART_KEY) {
607 $flags .= 'part_key ';
609 if ($f & DRIZZLE_COLUMN_FLAGS_SET) {
610 $flags .= 'set ';
612 if ($f & DRIZZLE_COLUMN_FLAGS_TIMESTAMP) {
613 $flags .= 'timestamp ';
615 if ($f & DRIZZLE_COLUMN_FLAGS_AUTO_INCREMENT) {
616 $flags .= 'auto_increment ';
618 if ($f & DRIZZLE_COLUMN_FLAGS_ENUM) {
619 $flags .= 'enum ';
621 // See http://dev.mysql.com/doc/refman/6.0/en/c-api-datatypes.html:
622 // to determine if a string is binary, we should not use MYSQLI_BINARY_FLAG
623 // but instead the charsetnr member of the MYSQL_FIELD
624 // structure. Watch out: some types like DATE returns 63 in charsetnr
625 // so we have to check also the type.
626 // Unfortunately there is no equivalent in the mysql extension.
627 if (($type == DRIZZLE_COLUMN_TYPE_DRIZZLE_BLOB
628 || $type == DRIZZLE_COLUMN_TYPE_DRIZZLE_VARCHAR)
629 && 63 == $charsetnr
631 $flags .= 'binary ';
633 if ($f & DRIZZLE_COLUMN_FLAGS_ZEROFILL) {
634 $flags .= 'zerofill ';
636 if ($f & DRIZZLE_COLUMN_FLAGS_UNSIGNED) {
637 $flags .= 'unsigned ';
639 if ($f & DRIZZLE_COLUMN_FLAGS_BLOB) {
640 $flags .= 'blob ';
642 if ($f & DRIZZLE_COLUMN_FLAGS_MULTIPLE_KEY) {
643 $flags .= 'multiple_key ';
645 if ($f & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY) {
646 $flags .= 'unique_key ';
648 if ($f & DRIZZLE_COLUMN_FLAGS_PRI_KEY) {
649 $flags .= 'primary_key ';
651 if ($f & DRIZZLE_COLUMN_FLAGS_NOT_NULL) {
652 $flags .= 'not_null ';
654 return trim($flags);
658 * Store the result returned from multi query
660 * @return false
662 function PMA_DBI_store_result()
664 return false;