diff --git a/adminer/drivers/elastic.inc.php b/adminer/drivers/elastic.inc.php index 6e1df1ef..69f273ba 100644 --- a/adminer/drivers/elastic.inc.php +++ b/adminer/drivers/elastic.inc.php @@ -8,13 +8,13 @@ if (isset($_GET["elastic"])) { class Min_DB { var $extension = "JSON", $server_info, $errno, $error, $_url, $_db; - /** Performs query - * @param string - * @param array - * @param string - * @return mixed + /** + * @param string $path + * @param array|null $content + * @param string $method + * @return array|false */ - function rootQuery($path, $content = array(), $method = 'GET') { + function rootQuery($path, array $content = null, $method = 'GET') { @ini_set('track_errors', 1); // @ - may be disabled $file = @file_get_contents("$this->_url/" . ltrim($path, '/'), false, stream_context_create(array('http' => array( 'method' => $method, @@ -24,39 +24,37 @@ if (isset($_GET["elastic"])) { 'follow_location' => 0, 'max_redirects' => 0, )))); - if (!$file) { - $this->error = error_get_last()['message']; - return $file; - } - if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) { - $this->error = lang('Invalid credentials.') . " $http_response_header[0]"; + + if ($file === false) { + $this->error = lang('Invalid credentials.'); return false; } + $return = json_decode($file, true); if ($return === null) { - $this->errno = json_last_error(); - if (function_exists('json_last_error_msg')) { - $this->error = json_last_error_msg(); - } else { - $constants = get_defined_constants(true); - foreach ($constants['json'] as $name => $value) { - if ($value == $this->errno && preg_match('~^JSON_ERROR_~', $name)) { - $this->error = $name; - break; - } - } - } + $this->error = lang('Invalid credentials.'); + return false; } + + if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) { + if (isset($return['error']['root_cause'][0]['type'])) { + $this->error = $return['error']['root_cause'][0]['type'] . ": " . $return['error']['root_cause'][0]['reason']; + } else { + $this->error = lang('Invalid credentials.'); + } + return false; + } + return $return; } /** Performs query relative to actual selected DB - * @param string - * @param array - * @param string - * @return mixed + * @param string $path + * @param array|null $content + * @param string $method + * @return array|false */ - function query($path, $content = array(), $method = 'GET') { + function query($path, array $content = null, $method = 'GET') { return $this->rootQuery(($this->_db != "" ? "$this->_db/" : "/") . ltrim($path, '/'), $content, $method); } @@ -70,10 +68,17 @@ if (isset($_GET["elastic"])) { $this->_url = build_http_url($server, $username, $password, "localhost", 9200); $return = $this->query(''); - if ($return) { - $this->server_info = $return['version']['number']; + if (!$return) { + return false; } - return (bool) $return; + + if (!isset($return['version']['number'])) { + $this->error = lang('Invalid credentials.'); + return false; + } + + $this->server_info = $return['version']['number']; + return true; } function select_db($database) { diff --git a/plugins/drivers/clickhouse.php b/plugins/drivers/clickhouse.php index 1d188219..2e1d95c4 100644 --- a/plugins/drivers/clickhouse.php +++ b/plugins/drivers/clickhouse.php @@ -8,6 +8,11 @@ if (isset($_GET["clickhouse"])) { var $extension = "JSON", $server_info, $errno, $_result, $error, $_url; var $_db = 'default'; + /** + * @param string $db + * @param string $query + * @return Min_Result|bool + */ function rootQuery($db, $query) { @ini_set('track_errors', 1); // @ - may be disabled $file = @file_get_contents("$this->_url/?database=$db", false, stream_context_create(array('http' => array( @@ -20,39 +25,48 @@ if (isset($_GET["clickhouse"])) { )))); if ($file === false) { - $this->error = $php_errormsg; - return $file; - } - if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) { - $this->error = lang('Invalid credentials.') . " $http_response_header[0]"; + $this->error = lang('Invalid credentials.'); return false; } - $return = json_decode($file, true); - if ($return === null) { - if (!$this->isQuerySelectLike($query) && $file === '') { - return true; - } - $this->errno = json_last_error(); - if (function_exists('json_last_error_msg')) { - $this->error = json_last_error_msg(); - } else { - $constants = get_defined_constants(true); - foreach ($constants['json'] as $name => $value) { - if ($value == $this->errno && preg_match('~^JSON_ERROR_~', $name)) { - $this->error = $name; - break; - } + if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) { + foreach ($http_response_header as $header) { + if (preg_match('~^X-ClickHouse-Exception-Code:~i', $header)) { + $this->error = preg_replace('~\(version [^(]+\(.+$~', '', $file); + return false; } } + + $this->error = lang('Invalid credentials.'); + return false; } - return new Min_Result($return); + + if (!$this->isQuerySelectLike($query) && $file === '') { + return true; + } + + $return = json_decode($file, true); + if ($return === null) { + $this->error = lang('Invalid credentials.'); + return false; + } + + if (!isset($return['rows']) || !isset($return['data']) || !isset($return['meta'])) { + $this->error = lang('Invalid credentials.'); + return false; + } + + return new Min_Result($return['rows'], $return['data'], $return['meta']); } function isQuerySelectLike($query) { return (bool) preg_match('~^(select|show)~i', $query); } + /** + * @param string $query + * @return bool|Min_Result + */ function query($query) { return $this->rootQuery($this->_db, $query); } @@ -100,11 +114,17 @@ if (isset($_GET["clickhouse"])) { class Min_Result { var $num_rows, $_rows, $columns, $meta, $_offset = 0; - function __construct($result) { - $this->num_rows = $result['rows']; - $this->_rows = $result['data']; - $this->meta = $result['meta']; - $this->columns = array_column($this->meta, 'name'); + /** + * @param int $rows + * @param array[] $data + * @param array[] $meta + */ + function __construct($rows, array $data, array $meta) { + $this->num_rows = $rows; + $this->_rows = $data; + $this->meta = $meta; + $this->columns = array_column($meta, 'name'); + reset($this->_rows); }