1
0
mirror of https://github.com/vrana/adminer.git synced 2025-08-08 07:36:44 +02:00

ClickHouse: Check for allow_url_fopen

This commit is contained in:
Jakub Vrana
2025-03-06 14:30:50 +01:00
parent 5fdaae27dc
commit d268e0ebb4

View File

@@ -6,130 +6,131 @@ add_driver("clickhouse", "ClickHouse (alpha)");
if (isset($_GET["clickhouse"])) { if (isset($_GET["clickhouse"])) {
define("DRIVER", "clickhouse"); define("DRIVER", "clickhouse");
class Db { if (ini_bool('allow_url_fopen')) {
var $extension = "JSON", $server_info, $errno, $_result, $error, $_url; class Db {
var $_db = 'default'; var $extension = "JSON", $server_info, $errno, $_result, $error, $_url;
var $_db = 'default';
function rootQuery($db, $query) { function rootQuery($db, $query) {
$file = @file_get_contents("$this->_url/?database=$db", false, stream_context_create(array('http' => array( $file = @file_get_contents("$this->_url/?database=$db", false, stream_context_create(array('http' => array(
'method' => 'POST', 'method' => 'POST',
'content' => $this->isQuerySelectLike($query) ? "$query FORMAT JSONCompact" : $query, 'content' => $this->isQuerySelectLike($query) ? "$query FORMAT JSONCompact" : $query,
'header' => 'Content-type: application/x-www-form-urlencoded', 'header' => 'Content-type: application/x-www-form-urlencoded',
'ignore_errors' => 1, 'ignore_errors' => 1,
'follow_location' => 0, 'follow_location' => 0,
'max_redirects' => 0, 'max_redirects' => 0,
)))); ))));
if ($file === false || !preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) { if ($file === false || !preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) {
$this->error = lang('Invalid credentials.'); $this->error = lang('Invalid credentials.');
return false; return false;
}
$return = json_decode($file, true);
if ($return === null) {
if (!$this->isQuerySelectLike($query) && $file === '') {
return true;
} }
$return = json_decode($file, true);
if ($return === null) {
if (!$this->isQuerySelectLike($query) && $file === '') {
return true;
}
$this->errno = json_last_error(); $this->errno = json_last_error();
if (function_exists('json_last_error_msg')) { if (function_exists('json_last_error_msg')) {
$this->error = json_last_error_msg(); $this->error = json_last_error_msg();
} else { } else {
$constants = get_defined_constants(true); $constants = get_defined_constants(true);
foreach ($constants['json'] as $name => $value) { foreach ($constants['json'] as $name => $value) {
if ($value == $this->errno && preg_match('~^JSON_ERROR_~', $name)) { if ($value == $this->errno && preg_match('~^JSON_ERROR_~', $name)) {
$this->error = $name; $this->error = $name;
break; break;
}
} }
} }
} }
return new Result($return);
}
function isQuerySelectLike($query) {
return (bool) preg_match('~^(select|show)~i', $query);
}
function query($query) {
return $this->rootQuery($this->_db, $query);
}
function connect($server, $username, $password) {
preg_match('~^(https?://)?(.*)~', $server, $match);
$this->_url = ($match[1] ? $match[1] : "http://") . urlencode($username) . ":" . urlencode($password) . "@$match[2]";
$return = $this->query('SELECT 1');
return (bool) $return;
}
function select_db($database) {
$this->_db = $database;
return true;
}
function quote($string) {
return "'" . addcslashes($string, "\\'") . "'";
}
function multi_query($query) {
return $this->_result = $this->query($query);
}
function store_result() {
return $this->_result;
}
function next_result() {
return false;
}
function result($query, $field = 0) {
$result = $this->query($query);
return $result['data'];
} }
return new Result($return);
} }
function isQuerySelectLike($query) { class Result {
return (bool) preg_match('~^(select|show)~i', $query); var $num_rows, $_rows, $columns, $meta, $_offset = 0;
}
function query($query) { function __construct($result) {
return $this->rootQuery($this->_db, $query); foreach ($result['data'] as $item) {
} $row = array();
foreach ($item as $key => $val) {
function connect($server, $username, $password) { $row[$key] = is_scalar($val) ? $val : json_encode($val, 256); // 256 - JSON_UNESCAPED_UNICODE
preg_match('~^(https?://)?(.*)~', $server, $match); }
$this->_url = ($match[1] ? $match[1] : "http://") . urlencode($username) . ":" . urlencode($password) . "@$match[2]"; $this->_rows[] = $row;
$return = $this->query('SELECT 1');
return (bool) $return;
}
function select_db($database) {
$this->_db = $database;
return true;
}
function quote($string) {
return "'" . addcslashes($string, "\\'") . "'";
}
function multi_query($query) {
return $this->_result = $this->query($query);
}
function store_result() {
return $this->_result;
}
function next_result() {
return false;
}
function result($query, $field = 0) {
$result = $this->query($query);
return $result['data'];
}
}
class Result {
var $num_rows, $_rows, $columns, $meta, $_offset = 0;
function __construct($result) {
foreach ($result['data'] as $item) {
$row = array();
foreach ($item as $key => $val) {
$row[$key] = is_scalar($val) ? $val : json_encode($val, 256); // 256 - JSON_UNESCAPED_UNICODE
} }
$this->_rows[] = $row; $this->num_rows = $result['rows'];
$this->meta = $result['meta'];
$this->columns = array_column($this->meta, 'name');
reset($this->_rows);
} }
$this->num_rows = $result['rows'];
$this->meta = $result['meta'];
$this->columns = array_column($this->meta, 'name');
reset($this->_rows);
}
function fetch_assoc() { function fetch_assoc() {
$row = current($this->_rows); $row = current($this->_rows);
next($this->_rows); next($this->_rows);
return $row === false ? false : array_combine($this->columns, $row); return $row === false ? false : array_combine($this->columns, $row);
} }
function fetch_row() { function fetch_row() {
$row = current($this->_rows); $row = current($this->_rows);
next($this->_rows); next($this->_rows);
return $row; return $row;
} }
function fetch_field() { function fetch_field() {
$column = $this->_offset++; $column = $this->_offset++;
$return = new \stdClass; $return = new \stdClass;
if ($column < count($this->columns)) { if ($column < count($this->columns)) {
$return->name = $this->meta[$column]['name']; $return->name = $this->meta[$column]['name'];
$return->orgname = $return->name; $return->orgname = $return->name;
$return->type = $this->meta[$column]['type']; $return->type = $this->meta[$column]['type'];
}
return $return;
} }
return $return;
} }
} }
class Driver extends SqlDriver { class Driver extends SqlDriver {
static $possibleDrivers = array("allow_url_fopen"); static $possibleDrivers = array("allow_url_fopen");
static $jush = "clickhouse"; static $jush = "clickhouse";