diff options
Diffstat (limited to 'hugo/libraries/dbi')
| -rw-r--r-- | hugo/libraries/dbi/drizzle-wrappers.lib.php | 437 | ||||
| -rw-r--r-- | hugo/libraries/dbi/drizzle.dbi.lib.php | 667 | ||||
| -rw-r--r-- | hugo/libraries/dbi/dummy.lib.php | 511 | ||||
| -rw-r--r-- | hugo/libraries/dbi/mysql.dbi.lib.php | 552 | ||||
| -rw-r--r-- | hugo/libraries/dbi/mysqli.dbi.lib.php | 748 |
5 files changed, 2915 insertions, 0 deletions
diff --git a/hugo/libraries/dbi/drizzle-wrappers.lib.php b/hugo/libraries/dbi/drizzle-wrappers.lib.php new file mode 100644 index 0000000..430a78d --- /dev/null +++ b/hugo/libraries/dbi/drizzle-wrappers.lib.php @@ -0,0 +1,437 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Wrappers for Drizzle extension classes + * + * Drizzle extension exposes libdrizzle functions and requires user to have it in + * mind while using them. + * This wrapper is not complete and hides a lot of original functionality, + * but allows for easy usage of the drizzle PHP extension. + * + * @package PhpMyAdmin-DBI + * @subpackage Drizzle + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/** + * Workaround for crashing module + * + * @return void + * + * @todo drizzle module segfaults while freeing resources, often. + * This allows at least for some development + */ +function PMA_drizzleShutdownFlush() +{ + flush(); +} +register_shutdown_function('PMA_drizzleShutdownFlush'); + +/** + * Wrapper for Drizzle class + * + * @package PhpMyAdmin-DBI + * @subpackage Drizzle + */ +class PMA_Drizzle extends Drizzle +{ + /** + * Fetch mode: result rows contain column names + */ + const FETCH_ASSOC = 1; + /** + * Fetch mode: result rows contain only numeric indices + */ + const FETCH_NUM = 2; + /** + * Fetch mode: result rows have both column names and numeric indices + */ + const FETCH_BOTH = 3; + + /** + * Result buffering: entire result set is buffered upon execution + */ + const BUFFER_RESULT = 1; + /** + * Result buffering: buffering occurs only on row level + */ + const BUFFER_ROW = 2; + + /** + * Constructor + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Creates a new database conection using TCP + * + * @param string $host Drizzle host + * @param integer $port Drizzle port + * @param string $user username + * @param string $password password + * @param string $db database name + * @param integer $options connection options + * + * @return PMA_DrizzleCon + */ + public function addTcp($host, $port, $user, $password, $db, $options) + { + $dcon = parent::addTcp($host, $port, $user, $password, $db, $options); + return $dcon instanceof DrizzleCon + ? new PMA_DrizzleCon($dcon) + : $dcon; + } + + /** + * Creates a new connection using unix domain socket + * + * @param string $uds socket + * @param string $user username + * @param string $password password + * @param string $db database name + * @param integer $options connection options + * + * @return PMA_DrizzleCon + */ + public function addUds($uds, $user, $password, $db, $options) + { + $dcon = parent::addUds($uds, $user, $password, $db, $options); + return $dcon instanceof DrizzleCon + ? new PMA_DrizzleCon($dcon) + : $dcon; + } +} + +/** + * Wrapper around DrizzleCon class + * + * Its main task is to wrap results with PMA_DrizzleResult class + * + * @package PhpMyAdmin-DBI + * @subpackage Drizzle + */ +class PMA_DrizzleCon +{ + /** + * Instance of DrizzleCon class + * @var DrizzleCon + */ + private $_dcon; + + /** + * Result of the most recent query + * @var PMA_DrizzleResult + */ + private $_lastResult; + + /** + * Constructor + * + * @param DrizzleCon $dcon connection handle + * + * @return void + */ + public function __construct(DrizzleCon $dcon) + { + $this->_dcon = $dcon; + } + + /** + * Executes given query. Opens database connection if not already done. + * + * @param string $query query to execute + * @param int $bufferMode PMA_Drizzle::BUFFER_RESULT,PMA_Drizzle::BUFFER_ROW + * @param int $fetchMode PMA_Drizzle::FETCH_ASSOC, PMA_Drizzle::FETCH_NUM + * or PMA_Drizzle::FETCH_BOTH + * + * @return PMA_DrizzleResult + */ + public function query($query, $bufferMode = PMA_Drizzle::BUFFER_RESULT, + $fetchMode = PMA_Drizzle::FETCH_ASSOC + ) { + $result = $this->_dcon->query($query); + if ($result instanceof DrizzleResult) { + $this->_lastResult = new PMA_DrizzleResult( + $result, $bufferMode, $fetchMode + ); + return $this->_lastResult; + } + return $result; + } + + /** + * Returns the number of rows affected by last query + * + * @return int|false + */ + public function affectedRows() + { + return $this->_lastResult + ? $this->_lastResult->affectedRows() + : false; + } + + /** + * Pass calls of undefined methods to DrizzleCon object + * + * @param string $method method name + * @param mixed $args method parameters + * + * @return mixed + */ + public function __call($method, $args) + { + return call_user_func_array(array($this->_dcon, $method), $args); + } + + /** + * Returns original Drizzle connection object + * + * @return DrizzleCon + */ + public function getConnectionObject() + { + return $this->_dcon; + } +} + +/** + * Wrapper around DrizzleResult. + * + * Allows for reading result rows as an associative array and hides complexity + * behind buffering. + * + * @package PhpMyAdmin-DBI + * @subpackage Drizzle + */ +class PMA_DrizzleResult +{ + /** + * Instamce of DrizzleResult class + * @var DrizzleResult + */ + private $_dresult; + /** + * Fetch mode + * @var int + */ + private $_fetchMode; + /** + * Buffering mode + * @var int + */ + private $_bufferMode; + + /** + * Cached column data + * @var DrizzleColumn[] + */ + private $_columns = null; + /** + * Cached column names + * @var string[] + */ + private $_columnNames = null; + + /** + * Constructor + * + * @param DrizzleResult $dresult result handler + * @param int $bufferMode buffering mode + * @param int $fetchMode fetching mode + */ + public function __construct(DrizzleResult $dresult, $bufferMode, $fetchMode) + { + $this->_dresult = $dresult; + $this->_bufferMode = $bufferMode; + $this->_fetchMode = $fetchMode; + + if ($this->_bufferMode == PMA_Drizzle::BUFFER_RESULT) { + $this->_dresult->buffer(); + } + } + + /** + * Sets fetch mode + * + * @param int $fetchMode fetch mode + * + * @return void + */ + public function setFetchMode($fetchMode) + { + $this->_fetchMode = $fetchMode; + } + + /** + * Reads information about columns contained in current result + * set into {@see $_columns} and {@see $_columnNames} arrays + * + * @return void + */ + private function _readColumns() + { + $this->_columns = array(); + $this->_columnNames = array(); + if ($this->_bufferMode == PMA_Drizzle::BUFFER_RESULT) { + while (($column = $this->_dresult->columnNext()) !== null) { + $this->_columns[] = $column; + $this->_columnNames[] = $column->name(); + } + } else { + while (($column = $this->_dresult->columnRead()) !== null) { + $this->_columns[] = $column; + $this->_columnNames[] = $column->name(); + } + } + } + + /** + * Returns columns in current result + * + * @return DrizzleColumn[] + */ + public function getColumns() + { + if (!$this->_columns) { + $this->_readColumns(); + } + return $this->_columns; + } + + /** + * Returns number if columns in result + * + * @return int + */ + public function numColumns() + { + return $this->_dresult->columnCount(); + } + + /** + * Transforms result row to conform to current fetch mode + * + * @param mixed &$row row to process + * @param int $fetchMode fetch mode + * + * @return void + */ + private function _transformResultRow(&$row, $fetchMode) + { + if (!$row) { + return; + } + + switch ($fetchMode) { + case PMA_Drizzle::FETCH_ASSOC: + $row = array_combine($this->_columnNames, $row); + break; + case PMA_Drizzle::FETCH_BOTH: + $length = count($row); + for ($i = 0; $i < $length; $i++) { + $row[$this->_columnNames[$i]] = $row[$i]; + } + break; + default: + break; + } + } + + /** + * Fetches next for from this result set + * + * @param int $fetchMode fetch mode to use, if not given the default one is used + * + * @return array|null + */ + public function fetchRow($fetchMode = null) + { + // read column names on first fetch, only buffered results + // allow for reading it later + if (!$this->_columns) { + $this->_readColumns(); + } + if ($fetchMode === null) { + $fetchMode = $this->_fetchMode; + } + $row = null; + switch ($this->_bufferMode) { + case PMA_Drizzle::BUFFER_RESULT: + $row = $this->_dresult->rowNext(); + break; + case PMA_Drizzle::BUFFER_ROW: + $row = $this->_dresult->rowBuffer(); + break; + } + $this->_transformResultRow($row, $fetchMode); + return $row; + } + + /** + * Adjusts the result pointer to an arbitrary row in buffered result + * + * @param integer $row_index where to seek + * + * @return bool + */ + public function seek($row_index) + { + if ($this->_bufferMode != PMA_Drizzle::BUFFER_RESULT) { + trigger_error( + __("Can't seek in an unbuffered result set"), E_USER_WARNING + ); + return false; + } + // rowSeek always returns NULL (drizzle extension v.0.5, API v.7) + if ($row_index >= 0 && $row_index < $this->_dresult->rowCount()) { + $this->_dresult->rowSeek($row_index); + return true; + } + return false; + } + + /** + * Returns the number of rows in buffered result set + * + * @return int|false + */ + public function numRows() + { + if ($this->_bufferMode != PMA_Drizzle::BUFFER_RESULT) { + trigger_error( + __("Can't count rows in an unbuffered result set"), E_USER_WARNING + ); + return false; + } + return $this->_dresult->rowCount(); + } + + /** + * Returns the number of rows affected by query + * + * @return int|false + */ + public function affectedRows() + { + return $this->_dresult->affectedRows(); + } + + /** + * Frees resources taken by this result + * + * @return void + */ + public function free() + { + unset($this->_columns); + unset($this->_columnNames); + drizzle_result_free($this->_dresult); + unset($this->_dresult); + } +} diff --git a/hugo/libraries/dbi/drizzle.dbi.lib.php b/hugo/libraries/dbi/drizzle.dbi.lib.php new file mode 100644 index 0000000..093e5d6 --- /dev/null +++ b/hugo/libraries/dbi/drizzle.dbi.lib.php @@ -0,0 +1,667 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Interface to the Drizzle extension + * + * WARNING - EXPERIMENTAL, never use in production, + * drizzle module segfaults often and when you least expect it to + * + * TODO: This file and drizzle-wrappers.lib.php should be devoid + * of any segault related hacks. + * TODO: Crashing versions of drizzle module and/or libdrizzle + * should be blacklisted + * + * @package PhpMyAdmin-DBI + * @subpackage Drizzle + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +require_once './libraries/logging.lib.php'; +require_once './libraries/dbi/drizzle-wrappers.lib.php'; + +/** + * MySQL client API + */ +if (!defined('PMA_MYSQL_CLIENT_API')) { + define('PMA_MYSQL_CLIENT_API', (int)drizzle_version()); +} + +/** + * Helper function for connecting to the database server + * + * @param PMA_Drizzle $drizzle connection handle + * @param string $host Drizzle host + * @param integer $port Drizzle port + * @param string $uds server socket + * @param string $user username + * @param string $password password + * @param string $db database name + * @param integer $options connection options + * + * @return PMA_DrizzleCon + */ +function PMA_DBI_real_connect($drizzle, $host, $port, $uds, $user, $password, + $db = null, $options = DRIZZLE_CON_NONE +) { + if ($uds) { + $con = $drizzle->addUds($uds, $user, $password, $db, $options); + } else { + $con = $drizzle->addTcp($host, $port, $user, $password, $db, $options); + } + + return $con; +} + +/** + * connects to the database server + * + * @param string $user drizzle user name + * @param string $password drizzle user password + * @param bool $is_controluser whether this is a control user connection + * @param array $server host/port/socket/persistent + * @param bool $auxiliary_connection (when true, don't go back to login if + * connection fails) + * + * @return mixed false on error or a mysqli object on success + */ +function PMA_DBI_connect($user, $password, $is_controluser = false, + $server = null, $auxiliary_connection = false +) { + global $cfg; + + if ($server) { + $server_port = (empty($server['port'])) + ? false + : (int)$server['port']; + $server_socket = (empty($server['socket'])) + ? '' + : $server['socket']; + $server['host'] = (empty($server['host'])) + ? 'localhost' + : $server['host']; + } else { + $server_port = (empty($cfg['Server']['port'])) + ? false + : (int) $cfg['Server']['port']; + $server_socket = (empty($cfg['Server']['socket'])) + ? null + : $cfg['Server']['socket']; + } + + if (strtolower($GLOBALS['cfg']['Server']['connect_type']) == 'tcp') { + $GLOBALS['cfg']['Server']['socket'] = ''; + } + + $drizzle = new PMA_Drizzle(); + + $client_flags = 0; + + /* Optionally compress connection */ + if ($GLOBALS['cfg']['Server']['compress']) { + $client_flags |= DRIZZLE_CAPABILITIES_COMPRESS; + } + + /* Optionally enable SSL */ + if ($GLOBALS['cfg']['Server']['ssl']) { + $client_flags |= DRIZZLE_CAPABILITIES_SSL; + } + + if (!$server) { + $link = @PMA_DBI_real_connect( + $drizzle, $cfg['Server']['host'], $server_port, $server_socket, $user, + $password, false, $client_flags + ); + // Retry with empty password if we're allowed to + if ($link == false && isset($cfg['Server']['nopassword']) + && $cfg['Server']['nopassword'] && !$is_controluser + ) { + $link = @PMA_DBI_real_connect( + $drizzle, $cfg['Server']['host'], $server_port, $server_socket, + $user, null, false, $client_flags + ); + } + } else { + $link = @PMA_DBI_real_connect( + $drizzle, $server['host'], $server_port, $server_socket, + $user, $password + ); + } + + if ($link == false) { + if ($is_controluser) { + trigger_error( + __( + 'Connection for controluser as defined' + . ' in your configuration failed.' + ), + E_USER_WARNING + ); + return false; + } + // we could be calling PMA_DBI_connect() to connect to another + // server, for example in the Synchronize feature, so do not + // go back to main login if it fails + if (! $auxiliary_connection) { + PMA_log_user($user, 'drizzle-denied'); + global $auth_plugin; + $auth_plugin->authFails(); + } else { + return false; + } + } else { + PMA_DBI_postConnect($link, $is_controluser); + } + + return $link; +} + +/** + * selects given database + * + * @param string $dbname database name to select + * @param PMA_DrizzleCom $link connection object + * + * @return bool + */ +function PMA_DBI_select_db($dbname, $link = null) +{ + if (empty($link)) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + return $link->selectDb($dbname); +} + +/** + * runs a query and returns the result + * + * @param string $query query to execute + * @param PMA_DrizzleCon $link connection object + * @param int $options query options + * + * @return PMA_DrizzleResult + */ +function PMA_DBI_real_query($query, $link, $options) +{ + $buffer_mode = $options & PMA_DBI_QUERY_UNBUFFERED + ? PMA_Drizzle::BUFFER_ROW + : PMA_Drizzle::BUFFER_RESULT; + $res = $link->query($query, $buffer_mode); + return $res; +} + +/** + * returns array of rows with associative and numeric keys from $result + * + * @param PMA_DrizzleResult $result Drizzle result object + * + * @return array + */ +function PMA_DBI_fetch_array($result) +{ + return $result->fetchRow(PMA_Drizzle::FETCH_BOTH); +} + +/** + * returns array of rows with associative keys from $result + * + * @param PMA_DrizzleResult $result Drizzle result object + * + * @return array + */ +function PMA_DBI_fetch_assoc($result) +{ + return $result->fetchRow(PMA_Drizzle::FETCH_ASSOC); +} + +/** + * returns array of rows with numeric keys from $result + * + * @param PMA_DrizzleResult $result Drizzle result object + * + * @return array + */ +function PMA_DBI_fetch_row($result) +{ + return $result->fetchRow(PMA_Drizzle::FETCH_NUM); +} + +/** + * Adjusts the result pointer to an arbitrary row in the result + * + * @param PMA_DrizzleResult $result Drizzle result object + * @param int $offset offset to seek + * + * @return boolean true on success, false on failure + */ +function PMA_DBI_data_seek($result, $offset) +{ + return $result->seek($offset); +} + +/** + * Frees memory associated with the result + * + * @param PMA_DrizzleResult $result database result + * + * @return void + */ +function PMA_DBI_free_result($result) +{ + if ($result instanceof PMA_DrizzleResult) { + $result->free(); + } +} + +/** + * Check if there are any more query results from a multi query + * + * @return bool false + */ +function PMA_DBI_more_results() +{ + // N.B.: PHP's 'mysql' extension does not support + // multi_queries so this function will always + // return false. Use the 'mysqli' extension, if + // you need support for multi_queries. + return false; +} + +/** + * Prepare next result from multi_query + * + * @return bool false + */ +function PMA_DBI_next_result() +{ + // N.B.: PHP's 'mysql' extension does not support + // multi_queries so this function will always + // return false. Use the 'mysqli' extension, if + // you need support for multi_queries. + return false; +} + +/** + * Returns a string representing the type of connection used + * + * @param PMA_DrizzleCon $link connection object + * + * @return string type of connection used + */ +function PMA_DBI_get_host_info($link = null) +{ + if (null === $link) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + + $str = $link->port() + ? $link->host() . ':' . $link->port() . ' via TCP/IP' + : 'Localhost via UNIX socket'; + return $str; +} + +/** + * Returns the version of the Drizzle protocol used + * + * @param PMA_DrizzleCon $link connection object + * + * @return int version of the Drizzle protocol used + */ +function PMA_DBI_get_proto_info($link = null) +{ + if (null === $link) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + + return $link->protocolVersion(); +} + +/** + * returns a string that represents the client library version + * + * @return string Drizzle client library version + */ +function PMA_DBI_get_client_info() +{ + return 'libdrizzle (Drizzle ' . drizzle_version() . ')'; +} + +/** + * returns last error message or false if no errors occured + * + * @param PMA_DrizzleCon $link connection object + * + * @return string|bool $error or false + */ +function PMA_DBI_getError($link = null) +{ + $GLOBALS['errno'] = 0; + + /* Treat false same as null because of controllink */ + if ($link === false) { + $link = null; + } + + if (null === $link && isset($GLOBALS['userlink'])) { + $link =& $GLOBALS['userlink']; + // Do not stop now. We still can get the error code + // with mysqli_connect_errno() + // } else { + // return false; + } + + if (null !== $link) { + $error_number = drizzle_con_errno($link->getConnectionObject()); + $error_message = drizzle_con_error($link->getConnectionObject()); + } else { + $error_number = drizzle_errno(); + $error_message = drizzle_error(); + } + if (0 == $error_number) { + return false; + } + + // keep the error number for further check after the call to PMA_DBI_getError() + $GLOBALS['errno'] = $error_number; + + return PMA_DBI_formatError($error_number, $error_message); +} + +/** + * returns the number of rows returned by last query + * + * @param PMA_DrizzleResult $result Drizzle result object + * + * @return string|int + */ +function PMA_DBI_num_rows($result) +{ + // see the note for PMA_DBI_try_query(); + if (!is_bool($result)) { + return @$result->numRows(); + } else { + return 0; + } +} + +/** + * returns last inserted auto_increment id for given $link or $GLOBALS['userlink'] + * + * @param PMA_DrizzleCon $link connection object + * + * @return string|int + */ +function PMA_DBI_insert_id($link = null) +{ + if (empty($link)) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + + // copied from mysql and mysqli + + // When no controluser is defined, using mysqli_insert_id($link) + // does not always return the last insert id due to a mixup with + // the tracking mechanism, but this works: + return PMA_DBI_fetch_value('SELECT LAST_INSERT_ID();', 0, 0, $link); + // Curiously, this problem does not happen with the mysql extension but + // there is another problem with BIGINT primary keys so PMA_DBI_insert_id() + // in the mysql extension also uses this logic. +} + +/** + * returns the number of rows affected by last query + * + * @param PMA_DrizzleResult $link connection object + * @param bool $get_from_cache whether to retrieve from cache + * + * @return string|int + */ +function PMA_DBI_affected_rows($link = null, $get_from_cache = true) +{ + if (empty($link)) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + if ($get_from_cache) { + return $GLOBALS['cached_affected_rows']; + } else { + return $link->affectedRows(); + } +} + +/** + * returns metainfo for fields in $result + * + * @param PMA_DrizzleResult $result Drizzle result object + * + * @return array meta info for fields in $result + */ +function PMA_DBI_get_fields_meta($result) +{ + // Build an associative array for a type look up + $typeAr = array(); + /*$typeAr[DRIZZLE_COLUMN_TYPE_DECIMAL] = 'real'; + $typeAr[DRIZZLE_COLUMN_TYPE_NEWDECIMAL] = 'real'; + $typeAr[DRIZZLE_COLUMN_TYPE_BIT] = 'int'; + $typeAr[DRIZZLE_COLUMN_TYPE_TINY] = 'int'; + $typeAr[DRIZZLE_COLUMN_TYPE_SHORT] = 'int'; + $typeAr[DRIZZLE_COLUMN_TYPE_LONG] = 'int'; + $typeAr[DRIZZLE_COLUMN_TYPE_FLOAT] = 'real'; + $typeAr[DRIZZLE_COLUMN_TYPE_DOUBLE] = 'real'; + $typeAr[DRIZZLE_COLUMN_TYPE_NULL] = 'null'; + $typeAr[DRIZZLE_COLUMN_TYPE_TIMESTAMP] = 'timestamp'; + $typeAr[DRIZZLE_COLUMN_TYPE_LONGLONG] = 'int'; + $typeAr[DRIZZLE_COLUMN_TYPE_INT24] = 'int'; + $typeAr[DRIZZLE_COLUMN_TYPE_DATE] = 'date'; + $typeAr[DRIZZLE_COLUMN_TYPE_TIME] = 'date'; + $typeAr[DRIZZLE_COLUMN_TYPE_DATETIME] = 'datetime'; + $typeAr[DRIZZLE_COLUMN_TYPE_YEAR] = 'year'; + $typeAr[DRIZZLE_COLUMN_TYPE_NEWDATE] = 'date'; + $typeAr[DRIZZLE_COLUMN_TYPE_ENUM] = 'unknown'; + $typeAr[DRIZZLE_COLUMN_TYPE_SET] = 'unknown'; + $typeAr[DRIZZLE_COLUMN_TYPE_VIRTUAL] = 'unknown'; + $typeAr[DRIZZLE_COLUMN_TYPE_TINY_BLOB] = 'blob'; + $typeAr[DRIZZLE_COLUMN_TYPE_MEDIUM_BLOB] = 'blob'; + $typeAr[DRIZZLE_COLUMN_TYPE_LONG_BLOB] = 'blob'; + $typeAr[DRIZZLE_COLUMN_TYPE_BLOB] = 'blob'; + $typeAr[DRIZZLE_COLUMN_TYPE_VAR_STRING] = 'string'; + $typeAr[DRIZZLE_COLUMN_TYPE_VARCHAR] = 'string'; + $typeAr[DRIZZLE_COLUMN_TYPE_STRING] = 'string'; + $typeAr[DRIZZLE_COLUMN_TYPE_GEOMETRY] = 'geometry';*/ + + $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_BLOB] = 'blob'; + $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DATE] = 'date'; + $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DATETIME] = 'datetime'; + $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DOUBLE] = 'real'; + $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_ENUM] = 'unknown'; + $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_LONG] = 'int'; + $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_LONGLONG] = 'int'; + $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_MAX] = 'unknown'; + $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_NULL] = 'null'; + $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_TIMESTAMP] = 'timestamp'; + $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_TINY] = 'int'; + $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_VARCHAR] = 'string'; + + // array of DrizzleColumn + $columns = $result->getColumns(); + // columns in a standarized format + $std_columns = array(); + + foreach ($columns as $k => $column) { + $c = new stdClass(); + $c->name = $column->name(); + $c->orgname = $column->origName(); + $c->table = $column->table(); + $c->orgtable = $column->origTable(); + $c->def = $column->defaultValue(); + $c->db = $column->db(); + $c->catalog = $column->catalog(); + // $column->maxSize() returns always 0 while size() seems + // to return a correct value (drizzle extension v.0.5, API v.7) + $c->max_length = $column->size(); + $c->decimals = $column->decimals(); + $c->charsetnr = $column->charset(); + $c->type = $typeAr[$column->typeDrizzle()]; + $c->_type = $column->type(); + $c->flags = PMA_DBI_field_flags($result, $k); + $c->_flags = $column->flags(); + + $c->multiple_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_MULTIPLE_KEY); + $c->primary_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_PRI_KEY); + $c->unique_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY); + $c->not_null = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_NOT_NULL); + $c->unsigned = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_UNSIGNED); + $c->zerofill = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_ZEROFILL); + $c->numeric = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_NUM); + $c->blob = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_BLOB); + + $std_columns[] = $c; + } + + return $std_columns; +} + +/** + * return number of fields in given $result + * + * @param PMA_DrizzleResult $result Drizzle result object + * + * @return int field count + */ +function PMA_DBI_num_fields($result) +{ + return $result->numColumns(); +} + +/** + * returns the length of the given field $i in $result + * + * @param PMA_DrizzleResult $result Drizzle result object + * @param int $i field + * + * @return int length of field + */ +function PMA_DBI_field_len($result, $i) +{ + $colums = $result->getColumns(); + return $colums[$i]->size(); +} + +/** + * returns name of $i. field in $result + * + * @param PMA_DrizzleResult $result Drizzle result object + * @param int $i field + * + * @return string name of $i. field in $result + */ +function PMA_DBI_field_name($result, $i) +{ + $colums = $result->getColumns(); + return $colums[$i]->name(); +} + +/** + * returns concatenated string of human readable field flags + * + * @param PMA_DrizzleResult $result Drizzle result object + * @param int $i field + * + * @return string field flags + */ +function PMA_DBI_field_flags($result, $i) +{ + $columns = $result->getColumns(); + $f = $columns[$i]; + $type = $f->typeDrizzle(); + $charsetnr = $f->charset(); + $f = $f->flags(); + $flags = ''; + if ($f & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY) { + $flags .= 'unique '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_NUM) { + $flags .= 'num '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_PART_KEY) { + $flags .= 'part_key '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_SET) { + $flags .= 'set '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_TIMESTAMP) { + $flags .= 'timestamp '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_AUTO_INCREMENT) { + $flags .= 'auto_increment '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_ENUM) { + $flags .= 'enum '; + } + // See http://dev.mysql.com/doc/refman/6.0/en/c-api-datatypes.html: + // to determine if a string is binary, we should not use MYSQLI_BINARY_FLAG + // but instead the charsetnr member of the MYSQL_FIELD + // structure. Watch out: some types like DATE returns 63 in charsetnr + // so we have to check also the type. + // Unfortunately there is no equivalent in the mysql extension. + if (($type == DRIZZLE_COLUMN_TYPE_DRIZZLE_BLOB + || $type == DRIZZLE_COLUMN_TYPE_DRIZZLE_VARCHAR) + && 63 == $charsetnr + ) { + $flags .= 'binary '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_ZEROFILL) { + $flags .= 'zerofill '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_UNSIGNED) { + $flags .= 'unsigned '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_BLOB) { + $flags .= 'blob '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_MULTIPLE_KEY) { + $flags .= 'multiple_key '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY) { + $flags .= 'unique_key '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_PRI_KEY) { + $flags .= 'primary_key '; + } + if ($f & DRIZZLE_COLUMN_FLAGS_NOT_NULL) { + $flags .= 'not_null '; + } + return trim($flags); +} + +/** + * Store the result returned from multi query + * + * @return false + */ +function PMA_DBI_store_result() +{ + return false; +} + +?> diff --git a/hugo/libraries/dbi/dummy.lib.php b/hugo/libraries/dbi/dummy.lib.php new file mode 100644 index 0000000..66138bc --- /dev/null +++ b/hugo/libraries/dbi/dummy.lib.php @@ -0,0 +1,511 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Fake database driver for testing purposes + * + * It has hardcoded results for given queries what makes easy to use it + * in testsuite. Feel free to include other queries which your test will + * need. + * + * @package PhpMyAdmin-DBI + * @subpackage Dummy + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/** + * Array of queries this "driver" supports + */ +$GLOBALS['dummy_queries'] = array( + array('query' => 'SELECT 1', 'result' => array(array('1'))), + array( + 'query' => 'SELECT CURRENT_USER();', + 'result' => array(array('pma_test@localhost')), + ), + array( + 'query' => 'SELECT COUNT(*) FROM mysql.user', + 'result' => false, + ), + array( + 'query' => 'SHOW MASTER LOGS', + 'result' => false, + ), + array( + 'query' => 'SHOW STORAGE ENGINES', + 'result' => array( + array('Engine' => 'dummy', 'Support' => 'YES', 'Comment' => 'dummy comment'), + array('Engine' => 'dummy2', 'Support' => 'NO', 'Comment' => 'dummy2 comment'), + ) + ), + array( + 'query' => 'SHOW STATUS WHERE Variable_name LIKE \'Innodb\\_buffer\\_pool\\_%\' OR Variable_name = \'Innodb_page_size\';', + 'result' => array( + array('Innodb_buffer_pool_pages_data', 0), + array('Innodb_buffer_pool_pages_dirty', 0), + array('Innodb_buffer_pool_pages_flushed', 0), + array('Innodb_buffer_pool_pages_free', 0), + array('Innodb_buffer_pool_pages_misc', 0), + array('Innodb_buffer_pool_pages_total', 4096), + array('Innodb_buffer_pool_read_ahead_rnd', 0), + array('Innodb_buffer_pool_read_ahead', 0), + array('Innodb_buffer_pool_read_ahead_evicted', 0), + array('Innodb_buffer_pool_read_requests', 64), + array('Innodb_buffer_pool_reads', 32), + array('Innodb_buffer_pool_wait_free', 0), + array('Innodb_buffer_pool_write_requests', 64), + array('Innodb_page_size', 16384), + ) + ), + array( + 'query' => 'SHOW INNODB STATUS;', + 'result' => false, + ), + array( + 'query' => 'SELECT @@innodb_version;', + 'result' => array( + array('1.1.8'), + ) + ), + array( + 'query' => 'SHOW GLOBAL VARIABLES LIKE \'innodb_file_per_table\';', + 'result' => array( + array('innodb_file_per_table', 'OFF'), + ) + ), + array( + 'query' => 'SHOW GLOBAL VARIABLES LIKE \'innodb_file_format\';', + 'result' => array( + array('innodb_file_format', 'Antelope'), + ) + ), + array( + 'query' => 'SHOW VARIABLES LIKE \'collation_server\'', + 'result' => array( + array('collation_server', 'utf8_general_ci'), + ) + ), + array( + 'query' => 'SHOW VARIABLES LIKE \'language\';', + 'result' => array(), + ), + array( + 'query' => 'SHOW TABLES FROM `pma_test`;', + 'result' => array( + array('table1'), + array('table2'), + ) + ), + array( + 'query' => 'SHOW TABLES FROM `pmadb`', + 'result' => array( + array('column_info'), + ) + ), + array( + 'query' => 'SHOW COLUMNS FROM `pma_test`.`table1`', + 'columns' => array( + 'Field', 'Type', 'Null', 'Key', 'Default', 'Extra' + ), + 'result' => array( + array('i', 'int(11)', 'NO', 'PRI', 'NULL', 'auto_increment'), + array('o', 'int(11)', 'NO', 'MUL', 'NULL', ''), + ) + ), + array( + 'query' => 'SHOW INDEXES FROM `pma_test`.`table1` WHERE (Non_unique = 0)', + 'result' => array(), + ), + array( + 'query' => 'SHOW COLUMNS FROM `pma_test`.`table2`', + 'columns' => array( + 'Field', 'Type', 'Null', 'Key', 'Default', 'Extra' + ), + 'result' => array( + array('i', 'int(11)', 'NO', 'PRI', 'NULL', 'auto_increment'), + array('o', 'int(11)', 'NO', 'MUL', 'NULL', ''), + ) + ), + array( + 'query' => 'SHOW INDEXES FROM `pma_test`.`table1`', + 'result' => array(), + ), + array( + 'query' => 'SHOW INDEXES FROM `pma_test`.`table2`', + 'result' => array(), + ), + array( + 'query' => 'SHOW COLUMNS FROM `pma`.`table1`', + 'columns' => array( + 'Field', 'Type', 'Null', 'Key', 'Default', 'Extra', 'Privileges', 'Comment' + ), + 'result' => array( + array('i', 'int(11)', 'NO', 'PRI', 'NULL', 'auto_increment', 'select,insert,update,references', ''), + array('o', 'varchar(100)', 'NO', 'MUL', 'NULL', '', 'select,insert,update,references', ''), + ) + ), + array( + 'query' => 'SELECT * FROM information_schema.CHARACTER_SETS', + 'columns' => array('CHARACTER_SET_NAME', 'DEFAULT_COLLATE_NAME', 'DESCRIPTION', 'MAXLEN'), + 'result' => array( + array('utf8', 'utf8_general_ci', 'UTF-8 Unicode', 3), + ) + ), + array( + 'query' => 'SELECT * FROM information_schema.COLLATIONS', + 'columns' => array( + 'COLLATION_NAME', 'CHARACTER_SET_NAME', 'ID', 'IS_DEFAULT', 'IS_COMPILED', 'SORTLEN' + ), + 'result' => array( + array('utf8_general_ci', 'utf8', 33, 'Yes', 'Yes', 1), + array('utf8_bin', 'utf8', 83, '', 'Yes', 1), + ) + ), + array( + 'query' => 'SELECT `TABLE_NAME` FROM `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=\'pma_test\' AND `TABLE_TYPE`=\'BASE TABLE\'', + 'result' => array(), + ), + array( + 'query' => 'SELECT upper(plugin_name) f FROM data_dictionary.plugins WHERE plugin_name IN (\'MYSQL_PASSWORD\',\'ROT13\') AND plugin_type = \'Function\' AND is_active', + 'columns' => array('f'), + 'result' => array(array('ROT13')), + ), + array( + 'query' => 'SELECT `column_name`, `mimetype`, `transformation`, `transformation_options` FROM `pmadb`.`column_info` WHERE `db_name` = \'pma_test\' AND `table_name` = \'table1\' AND ( `mimetype` != \'\' OR `transformation` != \'\' OR `transformation_options` != \'\')', + 'columns' => array('column_name', 'mimetype', 'transformation', 'transformation_options'), + 'result' => array( + array('o', 'text/plain', 'sql'), + ) + ), + array( + 'query' => 'SELECT TABLE_NAME FROM information_schema.VIEWS WHERE TABLE_SCHEMA = \'pma_test\' AND TABLE_NAME = \'table1\'', + 'result' => array(), + ), + array( + 'query' => 'SELECT *, `TABLE_SCHEMA` AS `Db`, `TABLE_NAME` AS `Name`, `TABLE_TYPE` AS `TABLE_TYPE`, `ENGINE` AS `Engine`, `ENGINE` AS `Type`, `VERSION` AS `Version`, `ROW_FORMAT` AS `Row_format`, `TABLE_ROWS` AS `Rows`, `AVG_ROW_LENGTH` AS `Avg_row_length`, `DATA_LENGTH` AS `Data_length`, `MAX_DATA_LENGTH` AS `Max_data_length`, `INDEX_LENGTH` AS `Index_length`, `DATA_FREE` AS `Data_free`, `AUTO_INCREMENT` AS `Auto_increment`, `CREATE_TIME` AS `Create_time`, `UPDATE_TIME` AS `Update_time`, `CHECK_TIME` AS `Check_time`, `TABLE_COLLATION` AS `Collation`, `CHECKSUM` AS `Checksum`, `CREATE_OPTIONS` AS `Create_options`, `TABLE_COMMENT` AS `Comment` FROM `information_schema`.`TABLES` t WHERE BINARY `TABLE_SCHEMA` IN (\'pma_test\') AND t.`TABLE_NAME` = \'table1\' ORDER BY Name ASC', + 'columns' => array('TABLE_CATALOG', 'TABLE_SCHEMA', 'TABLE_NAME', 'TABLE_TYPE', 'ENGINE', 'VERSION', 'ROW_FORMAT', 'TABLE_ROWS', 'AVG_ROW_LENGTH', 'DATA_LENGTH', 'MAX_DATA_LENGTH', 'INDEX_LENGTH', 'DATA_FREE', 'AUTO_INCREMENT', 'CREATE_TIME', 'UPDATE_TIME', 'CHECK_TIME', 'TABLE_COLLATION', 'CHECKSUM', 'CREATE_OPTIONS', 'TABLE_COMMENT', 'Db', 'Name', 'TABLE_TYPE', 'Engine', 'Type', 'Version', 'Row_format', 'Rows', 'Avg_row_length', 'Data_length', 'Max_data_length', 'Index_length', 'Data_free', 'Auto_increment', 'Create_time', 'Update_time', 'Check_time', 'Collation', 'Checksum', 'Create_options', 'Comment'), + 'result' => array( + array('def', 'smash', 'issues_issue', 'BASE TABLE', 'InnoDB', '10', 'Compact', '9136', '862', '7880704', '0', '1032192', '420478976', '155862', '2012-08-29 13:28:28', 'NULL', 'NULL', 'utf8_general_ci', 'NULL', '', '', 'smash', 'issues_issue', 'BASE TABLE', 'InnoDB', 'InnoDB', '10', 'Compact', '9136', '862', '7880704', '0', '1032192', '420478976', '155862', '2012-08-29 13:28:28', 'NULL', 'NULL', 'utf8_general_ci', 'NULL'), + ), + ), + array( + 'query' => 'SELECT *, `TABLE_SCHEMA` AS `Db`, `TABLE_NAME` AS `Name`, `TABLE_TYPE` AS `TABLE_TYPE`, `ENGINE` AS `Engine`, `ENGINE` AS `Type`, `VERSION` AS `Version`, `ROW_FORMAT` AS `Row_format`, `TABLE_ROWS` AS `Rows`, `AVG_ROW_LENGTH` AS `Avg_row_length`, `DATA_LENGTH` AS `Data_length`, `MAX_DATA_LENGTH` AS `Max_data_length`, `INDEX_LENGTH` AS `Index_length`, `DATA_FREE` AS `Data_free`, `AUTO_INCREMENT` AS `Auto_increment`, `CREATE_TIME` AS `Create_time`, `UPDATE_TIME` AS `Update_time`, `CHECK_TIME` AS `Check_time`, `TABLE_COLLATION` AS `Collation`, `CHECKSUM` AS `Checksum`, `CREATE_OPTIONS` AS `Create_options`, `TABLE_COMMENT` AS `Comment` FROM `information_schema`.`TABLES` t WHERE `TABLE_SCHEMA` IN (\'pma_test\') AND t.`TABLE_NAME` = \'table1\' ORDER BY Name ASC', + 'columns' => array('TABLE_CATALOG', 'TABLE_SCHEMA', 'TABLE_NAME', 'TABLE_TYPE', 'ENGINE', 'VERSION', 'ROW_FORMAT', 'TABLE_ROWS', 'AVG_ROW_LENGTH', 'DATA_LENGTH', 'MAX_DATA_LENGTH', 'INDEX_LENGTH', 'DATA_FREE', 'AUTO_INCREMENT', 'CREATE_TIME', 'UPDATE_TIME', 'CHECK_TIME', 'TABLE_COLLATION', 'CHECKSUM', 'CREATE_OPTIONS', 'TABLE_COMMENT', 'Db', 'Name', 'TABLE_TYPE', 'Engine', 'Type', 'Version', 'Row_format', 'Rows', 'Avg_row_length', 'Data_length', 'Max_data_length', 'Index_length', 'Data_free', 'Auto_increment', 'Create_time', 'Update_time', 'Check_time', 'Collation', 'Checksum', 'Create_options', 'Comment'), + 'result' => array( + array('def', 'smash', 'issues_issue', 'BASE TABLE', 'InnoDB', '10', 'Compact', '9136', '862', '7880704', '0', '1032192', '420478976', '155862', '2012-08-29 13:28:28', 'NULL', 'NULL', 'utf8_general_ci', 'NULL', '', '', 'smash', 'issues_issue', 'BASE TABLE', 'InnoDB', 'InnoDB', '10', 'Compact', '9136', '862', '7880704', '0', '1032192', '420478976', '155862', '2012-08-29 13:28:28', 'NULL', 'NULL', 'utf8_general_ci', 'NULL'), + ), + ), + array( + 'query' => 'SELECT COUNT(*) FROM `pma_test`.`table1`', + 'result' => array(array(0)), + ), + array( + 'query' => 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`USER_PRIVILEGES` WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'TRIGGER\'', + 'result' => array(), + ), + array( + 'query' => 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'TRIGGER\' AND TABLE_SCHEMA=\'pma\\\\_test\'', + + 'result' => array(), + ), + array( + 'query' => 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`TABLE_PRIVILEGES` WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'TRIGGER\' AND TABLE_SCHEMA=\'pma\\\\_test\' AND TABLE_NAME=\'table1\'', + 'result' => array(), + ), + array( + 'query' => 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`USER_PRIVILEGES` WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'EVENT\'', + 'result' => array(), + ), + array( + 'query' => 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'EVENT\' AND TABLE_SCHEMA=\'pma\\\\_test\'', + + 'result' => array(), + ), + array( + 'query' => 'SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`TABLE_PRIVILEGES` WHERE GRANTEE=\'\'\'pma_test\'\'@\'\'localhost\'\'\' AND PRIVILEGE_TYPE=\'EVENT\' AND TABLE_SCHEMA=\'pma\\\\_test\' AND TABLE_NAME=\'table1\'', + 'result' => array(), + ), + array( + 'query' => 'RENAME TABLE `pma_test`.`table1` TO `pma_test`.`table3`;', + 'result' => array(), + ), + array( + 'query' => 'SELECT TRIGGER_SCHEMA, TRIGGER_NAME, EVENT_MANIPULATION, EVENT_OBJECT_TABLE, ACTION_TIMING, ACTION_STATEMENT, EVENT_OBJECT_SCHEMA, EVENT_OBJECT_TABLE, DEFINER FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA= \'pma_test\' AND EVENT_OBJECT_TABLE = \'table1\';', + 'result' => array(), + ), + array( + 'query' => 'SHOW TABLES FROM `pma`;', + 'result' => array(), + ), + array( + 'query' => "SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE='''pma_test''@''localhost''' AND PRIVILEGE_TYPE='EVENT' AND TABLE_SCHEMA='pma'", + 'result' => array(), + ), + array( + 'query' => "SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE='''pma_test''@''localhost''' AND PRIVILEGE_TYPE='TRIGGER' AND TABLE_SCHEMA='pma'", + 'result' => array(), + ), + +); +/** + * Current database. + */ +$GLOBALS['dummy_db'] = ''; + +/* Some basic setup for dummy driver */ +$GLOBALS['userlink'] = 1; +$GLOBALS['controllink'] = 2; +$GLOBALS['cfg']['DBG']['sql'] = false; +if (! defined('PMA_DRIZZLE')) { + define('PMA_DRIZZLE', 0); +} + + +/** + * Run the multi query and output the results + * + * @param mysqli $link mysqli object + * @param string $query multi query statement to execute + * + * @return boolean false always false since mysql extention not support + * for multi query executions + */ +function PMA_DBI_real_multi_query($link, $query) +{ + return false; +} + +/** + * connects to the database server + * + * @param string $user mysql user name + * @param string $password mysql user password + * @param bool $is_controluser whether this is a control user connection + * @param array $server host/port/socket/persistent + * @param bool $auxiliary_connection (when true, don't go back to login if + * connection fails) + * + * @return mixed false on error or a mysqli object on success + */ +function PMA_DBI_connect( + $user, $password, $is_controluser = false, $server = null, + $auxiliary_connection = false +) { + return true; +} + +/** + * selects given database + * + * @param string $dbname name of db to select + * @param resource $link mysql link resource + * + * @return bool + */ +function PMA_DBI_select_db($dbname, $link = null) +{ + $GLOBALS['dummy_db'] = $dbname; + return true; +} + +/** + * runs a query and returns the result + * + * @param string $query query to run + * @param resource $link mysql link resource + * @param int $options query options + * + * @return mixed + */ +function PMA_DBI_real_query($query, $link = null, $options = 0) +{ + $query = trim(preg_replace('/ */', ' ', str_replace("\n", ' ', $query))); + for ($i = 0; $i < count($GLOBALS['dummy_queries']); $i++) { + if ($GLOBALS['dummy_queries'][$i]['query'] == $query) { + $GLOBALS['dummy_queries'][$i]['pos'] = 0; + if (is_array($GLOBALS['dummy_queries'][$i]['result'])) { + return $i; + } else { + return false; + } + } + } + echo "Not supported query: $query\n"; + return false; +} + +/** + * returns result data from $result + * + * @param resource $result result MySQL result + * + * @return array + */ +function PMA_DBI_fetch_any($result) +{ + $query_data = $GLOBALS['dummy_queries'][$result]; + if ($query_data['pos'] >= count($query_data['result'])) { + return false; + } + $ret = $query_data['result'][$query_data['pos']]; + $GLOBALS['dummy_queries'][$result]['pos'] += 1; + return $ret; +} + +/** + * returns array of rows with associative and numeric keys from $result + * + * @param resource $result result MySQL result + * + * @return array + */ +function PMA_DBI_fetch_array($result) +{ + $data = PMA_DBI_fetch_any($result); + if (is_array($data) && isset($GLOBALS['dummy_queries'][$result]['columns'])) { + foreach ($data as $key => $val) { + $data[$GLOBALS['dummy_queries'][$result]['columns'][$key]] = $val; + } + return $data; + } + return $data; +} + +/** + * returns array of rows with associative keys from $result + * + * @param resource $result MySQL result + * + * @return array + */ +function PMA_DBI_fetch_assoc($result) +{ + $data = PMA_DBI_fetch_any($result); + if (is_array($data) && isset($GLOBALS['dummy_queries'][$result]['columns'])) { + $ret = array(); + foreach ($data as $key => $val) { + $ret[$GLOBALS['dummy_queries'][$result]['columns'][$key]] = $val; + } + return $ret; + } + return $data; +} + +/** + * returns array of rows with numeric keys from $result + * + * @param resource $result MySQL result + * + * @return array + */ +function PMA_DBI_fetch_row($result) +{ + $data = PMA_DBI_fetch_any($result); + return $data; +} + +/** + * Adjusts the result pointer to an arbitrary row in the result + * + * @param resource $result database result + * @param integer $offset offset to seek + * + * @return bool true on success, false on failure + */ +function PMA_DBI_data_seek($result, $offset) +{ + if ($offset > count($GLOBALS['dummy_queries'][$result]['result'])) { + return false; + } + $GLOBALS['dummy_queries'][$result]['pos'] = $offset; + return true; +} + +/** + * Frees memory associated with the result + * + * @param resource $result database result + * + * @return void + */ +function PMA_DBI_free_result($result) +{ + return; +} + +/** + * Check if there are any more query results from a multi query + * + * @return bool false + */ +function PMA_DBI_more_results() +{ + return false; +} + +/** + * Prepare next result from multi_query + * + * @return boo false + */ +function PMA_DBI_next_result() +{ + return false; +} + +/** + * returns the number of rows returned by last query + * + * @param resource $result MySQL result + * + * @return string|int + */ +function PMA_DBI_num_rows($result) +{ + if (!is_bool($result)) { + return count($GLOBALS['dummy_queries'][$result]['result']); + } else { + return 0; + } +} + +/** + * returns the number of rows affected by last query + * + * @param resource $link the mysql object + * @param bool $get_from_cache whether to retrieve from cache + * + * @return string|int + */ +function PMA_DBI_affected_rows($link = null, $get_from_cache = true) +{ + return 0; +} + +/** + * return number of fields in given $result + * + * @param resource $result MySQL result + * + * @return int field count + */ +function PMA_DBI_num_fields($result) +{ + if (isset($GLOBALS['dummy_queries'][$result]['columns'])) { + return count($GLOBALS['dummy_queries'][$result]['columns']); + } else { + return 0; + } +} + +/** + * returns last error message or false if no errors occured + * + * @param resource $link mysql link + * + * @return string|bool $error or false + */ +function PMA_DBI_getError($link = null) +{ + return false; +} diff --git a/hugo/libraries/dbi/mysql.dbi.lib.php b/hugo/libraries/dbi/mysql.dbi.lib.php new file mode 100644 index 0000000..6a7e15d --- /dev/null +++ b/hugo/libraries/dbi/mysql.dbi.lib.php @@ -0,0 +1,552 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Interface to the classic MySQL extension + * + * @package PhpMyAdmin-DBI + * @subpackage MySQL + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +require_once './libraries/logging.lib.php'; + +/** + * MySQL client API + */ +if (! defined('PMA_MYSQL_CLIENT_API')) { + $client_api = explode('.', mysql_get_client_info()); + define( + 'PMA_MYSQL_CLIENT_API', + (int)sprintf( + '%d%02d%02d', + $client_api[0], $client_api[1], intval($client_api[2]) + ) + ); + unset($client_api); +} + +/** + * Helper function for connecting to the database server + * + * @param array $server host/port/socket + * @param string $user mysql user name + * @param string $password mysql user password + * @param int $client_flags client flags of connection + * @param bool $persistent whether to use peristent connection + * + * @return mixed false on error or a mysql connection resource on success + */ +function PMA_DBI_real_connect($server, $user, $password, $client_flags, + $persistent = false +) { + global $cfg; + + if (empty($client_flags)) { + if ($cfg['PersistentConnections'] || $persistent) { + $link = @mysql_pconnect($server, $user, $password); + } else { + $link = @mysql_connect($server, $user, $password); + } + } else { + if ($cfg['PersistentConnections'] || $persistent) { + $link = @mysql_pconnect($server, $user, $password, $client_flags); + } else { + $link = @mysql_connect($server, $user, $password, false, $client_flags); + } + } + + return $link; +} + +/** + * Run the multi query and output the results + * + * @param mysqli $link mysqli object + * @param string $query multi query statement to execute + * + * @return boolean false always false since mysql extention not support + * for multi query executions + */ +function PMA_DBI_real_multi_query($link, $query) +{ + // N.B.: PHP's 'mysql' extension does not support + // multi_queries so this function will always + // return false. Use the 'mysqli' extension, if + // you need support for multi_queries. + return false; +} + +/** + * connects to the database server + * + * @param string $user mysql user name + * @param string $password mysql user password + * @param bool $is_controluser whether this is a control user connection + * @param array $server host/port/socket/persistent + * @param bool $auxiliary_connection (when true, don't go back to login if + * connection fails) + * + * @return mixed false on error or a mysqli object on success + */ +function PMA_DBI_connect( + $user, $password, $is_controluser = false, $server = null, + $auxiliary_connection = false +) { + global $cfg; + + if ($server) { + $server_port = (empty($server['port'])) + ? '' + : ':' . (int)$server['port']; + $server_socket = (empty($server['socket'])) + ? '' + : ':' . $server['socket']; + } else { + $server_port = (empty($cfg['Server']['port'])) + ? '' + : ':' . (int)$cfg['Server']['port']; + $server_socket = (empty($cfg['Server']['socket'])) + ? '' + : ':' . $cfg['Server']['socket']; + } + + $client_flags = 0; + + // always use CLIENT_LOCAL_FILES as defined in mysql_com.h + // for the case where the client library was not compiled + // with --enable-local-infile + $client_flags |= 128; + + /* Optionally compress connection */ + if (defined('MYSQL_CLIENT_COMPRESS') && $cfg['Server']['compress']) { + $client_flags |= MYSQL_CLIENT_COMPRESS; + } + + /* Optionally enable SSL */ + if (defined('MYSQL_CLIENT_SSL') && $cfg['Server']['ssl']) { + $client_flags |= MYSQL_CLIENT_SSL; + } + + if (!$server) { + $link = PMA_DBI_real_connect( + $cfg['Server']['host'] . $server_port . $server_socket, + $user, $password, empty($client_flags) ? null : $client_flags + ); + + // Retry with empty password if we're allowed to + if (empty($link) && $cfg['Server']['nopassword'] && !$is_controluser) { + $link = PMA_DBI_real_connect( + $cfg['Server']['host'] . $server_port . $server_socket, + $user, '', empty($client_flags) ? null : $client_flags + ); + } + } else { + if (!isset($server['host'])) { + $link = PMA_DBI_real_connect($server_socket, $user, $password, null); + } else { + $link = PMA_DBI_real_connect( + $server['host'] . $server_port . $server_socket, + $user, $password, null + ); + } + } + if (empty($link)) { + if ($is_controluser) { + trigger_error( + __( + 'Connection for controluser as defined' + . ' in your configuration failed.' + ), + E_USER_WARNING + ); + return false; + } + // we could be calling PMA_DBI_connect() to connect to another + // server, for example in the Synchronize feature, so do not + // go back to main login if it fails + if (! $auxiliary_connection) { + PMA_log_user($user, 'mysql-denied'); + global $auth_plugin; + $auth_plugin->authFails(); + } else { + return false; + } + } // end if + if (! $server) { + PMA_DBI_postConnect($link, $is_controluser); + } + return $link; +} + +/** + * selects given database + * + * @param string $dbname name of db to select + * @param resource $link mysql link resource + * + * @return bool + */ +function PMA_DBI_select_db($dbname, $link = null) +{ + if (empty($link)) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + return mysql_select_db($dbname, $link); +} + +/** + * runs a query and returns the result + * + * @param string $query query to run + * @param resource $link mysql link resource + * @param int $options query options + * + * @return mixed + */ +function PMA_DBI_real_query($query, $link, $options) +{ + if ($options == ($options | PMA_DBI_QUERY_STORE)) { + return mysql_query($query, $link); + } elseif ($options == ($options | PMA_DBI_QUERY_UNBUFFERED)) { + return mysql_unbuffered_query($query, $link); + } else { + return mysql_query($query, $link); + } +} + +/** + * returns array of rows with associative and numeric keys from $result + * + * @param resource $result result MySQL result + * + * @return array + */ +function PMA_DBI_fetch_array($result) +{ + return mysql_fetch_array($result, MYSQL_BOTH); +} + +/** + * returns array of rows with associative keys from $result + * + * @param resource $result MySQL result + * + * @return array + */ +function PMA_DBI_fetch_assoc($result) +{ + return mysql_fetch_array($result, MYSQL_ASSOC); +} + +/** + * returns array of rows with numeric keys from $result + * + * @param resource $result MySQL result + * + * @return array + */ +function PMA_DBI_fetch_row($result) +{ + return mysql_fetch_array($result, MYSQL_NUM); +} + +/** + * Adjusts the result pointer to an arbitrary row in the result + * + * @param resource $result database result + * @param integer $offset offset to seek + * + * @return bool true on success, false on failure + */ +function PMA_DBI_data_seek($result, $offset) +{ + return mysql_data_seek($result, $offset); +} + +/** + * Frees memory associated with the result + * + * @param resource $result database result + * + * @return void + */ +function PMA_DBI_free_result($result) +{ + if (is_resource($result) && get_resource_type($result) === 'mysql result') { + mysql_free_result($result); + } +} + +/** + * Check if there are any more query results from a multi query + * + * @return bool false + */ +function PMA_DBI_more_results() +{ + // N.B.: PHP's 'mysql' extension does not support + // multi_queries so this function will always + // return false. Use the 'mysqli' extension, if + // you need support for multi_queries. + return false; +} + +/** + * Prepare next result from multi_query + * + * @return boo false + */ +function PMA_DBI_next_result() +{ + // N.B.: PHP's 'mysql' extension does not support + // multi_queries so this function will always + // return false. Use the 'mysqli' extension, if + // you need support for multi_queries. + return false; +} + +/** + * Returns a string representing the type of connection used + * + * @param resource $link mysql link + * + * @return string type of connection used + */ +function PMA_DBI_get_host_info($link = null) +{ + if (null === $link) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + return mysql_get_host_info($link); +} + +/** + * Returns the version of the MySQL protocol used + * + * @param resource $link mysql link + * + * @return int version of the MySQL protocol used + */ +function PMA_DBI_get_proto_info($link = null) +{ + if (null === $link) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + return mysql_get_proto_info($link); +} + +/** + * returns a string that represents the client library version + * + * @return string MySQL client library version + */ +function PMA_DBI_get_client_info() +{ + return mysql_get_client_info(); +} + +/** + * returns last error message or false if no errors occured + * + * @param resource $link mysql link + * + * @return string|bool $error or false + */ +function PMA_DBI_getError($link = null) +{ + $GLOBALS['errno'] = 0; + + /* Treat false same as null because of controllink */ + if ($link === false) { + $link = null; + } + + if (null === $link && isset($GLOBALS['userlink'])) { + $link =& $GLOBALS['userlink']; + + // Do not stop now. On the initial connection, we don't have a $link, + // we don't have a $GLOBALS['userlink'], but we can catch the error code + // } else { + // return false; + } + + if (null !== $link && false !== $link) { + $error_number = mysql_errno($link); + $error_message = mysql_error($link); + } else { + $error_number = mysql_errno(); + $error_message = mysql_error(); + } + if (0 == $error_number) { + return false; + } + + // keep the error number for further check after the call to PMA_DBI_getError() + $GLOBALS['errno'] = $error_number; + + return PMA_DBI_formatError($error_number, $error_message); +} + +/** + * returns the number of rows returned by last query + * + * @param resource $result MySQL result + * + * @return string|int + */ +function PMA_DBI_num_rows($result) +{ + if (!is_bool($result)) { + return mysql_num_rows($result); + } else { + return 0; + } +} + +/** + * returns last inserted auto_increment id for given $link or $GLOBALS['userlink'] + * + * @param resource $link the mysql object + * + * @return string|int + */ +function PMA_DBI_insert_id($link = null) +{ + if (empty($link)) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + // If the primary key is BIGINT we get an incorrect result + // (sometimes negative, sometimes positive) + // and in the present function we don't know if the PK is BIGINT + // so better play safe and use LAST_INSERT_ID() + // + return PMA_DBI_fetch_value('SELECT LAST_INSERT_ID();', 0, 0, $link); +} + +/** + * returns the number of rows affected by last query + * + * @param resource $link the mysql object + * @param bool $get_from_cache whether to retrieve from cache + * + * @return string|int + */ +function PMA_DBI_affected_rows($link = null, $get_from_cache = true) +{ + if (empty($link)) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + + if ($get_from_cache) { + return $GLOBALS['cached_affected_rows']; + } else { + return mysql_affected_rows($link); + } +} + +/** + * returns metainfo for fields in $result + * + * @param resource $result MySQL result + * + * @return array meta info for fields in $result + * + * @todo add missing keys like in mysqli_query (decimals) + */ +function PMA_DBI_get_fields_meta($result) +{ + $fields = array(); + $num_fields = mysql_num_fields($result); + for ($i = 0; $i < $num_fields; $i++) { + $field = mysql_fetch_field($result, $i); + $field->flags = mysql_field_flags($result, $i); + $field->orgtable = mysql_field_table($result, $i); + $field->orgname = mysql_field_name($result, $i); + $fields[] = $field; + } + return $fields; +} + +/** + * return number of fields in given $result + * + * @param resource $result MySQL result + * + * @return int field count + */ +function PMA_DBI_num_fields($result) +{ + return mysql_num_fields($result); +} + +/** + * returns the length of the given field $i in $result + * + * @param resource $result MySQL result + * @param int $i field + * + * @return int length of field + */ +function PMA_DBI_field_len($result, $i) +{ + return mysql_field_len($result, $i); +} + +/** + * returns name of $i. field in $result + * + * @param resource $result MySQL result + * @param int $i field + * + * @return string name of $i. field in $result + */ +function PMA_DBI_field_name($result, $i) +{ + return mysql_field_name($result, $i); +} + +/** + * returns concatenated string of human readable field flags + * + * @param resource $result MySQL result + * @param int $i field + * + * @return string field flags + */ +function PMA_DBI_field_flags($result, $i) +{ + return mysql_field_flags($result, $i); +} + +/** + * Store the result returned from multi query + * + * @return false + */ +function PMA_DBI_store_result() +{ + return false; +} +?> diff --git a/hugo/libraries/dbi/mysqli.dbi.lib.php b/hugo/libraries/dbi/mysqli.dbi.lib.php new file mode 100644 index 0000000..bf48521 --- /dev/null +++ b/hugo/libraries/dbi/mysqli.dbi.lib.php @@ -0,0 +1,748 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Interface to the improved MySQL extension (MySQLi) + * + * @package PhpMyAdmin-DBI + * @subpackage MySQLi + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +require_once './libraries/logging.lib.php'; + +/** + * MySQL client API + */ +if (!defined('PMA_MYSQL_CLIENT_API')) { + $client_api = explode('.', mysqli_get_client_info()); + define( + 'PMA_MYSQL_CLIENT_API', + (int)sprintf( + '%d%02d%02d', + $client_api[0], $client_api[1], intval($client_api[2]) + ) + ); + unset($client_api); +} + +/** + * some PHP versions are reporting extra messages like "No index used in query" + */ + +mysqli_report(MYSQLI_REPORT_OFF); + +/** + * some older mysql client libs are missing these constants ... + */ +if (! defined('MYSQLI_BINARY_FLAG')) { + define('MYSQLI_BINARY_FLAG', 128); +} + +/** + * @see http://bugs.php.net/36007 + */ +if (! defined('MYSQLI_TYPE_NEWDECIMAL')) { + define('MYSQLI_TYPE_NEWDECIMAL', 246); +} +if (! defined('MYSQLI_TYPE_BIT')) { + define('MYSQLI_TYPE_BIT', 16); +} + +// for Drizzle +if (! defined('MYSQLI_TYPE_VARCHAR')) { + define('MYSQLI_TYPE_VARCHAR', 15); +} + +/** + * Helper function for connecting to the database server + * + * @param mysqli $link connection link + * @param string $host mysql hostname + * @param string $user mysql user name + * @param string $password mysql user password + * @param string $dbname database name + * @param int $server_port server port + * @param string $server_socket server socket + * @param int $client_flags client flags of connection + * @param bool $persistent whether to use peristent connection + * + * @return bool + */ +function PMA_DBI_real_connect( + $link, $host, $user, $password, $dbname, $server_port, + $server_socket, $client_flags = null, $persistent = false +) { + global $cfg; + + // mysqli persistent connections only on PHP 5.3+ + if (PMA_PHP_INT_VERSION >= 50300) { + if ($cfg['PersistentConnections'] || $persistent) { + $host = 'p:' . $host; + } + } + if ($client_flags === null) { + return @mysqli_real_connect( + $link, + $host, + $user, + $password, + $dbname, + $server_port, + $server_socket + ); + } else { + return @mysqli_real_connect( + $link, + $host, + $user, + $password, + $dbname, + $server_port, + $server_socket, + $client_flags + ); + } +} + +/** + * connects to the database server + * + * @param string $user mysql user name + * @param string $password mysql user password + * @param bool $is_controluser whether this is a control user connection + * @param array $server host/port/socket/persistent + * @param bool $auxiliary_connection (when true, don't go back to login if + * connection fails) + * + * @return mixed false on error or a mysqli object on success + */ +function PMA_DBI_connect( + $user, $password, $is_controluser = false, $server = null, + $auxiliary_connection = false +) { + global $cfg; + + if ($server) { + $server_port = (empty($server['port'])) + ? false + : (int)$server['port']; + $server_socket = (empty($server['socket'])) + ? '' + : $server['socket']; + $server['host'] = (empty($server['host'])) + ? 'localhost' + : $server['host']; + } else { + $server_port = (empty($cfg['Server']['port'])) + ? false + : (int) $cfg['Server']['port']; + $server_socket = (empty($cfg['Server']['socket'])) + ? null + : $cfg['Server']['socket']; + } + + // NULL enables connection to the default socket + + $link = mysqli_init(); + + mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, true); + + $client_flags = 0; + + /* Optionally compress connection */ + if ($cfg['Server']['compress'] && defined('MYSQLI_CLIENT_COMPRESS')) { + $client_flags |= MYSQLI_CLIENT_COMPRESS; + } + + /* Optionally enable SSL */ + if ($cfg['Server']['ssl'] && defined('MYSQLI_CLIENT_SSL')) { + $client_flags |= MYSQLI_CLIENT_SSL; + } + + if (!$server) { + $return_value = @PMA_DBI_real_connect( + $link, + $cfg['Server']['host'], + $user, + $password, + false, + $server_port, + $server_socket, + $client_flags + ); + // Retry with empty password if we're allowed to + if ($return_value == false + && isset($cfg['Server']['nopassword']) && $cfg['Server']['nopassword'] + && !$is_controluser + ) { + $return_value = @PMA_DBI_real_connect( + $link, + $cfg['Server']['host'], + $user, + '', + false, + $server_port, + $server_socket, + $client_flags + ); + } + } else { + $return_value = @PMA_DBI_real_connect( + $link, + $server['host'], + $user, + $password, + false, + $server_port, + $server_socket + ); + } + + if ($return_value == false) { + if ($is_controluser) { + trigger_error( + __('Connection for controluser as defined in your configuration failed.'), + E_USER_WARNING + ); + return false; + } + // we could be calling PMA_DBI_connect() to connect to another + // server, for example in the Synchronize feature, so do not + // go back to main login if it fails + if (! $auxiliary_connection) { + PMA_log_user($user, 'mysql-denied'); + global $auth_plugin; + $auth_plugin->authFails(); + } else { + return false; + } + } else { + PMA_DBI_postConnect($link, $is_controluser); + } + + return $link; +} + +/** + * selects given database + * + * @param string $dbname database name to select + * @param mysqli $link the mysqli object + * + * @return boolean + */ +function PMA_DBI_select_db($dbname, $link = null) +{ + if (empty($link)) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + return mysqli_select_db($link, $dbname); +} + +/** + * runs a query and returns the result + * + * @param string $query query to execute + * @param mysqli $link mysqli object + * @param int $options query options + * + * @return mysqli_result|bool + */ +function PMA_DBI_real_query($query, $link, $options) +{ + if ($options == ($options | PMA_DBI_QUERY_STORE)) { + $method = MYSQLI_STORE_RESULT; + } elseif ($options == ($options | PMA_DBI_QUERY_UNBUFFERED)) { + $method = MYSQLI_USE_RESULT; + } else { + $method = 0; + } + + return mysqli_query($link, $query, $method); +} + +/** + * Run the multi query and output the results + * + * @param mysqli $link mysqli object + * @param string $query multi query statement to execute + * + * @return mysqli_result collection | boolean(false) + */ +function PMA_DBI_real_multi_query($link, $query) +{ + return mysqli_multi_query($link, $query); +} + +/** + * returns array of rows with associative and numeric keys from $result + * + * @param mysqli_result $result result set identifier + * + * @return array + */ +function PMA_DBI_fetch_array($result) +{ + return mysqli_fetch_array($result, MYSQLI_BOTH); +} + +/** + * returns array of rows with associative keys from $result + * + * @param mysqli_result $result result set identifier + * + * @return array + */ +function PMA_DBI_fetch_assoc($result) +{ + return mysqli_fetch_array($result, MYSQLI_ASSOC); +} + +/** + * returns array of rows with numeric keys from $result + * + * @param mysqli_result $result result set identifier + * + * @return array + */ +function PMA_DBI_fetch_row($result) +{ + return mysqli_fetch_array($result, MYSQLI_NUM); +} + +/** + * Adjusts the result pointer to an arbitrary row in the result + * + * @param resource $result database result + * @param integer $offset offset to seek + * + * @return bool true on success, false on failure + */ +function PMA_DBI_data_seek($result, $offset) +{ + return mysqli_data_seek($result, $offset); +} + +/** + * Frees memory associated with the result + * + * @param mysqli_result $result database result + * + * @return void + */ +function PMA_DBI_free_result($result) +{ + if ($result instanceof mysqli_result) { + mysqli_free_result($result); + } +} + +/** + * Check if there are any more query results from a multi query + * + * @param mysqli $link the mysqli object + * + * @return bool true or false + */ +function PMA_DBI_more_results($link = null) +{ + if (empty($link)) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + return mysqli_more_results($link); +} + +/** + * Prepare next result from multi_query + * + * @param mysqli $link the mysqli object + * + * @return bool true or false + */ +function PMA_DBI_next_result($link = null) +{ + if (empty($link)) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + return mysqli_next_result($link); +} + +/** + * Store the result returned from multi query + * + * @return mixed false when empty results / result set when not empty + */ +function PMA_DBI_store_result() +{ + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + return mysqli_store_result($link); +} + +/** + * Returns a string representing the type of connection used + * + * @param resource $link mysql link + * + * @return string type of connection used + */ +function PMA_DBI_get_host_info($link = null) +{ + if (null === $link) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + return mysqli_get_host_info($link); +} + +/** + * Returns the version of the MySQL protocol used + * + * @param resource $link mysql link + * + * @return integer version of the MySQL protocol used + */ +function PMA_DBI_get_proto_info($link = null) +{ + if (null === $link) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + return mysqli_get_proto_info($link); +} + +/** + * returns a string that represents the client library version + * + * @return string MySQL client library version + */ +function PMA_DBI_get_client_info() +{ + return mysqli_get_client_info(); +} + +/** + * returns last error message or false if no errors occured + * + * @param resource $link mysql link + * + * @return string|bool $error or false + */ +function PMA_DBI_getError($link = null) +{ + $GLOBALS['errno'] = 0; + + /* Treat false same as null because of controllink */ + if ($link === false) { + $link = null; + } + + if (null === $link && isset($GLOBALS['userlink'])) { + $link =& $GLOBALS['userlink']; + // Do not stop now. We still can get the error code + // with mysqli_connect_errno() + } + + if (null !== $link) { + $error_number = mysqli_errno($link); + $error_message = mysqli_error($link); + } else { + $error_number = mysqli_connect_errno(); + $error_message = mysqli_connect_error(); + } + if (0 == $error_number) { + return false; + } + + // keep the error number for further check after the call to PMA_DBI_getError() + $GLOBALS['errno'] = $error_number; + + return PMA_DBI_formatError($error_number, $error_message); +} + +/** + * returns the number of rows returned by last query + * + * @param mysqli_result $result result set identifier + * + * @return string|int + */ +function PMA_DBI_num_rows($result) +{ + // see the note for PMA_DBI_try_query(); + if (!is_bool($result)) { + return @mysqli_num_rows($result); + } else { + return 0; + } +} + +/** + * returns last inserted auto_increment id for given $link or $GLOBALS['userlink'] + * + * @param mysqli $link the mysqli object + * + * @return string|int + */ +function PMA_DBI_insert_id($link = null) +{ + if (empty($link)) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + // When no controluser is defined, using mysqli_insert_id($link) + // does not always return the last insert id due to a mixup with + // the tracking mechanism, but this works: + return PMA_DBI_fetch_value('SELECT LAST_INSERT_ID();', 0, 0, $link); + // Curiously, this problem does not happen with the mysql extension but + // there is another problem with BIGINT primary keys so PMA_DBI_insert_id() + // in the mysql extension also uses this logic. +} + +/** + * returns the number of rows affected by last query + * + * @param mysqli $link the mysqli object + * @param bool $get_from_cache whether to retrieve from cache + * + * @return string|int + */ +function PMA_DBI_affected_rows($link = null, $get_from_cache = true) +{ + if (empty($link)) { + if (isset($GLOBALS['userlink'])) { + $link = $GLOBALS['userlink']; + } else { + return false; + } + } + if ($get_from_cache) { + return $GLOBALS['cached_affected_rows']; + } else { + return mysqli_affected_rows($link); + } +} + +/** + * returns metainfo for fields in $result + * + * @param mysqli_result $result result set identifier + * + * @return array meta info for fields in $result + */ +function PMA_DBI_get_fields_meta($result) +{ + // Build an associative array for a type look up + $typeAr = array(); + $typeAr[MYSQLI_TYPE_DECIMAL] = 'real'; + $typeAr[MYSQLI_TYPE_NEWDECIMAL] = 'real'; + $typeAr[MYSQLI_TYPE_BIT] = 'int'; + $typeAr[MYSQLI_TYPE_TINY] = 'int'; + $typeAr[MYSQLI_TYPE_SHORT] = 'int'; + $typeAr[MYSQLI_TYPE_LONG] = 'int'; + $typeAr[MYSQLI_TYPE_FLOAT] = 'real'; + $typeAr[MYSQLI_TYPE_DOUBLE] = 'real'; + $typeAr[MYSQLI_TYPE_NULL] = 'null'; + $typeAr[MYSQLI_TYPE_TIMESTAMP] = 'timestamp'; + $typeAr[MYSQLI_TYPE_LONGLONG] = 'int'; + $typeAr[MYSQLI_TYPE_INT24] = 'int'; + $typeAr[MYSQLI_TYPE_DATE] = 'date'; + $typeAr[MYSQLI_TYPE_TIME] = 'time'; + $typeAr[MYSQLI_TYPE_DATETIME] = 'datetime'; + $typeAr[MYSQLI_TYPE_YEAR] = 'year'; + $typeAr[MYSQLI_TYPE_NEWDATE] = 'date'; + $typeAr[MYSQLI_TYPE_ENUM] = 'unknown'; + $typeAr[MYSQLI_TYPE_SET] = 'unknown'; + $typeAr[MYSQLI_TYPE_TINY_BLOB] = 'blob'; + $typeAr[MYSQLI_TYPE_MEDIUM_BLOB] = 'blob'; + $typeAr[MYSQLI_TYPE_LONG_BLOB] = 'blob'; + $typeAr[MYSQLI_TYPE_BLOB] = 'blob'; + $typeAr[MYSQLI_TYPE_VAR_STRING] = 'string'; + $typeAr[MYSQLI_TYPE_STRING] = 'string'; + $typeAr[MYSQLI_TYPE_VARCHAR] = 'string'; // for Drizzle + // MySQL returns MYSQLI_TYPE_STRING for CHAR + // and MYSQLI_TYPE_CHAR === MYSQLI_TYPE_TINY + // so this would override TINYINT and mark all TINYINT as string + // https://sourceforge.net/p/phpmyadmin/bugs/2205/ + //$typeAr[MYSQLI_TYPE_CHAR] = 'string'; + $typeAr[MYSQLI_TYPE_GEOMETRY] = 'geometry'; + $typeAr[MYSQLI_TYPE_BIT] = 'bit'; + + $fields = mysqli_fetch_fields($result); + + // this happens sometimes (seen under MySQL 4.0.25) + if (!is_array($fields)) { + return false; + } + + foreach ($fields as $k => $field) { + $fields[$k]->_type = $field->type; + $fields[$k]->type = $typeAr[$field->type]; + $fields[$k]->_flags = $field->flags; + $fields[$k]->flags = PMA_DBI_field_flags($result, $k); + + // Enhance the field objects for mysql-extension compatibilty + //$flags = explode(' ', $fields[$k]->flags); + //array_unshift($flags, 'dummy'); + $fields[$k]->multiple_key + = (int) (bool) ($fields[$k]->_flags & MYSQLI_MULTIPLE_KEY_FLAG); + $fields[$k]->primary_key + = (int) (bool) ($fields[$k]->_flags & MYSQLI_PRI_KEY_FLAG); + $fields[$k]->unique_key + = (int) (bool) ($fields[$k]->_flags & MYSQLI_UNIQUE_KEY_FLAG); + $fields[$k]->not_null + = (int) (bool) ($fields[$k]->_flags & MYSQLI_NOT_NULL_FLAG); + $fields[$k]->unsigned + = (int) (bool) ($fields[$k]->_flags & MYSQLI_UNSIGNED_FLAG); + $fields[$k]->zerofill + = (int) (bool) ($fields[$k]->_flags & MYSQLI_ZEROFILL_FLAG); + $fields[$k]->numeric + = (int) (bool) ($fields[$k]->_flags & MYSQLI_NUM_FLAG); + $fields[$k]->blob + = (int) (bool) ($fields[$k]->_flags & MYSQLI_BLOB_FLAG); + } + return $fields; +} + +/** + * return number of fields in given $result + * + * @param mysqli_result $result result set identifier + * + * @return int field count + */ +function PMA_DBI_num_fields($result) +{ + return mysqli_num_fields($result); +} + +/** + * returns the length of the given field $i in $result + * + * @param mysqli_result $result result set identifier + * @param int $i field + * + * @return int length of field + */ +function PMA_DBI_field_len($result, $i) +{ + return mysqli_fetch_field_direct($result, $i)->length; +} + +/** + * returns name of $i. field in $result + * + * @param mysqli_result $result result set identifier + * @param int $i field + * + * @return string name of $i. field in $result + */ +function PMA_DBI_field_name($result, $i) +{ + return mysqli_fetch_field_direct($result, $i)->name; +} + +/** + * returns concatenated string of human readable field flags + * + * @param mysqli_result $result result set identifier + * @param int $i field + * + * @return string field flags + */ +function PMA_DBI_field_flags($result, $i) +{ + // This is missing from PHP 5.2.5, see http://bugs.php.net/bug.php?id=44846 + if (! defined('MYSQLI_ENUM_FLAG')) { + define('MYSQLI_ENUM_FLAG', 256); // see MySQL source include/mysql_com.h + } + $f = mysqli_fetch_field_direct($result, $i); + $type = $f->type; + $charsetnr = $f->charsetnr; + $f = $f->flags; + $flags = ''; + if ($f & MYSQLI_UNIQUE_KEY_FLAG) { + $flags .= 'unique '; + } + if ($f & MYSQLI_NUM_FLAG) { + $flags .= 'num '; + } + if ($f & MYSQLI_PART_KEY_FLAG) { + $flags .= 'part_key '; + } + if ($f & MYSQLI_SET_FLAG) { + $flags .= 'set '; + } + if ($f & MYSQLI_TIMESTAMP_FLAG) { + $flags .= 'timestamp '; + } + if ($f & MYSQLI_AUTO_INCREMENT_FLAG) { + $flags .= 'auto_increment '; + } + if ($f & MYSQLI_ENUM_FLAG) { + $flags .= 'enum '; + } + // See http://dev.mysql.com/doc/refman/6.0/en/c-api-datatypes.html: + // to determine if a string is binary, we should not use MYSQLI_BINARY_FLAG + // but instead the charsetnr member of the MYSQL_FIELD + // structure. Watch out: some types like DATE returns 63 in charsetnr + // so we have to check also the type. + // Unfortunately there is no equivalent in the mysql extension. + if (($type == MYSQLI_TYPE_TINY_BLOB || $type == MYSQLI_TYPE_BLOB + || $type == MYSQLI_TYPE_MEDIUM_BLOB || $type == MYSQLI_TYPE_LONG_BLOB + || $type == MYSQLI_TYPE_VAR_STRING || $type == MYSQLI_TYPE_STRING) + && 63 == $charsetnr + ) { + $flags .= 'binary '; + } + if ($f & MYSQLI_ZEROFILL_FLAG) { + $flags .= 'zerofill '; + } + if ($f & MYSQLI_UNSIGNED_FLAG) { + $flags .= 'unsigned '; + } + if ($f & MYSQLI_BLOB_FLAG) { + $flags .= 'blob '; + } + if ($f & MYSQLI_MULTIPLE_KEY_FLAG) { + $flags .= 'multiple_key '; + } + if ($f & MYSQLI_UNIQUE_KEY_FLAG) { + $flags .= 'unique_key '; + } + if ($f & MYSQLI_PRI_KEY_FLAG) { + $flags .= 'primary_key '; + } + if ($f & MYSQLI_NOT_NULL_FLAG) { + $flags .= 'not_null '; + } + return trim($flags); +} + +?> |
