1
0
mirror of https://github.com/vrana/adminer.git synced 2025-09-13 15:42:20 +02:00

Compare commits

..

44 Commits

Author SHA1 Message Date
Jakub Vrana
5a4c4dd892 Release 5.0.3 2025-03-11 13:16:35 +01:00
Jakub Vrana
7ef009336f PostgreSQL: Fix where and order privileges (fix #902) 2025-03-11 13:07:50 +01:00
Jakub Vrana
1defc94d12 Fix $result visibility 2025-03-11 12:53:35 +01:00
Jakub Vrana
5d3376e620 Check more style 2025-03-11 12:21:07 +01:00
Jakub Vrana
d410cdc5be Mongo: Add helper method 2025-03-11 11:13:40 +01:00
Jakub Vrana
a44e625882 Set visibility to protected 2025-03-11 11:05:39 +01:00
Jakub Vrana
ae57d42105 SQLite: Fix calling private property 2025-03-11 11:05:10 +01:00
Jakub Vrana
199edfe11f Plugins: Add method dumpFooter() 2025-03-11 08:59:38 +01:00
Jakub Vrana
b02c3e1f7f Use private visibility 2025-03-11 08:36:35 +01:00
Jakub Vrana
98cb9b9aca Add comment 2025-03-11 08:29:01 +01:00
Jakub Vrana
514d64048d Disallow var 2025-03-11 08:17:02 +01:00
Jakub Vrana
1e963cf90f Change var to public 2025-03-11 08:17:00 +01:00
Jakub Vrana
0c15a9f42d Use private visibility on methods 2025-03-11 08:16:41 +01:00
Jakub Vrana
c454ea8430 Use protected visibility 2025-03-11 08:16:41 +01:00
Jakub Vrana
607febea8e Use private visibility 2025-03-11 08:16:39 +01:00
Jakub Vrana
ebd5f19dd4 Use protected visibility 2025-03-11 08:12:09 +01:00
Jakub Vrana
1b0984ff31 Compile: Change public to var 2025-03-11 07:16:20 +01:00
Jakub Vrana
b017928256 Revert accidental revert 2025-03-11 07:05:16 +01:00
Jakub Vrana
526077535e Update changes 2025-03-11 07:00:21 +01:00
Jakub Vrana
8274b2e0e8 Update bug template 2025-03-11 06:50:04 +01:00
Jakub Vrana
8f7d456887 Update changes 2025-03-11 06:45:38 +01:00
Jakub Vrana
91b735c576 Compile: Support \r\n line ends 2025-03-11 06:30:31 +01:00
Jakub Vrana
916b9e62de Fix double unescaping 2025-03-11 06:24:21 +01:00
Jakub Vrana
f25c65837f Add comment 2025-03-11 06:24:21 +01:00
Jakub Vrana
b0182834bf Fix typo 2025-03-11 06:24:21 +01:00
David Grudl
6bf0b85919 Compile: supports visibility modifiers 2025-03-11 06:24:07 +01:00
Jakub Vrana
37e63dd82f MySQL: Stop treating enum as set as numbers (bug #475) 2025-03-10 23:40:07 +01:00
Jakub Vrana
6fdde32f86 Remove check for PHP version 2025-03-10 23:03:20 +01:00
Jakub Vrana
aeac0a3329 MySQL: Allow setting default values of text column 2025-03-10 21:15:01 +01:00
Christian Weiske
fde7d7dde2 Elastic: Properly display sparse result rows
Result records in Elasticsearch do not always have all columns
that are defined in an index.
This often happens when multiple document types are stored in the same index.

The first row has columns ["_id", "html", "url"], while the second
misses the "html" column: ["_id", "url"].

Adminer expects that all result rows include all columns.
This leads to the problem that the "url" value in the 2nd example row
was rendered in the "html" column.

This patch fixes this problem by fetching the actual column list first
when all fields are to be shown, and using that field list
as base for all rows.
2025-03-10 21:14:54 +01:00
Christian Weiske
e993462412 Elastic: Fix record insertion on Elasticsearch 7
1. Make values NULLable by default, so that empty values do not
get submitted to the Elasticsearch server.
This helps e.g. with empty date fields - Elasticsearch would try to
convert the field type to string when the value is an empty string,
but that fails when there are documents with properly filled date fields

2. Remove _id from the POST array because this is not allowed.
The server fails if it is included with
> mapper_parsing_exception:
> Field [_id] is a metadata field and cannot be added inside a document.
> Use the index API request parameters.

3. Use the correct URL to create a document: "$index/_doc/"
and "$index/_doc/$id". This is the same for ES 7 and 8:
- https://www.elastic.co/guide/en/elasticsearch/reference/8.17/docs-index_.html#docs-index-api-request
- https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-index_.html#docs-index-api-request

4. Handle failed creations by checking for false

5. Return the "result" property string instead of the non-existing
"created" property.
2025-03-10 21:13:16 +01:00
Jakub Vrana
31f8f61d0e MySQL, MariaDB: Fix default values with ' (fix #895) 2025-03-10 21:01:21 +01:00
Jakub Vrana
e589ee3fde MariaDB: Fix creating and altering generated columns (fixes #897) 2025-03-10 19:18:14 +01:00
Jakub Vrána
35274f18bb Update issue templates 2025-03-10 19:09:56 +01:00
Jakub Vrana
f8b2640156 Fix gzip export (fixes #896) 2025-03-10 18:51:28 +01:00
Jakub Vrana
bb23546478 Use <datalist> for altering collations 2025-03-10 14:13:34 +01:00
Jakub Vrana
dddfc190a5 Split helper html_radios 2025-03-10 11:31:43 +01:00
Jakub Vrana
40760d153c Update changes 2025-03-10 09:09:09 +01:00
Peter Knut
4fe3d17255 Update Slovak translation 2025-03-10 09:09:09 +01:00
Jakub Vrana
6dcc5081e1 Fix importing multiple SQL files not terminated by semicolon
Inspired by adminneo-org/adminneo#1c08e86.
2025-03-10 09:09:09 +01:00
Jakub Vrana
df6fe6b108 Fix link 2025-03-10 09:09:09 +01:00
Jakub Vrana
e6339046ff Remove unused variable 2025-03-10 09:09:09 +01:00
Jakub Vrana
2c0cfbdd3f Develop 2025-03-10 09:09:09 +01:00
Christian Weiske
f13770c664 Make login to Elasticsearch work again
By partially reverting the changes made by
commit 2c9f380c64
> Elastic: Remove plugin for version 5
which removed the passwordless login plugin from adminer/elastic.php
2025-03-10 08:53:19 +01:00
63 changed files with 668 additions and 559 deletions

14
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,14 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Adminer version:** please use latest published or Git
**Driver:** e.g. MySQL
**Database version:** e.g. 10.1.48-MariaDB
Please provide reproducible steps including a SQL dump (with no personal information) if applicable.

View File

@@ -73,11 +73,8 @@ if ($in) {
echo "<tr><th>" . $adminer->fieldName($field); echo "<tr><th>" . $adminer->fieldName($field);
$value = $_POST["fields"][$name]; $value = $_POST["fields"][$name];
if ($value != "") { if ($value != "") {
if ($field["type"] == "enum") {
$value = +$value;
}
if ($field["type"] == "set") { if ($field["type"] == "set") {
$value = array_sum($value); $value = implode(",", $value);
} }
} }
input($field, $value, (string) $_POST["function"][$name]); // param name can be empty input($field, $value, (string) $_POST["function"][$name]); // param name can be empty

View File

@@ -183,7 +183,12 @@ foreach ($engines as $engine) {
<?php if (support("columns") || $TABLE == "") { ?> <?php if (support("columns") || $TABLE == "") { ?>
<?php echo lang('Table name'); ?>: <input name="name"<?php echo ($TABLE == "" && !$_POST ? " autofocus" : ""); ?> data-maxlength="64" value="<?php echo h($row["name"]); ?>" autocapitalize="off"> <?php echo lang('Table name'); ?>: <input name="name"<?php echo ($TABLE == "" && !$_POST ? " autofocus" : ""); ?> data-maxlength="64" value="<?php echo h($row["name"]); ?>" autocapitalize="off">
<?php echo ($engines ? html_select("Engine", array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . on_help("getTarget(event).value", 1) . script("qsl('select').onchange = helpClose;") : ""); ?> <?php echo ($engines ? html_select("Engine", array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . on_help("getTarget(event).value", 1) . script("qsl('select').onchange = helpClose;") : ""); ?>
<?php echo ($collations && !preg_match("~sqlite|mssql~", JUSH) ? html_select("Collation", array("" => "(" . lang('collation') . ")") + $collations, $row["Collation"]) : ""); ?> <?php
if ($collations) {
echo "<datalist id='collations'>" . optionlist($collations) . "</datalist>";
echo (preg_match("~sqlite|mssql~", JUSH) ? "" : "<input list='collations' name='Collation' value='" . h($row["Collation"]) . "' placeholder='(" . lang('collation') . ")'>");
}
?>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php } ?> <?php } ?>

View File

@@ -8,17 +8,21 @@ if (isset($_GET["mongo"])) {
if (class_exists('MongoDB\Driver\Manager')) { if (class_exists('MongoDB\Driver\Manager')) {
class Db { class Db {
var $extension = "MongoDB", $server_info = MONGODB_VERSION, $affected_rows, $error, $last_id; public $extension = "MongoDB", $server_info = MONGODB_VERSION, $affected_rows, $error, $last_id;
/** @var MongoDB\Driver\Manager */ /** @var MongoDB\Driver\Manager */
var $_link; public $_link;
var $_db, $_db_name; public $_db, $_db_name;
function connect($uri, $options) { function connect($uri, $options) {
$this->_link = new \MongoDB\Driver\Manager($uri, $options); $this->_link = new \MongoDB\Driver\Manager($uri, $options);
$this->executeCommand($options["db"], array('ping' => 1)); $this->executeDbCommand($options["db"], array('ping' => 1));
} }
function executeCommand($db, $command) { function executeCommand($command) {
return $this->executeDbCommand($this->_db_name);
}
function executeDbCommand($db, $command) {
try { try {
return $this->_link->executeCommand($db, new \MongoDB\Driver\Command($command)); return $this->_link->executeCommand($db, new \MongoDB\Driver\Command($command));
} catch (Exception $e) { } catch (Exception $e) {
@@ -53,14 +57,15 @@ if (isset($_GET["mongo"])) {
} }
class Result { class Result {
var $num_rows, $_rows = array(), $_offset = 0, $_charset = array(); public $num_rows;
private $rows = array(), $offset = 0, $charset = array();
function __construct($result) { function __construct($result) {
foreach ($result as $item) { foreach ($result as $item) {
$row = array(); $row = array();
foreach ($item as $key => $val) { foreach ($item as $key => $val) {
if (is_a($val, 'MongoDB\BSON\Binary')) { if (is_a($val, 'MongoDB\BSON\Binary')) {
$this->_charset[$key] = 63; $this->charset[$key] = 63;
} }
$row[$key] = $row[$key] =
(is_a($val, 'MongoDB\BSON\ObjectID') ? 'MongoDB\BSON\ObjectID("' . "$val\")" : (is_a($val, 'MongoDB\BSON\ObjectID') ? 'MongoDB\BSON\ObjectID("' . "$val\")" :
@@ -71,26 +76,26 @@ if (isset($_GET["mongo"])) {
$val // MongoMinKey, MongoMaxKey $val // MongoMinKey, MongoMaxKey
))))); )))));
} }
$this->_rows[] = $row; $this->rows[] = $row;
foreach ($row as $key => $val) { foreach ($row as $key => $val) {
if (!isset($this->_rows[0][$key])) { if (!isset($this->rows[0][$key])) {
$this->_rows[0][$key] = null; $this->rows[0][$key] = null;
} }
} }
} }
$this->num_rows = count($this->_rows); $this->num_rows = count($this->rows);
} }
function fetch_assoc() { function fetch_assoc() {
$row = current($this->_rows); $row = current($this->rows);
if (!$row) { if (!$row) {
return $row; return $row;
} }
$return = array(); $return = array();
foreach ($this->_rows[0] as $key => $val) { foreach ($this->rows[0] as $key => $val) {
$return[$key] = $row[$key]; $return[$key] = $row[$key];
} }
next($this->_rows); next($this->rows);
return $return; return $return;
} }
@@ -103,11 +108,11 @@ if (isset($_GET["mongo"])) {
} }
function fetch_field() { function fetch_field() {
$keys = array_keys($this->_rows[0]); $keys = array_keys($this->rows[0]);
$name = $keys[$this->_offset++]; $name = $keys[$this->offset++];
return (object) array( return (object) array(
'name' => $name, 'name' => $name,
'charsetnr' => $this->_charset[$name], 'charsetnr' => $this->charset[$name],
); );
} }
} }
@@ -117,7 +122,7 @@ if (isset($_GET["mongo"])) {
function get_databases($flush) { function get_databases($flush) {
global $connection; global $connection;
$return = array(); $return = array();
foreach ($connection->executeCommand($connection->_db_name, array('listDatabases' => 1)) as $dbs) { foreach ($connection->executeCommand(array('listDatabases' => 1)) as $dbs) {
foreach ($dbs->databases as $db) { foreach ($dbs->databases as $db) {
$return[] = $db->name; $return[] = $db->name;
} }
@@ -133,7 +138,7 @@ if (isset($_GET["mongo"])) {
function tables_list() { function tables_list() {
global $connection; global $connection;
$collections = array(); $collections = array();
foreach ($connection->executeCommand($connection->_db_name, array('listCollections' => 1)) as $result) { foreach ($connection->executeCommand(array('listCollections' => 1)) as $result) {
$collections[$result->name] = 'table'; $collections[$result->name] = 'table';
} }
return $collections; return $collections;
@@ -146,7 +151,7 @@ if (isset($_GET["mongo"])) {
function indexes($table, $connection2 = null) { function indexes($table, $connection2 = null) {
global $connection; global $connection;
$return = array(); $return = array();
foreach ($connection->executeCommand($connection->_db_name, array('listIndexes' => $table)) as $index) { foreach ($connection->executeCommand(array('listIndexes' => $table)) as $index) {
$descs = array(); $descs = array();
$columns = array(); $columns = array();
foreach (get_object_vars($index->key) as $column => $type) { foreach (get_object_vars($index->key) as $column => $type) {
@@ -195,7 +200,7 @@ if (isset($_GET["mongo"])) {
function found_rows($table_status, $where) { function found_rows($table_status, $where) {
global $connection; global $connection;
$where = where_to_query($where); $where = where_to_query($where);
$toArray = $connection->executeCommand($connection->_db_name, array('count' => $table_status['Name'], 'query' => $where))->toArray(); $toArray = $connection->executeCommand(array('count' => $table_status['Name'], 'query' => $where))->toArray();
return $toArray[0]->n; return $toArray[0]->n;
} }
@@ -284,9 +289,9 @@ if (isset($_GET["mongo"])) {
static $possibleDrivers = array("mongodb"); static $possibleDrivers = array("mongodb");
static $jush = "mongo"; static $jush = "mongo";
var $editFunctions = array(array("json")); public $editFunctions = array(array("json"));
var $operators = array( public $operators = array(
"=", "=",
"!=", "!=",
">", ">",
@@ -330,15 +335,15 @@ if (isset($_GET["mongo"])) {
$limit = min(200, max(1, (int) $limit)); $limit = min(200, max(1, (int) $limit));
$skip = $page * $limit; $skip = $page * $limit;
try { try {
return new Result($this->_conn->_link->executeQuery($this->_conn->_db_name . ".$table", new \MongoDB\Driver\Query($where, array('projection' => $select, 'limit' => $limit, 'skip' => $skip, 'sort' => $sort)))); return new Result($this->conn->_link->executeQuery($this->conn->_db_name . ".$table", new \MongoDB\Driver\Query($where, array('projection' => $select, 'limit' => $limit, 'skip' => $skip, 'sort' => $sort))));
} catch (Exception $e) { } catch (Exception $e) {
$this->_conn->error = $e->getMessage(); $this->conn->error = $e->getMessage();
return false; return false;
} }
} }
function update($table, $set, $queryWhere, $limit = 0, $separator = "\n") { function update($table, $set, $queryWhere, $limit = 0, $separator = "\n") {
$db = $this->_conn->_db_name; $db = $this->conn->_db_name;
$where = sql_query_where_parser($queryWhere); $where = sql_query_where_parser($queryWhere);
$bulk = new \MongoDB\Driver\BulkWrite(array()); $bulk = new \MongoDB\Driver\BulkWrite(array());
if (isset($set['_id'])) { if (isset($set['_id'])) {
@@ -356,25 +361,25 @@ if (isset($_GET["mongo"])) {
$update['$unset'] = $removeFields; $update['$unset'] = $removeFields;
} }
$bulk->update($where, $update, array('upsert' => false)); $bulk->update($where, $update, array('upsert' => false));
return $this->_conn->executeBulkWrite("$db.$table", $bulk, 'getModifiedCount'); return $this->conn->executeBulkWrite("$db.$table", $bulk, 'getModifiedCount');
} }
function delete($table, $queryWhere, $limit = 0) { function delete($table, $queryWhere, $limit = 0) {
$db = $this->_conn->_db_name; $db = $this->conn->_db_name;
$where = sql_query_where_parser($queryWhere); $where = sql_query_where_parser($queryWhere);
$bulk = new \MongoDB\Driver\BulkWrite(array()); $bulk = new \MongoDB\Driver\BulkWrite(array());
$bulk->delete($where, array('limit' => $limit)); $bulk->delete($where, array('limit' => $limit));
return $this->_conn->executeBulkWrite("$db.$table", $bulk, 'getDeletedCount'); return $this->conn->executeBulkWrite("$db.$table", $bulk, 'getDeletedCount');
} }
function insert($table, $set) { function insert($table, $set) {
$db = $this->_conn->_db_name; $db = $this->conn->_db_name;
$bulk = new \MongoDB\Driver\BulkWrite(array()); $bulk = new \MongoDB\Driver\BulkWrite(array());
if ($set['_id'] == '') { if ($set['_id'] == '') {
unset($set['_id']); unset($set['_id']);
} }
$bulk->insert($set); $bulk->insert($set);
return $this->_conn->executeBulkWrite("$db.$table", $bulk, 'getInsertedCount'); return $this->conn->executeBulkWrite("$db.$table", $bulk, 'getInsertedCount');
} }
} }

View File

@@ -13,9 +13,10 @@ if (isset($_GET["mssql"])) {
define('Adminer\DRIVER', "mssql"); define('Adminer\DRIVER', "mssql");
if (extension_loaded("sqlsrv")) { if (extension_loaded("sqlsrv")) {
class Db { class Db {
var $extension = "sqlsrv", $_link, $_result, $server_info, $affected_rows, $errno, $error; public $extension = "sqlsrv", $server_info, $affected_rows, $errno, $error;
private $link, $result;
function _get_error() { private function get_error() {
$this->error = ""; $this->error = "";
foreach (sqlsrv_errors() as $error) { foreach (sqlsrv_errors() as $error) {
$this->errno = $error["code"]; $this->errno = $error["code"];
@@ -38,14 +39,14 @@ if (isset($_GET["mssql"])) {
if ($db != "") { if ($db != "") {
$connection_info["Database"] = $db; $connection_info["Database"] = $db;
} }
$this->_link = @sqlsrv_connect(preg_replace('~:~', ',', $server), $connection_info); $this->link = @sqlsrv_connect(preg_replace('~:~', ',', $server), $connection_info);
if ($this->_link) { if ($this->link) {
$info = sqlsrv_server_info($this->_link); $info = sqlsrv_server_info($this->link);
$this->server_info = $info['SQLServerVersion']; $this->server_info = $info['SQLServerVersion'];
} else { } else {
$this->_get_error(); $this->get_error();
} }
return (bool) $this->_link; return (bool) $this->link;
} }
function quote($string) { function quote($string) {
@@ -58,20 +59,20 @@ if (isset($_GET["mssql"])) {
} }
function query($query, $unbuffered = false) { function query($query, $unbuffered = false) {
$result = sqlsrv_query($this->_link, $query); //! , array(), ($unbuffered ? array() : array("Scrollable" => "keyset")) $result = sqlsrv_query($this->link, $query); //! , array(), ($unbuffered ? array() : array("Scrollable" => "keyset"))
$this->error = ""; $this->error = "";
if (!$result) { if (!$result) {
$this->_get_error(); $this->get_error();
return false; return false;
} }
return $this->store_result($result); return $this->store_result($result);
} }
function multi_query($query) { function multi_query($query) {
$this->_result = sqlsrv_query($this->_link, $query); $this->result = sqlsrv_query($this->link, $query);
$this->error = ""; $this->error = "";
if (!$this->_result) { if (!$this->result) {
$this->_get_error(); $this->get_error();
return false; return false;
} }
return true; return true;
@@ -79,7 +80,7 @@ if (isset($_GET["mssql"])) {
function store_result($result = null) { function store_result($result = null) {
if (!$result) { if (!$result) {
$result = $this->_result; $result = $this->result;
} }
if (!$result) { if (!$result) {
return false; return false;
@@ -92,7 +93,7 @@ if (isset($_GET["mssql"])) {
} }
function next_result() { function next_result() {
return $this->_result ? sqlsrv_next_result($this->_result) : null; return $this->result ? sqlsrv_next_result($this->result) : null;
} }
function result($query, $field = 0) { function result($query, $field = 0) {
@@ -106,14 +107,15 @@ if (isset($_GET["mssql"])) {
} }
class Result { class Result {
var $_result, $_offset = 0, $_fields, $num_rows; public $num_rows;
private $result, $offset = 0, $fields;
function __construct($result) { function __construct($result) {
$this->_result = $result; $this->result = $result;
// $this->num_rows = sqlsrv_num_rows($result); // available only in scrollable results // $this->num_rows = sqlsrv_num_rows($result); // available only in scrollable results
} }
function _convert($row) { private function convert($row) {
foreach ((array) $row as $key => $val) { foreach ((array) $row as $key => $val) {
if (is_a($val, 'DateTime')) { if (is_a($val, 'DateTime')) {
$row[$key] = $val->format("Y-m-d H:i:s"); $row[$key] = $val->format("Y-m-d H:i:s");
@@ -124,18 +126,18 @@ if (isset($_GET["mssql"])) {
} }
function fetch_assoc() { function fetch_assoc() {
return $this->_convert(sqlsrv_fetch_array($this->_result, SQLSRV_FETCH_ASSOC)); return $this->convert(sqlsrv_fetch_array($this->result, SQLSRV_FETCH_ASSOC));
} }
function fetch_row() { function fetch_row() {
return $this->_convert(sqlsrv_fetch_array($this->_result, SQLSRV_FETCH_NUMERIC)); return $this->convert(sqlsrv_fetch_array($this->result, SQLSRV_FETCH_NUMERIC));
} }
function fetch_field() { function fetch_field() {
if (!$this->_fields) { if (!$this->fields) {
$this->_fields = sqlsrv_field_metadata($this->_result); $this->fields = sqlsrv_field_metadata($this->result);
} }
$field = $this->_fields[$this->_offset++]; $field = $this->fields[$this->offset++];
$return = new \stdClass; $return = new \stdClass;
$return->name = $field["Name"]; $return->name = $field["Name"];
$return->orgname = $field["Name"]; $return->orgname = $field["Name"];
@@ -145,18 +147,18 @@ if (isset($_GET["mssql"])) {
function seek($offset) { function seek($offset) {
for ($i=0; $i < $offset; $i++) { for ($i=0; $i < $offset; $i++) {
sqlsrv_fetch($this->_result); // SQLSRV_SCROLL_ABSOLUTE added in sqlsrv 1.1 sqlsrv_fetch($this->result); // SQLSRV_SCROLL_ABSOLUTE added in sqlsrv 1.1
} }
} }
function __destruct() { function __destruct() {
sqlsrv_free_stmt($this->_result); sqlsrv_free_stmt($this->result);
} }
} }
} elseif (extension_loaded("pdo_sqlsrv")) { } elseif (extension_loaded("pdo_sqlsrv")) {
class Db extends PdoDb { class Db extends PdoDb {
var $extension = "PDO_SQLSRV"; public $extension = "PDO_SQLSRV";
function connect($server, $username, $password) { function connect($server, $username, $password) {
$this->dsn("sqlsrv:Server=" . str_replace(":", ",", $server), $username, $password); $this->dsn("sqlsrv:Server=" . str_replace(":", ",", $server), $username, $password);
@@ -171,7 +173,7 @@ if (isset($_GET["mssql"])) {
} elseif (extension_loaded("pdo_dblib")) { } elseif (extension_loaded("pdo_dblib")) {
class Db extends PdoDb { class Db extends PdoDb {
var $extension = "PDO_DBLIB"; public $extension = "PDO_DBLIB";
function connect($server, $username, $password) { function connect($server, $username, $password) {
$this->dsn("dblib:charset=utf8;host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\d)~', ';port=\1', $server)), $username, $password); $this->dsn("dblib:charset=utf8;host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\d)~', ';port=\1', $server)), $username, $password);
@@ -189,7 +191,7 @@ if (isset($_GET["mssql"])) {
static $possibleDrivers = array("SQLSRV", "PDO_SQLSRV", "PDO_DBLIB"); static $possibleDrivers = array("SQLSRV", "PDO_SQLSRV", "PDO_DBLIB");
static $jush = "mssql"; static $jush = "mssql";
var $editFunctions = array( public $editFunctions = array(
array( array(
"date|time" => "getdate", "date|time" => "getdate",
), array( ), array(
@@ -198,11 +200,11 @@ if (isset($_GET["mssql"])) {
) )
); );
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"); public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL");
var $functions = array("len", "lower", "round", "upper"); public $functions = array("len", "lower", "round", "upper");
var $grouping = array("avg", "count", "count distinct", "max", "min", "sum"); public $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
var $onActions = "NO ACTION|CASCADE|SET NULL|SET DEFAULT"; public $onActions = "NO ACTION|CASCADE|SET NULL|SET DEFAULT";
var $generated = array("PERSISTED", "VIRTUAL"); public $generated = array("PERSISTED", "VIRTUAL");
function __construct($connection) { function __construct($connection) {
parent::__construct($connection); parent::__construct($connection);

View File

@@ -8,7 +8,7 @@ if (!defined('Adminer\DRIVER')) {
// MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable // MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable
if (extension_loaded("mysqli")) { if (extension_loaded("mysqli")) {
class Db extends \MySQLi { class Db extends \MySQLi {
var $extension = "MySQLi"; public $extension = "MySQLi";
function __construct() { function __construct() {
parent::init(); parent::init();
@@ -60,14 +60,14 @@ if (!defined('Adminer\DRIVER')) {
} elseif (extension_loaded("mysql") && !((ini_bool("sql.safe_mode") || ini_bool("mysql.allow_local_infile")) && extension_loaded("pdo_mysql"))) { } elseif (extension_loaded("mysql") && !((ini_bool("sql.safe_mode") || ini_bool("mysql.allow_local_infile")) && extension_loaded("pdo_mysql"))) {
class Db { class Db {
var public
$extension = "MySQL", ///< @var string extension name $extension = "MySQL", ///< @var string extension name
$server_info, ///< @var string server version $server_info, ///< @var string server version
$affected_rows, ///< @var int number of affected rows $affected_rows, ///< @var int number of affected rows
$errno, ///< @var int last error code $errno, ///< @var int last error code
$error, ///< @var string last error message $error ///< @var string last error message
$_link, $_result ///< @access private
; ;
private $link, $result;
/** Connect to server /** Connect to server
* @param string * @param string
@@ -80,19 +80,19 @@ if (!defined('Adminer\DRIVER')) {
$this->error = lang('Disable %s or enable %s or %s extensions.', "'mysql.allow_local_infile'", "MySQLi", "PDO_MySQL"); $this->error = lang('Disable %s or enable %s or %s extensions.', "'mysql.allow_local_infile'", "MySQLi", "PDO_MySQL");
return false; return false;
} }
$this->_link = @mysql_connect( $this->link = @mysql_connect(
($server != "" ? $server : ini_get("mysql.default_host")), ($server != "" ? $server : ini_get("mysql.default_host")),
("$server$username" != "" ? $username : ini_get("mysql.default_user")), ("$server$username" != "" ? $username : ini_get("mysql.default_user")),
("$server$username$password" != "" ? $password : ini_get("mysql.default_password")), ("$server$username$password" != "" ? $password : ini_get("mysql.default_password")),
true, true,
131072 // CLIENT_MULTI_RESULTS for CALL 131072 // CLIENT_MULTI_RESULTS for CALL
); );
if ($this->_link) { if ($this->link) {
$this->server_info = mysql_get_server_info($this->_link); $this->server_info = mysql_get_server_info($this->link);
} else { } else {
$this->error = mysql_error(); $this->error = mysql_error();
} }
return (bool) $this->_link; return (bool) $this->link;
} }
/** Sets the client character set /** Sets the client character set
@@ -101,11 +101,11 @@ if (!defined('Adminer\DRIVER')) {
*/ */
function set_charset($charset) { function set_charset($charset) {
if (function_exists('mysql_set_charset')) { if (function_exists('mysql_set_charset')) {
if (mysql_set_charset($charset, $this->_link)) { if (mysql_set_charset($charset, $this->link)) {
return true; return true;
} }
// the client library may not support utf8mb4 // the client library may not support utf8mb4
mysql_set_charset('utf8', $this->_link); mysql_set_charset('utf8', $this->link);
} }
return $this->query("SET NAMES $charset"); return $this->query("SET NAMES $charset");
} }
@@ -115,7 +115,7 @@ if (!defined('Adminer\DRIVER')) {
* @return string escaped string enclosed in ' * @return string escaped string enclosed in '
*/ */
function quote($string) { function quote($string) {
return "'" . mysql_real_escape_string($string, $this->_link) . "'"; return "'" . mysql_real_escape_string($string, $this->link) . "'";
} }
/** Select database /** Select database
@@ -123,7 +123,7 @@ if (!defined('Adminer\DRIVER')) {
* @return bool * @return bool
*/ */
function select_db($database) { function select_db($database) {
return mysql_select_db($database, $this->_link); return mysql_select_db($database, $this->link);
} }
/** Send query /** Send query
@@ -132,16 +132,16 @@ if (!defined('Adminer\DRIVER')) {
* @return mixed bool or Result * @return mixed bool or Result
*/ */
function query($query, $unbuffered = false) { function query($query, $unbuffered = false) {
$result = @($unbuffered ? mysql_unbuffered_query($query, $this->_link) : mysql_query($query, $this->_link)); // @ - mute mysql.trace_mode $result = @($unbuffered ? mysql_unbuffered_query($query, $this->link) : mysql_query($query, $this->link)); // @ - mute mysql.trace_mode
$this->error = ""; $this->error = "";
if (!$result) { if (!$result) {
$this->errno = mysql_errno($this->_link); $this->errno = mysql_errno($this->link);
$this->error = mysql_error($this->_link); $this->error = mysql_error($this->link);
return false; return false;
} }
if ($result === true) { if ($result === true) {
$this->affected_rows = mysql_affected_rows($this->_link); $this->affected_rows = mysql_affected_rows($this->link);
$this->info = mysql_info($this->_link); $this->info = mysql_info($this->link);
return true; return true;
} }
return new Result($result); return new Result($result);
@@ -152,14 +152,14 @@ if (!defined('Adminer\DRIVER')) {
* @return bool * @return bool
*/ */
function multi_query($query) { function multi_query($query) {
return $this->_result = $this->query($query); return $this->result = $this->query($query);
} }
/** Get current resultset /** Get current resultset
* @return Result * @return Result
*/ */
function store_result() { function store_result() {
return $this->_result; return $this->result;
} }
/** Fetch next resultset /** Fetch next resultset
@@ -177,24 +177,19 @@ if (!defined('Adminer\DRIVER')) {
*/ */
function result($query, $field = 0) { function result($query, $field = 0) {
$result = $this->query($query); $result = $this->query($query);
if (!$result || !$result->num_rows) { return ($result ? $result->fetch_column($field) : false);
return false;
}
return mysql_result($result->_result, 0, $field);
} }
} }
class Result { class Result {
var public $num_rows; ///< @var int number of rows in the result
$num_rows, ///< @var int number of rows in the result private $result, $offset = 0;
$_result, $_offset = 0 ///< @access private
;
/** Constructor /** Constructor
* @param resource * @param resource
*/ */
function __construct($result) { function __construct($result) {
$this->_result = $result; $this->result = $result;
$this->num_rows = mysql_num_rows($result); $this->num_rows = mysql_num_rows($result);
} }
@@ -202,21 +197,29 @@ if (!defined('Adminer\DRIVER')) {
* @return array * @return array
*/ */
function fetch_assoc() { function fetch_assoc() {
return mysql_fetch_assoc($this->_result); return mysql_fetch_assoc($this->result);
} }
/** Fetch next row as numbered array /** Fetch next row as numbered array
* @return array * @return array
*/ */
function fetch_row() { function fetch_row() {
return mysql_fetch_row($this->_result); return mysql_fetch_row($this->result);
}
/** Fetch a single column
* @param int
* @return string or false if there are no rows
*/
function fetch_column($field) {
return ($this->num_rows ? mysql_result($this->result, 0, $field) : false);
} }
/** Fetch next field /** Fetch next field
* @return object properties: name, type, orgtable, orgname, charsetnr * @return object properties: name, type, orgtable, orgname, charsetnr
*/ */
function fetch_field() { function fetch_field() {
$return = mysql_fetch_field($this->_result, $this->_offset++); // offset required under certain conditions $return = mysql_fetch_field($this->result, $this->offset++); // offset required under certain conditions
$return->orgtable = $return->table; $return->orgtable = $return->table;
$return->orgname = $return->name; $return->orgname = $return->name;
$return->charsetnr = ($return->blob ? 63 : 0); $return->charsetnr = ($return->blob ? 63 : 0);
@@ -226,13 +229,13 @@ if (!defined('Adminer\DRIVER')) {
/** Free result set /** Free result set
*/ */
function __destruct() { function __destruct() {
mysql_free_result($this->_result); mysql_free_result($this->result);
} }
} }
} elseif (extension_loaded("pdo_mysql")) { } elseif (extension_loaded("pdo_mysql")) {
class Db extends PdoDb { class Db extends PdoDb {
var $extension = "PDO_MySQL"; public $extension = "PDO_MySQL";
function connect($server, $username, $password) { function connect($server, $username, $password) {
global $adminer; global $adminer;
@@ -284,10 +287,10 @@ if (!defined('Adminer\DRIVER')) {
static $possibleDrivers = array("MySQLi", "MySQL", "PDO_MySQL"); static $possibleDrivers = array("MySQLi", "MySQL", "PDO_MySQL");
static $jush = "sql"; ///< @var string JUSH identifier static $jush = "sql"; ///< @var string JUSH identifier
var $unsigned = array("unsigned", "zerofill", "unsigned zerofill"); public $unsigned = array("unsigned", "zerofill", "unsigned zerofill");
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "FIND_IN_SET", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL"); public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "FIND_IN_SET", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL");
var $functions = array("char_length", "date", "from_unixtime", "lower", "round", "floor", "ceil", "sec_to_time", "time_to_sec", "upper"); public $functions = array("char_length", "date", "from_unixtime", "lower", "round", "floor", "ceil", "sec_to_time", "time_to_sec", "upper");
var $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"); public $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
function __construct($connection) { function __construct($connection) {
parent::__construct($connection); parent::__construct($connection);
@@ -358,7 +361,7 @@ if (!defined('Adminer\DRIVER')) {
function slowQuery($query, $timeout) { function slowQuery($query, $timeout) {
if (min_version('5.7.8', '10.1.2')) { if (min_version('5.7.8', '10.1.2')) {
if (preg_match('~MariaDB~', $this->_conn->server_info)) { if (preg_match('~MariaDB~', $this->conn->server_info)) {
return "SET STATEMENT max_statement_time=$timeout FOR $query"; return "SET STATEMENT max_statement_time=$timeout FOR $query";
} elseif (preg_match('~^(SELECT\b)(.+)~is', $query, $match)) { } elseif (preg_match('~^(SELECT\b)(.+)~is', $query, $match)) {
return "$match[1] /*+ MAX_EXECUTION_TIME(" . ($timeout * 1000) . ") */ $match[2]"; return "$match[1] /*+ MAX_EXECUTION_TIME(" . ($timeout * 1000) . ") */ $match[2]";
@@ -368,13 +371,13 @@ if (!defined('Adminer\DRIVER')) {
function convertSearch($idf, $val, $field) { function convertSearch($idf, $val, $field) {
return (preg_match('~char|text|enum|set~', $field["type"]) && !preg_match("~^utf8~", $field["collation"]) && preg_match('~[\x80-\xFF]~', $val['val']) return (preg_match('~char|text|enum|set~', $field["type"]) && !preg_match("~^utf8~", $field["collation"]) && preg_match('~[\x80-\xFF]~', $val['val'])
? "CONVERT($idf USING " . charset($this->_conn) . ")" ? "CONVERT($idf USING " . charset($this->conn) . ")"
: $idf : $idf
); );
} }
function warnings() { function warnings() {
$result = $this->_conn->query("SHOW WARNINGS"); $result = $this->conn->query("SHOW WARNINGS");
if ($result && $result->num_rows) { if ($result && $result->num_rows) {
ob_start(); ob_start();
select($result); // select() usually needs to print a big table progressively select($result); // select() usually needs to print a big table progressively
@@ -383,7 +386,7 @@ if (!defined('Adminer\DRIVER')) {
} }
function tableHelp($name, $is_view = false) { function tableHelp($name, $is_view = false) {
$maria = preg_match('~MariaDB~', $this->_conn->server_info); $maria = preg_match('~MariaDB~', $this->conn->server_info);
if (information_schema(DB)) { if (information_schema(DB)) {
return strtolower("information-schema-" . ($maria ? "$name-table/" : str_replace("_", "-", $name) . "-table.html")); return strtolower("information-schema-" . ($maria ? "$name-table/" : str_replace("_", "-", $name) . "-table.html"));
} }
@@ -395,7 +398,7 @@ if (!defined('Adminer\DRIVER')) {
function hasCStyleEscapes() { function hasCStyleEscapes() {
static $c_style; static $c_style;
if ($c_style === null) { if ($c_style === null) {
$sql_mode = $this->_conn->result("SHOW VARIABLES LIKE 'sql_mode'", 1); $sql_mode = $this->conn->result("SHOW VARIABLES LIKE 'sql_mode'", 1);
$c_style = (strpos($sql_mode, 'NO_BACKSLASH_ESCAPES') === false); $c_style = (strpos($sql_mode, 'NO_BACKSLASH_ESCAPES') === false);
} }
return $c_style; return $c_style;
@@ -587,15 +590,28 @@ if (!defined('Adminer\DRIVER')) {
* @return array [$name => ["field" => , "full_type" => , "type" => , "length" => , "unsigned" => , "default" => , "null" => , "auto_increment" => , "on_update" => , "collation" => , "privileges" => , "comment" => , "primary" => , "generated" => ]] * @return array [$name => ["field" => , "full_type" => , "type" => , "length" => , "unsigned" => , "default" => , "null" => , "auto_increment" => , "on_update" => , "collation" => , "privileges" => , "comment" => , "primary" => , "generated" => ]]
*/ */
function fields($table) { function fields($table) {
global $connection;
$maria = preg_match('~MariaDB~', $connection->server_info);
$return = array(); $return = array();
foreach (get_rows("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . q($table) . " ORDER BY ORDINAL_POSITION") as $row) { foreach (get_rows("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . q($table) . " ORDER BY ORDINAL_POSITION") as $row) {
$field = $row["COLUMN_NAME"]; $field = $row["COLUMN_NAME"];
$default = $row["COLUMN_DEFAULT"];
$type = $row["COLUMN_TYPE"]; $type = $row["COLUMN_TYPE"];
$generation = $row["GENERATION_EXPRESSION"];
$extra = $row["EXTRA"]; $extra = $row["EXTRA"];
// https://mariadb.com/kb/en/library/show-columns/, https://github.com/vrana/adminer/pull/359#pullrequestreview-276677186 // https://mariadb.com/kb/en/library/show-columns/, https://github.com/vrana/adminer/pull/359#pullrequestreview-276677186
preg_match('~^(VIRTUAL|PERSISTENT|STORED)~', $extra, $generated); preg_match('~^(VIRTUAL|PERSISTENT|STORED)~', $extra, $generated);
preg_match('~^([^( ]+)(?:\((.+)\))?( unsigned)?( zerofill)?$~', $type, $match); preg_match('~^([^( ]+)(?:\((.+)\))?( unsigned)?( zerofill)?$~', $type, $match);
$default = $row["COLUMN_DEFAULT"];
$is_text = preg_match('~text~', $match[1]);
if (!$maria && $is_text) {
// default value a'b of text column is stored as _utf8mb4\'a\\\'b\' in MySQL
$default = preg_replace("~^(_\w+)?('.*')$~", '\2', stripslashes($default));
}
if ($maria || $is_text) {
$default = preg_replace_callback("~^'(.*)'$~", function ($match) {
return stripslashes(str_replace("''", "'", $match[1]));
}, $default);
}
$return[$field] = array( $return[$field] = array(
"field" => $field, "field" => $field,
"full_type" => $type, "full_type" => $type,
@@ -603,11 +619,8 @@ if (!defined('Adminer\DRIVER')) {
"length" => $match[2], "length" => $match[2],
"unsigned" => ltrim($match[3] . $match[4]), "unsigned" => ltrim($match[3] . $match[4]),
"default" => ($generated "default" => ($generated
? $row["GENERATION_EXPRESSION"] ? ($maria ? $generation : stripslashes($generation))
: ($default != "" || preg_match("~char|set~", $match[1]) : ($default != "" || preg_match("~char|set~", $match[1]) ? $default : null)
? (preg_match('~text~', $match[1]) ? stripslashes(preg_replace("~^'(.*)'\$~", '\1', $default)) : $default)
: null
)
), ),
"null" => ($row["IS_NULLABLE"] == "YES"), "null" => ($row["IS_NULLABLE"] == "YES"),
"auto_increment" => ($extra == "auto_increment"), "auto_increment" => ($extra == "auto_increment"),
@@ -786,12 +799,14 @@ if (!defined('Adminer\DRIVER')) {
* @return bool * @return bool
*/ */
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) { function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
global $connection;
$alter = array(); $alter = array();
foreach ($fields as $field) { foreach ($fields as $field) {
if ($field[1]) { if ($field[1]) {
$default = $field[1][3]; $default = $field[1][3];
if (preg_match('~ GENERATED~', $default)) { if (preg_match('~ GENERATED~', $default)) {
$field[1][3] = $field[1][2]; // swap default and null
$field[1][3] = (preg_match('~MariaDB~', $connection->server_info) ? "" : $field[1][2]); // MariaDB doesn't support NULL on virtual columns
$field[1][2] = $default; $field[1][2] = $default;
} }
$alter[] = ($table != "" ? ($field[0] != "" ? "CHANGE " . idf_escape($field[0]) : "ADD") : " ") . " " . implode($field[1]) . ($table != "" ? $field[2] : ""); $alter[] = ($table != "" ? ($field[0] != "" ? "CHANGE " . idf_escape($field[0]) : "ADD") : " ") . " " . implode($field[1]) . ($table != "" ? $field[2] : "");

View File

@@ -7,8 +7,9 @@ if (isset($_GET["oracle"])) {
define('Adminer\DRIVER', "oracle"); define('Adminer\DRIVER', "oracle");
if (extension_loaded("oci8")) { if (extension_loaded("oci8")) {
class Db { class Db {
var $extension = "oci8", $_link, $_result, $server_info, $affected_rows, $errno, $error; public $extension = "oci8", $server_info, $affected_rows, $errno, $error;
var $_current_db; public $_current_db;
private $link, $result;
function _error($errno, $error) { function _error($errno, $error) {
if (ini_bool("html_errors")) { if (ini_bool("html_errors")) {
@@ -19,9 +20,9 @@ if (isset($_GET["oracle"])) {
} }
function connect($server, $username, $password) { function connect($server, $username, $password) {
$this->_link = @oci_new_connect($username, $password, $server, "AL32UTF8"); $this->link = @oci_new_connect($username, $password, $server, "AL32UTF8");
if ($this->_link) { if ($this->link) {
$this->server_info = oci_server_version($this->_link); $this->server_info = oci_server_version($this->link);
return true; return true;
} }
$error = oci_error(); $error = oci_error();
@@ -39,10 +40,10 @@ if (isset($_GET["oracle"])) {
} }
function query($query, $unbuffered = false) { function query($query, $unbuffered = false) {
$result = oci_parse($this->_link, $query); $result = oci_parse($this->link, $query);
$this->error = ""; $this->error = "";
if (!$result) { if (!$result) {
$error = oci_error($this->_link); $error = oci_error($this->link);
$this->errno = $error["code"]; $this->errno = $error["code"];
$this->error = $error["message"]; $this->error = $error["message"];
return false; return false;
@@ -61,11 +62,11 @@ if (isset($_GET["oracle"])) {
} }
function multi_query($query) { function multi_query($query) {
return $this->_result = $this->query($query); return $this->result = $this->query($query);
} }
function store_result() { function store_result() {
return $this->_result; return $this->result;
} }
function next_result() { function next_result() {
@@ -74,21 +75,19 @@ if (isset($_GET["oracle"])) {
function result($query, $field = 0) { function result($query, $field = 0) {
$result = $this->query($query); $result = $this->query($query);
if (!is_object($result) || !oci_fetch($result->_result)) { return (is_object($result) ? $result->fetch_column($field) : false);
return false;
}
return oci_result($result->_result, $field + 1);
} }
} }
class Result { class Result {
var $_result, $_offset = 1, $num_rows; public $num_rows;
private $result, $offset = 1;
function __construct($result) { function __construct($result) {
$this->_result = $result; $this->result = $result;
} }
function _convert($row) { private function convert($row) {
foreach ((array) $row as $key => $val) { foreach ((array) $row as $key => $val) {
if (is_a($val, 'OCI-Lob')) { if (is_a($val, 'OCI-Lob')) {
$row[$key] = $val->load(); $row[$key] = $val->load();
@@ -98,32 +97,36 @@ if (isset($_GET["oracle"])) {
} }
function fetch_assoc() { function fetch_assoc() {
return $this->_convert(oci_fetch_assoc($this->_result)); return $this->convert(oci_fetch_assoc($this->result));
} }
function fetch_row() { function fetch_row() {
return $this->_convert(oci_fetch_row($this->_result)); return $this->convert(oci_fetch_row($this->result));
}
function fetch_column($field) {
return (oci_fetch($this->result) ? oci_result($this->result, $field + 1) : false);
} }
function fetch_field() { function fetch_field() {
$column = $this->_offset++; $column = $this->offset++;
$return = new \stdClass; $return = new \stdClass;
$return->name = oci_field_name($this->_result, $column); $return->name = oci_field_name($this->result, $column);
$return->orgname = $return->name; $return->orgname = $return->name;
$return->type = oci_field_type($this->_result, $column); $return->type = oci_field_type($this->result, $column);
$return->charsetnr = (preg_match("~raw|blob|bfile~", $return->type) ? 63 : 0); // 63 - binary $return->charsetnr = (preg_match("~raw|blob|bfile~", $return->type) ? 63 : 0); // 63 - binary
return $return; return $return;
} }
function __destruct() { function __destruct() {
oci_free_statement($this->_result); oci_free_statement($this->result);
} }
} }
} elseif (extension_loaded("pdo_oci")) { } elseif (extension_loaded("pdo_oci")) {
class Db extends PdoDb { class Db extends PdoDb {
var $extension = "PDO_OCI"; public $extension = "PDO_OCI";
var $_current_db; public $_current_db;
function connect($server, $username, $password) { function connect($server, $username, $password) {
$this->dsn("oci:dbname=//$server;charset=AL32UTF8", $username, $password); $this->dsn("oci:dbname=//$server;charset=AL32UTF8", $username, $password);
@@ -144,7 +147,7 @@ if (isset($_GET["oracle"])) {
static $possibleDrivers = array("OCI8", "PDO_OCI"); static $possibleDrivers = array("OCI8", "PDO_OCI");
static $jush = "oracle"; static $jush = "oracle";
var $editFunctions = array( public $editFunctions = array(
array( //! no parentheses array( //! no parentheses
"date" => "current_date", "date" => "current_date",
"timestamp" => "current_timestamp", "timestamp" => "current_timestamp",
@@ -155,9 +158,9 @@ if (isset($_GET["oracle"])) {
) )
); );
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"); public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL");
var $functions = array("length", "lower", "round", "upper"); public $functions = array("length", "lower", "round", "upper");
var $grouping = array("avg", "count", "count distinct", "max", "min", "sum"); public $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
function __construct($connection) { function __construct($connection) {
parent::__construct($connection); parent::__construct($connection);

View File

@@ -7,7 +7,8 @@ if (isset($_GET["pgsql"])) {
define('Adminer\DRIVER', "pgsql"); define('Adminer\DRIVER', "pgsql");
if (extension_loaded("pgsql")) { if (extension_loaded("pgsql")) {
class Db { class Db {
var $extension = "PgSQL", $_link, $_result, $_string, $_database = true, $server_info, $affected_rows, $error, $timeout; public $extension = "PgSQL", $server_info, $affected_rows, $error, $timeout;
private $link, $result, $string, $database = true;
function _error($errno, $error) { function _error($errno, $error) {
if (ini_bool("html_errors")) { if (ini_bool("html_errors")) {
@@ -21,28 +22,28 @@ if (isset($_GET["pgsql"])) {
global $adminer; global $adminer;
$db = $adminer->database(); $db = $adminer->database();
set_error_handler(array($this, '_error')); set_error_handler(array($this, '_error'));
$this->_string = "host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' user='" . addcslashes($username, "'\\") . "' password='" . addcslashes($password, "'\\") . "'"; $this->string = "host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' user='" . addcslashes($username, "'\\") . "' password='" . addcslashes($password, "'\\") . "'";
$ssl = $adminer->connectSsl(); $ssl = $adminer->connectSsl();
if (isset($ssl["mode"])) { if (isset($ssl["mode"])) {
$this->_string .= " sslmode='" . $ssl["mode"] . "'"; $this->string .= " sslmode='" . $ssl["mode"] . "'";
} }
$this->_link = @pg_connect("$this->_string dbname='" . ($db != "" ? addcslashes($db, "'\\") : "postgres") . "'", PGSQL_CONNECT_FORCE_NEW); $this->link = @pg_connect("$this->string dbname='" . ($db != "" ? addcslashes($db, "'\\") : "postgres") . "'", PGSQL_CONNECT_FORCE_NEW);
if (!$this->_link && $db != "") { if (!$this->link && $db != "") {
// try to connect directly with database for performance // try to connect directly with database for performance
$this->_database = false; $this->database = false;
$this->_link = @pg_connect("$this->_string dbname='postgres'", PGSQL_CONNECT_FORCE_NEW); $this->link = @pg_connect("$this->string dbname='postgres'", PGSQL_CONNECT_FORCE_NEW);
} }
restore_error_handler(); restore_error_handler();
if ($this->_link) { if ($this->link) {
$version = pg_version($this->_link); $version = pg_version($this->link);
$this->server_info = $version["server"]; $this->server_info = $version["server"];
pg_set_client_encoding($this->_link, "UTF8"); pg_set_client_encoding($this->link, "UTF8");
} }
return (bool) $this->_link; return (bool) $this->link;
} }
function quote($string) { function quote($string) {
return pg_escape_literal($this->_link, $string); return pg_escape_literal($this->link, $string);
} }
function value($val, $field) { function value($val, $field) {
@@ -50,30 +51,30 @@ if (isset($_GET["pgsql"])) {
} }
function quoteBinary($string) { function quoteBinary($string) {
return "'" . pg_escape_bytea($this->_link, $string) . "'"; return "'" . pg_escape_bytea($this->link, $string) . "'";
} }
function select_db($database) { function select_db($database) {
global $adminer; global $adminer;
if ($database == $adminer->database()) { if ($database == $adminer->database()) {
return $this->_database; return $this->database;
} }
$return = @pg_connect("$this->_string dbname='" . addcslashes($database, "'\\") . "'", PGSQL_CONNECT_FORCE_NEW); $return = @pg_connect("$this->string dbname='" . addcslashes($database, "'\\") . "'", PGSQL_CONNECT_FORCE_NEW);
if ($return) { if ($return) {
$this->_link = $return; $this->link = $return;
} }
return $return; return $return;
} }
function close() { function close() {
$this->_link = @pg_connect("$this->_string dbname='postgres'"); $this->link = @pg_connect("$this->string dbname='postgres'");
} }
function query($query, $unbuffered = false) { function query($query, $unbuffered = false) {
$result = @pg_query($this->_link, $query); $result = @pg_query($this->link, $query);
$this->error = ""; $this->error = "";
if (!$result) { if (!$result) {
$this->error = pg_last_error($this->_link); $this->error = pg_last_error($this->link);
$return = false; $return = false;
} elseif (!pg_num_fields($result)) { } elseif (!pg_num_fields($result)) {
$this->affected_rows = pg_affected_rows($result); $this->affected_rows = pg_affected_rows($result);
@@ -89,11 +90,11 @@ if (isset($_GET["pgsql"])) {
} }
function multi_query($query) { function multi_query($query) {
return $this->_result = $this->query($query); return $this->result = $this->query($query);
} }
function store_result() { function store_result() {
return $this->_result; return $this->result;
} }
function next_result() { function next_result() {
@@ -103,54 +104,56 @@ if (isset($_GET["pgsql"])) {
function result($query, $field = 0) { function result($query, $field = 0) {
$result = $this->query($query); $result = $this->query($query);
if (!$result || !$result->num_rows) { return ($result ? $result->fetch_column($field) : false);
return false;
}
return pg_fetch_result($result->_result, 0, $field);
} }
function warnings() { function warnings() {
return h(pg_last_notice($this->_link)); // second parameter is available since PHP 7.1.0 return h(pg_last_notice($this->link)); // second parameter is available since PHP 7.1.0
} }
} }
class Result { class Result {
var $_result, $_offset = 0, $num_rows; public $num_rows;
private $result, $offset = 0;
function __construct($result) { function __construct($result) {
$this->_result = $result; $this->result = $result;
$this->num_rows = pg_num_rows($result); $this->num_rows = pg_num_rows($result);
} }
function fetch_assoc() { function fetch_assoc() {
return pg_fetch_assoc($this->_result); return pg_fetch_assoc($this->result);
} }
function fetch_row() { function fetch_row() {
return pg_fetch_row($this->_result); return pg_fetch_row($this->result);
}
function fetch_column($field) {
return ($this->num_rows ? pg_fetch_result($this->result, 0, $field) : false);
} }
function fetch_field() { function fetch_field() {
$column = $this->_offset++; $column = $this->offset++;
$return = new \stdClass; $return = new \stdClass;
if (function_exists('pg_field_table')) { if (function_exists('pg_field_table')) {
$return->orgtable = pg_field_table($this->_result, $column); $return->orgtable = pg_field_table($this->result, $column);
} }
$return->name = pg_field_name($this->_result, $column); $return->name = pg_field_name($this->result, $column);
$return->orgname = $return->name; $return->orgname = $return->name;
$return->type = pg_field_type($this->_result, $column); $return->type = pg_field_type($this->result, $column);
$return->charsetnr = ($return->type == "bytea" ? 63 : 0); // 63 - binary $return->charsetnr = ($return->type == "bytea" ? 63 : 0); // 63 - binary
return $return; return $return;
} }
function __destruct() { function __destruct() {
pg_free_result($this->_result); pg_free_result($this->result);
} }
} }
} elseif (extension_loaded("pdo_pgsql")) { } elseif (extension_loaded("pdo_pgsql")) {
class Db extends PdoDb { class Db extends PdoDb {
var $extension = "PDO_PgSQL", $timeout; public $extension = "PDO_PgSQL", $timeout;
function connect($server, $username, $password) { function connect($server, $username, $password) {
global $adminer; global $adminer;
@@ -199,9 +202,9 @@ if (isset($_GET["pgsql"])) {
static $possibleDrivers = array("PgSQL", "PDO_PgSQL"); static $possibleDrivers = array("PgSQL", "PDO_PgSQL");
static $jush = "pgsql"; static $jush = "pgsql";
var $operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "ILIKE", "ILIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"); // no "SQL" to avoid CSRF public $operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "ILIKE", "ILIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"); // no "SQL" to avoid CSRF
var $functions = array("char_length", "lower", "round", "to_hex", "to_timestamp", "upper"); public $functions = array("char_length", "lower", "round", "to_hex", "to_timestamp", "upper");
var $grouping = array("avg", "count", "count distinct", "max", "min", "sum"); public $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
function __construct($connection) { function __construct($connection) {
parent::__construct($connection); parent::__construct($connection);
@@ -265,8 +268,8 @@ if (isset($_GET["pgsql"])) {
} }
function slowQuery($query, $timeout) { function slowQuery($query, $timeout) {
$this->_conn->query("SET statement_timeout = " . (1000 * $timeout)); $this->conn->query("SET statement_timeout = " . (1000 * $timeout));
$this->_conn->timeout = 1000 * $timeout; $this->conn->timeout = 1000 * $timeout;
return $query; return $query;
} }
@@ -280,11 +283,11 @@ if (isset($_GET["pgsql"])) {
} }
function quoteBinary($s) { function quoteBinary($s) {
return $this->_conn->quoteBinary($s); return $this->conn->quoteBinary($s);
} }
function warnings() { function warnings() {
return $this->_conn->warnings(); return $this->conn->warnings();
} }
function tableHelp($name, $is_view = false) { function tableHelp($name, $is_view = false) {
@@ -299,13 +302,14 @@ if (isset($_GET["pgsql"])) {
} }
function supportsIndex($table_status) { function supportsIndex($table_status) {
// returns true for "materialized view"
return $table_status["Engine"] != "view"; return $table_status["Engine"] != "view";
} }
function hasCStyleEscapes() { function hasCStyleEscapes() {
static $c_style; static $c_style;
if ($c_style === null) { if ($c_style === null) {
$c_style = ($this->_conn->result("SHOW standard_conforming_strings") == "off"); $c_style = ($this->conn->result("SHOW standard_conforming_strings") == "off");
} }
return $c_style; return $c_style;
} }
@@ -457,7 +461,7 @@ ORDER BY a.attnum") as $row
$row["generated"] = ($row["attgenerated"] == "s" ? "STORED" : ""); $row["generated"] = ($row["attgenerated"] == "s" ? "STORED" : "");
$row["null"] = !$row["attnotnull"]; $row["null"] = !$row["attnotnull"];
$row["auto_increment"] = $row['attidentity'] || preg_match('~^nextval\(~i', $row["default"]); $row["auto_increment"] = $row['attidentity'] || preg_match('~^nextval\(~i', $row["default"]);
$row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1); $row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1, "where" => 1, "order" => 1);
if (preg_match('~(.+)::[^,)]+(.*)~', $row["default"], $match)) { if (preg_match('~(.+)::[^,)]+(.*)~', $row["default"], $match)) {
$row["default"] = ($match[1] == "NULL" ? null : idf_unescape($match[1]) . $match[2]); $row["default"] = ($match[1] == "NULL" ? null : idf_unescape($match[1]) . $match[2]);
} }
@@ -658,7 +662,6 @@ ORDER BY conkey, conname") as $row
function truncate_tables($tables) { function truncate_tables($tables) {
return queries("TRUNCATE " . implode(", ", array_map('Adminer\table', $tables))); return queries("TRUNCATE " . implode(", ", array_map('Adminer\table', $tables)));
return true;
} }
function drop_views($views) { function drop_views($views) {

View File

@@ -8,37 +8,38 @@ if (isset($_GET["sqlite"])) {
if (class_exists("SQLite3")) { if (class_exists("SQLite3")) {
class SqliteDb { class SqliteDb {
var $extension = "SQLite3", $server_info, $affected_rows, $errno, $error, $_link; public $extension = "SQLite3", $server_info, $affected_rows, $errno, $error;
private $link;
function __construct($filename) { function __construct($filename) {
$this->_link = new \SQLite3($filename); $this->link = new \SQLite3($filename);
$version = $this->_link->version(); $version = $this->link->version();
$this->server_info = $version["versionString"]; $this->server_info = $version["versionString"];
} }
function query($query) { function query($query) {
$result = @$this->_link->query($query); $result = @$this->link->query($query);
$this->error = ""; $this->error = "";
if (!$result) { if (!$result) {
$this->errno = $this->_link->lastErrorCode(); $this->errno = $this->link->lastErrorCode();
$this->error = $this->_link->lastErrorMsg(); $this->error = $this->link->lastErrorMsg();
return false; return false;
} elseif ($result->numColumns()) { } elseif ($result->numColumns()) {
return new Result($result); return new Result($result);
} }
$this->affected_rows = $this->_link->changes(); $this->affected_rows = $this->link->changes();
return true; return true;
} }
function quote($string) { function quote($string) {
return (is_utf8($string) return (is_utf8($string)
? "'" . $this->_link->escapeString($string) . "'" ? "'" . $this->link->escapeString($string) . "'"
: "x'" . reset(unpack('H*', $string)) . "'" : "x'" . reset(unpack('H*', $string)) . "'"
); );
} }
function store_result() { function store_result() {
return $this->_result; return $this->result;
} }
function result($query, $field = 0) { function result($query, $field = 0) {
@@ -46,44 +47,45 @@ if (isset($_GET["sqlite"])) {
if (!is_object($result)) { if (!is_object($result)) {
return false; return false;
} }
$row = $result->_result->fetchArray(); $row = $result->fetch_row();
return $row ? $row[$field] : false; return $row ? $row[$field] : false;
} }
} }
class Result { class Result {
var $_result, $_offset = 0, $num_rows; public $num_rows;
private $result, $offset = 0;
function __construct($result) { function __construct($result) {
$this->_result = $result; $this->result = $result;
} }
function fetch_assoc() { function fetch_assoc() {
return $this->_result->fetchArray(SQLITE3_ASSOC); return $this->result->fetchArray(SQLITE3_ASSOC);
} }
function fetch_row() { function fetch_row() {
return $this->_result->fetchArray(SQLITE3_NUM); return $this->result->fetchArray(SQLITE3_NUM);
} }
function fetch_field() { function fetch_field() {
$column = $this->_offset++; $column = $this->offset++;
$type = $this->_result->columnType($column); $type = $this->result->columnType($column);
return (object) array( return (object) array(
"name" => $this->_result->columnName($column), "name" => $this->result->columnName($column),
"type" => $type, "type" => $type,
"charsetnr" => ($type == SQLITE3_BLOB ? 63 : 0), // 63 - binary "charsetnr" => ($type == SQLITE3_BLOB ? 63 : 0), // 63 - binary
); );
} }
function __desctruct() { function __desctruct() {
return $this->_result->finalize(); return $this->result->finalize();
} }
} }
} elseif (extension_loaded("pdo_sqlite")) { } elseif (extension_loaded("pdo_sqlite")) {
class SqliteDb extends PdoDb { class SqliteDb extends PdoDb {
var $extension = "PDO_SQLite"; public $extension = "PDO_SQLite";
function __construct($filename) { function __construct($filename) {
$this->dsn(DRIVER . ":$filename", "", ""); $this->dsn(DRIVER . ":$filename", "", "");
@@ -115,7 +117,7 @@ if (isset($_GET["sqlite"])) {
} }
function multi_query($query) { function multi_query($query) {
return $this->_result = $this->query($query); return $this->result = $this->query($query);
} }
function next_result() { function next_result() {
@@ -132,7 +134,7 @@ if (isset($_GET["sqlite"])) {
protected $types = array(array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0)); protected $types = array(array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0));
var $editFunctions = array( public $editFunctions = array(
array( array(
// "text" => "date('now')/time('now')/datetime('now')", // "text" => "date('now')/time('now')/datetime('now')",
), array( ), array(
@@ -142,9 +144,9 @@ if (isset($_GET["sqlite"])) {
) )
); );
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"); // REGEXP can be user defined function public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"); // REGEXP can be user defined function
var $functions = array("hex", "length", "lower", "round", "unixepoch", "upper"); public $functions = array("hex", "length", "lower", "round", "unixepoch", "upper");
var $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"); public $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
function __construct($connection) { function __construct($connection) {
parent::__construct($connection); parent::__construct($connection);
@@ -175,7 +177,7 @@ if (isset($_GET["sqlite"])) {
} }
function checkConstraints($table) { function checkConstraints($table) {
preg_match_all('~ CHECK *(\( *(((?>[^()]*[^() ])|(?1))*) *\))~', $this->_conn->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table)), $matches); //! could be inside a comment preg_match_all('~ CHECK *(\( *(((?>[^()]*[^() ])|(?1))*) *\))~', $this->conn->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table)), $matches); //! could be inside a comment
return array_combine($matches[2], $matches[2]); return array_combine($matches[2], $matches[2]);
} }
} }

View File

@@ -140,9 +140,7 @@ SET foreign_key_checks = 0;
} }
} }
if ($is_sql) { $adminer->dumpFooter();
echo "-- " . gmdate("Y-m-d H:i:s e") . "\n";
}
exit; exit;
} }
@@ -167,9 +165,9 @@ if (!isset($row["events"])) { // backwards compatibility
$row["triggers"] = $row["table_style"]; $row["triggers"] = $row["table_style"];
} }
echo "<tr><th>" . lang('Output') . "<td>" . html_select("output", $adminer->dumpOutput(), $row["output"], 0) . "\n"; // 0 - radio echo "<tr><th>" . lang('Output') . "<td>" . html_radios("output", $adminer->dumpOutput(), $row["output"]) . "\n";
echo "<tr><th>" . lang('Format') . "<td>" . html_select("format", $adminer->dumpFormat(), $row["format"], 0) . "\n"; // 0 - radio echo "<tr><th>" . lang('Format') . "<td>" . html_radios("format", $adminer->dumpFormat(), $row["format"]) . "\n";
echo (JUSH == "sqlite" ? "" : "<tr><th>" . lang('Database') . "<td>" . html_select('db_style', $db_style, $row["db_style"]) echo (JUSH == "sqlite" ? "" : "<tr><th>" . lang('Database') . "<td>" . html_select('db_style', $db_style, $row["db_style"])
. (support("type") ? checkbox("types", 1, $row["types"], lang('User types')) : "") . (support("type") ? checkbox("types", 1, $row["types"], lang('User types')) : "")

View File

@@ -68,13 +68,7 @@ if ($_POST["save"]) {
$select = array(); $select = array();
foreach ($fields as $name => $field) { foreach ($fields as $name => $field) {
if (isset($field["privileges"]["select"])) { if (isset($field["privileges"]["select"])) {
$as = convert_field($field); $as = ($_POST["clone"] && $field["auto_increment"] ? "''" : convert_field($field));
if ($_POST["clone"] && $field["auto_increment"]) {
$as = "''";
}
if (JUSH == "sql" && preg_match("~enum|set~", $field["type"])) {
$as = "1*" . idf_escape($name);
}
$select[] = ($as ? "$as AS " : "") . idf_escape($name); $select[] = ($as ? "$as AS " : "") . idf_escape($name);
} }
} }

View File

@@ -2,8 +2,13 @@
// To create Adminer just for Elasticsearch, run `../compile.php elastic`. // To create Adminer just for Elasticsearch, run `../compile.php elastic`.
function adminer_object() { function adminer_object() {
include_once "../plugins/plugin.php";
include_once "../plugins/login-password-less.php";
include_once "../plugins/drivers/elastic.php"; include_once "../plugins/drivers/elastic.php";
return new Adminer\Adminer; return new AdminerPlugin(array(
// TODO: inline the result of password_hash() so that the password is not visible in source codes
new AdminerLoginPasswordLess(password_hash("YOUR_PASSWORD_HERE", PASSWORD_DEFAULT)),
));
} }
include "./index.php"; include "./index.php";

View File

@@ -94,8 +94,8 @@ if (support("scheme")) {
$j = 0; $j = 0;
foreach ($row["source"] as $key => $val) { foreach ($row["source"] as $key => $val) {
echo "<tr>"; echo "<tr>";
echo "<td>" . html_select("source[" . (+$key) . "]", array(-1 => "") + $source, $val, ($j == count($row["source"]) - 1 ? "foreignAddRow.call(this);" : 1), "label-source"); echo "<td>" . html_select("source[" . (+$key) . "]", array(-1 => "") + $source, $val, ($j == count($row["source"]) - 1 ? "foreignAddRow.call(this);" : ""), "label-source");
echo "<td>" . html_select("target[" . (+$key) . "]", $target, $row["target"][$key], 1, "label-target"); echo "<td>" . html_select("target[" . (+$key) . "]", $target, $row["target"][$key], "", "label-target");
$j++; $j++;
} }
?> ?>

View File

@@ -5,7 +5,7 @@ namespace Adminer;
class Adminer { class Adminer {
/** @var array operators used in select, null for all operators */ /** @var array operators used in select, null for all operators */
var $operators; public $operators;
/** Name in title and navigation /** Name in title and navigation
* @return string HTML code * @return string HTML code
@@ -937,11 +937,23 @@ class Adminer {
($ext == "sql" || $output != "file" ? "text/plain" : "text/csv") . "; charset=utf-8" ($ext == "sql" || $output != "file" ? "text/plain" : "text/csv") . "; charset=utf-8"
))); )));
if ($output == "gz") { if ($output == "gz") {
ob_start('ob_gzencode', 1e6); ob_start(function ($string) {
// ob_start() callback receives an optional parameter $phase but gzencode() accepts optional parameter $level
return gzencode($string);
}, 1e6);
} }
return $ext; return $ext;
} }
/** Print text after export
* @return null prints data
*/
function dumpFooter() {
if ($_POST["format"] == "sql") {
echo "-- " . gmdate("Y-m-d H:i:s e") . "\n";
}
}
/** Set the path of the file for webserver load /** Set the path of the file for webserver load
* @return string path of the sql dump file * @return string path of the sql dump file
*/ */

View File

@@ -26,23 +26,23 @@ abstract class SqlDriver {
static $possibleDrivers = array(); static $possibleDrivers = array();
static $jush; ///< @var string JUSH identifier static $jush; ///< @var string JUSH identifier
var $_conn; protected $conn;
protected $types = array(); ///< @var array [$description => [$type => $maximum_unsigned_length, ...], ...] protected $types = array(); ///< @var array [$description => [$type => $maximum_unsigned_length, ...], ...]
var $editFunctions = array(); ///< @var array of ["$type|$type2" => "$function/$function2"] functions used in editing, [0] - edit and insert, [1] - edit only public $editFunctions = array(); ///< @var array of ["$type|$type2" => "$function/$function2"] functions used in editing, [0] - edit and insert, [1] - edit only
var $unsigned = array(); ///< @var array number variants public $unsigned = array(); ///< @var array number variants
var $operators = array(); ///< @var array operators used in select public $operators = array(); ///< @var array operators used in select
var $functions = array(); ///< @var array functions used in select public $functions = array(); ///< @var array functions used in select
var $grouping = array(); ///< @var array grouping functions used in select public $grouping = array(); ///< @var array grouping functions used in select
var $onActions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; ///< @var string used in foreign_keys() public $onActions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; ///< @var string used in foreign_keys()
var $inout = "IN|OUT|INOUT"; public $inout = "IN|OUT|INOUT"; ///< @var string used in routines
var $enumLength = "'(?:''|[^'\\\\]|\\\\.)*'"; public $enumLength = "'(?:''|[^'\\\\]|\\\\.)*'"; ///< @var string regular expression for parsing enum lengths
var $generated = array(); public $generated = array(); ///< @var array allowed types of generated columns
/** Create object for performing database operations /** Create object for performing database operations
* @param Db * @param Db
*/ */
function __construct($connection) { function __construct($connection) {
$this->_conn = $connection; $this->conn = $connection;
} }
/** Get all types /** Get all types
@@ -91,7 +91,7 @@ abstract class SqlDriver {
); );
} }
$start = microtime(true); $start = microtime(true);
$return = $this->_conn->query($query); $return = $this->conn->query($query);
if ($print) { if ($print) {
echo $adminer->selectQuery($query, $start, !$return); echo $adminer->selectQuery($query, $start, !$return);
} }
@@ -201,8 +201,8 @@ abstract class SqlDriver {
* @return string * @return string
*/ */
function value($val, $field) { function value($val, $field) {
return (method_exists($this->_conn, 'value') return (method_exists($this->conn, 'value')
? $this->_conn->value($val, $field) ? $this->conn->value($val, $field)
: (is_resource($val) ? stream_get_contents($val) : $val) : (is_resource($val) ? stream_get_contents($val) : $val)
); );
} }

View File

@@ -224,7 +224,7 @@ function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_ty
size="3" size="3"
<?php echo (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : ""); //! type="number" with enabled JavaScript ?> <?php echo (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : ""); //! type="number" with enabled JavaScript ?>
aria-labelledby="label-length"><td class="options"><?php aria-labelledby="label-length"><td class="options"><?php
echo ($collations ? "<select name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>' : ''); echo ($collations ? "<input list='collations' name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . " value='" . h($field["collation"]) . "' placeholder='(" . lang('collation') . ")'>" : '');
echo ($driver->unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist($driver->unsigned, $field["unsigned"]) . '</select>' : ''); echo ($driver->unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist($driver->unsigned, $field["unsigned"]) . '</select>' : '');
echo (isset($field['on_update']) ? "<select name='" . h($key) . "[on_update]'" . (preg_match('~timestamp|datetime~', $type) ? "" : " class='hidden'") . '>' echo (isset($field['on_update']) ? "<select name='" . h($key) . "[on_update]'" . (preg_match('~timestamp|datetime~', $type) ? "" : " class='hidden'") . '>'
. optionlist(array("" => "(" . lang('ON UPDATE') . ")", "CURRENT_TIMESTAMP"), (preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"]) ? "CURRENT_TIMESTAMP" : $field["on_update"])) . optionlist(array("" => "(" . lang('ON UPDATE') . ")", "CURRENT_TIMESTAMP"), (preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"]) ? "CURRENT_TIMESTAMP" : $field["on_update"]))
@@ -308,7 +308,7 @@ function default_value($field) {
return ($default === null ? "" : (in_array($generated, $driver->generated) return ($default === null ? "" : (in_array($generated, $driver->generated)
? (JUSH == "mssql" ? " AS ($default)" . ($generated == "VIRTUAL" ? "" : " $generated") . "" : " GENERATED ALWAYS AS ($default) $generated") ? (JUSH == "mssql" ? " AS ($default)" . ($generated == "VIRTUAL" ? "" : " $generated") . "" : " GENERATED ALWAYS AS ($default) $generated")
: " DEFAULT " . (!preg_match('~^GENERATED ~i', $default) && (preg_match('~char|binary|text|enum|set~', $field["type"]) || preg_match('~^(?![a-z])~i', $default)) : " DEFAULT " . (!preg_match('~^GENERATED ~i', $default) && (preg_match('~char|binary|text|enum|set~', $field["type"]) || preg_match('~^(?![a-z])~i', $default))
? q($default) ? (JUSH == "sql" && preg_match('~text~', $field["type"]) ? "(" . q($default) . ")" : q($default)) // MySQL requires () around default value of text column
: str_ireplace("current_timestamp()", "CURRENT_TIMESTAMP", (JUSH == "sqlite" ? "($default)" : $default)) : str_ireplace("current_timestamp()", "CURRENT_TIMESTAMP", (JUSH == "sqlite" ? "($default)" : $default))
) )
)); ));
@@ -631,15 +631,6 @@ function doc_link($paths, $text = "<sup>?</sup>") {
return ($paths[JUSH] ? "<a href='" . h($urls[JUSH] . $paths[JUSH] . (JUSH == 'mssql' ? "?view=sql-server-ver$version" : "")) . "'" . target_blank() . ">$text</a>" : ""); return ($paths[JUSH] ? "<a href='" . h($urls[JUSH] . $paths[JUSH] . (JUSH == 'mssql' ? "?view=sql-server-ver$version" : "")) . "'" . target_blank() . ">$text</a>" : "");
} }
/** Wrap gzencode() for usage in ob_start()
* @param string
* @return string
*/
function ob_gzencode($string) {
// ob_start() callback receives an optional parameter $phase but gzencode() accepts optional parameter $level
return gzencode($string);
}
/** Compute size of database /** Compute size of database
* @param string * @param string
* @return string formatted * @return string formatted

View File

@@ -217,22 +217,29 @@ function optionlist($options, $selected = null, $use_keys = false) {
return $return; return $return;
} }
/** Generate HTML <select>
* @param string
* @param array
* @param string
* @param string
* @param string
* @return string
*/
function html_select($name, $options, $value = "", $onchange = "", $labelled_by = "") {
return "<select name='" . h($name) . "'"
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
. ">" . optionlist($options, $value) . "</select>"
. ($onchange ? script("qsl('select').onchange = function () { $onchange };", "") : "")
;
}
/** Generate HTML radio list /** Generate HTML radio list
* @param string * @param string
* @param array * @param array
* @param string * @param string
* @param string true for no onchange, false for radio
* @param string
* @return string * @return string
*/ */
function html_select($name, $options, $value = "", $onchange = true, $labelled_by = "") { function html_radios($name, $options, $value = "") {
if ($onchange) {
return "<select name='" . h($name) . "'"
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
. ">" . optionlist($options, $value) . "</select>"
. (is_string($onchange) ? script("qsl('select').onchange = function () { $onchange };", "") : "")
;
}
$return = ""; $return = "";
foreach ($options as $key => $val) { foreach ($options as $key => $val) {
$return .= "<label><input type='radio' name='" . h($name) . "' value='" . h($key) . "'" . ($key == $value ? " checked" : "") . ">" . h($val) . "</label>"; $return .= "<label><input type='radio' name='" . h($name) . "' value='" . h($key) . "'" . ($key == $value ? " checked" : "") . ">" . h($val) . "</label>";
@@ -728,9 +735,10 @@ function pagination($page, $current) {
/** Get file contents from $_FILES /** Get file contents from $_FILES
* @param string * @param string
* @param bool * @param bool
* @param string
* @return mixed int for error, string otherwise * @return mixed int for error, string otherwise
*/ */
function get_file($key, $decompress = false) { function get_file($key, $decompress = false, $delimiter = "") {
$file = $_FILES[$key]; $file = $_FILES[$key];
if (!$file) { if (!$file) {
return null; return null;
@@ -752,17 +760,17 @@ function get_file($key, $decompress = false) {
); //! may not be reachable because of open_basedir ); //! may not be reachable because of open_basedir
if ($decompress) { if ($decompress) {
$start = substr($content, 0, 3); $start = substr($content, 0, 3);
if (function_exists("iconv") && preg_match("~^\xFE\xFF|^\xFF\xFE~", $start, $regs)) { // not ternary operator to save memory if (function_exists("iconv") && preg_match("~^\xFE\xFF|^\xFF\xFE~", $start)) { // not ternary operator to save memory
$content = iconv("utf-16", "utf-8", $content); $content = iconv("utf-16", "utf-8", $content);
} elseif ($start == "\xEF\xBB\xBF") { // UTF-8 BOM } elseif ($start == "\xEF\xBB\xBF") { // UTF-8 BOM
$content = substr($content, 3); $content = substr($content, 3);
} }
$return .= $content . "\n\n"; }
} else { $return .= $content;
$return .= $content; if ($delimiter) {
$return .= (preg_match("($delimiter\\s*\$)", $content) ? "" : $delimiter) . "\n\n";
} }
} }
//! support SQL files not ending with semicolon
return $return; return $return;
} }
@@ -883,18 +891,18 @@ function column_foreign_keys($table) {
* @param string "radio"|"checkbox" * @param string "radio"|"checkbox"
* @param string * @param string
* @param array * @param array
* @param mixed int|string|array * @param mixed string|array
* @param string * @param string
* @return null * @return null
*/ */
function enum_input($type, $attrs, $field, $value, $empty = null) { function enum_input($type, $attrs, $field, $value, $empty = null) {
global $adminer; global $adminer;
preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches); preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
$return = ($empty !== null ? "<label><input type='$type'$attrs value='$empty'" . ((is_array($value) ? in_array($empty, $value) : $value === 0) ? " checked" : "") . "><i>" . lang('empty') . "</i></label>" : ""); $return = ($empty !== null ? "<label><input type='$type'$attrs value='$empty'" . ((is_array($value) ? in_array($empty, $value) : $value === $empty) ? " checked" : "") . "><i>" . lang('empty') . "</i></label>" : "");
foreach ($matches[1] as $i => $val) { foreach ($matches[1] as $i => $val) {
$val = stripcslashes(str_replace("''", "'", $val)); $val = stripcslashes(str_replace("''", "'", $val));
$checked = (is_int($value) ? $value == $i+1 : (is_array($value) ? in_array($i+1, $value) : $value === $val)); $checked = (is_array($value) ? in_array($val, $value) : $value === $val);
$return .= " <label><input type='$type'$attrs value='" . (JUSH == "sql" ? $i+1 : h($val)) . "'" . ($checked ? ' checked' : '') . '>' . h($adminer->editVal($val, $field)) . '</label>'; $return .= " <label><input type='$type'$attrs value='" . h($val) . "'" . ($checked ? ' checked' : '') . '>' . h($adminer->editVal($val, $field)) . '</label>';
} }
return $return; return $return;
} }
@@ -910,11 +918,7 @@ function input($field, $value, $function) {
$name = h(bracket_escape($field["field"])); $name = h(bracket_escape($field["field"]));
echo "<td class='function'>"; echo "<td class='function'>";
if (is_array($value) && !$function) { if (is_array($value) && !$function) {
$args = array($value); $value = json_encode($value, 128); // 128 - JSON_PRETTY_PRINT available since PHP 5.4
if (version_compare(PHP_VERSION, 5.4) >= 0) {
$args[] = JSON_PRETTY_PRINT;
}
$value = call_user_func_array('json_encode', $args); //! requires PHP 5.2
$function = "json"; $function = "json";
} }
$reset = (JUSH == "mssql" && $field["auto_increment"]); $reset = (JUSH == "mssql" && $field["auto_increment"]);
@@ -945,12 +949,12 @@ function input($field, $value, $function) {
} elseif (preg_match('~bool~', $field["type"])) { } elseif (preg_match('~bool~', $field["type"])) {
echo "<input type='hidden'$attrs value='0'>" echo "<input type='hidden'$attrs value='0'>"
. "<input type='checkbox'" . (preg_match('~^(1|t|true|y|yes|on)$~i', $value) ? " checked='checked'" : "") . "$attrs value='1'>"; . "<input type='checkbox'" . (preg_match('~^(1|t|true|y|yes|on)$~i', $value) ? " checked='checked'" : "") . "$attrs value='1'>";
} elseif ($field["type"] == "set") { //! 64 bits } elseif ($field["type"] == "set") {
preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches); preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
foreach ($matches[1] as $i => $val) { foreach ($matches[1] as $i => $val) {
$val = stripcslashes(str_replace("''", "'", $val)); $val = stripcslashes(str_replace("''", "'", $val));
$checked = (is_int($value) ? ($value >> $i) & 1 : in_array($val, explode(",", $value), true)); $checked = in_array($val, explode(",", $value), true);
echo " <label><input type='checkbox' name='fields[$name][$i]' value='" . (1 << $i) . "'" . ($checked ? ' checked' : '') . ">" . h($adminer->editVal($val, $field)) . '</label>'; echo " <label><input type='checkbox' name='fields[$name][$i]' value='" . h($val) . "'" . ($checked ? ' checked' : '') . ">" . h($adminer->editVal($val, $field)) . '</label>';
} }
} elseif (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) { } elseif (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
echo "<input type='file' name='fields-$name'>"; echo "<input type='file' name='fields-$name'>";
@@ -1019,9 +1023,6 @@ function process_input($field) {
return "NULL"; return "NULL";
} }
} }
if ($field["type"] == "enum") {
return +$value;
}
if ($field["auto_increment"] && $value == "") { if ($field["auto_increment"] && $value == "") {
return null; return null;
} }
@@ -1032,7 +1033,7 @@ function process_input($field) {
return "NULL"; return "NULL";
} }
if ($field["type"] == "set") { if ($field["type"] == "set") {
return array_sum((array) $value); $value = implode(",", (array) $value);
} }
if ($function == "json") { if ($function == "json") {
$function = ""; $function = "";
@@ -1436,8 +1437,8 @@ function edit_form($table, $fields, $row, $update) {
} }
} }
$value = ($row !== null $value = ($row !== null
? ($row[$name] != "" && JUSH == "sql" && preg_match("~enum|set~", $field["type"]) ? ($row[$name] != "" && JUSH == "sql" && preg_match("~enum|set~", $field["type"]) && is_array($row[$name])
? (is_array($row[$name]) ? array_sum($row[$name]) : +$row[$name]) ? implode(",", $row[$name])
: (is_bool($row[$name]) ? +$row[$name] : $row[$name]) : (is_bool($row[$name]) ? +$row[$name] : $row[$name])
) )
: (!$update && $field["auto_increment"] : (!$update && $field["auto_increment"]

View File

@@ -4,7 +4,9 @@ namespace Adminer;
// PDO can be used in several database drivers // PDO can be used in several database drivers
if (extension_loaded('pdo')) { if (extension_loaded('pdo')) {
abstract class PdoDb { abstract class PdoDb {
var $_result, $server_info, $affected_rows, $errno, $error, $pdo; public $server_info, $affected_rows, $errno, $error;
protected $pdo;
private $result;
function dsn($dsn, $username, $password, $options = array()) { function dsn($dsn, $username, $password, $options = array()) {
$options[\PDO::ATTR_ERRMODE] = \PDO::ERRMODE_SILENT; $options[\PDO::ATTR_ERRMODE] = \PDO::ERRMODE_SILENT;
@@ -38,12 +40,12 @@ if (extension_loaded('pdo')) {
} }
function multi_query($query) { function multi_query($query) {
return $this->_result = $this->query($query); return $this->result = $this->query($query);
} }
function store_result($result = null) { function store_result($result = null) {
if (!$result) { if (!$result) {
$result = $this->_result; $result = $this->result;
if (!$result) { if (!$result) {
return false; return false;
} }
@@ -57,11 +59,11 @@ if (extension_loaded('pdo')) {
} }
function next_result() { function next_result() {
if (!$this->_result) { if (!$this->result) {
return false; return false;
} }
$this->_result->_offset = 0; $this->result->_offset = 0;
return @$this->_result->nextRowset(); // @ - PDO_PgSQL doesn't support it return @$this->result->nextRowset(); // @ - PDO_PgSQL doesn't support it
} }
function result($query, $field = 0) { function result($query, $field = 0) {
@@ -75,7 +77,7 @@ if (extension_loaded('pdo')) {
} }
class PdoDbStatement extends \PDOStatement { class PdoDbStatement extends \PDOStatement {
var $_offset = 0, $num_rows; public $_offset = 0, $num_rows;
function fetch_assoc() { function fetch_assoc() {
return $this->fetch(\PDO::FETCH_ASSOC); return $this->fetch(\PDO::FETCH_ASSOC);

View File

@@ -2,8 +2,7 @@
namespace Adminer; namespace Adminer;
class TmpFile { class TmpFile {
var $handler; private $handler, $size;
var $size;
function __construct() { function __construct() {
$this->handler = tmpfile(); $this->handler = tmpfile();

View File

@@ -1,4 +1,4 @@
<?php <?php
namespace Adminer; namespace Adminer;
$VERSION = "5.0.2"; $VERSION = "5.0.3";

View File

@@ -126,7 +126,7 @@ if ($primary) {
$j = 1; $j = 1;
foreach ($row["indexes"] as $index) { foreach ($row["indexes"] as $index) {
if (!$_POST["drop_col"] || $j != key($_POST["drop_col"])) { if (!$_POST["drop_col"] || $j != key($_POST["drop_col"])) {
echo "<tr><td>" . html_select("indexes[$j][type]", array(-1 => "") + $index_types, $index["type"], ($j == count($row["indexes"]) ? "indexesAddRow.call(this);" : 1), "label-type"); echo "<tr><td>" . html_select("indexes[$j][type]", array(-1 => "") + $index_types, $index["type"], ($j == count($row["indexes"]) ? "indexesAddRow.call(this);" : ""), "label-type");
echo "<td>"; echo "<td>";
ksort($index["columns"]); ksort($index["columns"]);

View File

@@ -285,7 +285,7 @@ $translations = array(
'Default value' => 'Predvolená hodnota', 'Default value' => 'Predvolená hodnota',
'Full table scan' => 'Prechod celej tabuľky', 'Full table scan' => 'Prechod celej tabuľky',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Príliš veľa pokusov o prihlásenie, skúste to znova za %d minutu.', 'Príliš veľa pokusov o prihlásenie, skúste to znova za %d minuty.', 'Príliš veľa pokusov o prihlásenie, skúste to znova za %d minút.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Príliš veľa pokusov o prihlásenie, skúste to znova za %d minutu.', 'Príliš veľa pokusov o prihlásenie, skúste to znova za %d minuty.', 'Príliš veľa pokusov o prihlásenie, skúste to znova za %d minút.'),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Vďaka za používanie Admineru, <a href="https://www.adminer.org/cs/donation/">prispejte</a> na vývoj.', 'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Vďaka za používanie Admineru, <a href="https://www.adminer.org/sk/donation/">prispejte</a> na vývoj.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Platnosť hlavného hesla vypršala. <a href="https://www.adminer.org/cs/extension/"%s>Implementujte</a> metodu %s, aby platilo natrvalo.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Platnosť hlavného hesla vypršala. <a href="https://www.adminer.org/cs/extension/"%s>Implementujte</a> metodu %s, aby platilo natrvalo.',
'The action will be performed after successful login with the same credentials.' => 'Akcia sa vykoná po úspešnom prihlásení s rovnakými prihlasovacími údajmi.', 'The action will be performed after successful login with the same credentials.' => 'Akcia sa vykoná po úspešnom prihlásení s rovnakými prihlasovacími údajmi.',
'Connecting to privileged ports is not allowed.' => 'Pripojenie k privilegovaným portom nie je povolené.', 'Connecting to privileged ports is not allowed.' => 'Pripojenie k privilegovaným portom nie je povolené.',
@@ -302,4 +302,10 @@ $translations = array(
'Disable %s or enable %s or %s extensions.' => 'Zakážte %s alebo povoľte rozšírenie %s alebo %s.', 'Disable %s or enable %s or %s extensions.' => 'Zakážte %s alebo povoľte rozšírenie %s alebo %s.',
'yes' => 'áno', 'yes' => 'áno',
'no' => 'nie', 'no' => 'nie',
'Checks' => 'Kontroly',
'Create check' => 'Vytvoriť kontrolu',
'Alter check' => 'Zmeniť kontrolu',
'Check has been created.' => 'Kontrola bola vytvorená.',
'Check has been altered.' => 'Kontrola bola zmenená.',
'Check has been dropped.' => 'Kontrola bola odstránená.',
); );

View File

@@ -34,6 +34,7 @@ if (!$_POST && $PROCEDURE != "") {
$collations = get_vals("SHOW CHARACTER SET"); $collations = get_vals("SHOW CHARACTER SET");
sort($collations); sort($collations);
$routine_languages = routine_languages(); $routine_languages = routine_languages();
echo ($collations ? "<datalist id='collations'>" . optionlist($collations) . "</datalist>" : "");
?> ?>
<form action="" method="post" id="form"> <form action="" method="post" id="form">

View File

@@ -100,6 +100,7 @@ if ($_POST && !$error) {
$query = implode(" UNION ALL ", $union); $query = implode(" UNION ALL ", $union);
} }
$adminer->dumpData($TABLE, "table", $query); $adminer->dumpData($TABLE, "table", $query);
$adminer->dumpFooter();
exit; exit;
} }
@@ -587,7 +588,7 @@ if (!$columns && support("table")) {
echo script("qsl('a').onclick = partial(toggle, 'import');", ""); echo script("qsl('a').onclick = partial(toggle, 'import');", "");
echo "<span id='import'" . ($_POST["import"] ? "" : " class='hidden'") . ">: "; echo "<span id='import'" . ($_POST["import"] ? "" : " class='hidden'") . ">: ";
echo "<input type='file' name='csv_file'> "; echo "<input type='file' name='csv_file'> ";
echo html_select("separator", array("csv" => "CSV,", "csv;" => "CSV;", "tsv" => "TSV"), $adminer_import["format"], 1); // 1 - select echo html_select("separator", array("csv" => "CSV,", "csv;" => "CSV;", "tsv" => "TSV"), $adminer_import["format"]);
echo " <input type='submit' name='import' value='" . lang('Import') . "'>"; echo " <input type='submit' name='import' value='" . lang('Import') . "'>";
echo "</span>"; echo "</span>";
echo "</div>"; echo "</div>";

View File

@@ -5,6 +5,7 @@ if (!$error && $_POST["export"]) {
dump_headers("sql"); dump_headers("sql");
$adminer->dumpTable("", ""); $adminer->dumpTable("", "");
$adminer->dumpData("", "table", $_POST["query"]); $adminer->dumpData("", "table", $_POST["query"]);
$adminer->dumpFooter();
exit; exit;
} }
@@ -30,7 +31,7 @@ if (!$error && $_POST) {
), "rb"); ), "rb");
$query = ($fp ? fread($fp, 1e6) : false); $query = ($fp ? fread($fp, 1e6) : false);
} else { } else {
$query = get_file("sql_file", true); $query = get_file("sql_file", true, ";");
} }
if (is_string($query)) { // get_file() returns error as number, fread() as false if (is_string($query)) { // get_file() returns error as number, fread() as false

View File

@@ -53,8 +53,8 @@ input.wayoff { left: -1000px; position: absolute; }
.function { text-align: right; } .function { text-align: right; }
.number { text-align: right; } .number { text-align: right; }
.datetime { text-align: right; } .datetime { text-align: right; }
.type { width: 15ex; width: auto\9; } .type { width: 15ex; }
.options select { width: 20ex; width: auto\9; } .options select, .options input { width: 20ex; }
.view { font-style: italic; } .view { font-style: italic; }
.active { font-weight: bold; } .active { font-weight: bold; }
.sqlarea { width: 98%; } .sqlarea { width: 98%; }

View File

@@ -1,3 +1,17 @@
Adminer 5.0.3 (released 2025-03-11):
Fix gzip export (bug #896, regression from 5.0.0)
Fix importing multiple SQL files not terminated by semicolon
Use <datalist> for altering collations
MySQL: Allow setting default values of text column
MySQL: Stop treating enum and set as numbers (bug #475)
MySQL, MariaDB: Fix default values with ' (bug #895)
MariaDB: Fix creating and altering generated columns (bug #897)
PostgreSQL: Fix "where" and "order" privileges (bug #902, regression from 5.0.2)
SQLite: Fix creating table in compiled version (bug #901, regression from 5.0.0)
Elastic: Do not pass null values on insert (PR #892)
Elastic: Fix displaying sparse rows (PR #893)
Plugins: Add method dumpFooter()
Adminer 5.0.2 (released 2025-03-10): Adminer 5.0.2 (released 2025-03-10):
PostgreSQL: Fix setting NULL and original value on enum (bug #884) PostgreSQL: Fix setting NULL and original value on enum (bug #884)
CockroachDB: Add support via PostgreSQL driver CockroachDB: Add support via PostgreSQL driver
@@ -83,6 +97,7 @@ Escape unknown field in select
HTTP drivers: Don't allow path in server name HTTP drivers: Don't allow path in server name
HTTP drivers: Hide connection error message HTTP drivers: Hide connection error message
SimpleDB: Disable XML entity loader SimpleDB: Disable XML entity loader
Latvian translation
Adminer 4.14.0: Adminer 4.14.0:
Use autofocus HTML attribute Use autofocus HTML attribute
@@ -546,7 +561,7 @@ MySQL: Speed up updating rows without numeric or UTF-8 primary key
Non-MySQL: Descending indexes Non-MySQL: Descending indexes
PostgreSQL: Fix detecting oid column in PDO PostgreSQL: Fix detecting oid column in PDO
PostgreSQL: Handle timestamp types (bug #324) PostgreSQL: Handle timestamp types (bug #324)
Add Korean translation Korean translation
Adminer 3.7.0 (released 2013-05-19): Adminer 3.7.0 (released 2013-05-19):
Allow more SQL files to be uploaded at the same time Allow more SQL files to be uploaded at the same time

View File

@@ -41,7 +41,7 @@ function put_file($match) {
return $match[0]; // processed later return $match[0]; // processed later
} }
$return = file_get_contents(__DIR__ . "/$project/$match[2]"); $return = file_get_contents(__DIR__ . "/$project/$match[2]");
$return = str_replace("namespace Adminer;\n", "", $return); $return = preg_replace('~namespace Adminer;\s*~', '', $return);
if (basename($match[2]) == "file.inc.php") { if (basename($match[2]) == "file.inc.php") {
$return = str_replace("\n// caching headers added in compile.php", (preg_match('~-dev$~', $VERSION) ? '' : ' $return = str_replace("\n// caching headers added in compile.php", (preg_match('~-dev$~', $VERSION) ? '' : '
if ($_SERVER["HTTP_IF_MODIFIED_SINCE"]) { if ($_SERVER["HTTP_IF_MODIFIED_SINCE"]) {
@@ -297,7 +297,10 @@ function php_shrink($input) {
$doc_comment = true; $doc_comment = true;
$token[1] = substr_replace($token[1], "* @version $VERSION\n", -2, 0); $token[1] = substr_replace($token[1], "* @version $VERSION\n", -2, 0);
} }
if ($token[0] == T_VAR) { if ($token[0] == T_VAR || $token[0] == T_PUBLIC || $token[0] == T_PROTECTED || $token[0] == T_PRIVATE) {
if ($token[0] == T_PUBLIC && $tokens[$i+2][1][0] == '$') {
$token[1] = 'var';
}
$shortening = false; $shortening = false;
} elseif (!$shortening) { } elseif (!$shortening) {
if ($token[1] == ';') { if ($token[1] == ';') {

View File

@@ -234,7 +234,7 @@ legend a:hover {
select[name^="columns"] optgroup:last-child option:nth-child(3)::before { select[name^="columns"] optgroup:last-child option:nth-child(3)::before {
content: "count "; } content: "count "; }
select[name$="[collation]"] { input[name$="[collation]"] {
max-width: 120px; } max-width: 120px; }
.logout a:first-child, p a { .logout a:first-child, p a {

View File

@@ -1,6 +1,5 @@
<?php <?php
function adminer_object() { function adminer_object() {
class AdminerCds extends Adminer\Adminer { class AdminerCds extends Adminer\Adminer {
function name() { function name() {

View File

@@ -2,8 +2,8 @@
namespace Adminer; namespace Adminer;
class Adminer { class Adminer {
var $operators = array("<=", ">="); public $operators = array("<=", ">=");
var $_values = array(); private $values = array();
function name() { function name() {
return "<a href='https://www.adminer.org/editor/'" . target_blank() . " id='h1'>" . lang('Editor') . "</a>"; return "<a href='https://www.adminer.org/editor/'" . target_blank() . " id='h1'>" . lang('Editor') . "</a>";
@@ -175,7 +175,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row //! requires MySQL 5
$ids[$row[$key]] = q($row[$key]); $ids[$row[$key]] = q($row[$key]);
} }
// uses constant number of queries to get the descriptions, join would be complex, multiple queries would be slow // uses constant number of queries to get the descriptions, join would be complex, multiple queries would be slow
$descriptions = $this->_values[$table]; $descriptions = $this->values[$table];
if (!$descriptions) { if (!$descriptions) {
$descriptions = get_key_vals("SELECT $id, $name FROM " . table($table) . " WHERE $id IN (" . implode(", ", $ids) . ")"); $descriptions = get_key_vals("SELECT $id, $name FROM " . table($table) . " WHERE $id IN (" . implode(", ", $ids) . ")");
} }
@@ -248,7 +248,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row //! requires MySQL 5
); );
echo "</div>\n"; echo "</div>\n";
unset($columns[$name]); unset($columns[$name]);
} elseif (is_array($options = $this->_foreignKeyOptions($_GET["select"], $name))) { } elseif (is_array($options = $this->foreignKeyOptions($_GET["select"], $name))) {
if ($fields[$name]["null"]) { if ($fields[$name]["null"]) {
$options[0] = '(' . lang('empty') . ')'; $options[0] = '(' . lang('empty') . ')';
} }
@@ -482,7 +482,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row //! requires MySQL 5
. enum_input("radio", $attrs, $field, ($value || isset($_GET["select"]) ? $value : 0), ($field["null"] ? "" : null)) . enum_input("radio", $attrs, $field, ($value || isset($_GET["select"]) ? $value : 0), ($field["null"] ? "" : null))
; ;
} }
$options = $this->_foreignKeyOptions($table, $field["field"], $value); $options = $this->foreignKeyOptions($table, $field["field"], $value);
if ($options !== null) { if ($options !== null) {
return (is_array($options) return (is_array($options)
? "<select$attrs>" . optionlist($options, $value, true) . "</select>" ? "<select$attrs>" . optionlist($options, $value, true) . "</select>"
@@ -574,6 +574,9 @@ qsl('div').onclick = whisperClick;", "")
return $ext; return $ext;
} }
function dumpFooter() {
}
function importServerPath() { function importServerPath() {
} }
@@ -651,9 +654,9 @@ qsl('div').onclick = whisperClick;", "")
} }
} }
function _foreignKeyOptions($table, $column, $value = null) { private function foreignKeyOptions($table, $column, $value = null) {
if (list($target, $id, $name) = $this->_foreignColumn(column_foreign_keys($table), $column)) { if (list($target, $id, $name) = $this->_foreignColumn(column_foreign_keys($table), $column)) {
$return = &$this->_values[$target]; $return = &$this->values[$target];
if ($return === null) { if ($return === null) {
$table_status = table_status($target); $table_status = table_status($target);
$return = ($table_status["Rows"] > 1000 ? "" : array("" => "") + get_key_vals("SELECT $id, $name FROM " . table($target) . " ORDER BY 2")); $return = ($table_status["Rows"] > 1000 ? "" : array("" => "") + get_key_vals("SELECT $id, $name FROM " . table($target) . " ORDER BY 2"));

View File

@@ -44,7 +44,7 @@ foreach (glob(__DIR__ . "/adminer/lang/" . ($_SESSION["lang"] ?: "*") . ".inc.ph
unset($messages[$en]); unset($messages[$en]);
$en_fullstop = (substr($en, -2, 1) == "."); $en_fullstop = (substr($en, -2, 1) == ".");
//! check in array //! check in array
if ($en != "','" && ($en_fullstop xor preg_match("~($fullstop)'\)?\$~", $line, $match))) { if ($en != "','" && ($en_fullstop xor preg_match("~$fullstop'\)?\$~", $line))) {
if ($lang != ($en_fullstop ? "ja" : "he")) { // fullstop is optional in 'ja', forbidden in 'he' if ($lang != ($en_fullstop ? "ja" : "he")) { // fullstop is optional in 'ja', forbidden in 'he'
echo "$filename:" . (substr_count($file, "\n", 0, $offset) + 1) . ":Not matching fullstop: $line\n"; echo "$filename:" . (substr_count($file, "\n", 0, $offset) + 1) . ":Not matching fullstop: $line\n";
} }

View File

@@ -28,7 +28,6 @@
<!-- Saves bytes. --> <!-- Saves bytes. -->
<exclude name="PSR2.Classes.PropertyDeclaration.Multiple"/> <exclude name="PSR2.Classes.PropertyDeclaration.Multiple"/>
<exclude name="PSR2.Classes.PropertyDeclaration.VarUsed"/>
<exclude name="PSR2.Classes.PropertyDeclaration.ScopeMissing"/> <exclude name="PSR2.Classes.PropertyDeclaration.ScopeMissing"/>
<exclude name="PSR12.Classes.ClassInstantiation.MissingParentheses"/> <exclude name="PSR12.Classes.ClassInstantiation.MissingParentheses"/>
<exclude name="Squiz.Scope.MethodScope.Missing"/> <exclude name="Squiz.Scope.MethodScope.Missing"/>
@@ -79,4 +78,34 @@
<rule ref="Generic.VersionControl.GitMergeConflict"/> <rule ref="Generic.VersionControl.GitMergeConflict"/>
<rule ref="Generic.Whitespace.DisallowSpaceIndent"/> <rule ref="Generic.Whitespace.DisallowSpaceIndent"/>
<rule ref="Generic.WhiteSpace.LanguageConstructSpacing"/> <rule ref="Generic.WhiteSpace.LanguageConstructSpacing"/>
<rule ref="Squiz.Arrays.ArrayBracketSpacing"/>
<rule ref="Squiz.Classes.LowercaseClassKeywords"/>
<rule ref="Squiz.Classes.SelfMemberReference"/>
<rule ref="Squiz.CSS.ClassDefinitionNameSpacing"/>
<rule ref="Squiz.CSS.ColonSpacing"/>
<rule ref="Squiz.CSS.DuplicateClassDefinition"/>
<rule ref="Squiz.CSS.DuplicateStyleDefinition"/>
<rule ref="Squiz.CSS.EmptyClassDefinition"/>
<rule ref="Squiz.CSS.EmptyStyleDefinition"/>
<rule ref="Squiz.CSS.ForbiddenStyles"/>
<rule ref="Squiz.CSS.Indentation"/>
<rule ref="Squiz.CSS.MissingColon"/>
<rule ref="Squiz.CSS.Opacity"/>
<rule ref="Squiz.CSS.SemicolonSpacing"/>
<rule ref="Squiz.Functions.FunctionDuplicateArgument"/>
<rule ref="Squiz.Objects.ObjectMemberComma"/>
<rule ref="Squiz.Operators.IncrementDecrementUsage"/>
<rule ref="Squiz.Operators.ValidLogicalOperators"/>
<rule ref="Squiz.PHP.DiscouragedFunctions"/>
<rule ref="Squiz.PHP.Eval"/>
<rule ref="Squiz.PHP.Heredoc"/>
<rule ref="Squiz.PHP.InnerFunctions"/>
<rule ref="Squiz.PHP.LowercasePHPFunctions"/>
<rule ref="Squiz.PHP.NonExecutableCode"/>
<rule ref="Squiz.Scope.StaticThisUsage"/>
<rule ref="Squiz.WhiteSpace.FunctionOpeningBraceSpace"/>
<rule ref="Squiz.WhiteSpace.LanguageConstructSpacing"/>
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
<rule ref="Squiz.WhiteSpace.ObjectOperatorSpacing"/>
</ruleset> </ruleset>

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerDesigns { class AdminerDesigns {
/** @access protected */ protected $designs;
var $designs;
/** /**
* @param array URL in key, name in value * @param array URL in key, name in value

View File

@@ -8,11 +8,12 @@ if (isset($_GET["clickhouse"])) {
if (ini_bool('allow_url_fopen')) { if (ini_bool('allow_url_fopen')) {
class Db { class Db {
var $extension = "JSON", $server_info, $errno, $_result, $error, $_url; public $extension = "JSON", $server_info, $errno, $error;
var $_db = 'default'; public $_db = 'default';
private $result, $url;
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',
@@ -57,7 +58,7 @@ if (isset($_GET["clickhouse"])) {
function connect($server, $username, $password) { function connect($server, $username, $password) {
preg_match('~^(https?://)?(.*)~', $server, $match); preg_match('~^(https?://)?(.*)~', $server, $match);
$this->_url = ($match[1] ?: "http://") . urlencode($username) . ":" . urlencode($password) . "@$match[2]"; $this->url = ($match[1] ?: "http://") . urlencode($username) . ":" . urlencode($password) . "@$match[2]";
$return = $this->query('SELECT 1'); $return = $this->query('SELECT 1');
return (bool) $return; return (bool) $return;
} }
@@ -72,11 +73,11 @@ if (isset($_GET["clickhouse"])) {
} }
function multi_query($query) { function multi_query($query) {
return $this->_result = $this->query($query); return $this->result = $this->query($query);
} }
function store_result() { function store_result() {
return $this->_result; return $this->result;
} }
function next_result() { function next_result() {
@@ -90,7 +91,8 @@ if (isset($_GET["clickhouse"])) {
} }
class Result { class Result {
var $num_rows, $_rows, $columns, $meta, $_offset = 0; public $num_rows, $columns, $meta;
private $rows, $offset = 0;
function __construct($result) { function __construct($result) {
foreach ($result['data'] as $item) { foreach ($result['data'] as $item) {
@@ -98,28 +100,28 @@ if (isset($_GET["clickhouse"])) {
foreach ($item as $key => $val) { foreach ($item as $key => $val) {
$row[$key] = is_scalar($val) ? $val : json_encode($val, 256); // 256 - JSON_UNESCAPED_UNICODE $row[$key] = is_scalar($val) ? $val : json_encode($val, 256); // 256 - JSON_UNESCAPED_UNICODE
} }
$this->_rows[] = $row; $this->rows[] = $row;
} }
$this->num_rows = $result['rows']; $this->num_rows = $result['rows'];
$this->meta = $result['meta']; $this->meta = $result['meta'];
$this->columns = array_column($this->meta, 'name'); $this->columns = array_column($this->meta, 'name');
reset($this->_rows); 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'];
@@ -135,8 +137,8 @@ if (isset($_GET["clickhouse"])) {
static $possibleDrivers = array("allow_url_fopen"); static $possibleDrivers = array("allow_url_fopen");
static $jush = "clickhouse"; static $jush = "clickhouse";
var $operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"); public $operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL");
var $grouping = array("avg", "count", "count distinct", "max", "min", "sum"); public $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
function __construct($connection) { function __construct($connection) {
parent::__construct($connection); parent::__construct($connection);

View File

@@ -9,7 +9,8 @@ if (isset($_GET["elastic"])) {
if (ini_bool('allow_url_fopen')) { if (ini_bool('allow_url_fopen')) {
class Db { class Db {
var $extension = "JSON", $server_info, $errno, $error, $_url; public $extension = "JSON", $server_info, $errno, $error;
private $url;
/** /**
* @param string $path * @param string $path
@@ -18,7 +19,7 @@ if (isset($_GET["elastic"])) {
* @return array|false * @return array|false
*/ */
function rootQuery($path, array $content = null, $method = 'GET') { function rootQuery($path, array $content = null, $method = 'GET') {
$file = @file_get_contents("$this->_url/" . ltrim($path, '/'), false, stream_context_create(array('http' => array( $file = @file_get_contents("$this->url/" . ltrim($path, '/'), false, stream_context_create(array('http' => array(
'method' => $method, 'method' => $method,
'content' => $content !== null ? json_encode($content) : null, 'content' => $content !== null ? json_encode($content) : null,
'header' => $content !== null ? 'Content-Type: application/json' : array(), 'header' => $content !== null ? 'Content-Type: application/json' : array(),
@@ -78,7 +79,7 @@ if (isset($_GET["elastic"])) {
*/ */
function connect($server, $username, $password) { function connect($server, $username, $password) {
preg_match('~^(https?://)?(.*)~', $server, $match); preg_match('~^(https?://)?(.*)~', $server, $match);
$this->_url = ($match[1] ?: "http://") . urlencode($username) . ":" . urlencode($password) . "@$match[2]"; $this->url = ($match[1] ?: "http://") . urlencode($username) . ":" . urlencode($password) . "@$match[2]";
$return = $this->query(''); $return = $this->query('');
if ($return) { if ($return) {
$this->server_info = $return['version']['number']; $this->server_info = $return['version']['number'];
@@ -96,18 +97,19 @@ if (isset($_GET["elastic"])) {
} }
class Result { class Result {
var $num_rows, $_rows; public $num_rows;
private $rows;
function __construct($rows) { function __construct($rows) {
$this->num_rows = count($rows); $this->num_rows = count($rows);
$this->_rows = $rows; $this->rows = $rows;
reset($this->_rows); reset($this->rows);
} }
function fetch_assoc() { function fetch_assoc() {
$return = current($this->_rows); $return = current($this->rows);
next($this->_rows); next($this->rows);
return $return; return $return;
} }
@@ -124,8 +126,8 @@ if (isset($_GET["elastic"])) {
static $possibleDrivers = array("json + allow_url_fopen"); static $possibleDrivers = array("json + allow_url_fopen");
static $jush = "elastic"; static $jush = "elastic";
var $editFunctions = array(array("json")); public $editFunctions = array(array("json"));
var $operators = array("=", "must", "should", "must_not"); public $operators = array("=", "must", "should", "must_not");
function __construct($connection) { function __construct($connection) {
parent::__construct($connection); parent::__construct($connection);
@@ -197,7 +199,7 @@ if (isset($_GET["elastic"])) {
$query = "$table/_search"; $query = "$table/_search";
$start = microtime(true); $start = microtime(true);
$search = $this->_conn->rootQuery($query, $data); $search = $this->conn->rootQuery($query, $data);
if ($print) { if ($print) {
echo adminer()->selectQuery("$query: " . json_encode($data), $start, !$search); echo adminer()->selectQuery("$query: " . json_encode($data), $start, !$search);
@@ -205,6 +207,9 @@ if (isset($_GET["elastic"])) {
if (empty($search)) { if (empty($search)) {
return false; return false;
} }
if ($select == array("*")) {
$tableFields = array_keys(fields($table));
}
$return = array(); $return = array();
foreach ($search["hits"]["hits"] as $hit) { foreach ($search["hits"]["hits"] as $hit) {
@@ -219,7 +224,9 @@ if (isset($_GET["elastic"])) {
$fields[$key] = $key == "_id" ? $hit["_id"] : $hit["_source"][$key]; $fields[$key] = $key == "_id" ? $hit["_id"] : $hit["_source"][$key];
} }
} else { } else {
$fields = $hit["_source"]; foreach ($tableFields as $key) {
$fields[$key] = $key == "_id" ? $hit["_id"] : $hit["_source"][$key];
}
} }
foreach ($fields as $key => $val) { foreach ($fields as $key => $val) {
$row[$key] = (is_array($val) ? json_encode($val) : $val); $row[$key] = (is_array($val) ? json_encode($val) : $val);
@@ -238,19 +245,30 @@ if (isset($_GET["elastic"])) {
$id = trim($parts[1]); $id = trim($parts[1]);
$query = "$type/$id"; $query = "$type/$id";
return $this->_conn->query($query, $record, 'POST'); return $this->conn->query($query, $record, 'POST');
} }
return false; return false;
} }
function insert($type, $record) { function insert($type, $record) {
$id = ""; //! user should be able to inform _id $query = "$type/_doc/";
$query = "$type/$id"; if (isset($record["_id"]) && $record["_id"] != "NULL") {
$response = $this->_conn->query($query, $record, 'POST'); $query .= $record["_id"];
$this->_conn->last_id = $response['_id']; unset($record["_id"]);
}
foreach ($record as $key => $value) {
if ($value == "NULL") {
unset($record[$key]);
}
}
$response = $this->conn->query($query, $record, 'POST');
if ($response == false) {
return false;
}
$this->conn->last_id = $response['_id'];
return $response['created']; return $response['result'];
} }
function delete($table, $queryWhere, $limit = 0) { function delete($table, $queryWhere, $limit = 0) {
@@ -268,17 +286,17 @@ if (isset($_GET["elastic"])) {
} }
} }
$this->_conn->affected_rows = 0; $this->conn->affected_rows = 0;
foreach ($ids as $id) { foreach ($ids as $id) {
$query = "$table/_doc/$id"; $query = "$table/_doc/$id";
$response = $this->_conn->query($query, null, 'DELETE'); $response = $this->conn->query($query, null, 'DELETE');
if (isset($response['result']) && $response['result'] == 'deleted') { if (isset($response['result']) && $response['result'] == 'deleted') {
$this->_conn->affected_rows++; $this->conn->affected_rows++;
} }
} }
return $this->_conn->affected_rows; return $this->conn->affected_rows;
} }
function convertOperator($operator) { function convertOperator($operator) {
@@ -466,6 +484,7 @@ if (isset($_GET["elastic"])) {
"field" => "_id", "field" => "_id",
"full_type" => "text", "full_type" => "text",
"type" => "text", "type" => "text",
"null" => true,
"privileges" => array("insert" => 1, "select" => 1, "where" => 1, "order" => 1), "privileges" => array("insert" => 1, "select" => 1, "where" => 1, "order" => 1),
) )
); );
@@ -475,6 +494,7 @@ if (isset($_GET["elastic"])) {
"field" => $name, "field" => $name,
"full_type" => $field["type"], "full_type" => $field["type"],
"type" => $field["type"], "type" => $field["type"],
"null" => true,
"privileges" => array( "privileges" => array(
"insert" => 1, "insert" => 1,
"select" => 1, "select" => 1,

View File

@@ -12,14 +12,15 @@ if (isset($_GET["firebird"])) {
if (extension_loaded("interbase")) { if (extension_loaded("interbase")) {
class Db { class Db {
var public
$extension = "Firebird", $extension = "Firebird",
$server_info, $server_info,
$affected_rows, $affected_rows,
$errno, $errno,
$error, $error,
$_link, $_result $_link
; ;
private $result;
function connect($server, $username, $password) { function connect($server, $username, $password) {
$this->_link = ibase_connect($server, $username, $password); $this->_link = ibase_connect($server, $username, $password);
@@ -58,11 +59,11 @@ if (isset($_GET["firebird"])) {
} }
function multi_query($query) { function multi_query($query) {
return $this->_result = $this->query($query); return $this->result = $this->query($query);
} }
function store_result() { function store_result() {
return $this->_result; return $this->result;
} }
function next_result() { function next_result() {
@@ -80,23 +81,24 @@ if (isset($_GET["firebird"])) {
} }
class Result { class Result {
var $num_rows, $_result, $_offset = 0; public $num_rows;
private $result, $offset = 0;
function __construct($result) { function __construct($result) {
$this->_result = $result; $this->result = $result;
// $this->num_rows = ibase_num_rows($result); // $this->num_rows = ibase_num_rows($result);
} }
function fetch_assoc() { function fetch_assoc() {
return ibase_fetch_assoc($this->_result); return ibase_fetch_assoc($this->result);
} }
function fetch_row() { function fetch_row() {
return ibase_fetch_row($this->_result); return ibase_fetch_row($this->result);
} }
function fetch_field() { function fetch_field() {
$field = ibase_field_info($this->_result, $this->_offset++); $field = ibase_field_info($this->result, $this->offset++);
return (object) array( return (object) array(
'name' => $field['name'], 'name' => $field['name'],
'orgname' => $field['name'], 'orgname' => $field['name'],
@@ -106,7 +108,7 @@ if (isset($_GET["firebird"])) {
} }
function __destruct() { function __destruct() {
ibase_free_result($this->_result); ibase_free_result($this->result);
} }
} }
@@ -118,7 +120,7 @@ if (isset($_GET["firebird"])) {
static $possibleDrivers = array("interbase"); static $possibleDrivers = array("interbase");
static $jush = "firebird"; static $jush = "firebird";
var $operators = array("="); public $operators = array("=");
} }

View File

@@ -8,7 +8,8 @@ if (isset($_GET["simpledb"])) {
if (class_exists('SimpleXMLElement') && ini_bool('allow_url_fopen')) { if (class_exists('SimpleXMLElement') && ini_bool('allow_url_fopen')) {
class Db { class Db {
var $extension = "SimpleXML", $server_info = '2009-04-15', $error, $timeout, $next, $affected_rows, $_result; public $extension = "SimpleXML", $server_info = '2009-04-15', $error, $timeout, $next, $affected_rows;
private $result;
function select_db($database) { function select_db($database) {
return ($database == "domain"); return ($database == "domain");
@@ -38,11 +39,11 @@ if (isset($_GET["simpledb"])) {
} }
function multi_query($query) { function multi_query($query) {
return $this->_result = $this->query($query); return $this->result = $this->query($query);
} }
function store_result() { function store_result() {
return $this->_result; return $this->result;
} }
function next_result() { function next_result() {
@@ -55,7 +56,8 @@ if (isset($_GET["simpledb"])) {
} }
class Result { class Result {
var $num_rows, $_rows = array(), $_offset = 0; public $num_rows;
private $rows = array(), $offset = 0;
function __construct($result) { function __construct($result) {
foreach ($result as $item) { foreach ($result as $item) {
@@ -64,8 +66,8 @@ if (isset($_GET["simpledb"])) {
$row['itemName()'] = (string) $item->Name; $row['itemName()'] = (string) $item->Name;
} }
foreach ($item->Attribute as $attribute) { foreach ($item->Attribute as $attribute) {
$name = $this->_processValue($attribute->Name); $name = $this->processValue($attribute->Name);
$value = $this->_processValue($attribute->Value); $value = $this->processValue($attribute->Value);
if (isset($row[$name])) { if (isset($row[$name])) {
$row[$name] = (array) $row[$name]; $row[$name] = (array) $row[$name];
$row[$name][] = $value; $row[$name][] = $value;
@@ -73,30 +75,30 @@ if (isset($_GET["simpledb"])) {
$row[$name] = $value; $row[$name] = $value;
} }
} }
$this->_rows[] = $row; $this->rows[] = $row;
foreach ($row as $key => $val) { foreach ($row as $key => $val) {
if (!isset($this->_rows[0][$key])) { if (!isset($this->rows[0][$key])) {
$this->_rows[0][$key] = null; $this->rows[0][$key] = null;
} }
} }
} }
$this->num_rows = count($this->_rows); $this->num_rows = count($this->rows);
} }
function _processValue($element) { private function processValue($element) {
return (is_object($element) && $element['encoding'] == 'base64' ? base64_decode($element) : (string) $element); return (is_object($element) && $element['encoding'] == 'base64' ? base64_decode($element) : (string) $element);
} }
function fetch_assoc() { function fetch_assoc() {
$row = current($this->_rows); $row = current($this->rows);
if (!$row) { if (!$row) {
return $row; return $row;
} }
$return = array(); $return = array();
foreach ($this->_rows[0] as $key => $val) { foreach ($this->rows[0] as $key => $val) {
$return[$key] = $row[$key]; $return[$key] = $row[$key];
} }
next($this->_rows); next($this->rows);
return $return; return $return;
} }
@@ -109,8 +111,8 @@ if (isset($_GET["simpledb"])) {
} }
function fetch_field() { function fetch_field() {
$keys = array_keys($this->_rows[0]); $keys = array_keys($this->rows[0]);
return (object) array('name' => $keys[$this->_offset++]); return (object) array('name' => $keys[$this->offset++]);
} }
} }
} }
@@ -121,12 +123,12 @@ if (isset($_GET["simpledb"])) {
static $possibleDrivers = array("SimpleXML + allow_url_fopen"); static $possibleDrivers = array("SimpleXML + allow_url_fopen");
static $jush = "simpledb"; static $jush = "simpledb";
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "IS NOT NULL"); public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "IS NOT NULL");
var $grouping = array("count"); public $grouping = array("count");
public $primary = "itemName()"; public $primary = "itemName()";
function _chunkRequest($ids, $action, $params, $expand = array()) { private function chunkRequest($ids, $action, $params, $expand = array()) {
$connection = connection(); $connection = connection();
foreach (array_chunk($ids, 25) as $chunk) { foreach (array_chunk($ids, 25) as $chunk) {
$params2 = $params; $params2 = $params;
@@ -144,7 +146,7 @@ if (isset($_GET["simpledb"])) {
return true; return true;
} }
function _extractIds($table, $queryWhere, $limit) { private function extractIds($table, $queryWhere, $limit) {
$return = array(); $return = array();
if (preg_match_all("~itemName\(\) = (('[^']*+')+)~", $queryWhere, $matches)) { if (preg_match_all("~itemName\(\) = (('[^']*+')+)~", $queryWhere, $matches)) {
$return = array_map('Adminer\idf_unescape', $matches[1]); $return = array_map('Adminer\idf_unescape', $matches[1]);
@@ -165,8 +167,8 @@ if (isset($_GET["simpledb"])) {
} }
function delete($table, $queryWhere, $limit = 0) { function delete($table, $queryWhere, $limit = 0) {
return $this->_chunkRequest( return $this->chunkRequest(
$this->_extractIds($table, $queryWhere, $limit), $this->extractIds($table, $queryWhere, $limit),
'BatchDeleteAttributes', 'BatchDeleteAttributes',
array('DomainName' => $table) array('DomainName' => $table)
); );
@@ -176,7 +178,7 @@ if (isset($_GET["simpledb"])) {
$delete = array(); $delete = array();
$insert = array(); $insert = array();
$i = 0; $i = 0;
$ids = $this->_extractIds($table, $queryWhere, $limit); $ids = $this->extractIds($table, $queryWhere, $limit);
$id = idf_unescape($set["`itemName()`"]); $id = idf_unescape($set["`itemName()`"]);
unset($set["`itemName()`"]); unset($set["`itemName()`"]);
foreach ($set as $key => $val) { foreach ($set as $key => $val) {
@@ -196,8 +198,8 @@ if (isset($_GET["simpledb"])) {
} }
} }
$params = array('DomainName' => $table); $params = array('DomainName' => $table);
return (!$insert || $this->_chunkRequest(($id != "" ? array($id) : $ids), 'BatchPutAttributes', $params, $insert)) return (!$insert || $this->chunkRequest(($id != "" ? array($id) : $ids), 'BatchPutAttributes', $params, $insert))
&& (!$delete || $this->_chunkRequest($ids, 'BatchDeleteAttributes', $params, $delete)) && (!$delete || $this->chunkRequest($ids, 'BatchDeleteAttributes', $params, $delete))
; ;
} }
@@ -244,7 +246,7 @@ if (isset($_GET["simpledb"])) {
} }
function slowQuery($query, $timeout) { function slowQuery($query, $timeout) {
$this->_conn->timeout = $timeout; $this->conn->timeout = $timeout;
return $query; return $query;
} }
} }

View File

@@ -8,8 +8,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerDumpBz2 { class AdminerDumpBz2 {
/** @access protected */ protected $filename, $fp;
var $filename, $fp;
function dumpOutput() { function dumpOutput() {
if (!function_exists('bzopen')) { if (!function_exists('bzopen')) {

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerDumpJson { class AdminerDumpJson {
/** @access protected */ protected $database = false;
var $database = false;
function dumpFormat() { function dumpFormat() {
return array('json' => 'JSON'); return array('json' => 'JSON');
@@ -20,10 +19,6 @@ class AdminerDumpJson {
} }
} }
function _database() {
echo "}\n";
}
function dumpData($table, $style, $query) { function dumpData($table, $style, $query) {
if ($_POST["format"] == "json") { if ($_POST["format"] == "json") {
if ($this->database) { if ($this->database) {
@@ -31,7 +26,6 @@ class AdminerDumpJson {
} else { } else {
$this->database = true; $this->database = true;
echo "{\n"; echo "{\n";
register_shutdown_function(array($this, '_database'));
} }
$connection = Adminer\connection(); $connection = Adminer\connection();
$result = $connection->query($query, 1); $result = $connection->query($query, 1);
@@ -58,4 +52,10 @@ class AdminerDumpJson {
return "json"; return "json";
} }
} }
function dumpFooter() {
if ($_POST["format"] == "json" && $this->database) {
echo "}\n";
}
}
} }

View File

@@ -6,8 +6,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerDumpPhp { class AdminerDumpPhp {
var $output = array(); protected $output = array();
var $shutdown_callback = false;
function dumpFormat() { function dumpFormat() {
return array('php' => 'PHP'); return array('php' => 'PHP');
@@ -23,10 +22,6 @@ class AdminerDumpPhp {
function dumpTable($table, $style, $is_view = 0) { function dumpTable($table, $style, $is_view = 0) {
if ($_POST['format'] == 'php') { if ($_POST['format'] == 'php') {
$this->output[$table] = array(); $this->output[$table] = array();
if (!$this->shutdown_callback) {
$this->shutdown_callback = true;
register_shutdown_function(array($this, '_export'));
}
return true; return true;
} }
} }
@@ -44,8 +39,11 @@ class AdminerDumpPhp {
} }
} }
function _export() { function dumpFooter() {
echo "<?php\n"; if ($_POST['format'] == 'php') {
var_export($this->output); echo "<?php\n";
var_export($this->output);
echo ";\n";
}
} }
} }

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerDumpXml { class AdminerDumpXml {
/** @access protected */ protected $database = false;
var $database = false;
function dumpFormat() { function dumpFormat() {
return array('xml' => 'XML'); return array('xml' => 'XML');
@@ -20,16 +19,11 @@ class AdminerDumpXml {
} }
} }
function _database() {
echo "</database>\n";
}
function dumpData($table, $style, $query) { function dumpData($table, $style, $query) {
if ($_POST["format"] == "xml") { if ($_POST["format"] == "xml") {
if (!$this->database) { if (!$this->database) {
$this->database = true; $this->database = true;
echo "<database name='" . Adminer\h(Adminer\DB) . "'>\n"; echo "<database name='" . Adminer\h(Adminer\DB) . "'>\n";
register_shutdown_function(array($this, '_database'));
} }
$connection = Adminer\connection(); $connection = Adminer\connection();
$result = $connection->query($query, 1); $result = $connection->query($query, 1);
@@ -52,4 +46,10 @@ class AdminerDumpXml {
return "xml"; return "xml";
} }
} }
function dumpFooter() {
if ($_POST["format"] == "xml" && $this->database) {
echo "</database>\n";
}
}
} }

View File

@@ -8,8 +8,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerDumpZip { class AdminerDumpZip {
/** @access protected */ protected $filename, $data;
var $filename, $data;
function dumpOutput() { function dumpOutput() {
if (!class_exists('ZipArchive')) { if (!class_exists('ZipArchive')) {

View File

@@ -9,8 +9,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerEditCalendar { class AdminerEditCalendar {
/** @access protected */ protected $prepend, $langPath;
var $prepend, $langPath;
/** /**
* @param string text to append before first calendar usage * @param string text to append before first calendar usage

View File

@@ -7,10 +7,10 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerEditForeign { class AdminerEditForeign {
var $_limit; protected $limit;
function __construct($limit = 0) { function __construct($limit = 0) {
$this->_limit = $limit; $this->limit = $limit;
} }
function editInput($table, $field, $attrs, $value) { function editInput($table, $field, $attrs, $value) {
@@ -30,8 +30,8 @@ class AdminerEditForeign {
if (preg_match('~binary~', $field["type"])) { if (preg_match('~binary~', $field["type"])) {
$column = "HEX($column)"; $column = "HEX($column)";
} }
$options = array("" => "") + Adminer\get_vals("SELECT $column FROM " . Adminer\table($target) . " ORDER BY 1" . ($this->_limit ? " LIMIT " . ($this->_limit + 1) : "")); $options = array("" => "") + Adminer\get_vals("SELECT $column FROM " . Adminer\table($target) . " ORDER BY 1" . ($this->limit ? " LIMIT " . ($this->limit + 1) : ""));
if ($this->_limit && count($options) - 1 > $this->_limit) { if ($this->limit && count($options) - 1 > $this->limit) {
return; return;
} }
} }

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerEmailTable { class AdminerEmailTable {
/** @access protected */ protected $table, $id, $title, $subject, $message;
var $table, $id, $title, $subject, $message;
/** /**
* @param string quoted table name * @param string quoted table name

View File

@@ -20,20 +20,16 @@ class AdminerEnumOption {
} }
if ($field["null"]) { if ($field["null"]) {
$options[""] = "NULL"; $options[""] = "NULL";
if ($value === null && !isset($_GET["select"])) { if ($selected === null) {
$selected = ""; $selected = "";
} }
} }
$options[0] = Adminer\lang('empty');
preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches); preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
foreach ($matches[1] as $i => $val) { foreach ($matches[1] as $val) {
$val = stripcslashes(str_replace("''", "'", $val)); $val = stripcslashes(str_replace("''", "'", $val));
$options[$i + 1] = $val; $options[$val] = $val;
if ($value === $val) {
$selected = $i + 1;
}
} }
return "<select$attrs>" . Adminer\optionlist($options, (string) $selected, 1) . "</select>"; // 1 - use keys return "<select$attrs>" . Adminer\optionlist($options, $selected, 1) . "</select>"; // 1 - use keys
} }
} }
} }

View File

@@ -8,8 +8,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerFileUpload { class AdminerFileUpload {
/** @access protected */ protected $uploadPath, $displayPath, $extensions;
var $uploadPath, $displayPath, $extensions;
/** /**
* @param string prefix for uploading data (create writable subdirectory for each table containing uploadable fields) * @param string prefix for uploading data (create writable subdirectory for each table containing uploadable fields)

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerFrames { class AdminerFrames {
/** @access protected */ protected $sameOrigin;
var $sameOrigin;
/** /**
* @param bool allow running from the same origin only * @param bool allow running from the same origin only

View File

@@ -8,14 +8,14 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerJsonColumn { class AdminerJsonColumn {
private function _testJson($value) { private function testJson($value) {
if ((substr($value, 0, 1) == '{' || substr($value, 0, 1) == '[') && ($json = json_decode($value, true))) { if ((substr($value, 0, 1) == '{' || substr($value, 0, 1) == '[') && ($json = json_decode($value, true))) {
return $json; return $json;
} }
return $value; return $value;
} }
private function _buildTable($json) { private function buildTable($json) {
echo '<table style="margin:2px; font-size:100%;">'; echo '<table style="margin:2px; font-size:100%;">';
foreach ($json as $key => $val) { foreach ($json as $key => $val) {
echo '<tr>'; echo '<tr>';
@@ -31,7 +31,7 @@ class AdminerJsonColumn {
} }
echo '<code class="jush-js">' . $val . '</code>'; echo '<code class="jush-js">' . $val . '</code>';
} else { } else {
$this->_buildTable($val); $this->buildTable($val);
} }
echo '</td>'; echo '</td>';
echo '</tr>'; echo '</tr>';
@@ -40,9 +40,9 @@ class AdminerJsonColumn {
} }
function editInput($table, $field, $attrs, $value) { function editInput($table, $field, $attrs, $value) {
$json = $this->_testJson($value); $json = $this->testJson($value);
if ($json !== $value) { if ($json !== $value) {
$this->_buildTable($json); $this->buildTable($json);
} }
} }
} }

View File

@@ -7,10 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerLoginIp { class AdminerLoginIp {
/** @access protected */ protected $ips, $forwarded_for;
var $ips;
/** @access protected */
var $forwarded_for;
/** Set allowed IP addresses /** Set allowed IP addresses
* @param array IP address prefixes * @param array IP address prefixes

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerLoginOtp { class AdminerLoginOtp {
/** @access protected */ protected $secret;
var $secret;
/** /**
* @param string decoded secret, e.g. base64_decode("SECRET") * @param string decoded secret, e.g. base64_decode("SECRET")

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerLoginPasswordLess { class AdminerLoginPasswordLess {
/** @access protected */ protected $password_hash;
var $password_hash;
/** Set allowed password /** Set allowed password
* @param string result of password_hash * @param string result of password_hash

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerLoginServers { class AdminerLoginServers {
/** @access protected */ protected $servers;
var $servers;
/** Set supported servers /** Set supported servers
* @param array [$description => ["server" => , "driver" => "server|pgsql|sqlite|..."]] * @param array [$description => ["server" => , "driver" => "server|pgsql|sqlite|..."]]

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerLoginSsl { class AdminerLoginSsl {
/** @access protected */ protected $ssl;
var $ssl;
/** /**
* @param array * @param array

View File

@@ -16,8 +16,7 @@ CREATE TABLE login (
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerLoginTable { class AdminerLoginTable {
/** @access protected */ protected $database;
var $database;
/** Set database of login table /** Set database of login table
* @param string * @param string

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerPlugin extends Adminer\Adminer { class AdminerPlugin extends Adminer\Adminer {
/** @access protected */ protected $plugins;
var $plugins;
/** Register plugins /** Register plugins
* @param array object instances or null to register all classes starting by 'Adminer' * @param array object instances or null to register all classes starting by 'Adminer'
@@ -26,11 +25,11 @@ class AdminerPlugin extends Adminer\Adminer {
//! it is possible to use ReflectionObject to find out which plugins defines which methods at once //! it is possible to use ReflectionObject to find out which plugins defines which methods at once
} }
function _callParent($function, $args) { private function callParent($function, $args) {
return call_user_func_array(array('parent', $function), $args); return call_user_func_array(array('parent', $function), $args);
} }
function _applyPlugin($function, $args) { private function applyPlugin($function, $args) {
foreach ($this->plugins as $plugin) { foreach ($this->plugins as $plugin) {
if (method_exists($plugin, $function)) { if (method_exists($plugin, $function)) {
switch (count($args)) { // call_user_func_array() doesn't work well with references switch (count($args)) { // call_user_func_array() doesn't work well with references
@@ -63,11 +62,11 @@ class AdminerPlugin extends Adminer\Adminer {
} }
} }
} }
return $this->_callParent($function, $args); return $this->callParent($function, $args);
} }
function _appendPlugin($function, $args) { private function appendPlugin($function, $args) {
$return = $this->_callParent($function, $args); $return = $this->callParent($function, $args);
foreach ($this->plugins as $plugin) { foreach ($this->plugins as $plugin) {
if (method_exists($plugin, $function)) { if (method_exists($plugin, $function)) {
$value = call_user_func_array(array($plugin, $function), $args); $value = call_user_func_array(array($plugin, $function), $args);
@@ -83,333 +82,338 @@ class AdminerPlugin extends Adminer\Adminer {
function dumpFormat() { function dumpFormat() {
$args = func_get_args(); $args = func_get_args();
return $this->_appendPlugin(__FUNCTION__, $args); return $this->appendPlugin(__FUNCTION__, $args);
} }
function dumpOutput() { function dumpOutput() {
$args = func_get_args(); $args = func_get_args();
return $this->_appendPlugin(__FUNCTION__, $args); return $this->appendPlugin(__FUNCTION__, $args);
} }
function editRowPrint($table, $fields, $row, $update) { function editRowPrint($table, $fields, $row, $update) {
$args = func_get_args(); $args = func_get_args();
return $this->_appendPlugin(__FUNCTION__, $args); return $this->appendPlugin(__FUNCTION__, $args);
} }
function editFunctions($field) { function editFunctions($field) {
$args = func_get_args(); $args = func_get_args();
return $this->_appendPlugin(__FUNCTION__, $args); return $this->appendPlugin(__FUNCTION__, $args);
} }
// applyPlugin // applyPlugin
function name() { function name() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function credentials() { function credentials() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function connectSsl() { function connectSsl() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function permanentLogin($create = false) { function permanentLogin($create = false) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function bruteForceKey() { function bruteForceKey() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function serverName($server) { function serverName($server) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function database() { function database() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function schemas() { function schemas() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function databases($flush = true) { function databases($flush = true) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function queryTimeout() { function queryTimeout() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function headers() { function headers() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function csp() { function csp() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function head() { function head() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function css() { function css() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function loginForm() { function loginForm() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function loginFormField($name, $heading, $value) { function loginFormField($name, $heading, $value) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function login($login, $password) { function login($login, $password) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function tableName($tableStatus) { function tableName($tableStatus) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function fieldName($field, $order = 0) { function fieldName($field, $order = 0) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectLinks($tableStatus, $set = "") { function selectLinks($tableStatus, $set = "") {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function foreignKeys($table) { function foreignKeys($table) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function backwardKeys($table, $tableName) { function backwardKeys($table, $tableName) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function backwardKeysPrint($backwardKeys, $row) { function backwardKeysPrint($backwardKeys, $row) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectQuery($query, $start, $failed = false) { function selectQuery($query, $start, $failed = false) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function sqlCommandQuery($query) { function sqlCommandQuery($query) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function rowDescription($table) { function rowDescription($table) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function rowDescriptions($rows, $foreignKeys) { function rowDescriptions($rows, $foreignKeys) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectLink($val, $field) { function selectLink($val, $field) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectVal($val, $link, $field, $original) { function selectVal($val, $link, $field, $original) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function editVal($val, $field) { function editVal($val, $field) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function tableStructurePrint($fields) { function tableStructurePrint($fields) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function tableIndexesPrint($indexes) { function tableIndexesPrint($indexes) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectColumnsPrint($select, $columns) { function selectColumnsPrint($select, $columns) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectSearchPrint($where, $columns, $indexes) { function selectSearchPrint($where, $columns, $indexes) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectOrderPrint($order, $columns, $indexes) { function selectOrderPrint($order, $columns, $indexes) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectLimitPrint($limit) { function selectLimitPrint($limit) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectLengthPrint($text_length) { function selectLengthPrint($text_length) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectActionPrint($indexes) { function selectActionPrint($indexes) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectCommandPrint() { function selectCommandPrint() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectImportPrint() { function selectImportPrint() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectEmailPrint($emailFields, $columns) { function selectEmailPrint($emailFields, $columns) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectColumnsProcess($columns, $indexes) { function selectColumnsProcess($columns, $indexes) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectSearchProcess($fields, $indexes) { function selectSearchProcess($fields, $indexes) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectOrderProcess($fields, $indexes) { function selectOrderProcess($fields, $indexes) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectLimitProcess() { function selectLimitProcess() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectLengthProcess() { function selectLengthProcess() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectEmailProcess($where, $foreignKeys) { function selectEmailProcess($where, $foreignKeys) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function selectQueryBuild($select, $where, $group, $order, $limit, $page) { function selectQueryBuild($select, $where, $group, $order, $limit, $page) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function messageQuery($query, $time, $failed = false) { function messageQuery($query, $time, $failed = false) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function editInput($table, $field, $attrs, $value) { function editInput($table, $field, $attrs, $value) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function editHint($table, $field, $value) { function editHint($table, $field, $value) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function processInput($field, $value, $function = "") { function processInput($field, $value, $function = "") {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function dumpDatabase($db) { function dumpDatabase($db) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function dumpTable($table, $style, $is_view = 0) { function dumpTable($table, $style, $is_view = 0) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function dumpData($table, $style, $query) { function dumpData($table, $style, $query) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function dumpFilename($identifier) { function dumpFilename($identifier) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function dumpHeaders($identifier, $multi_table = false) { function dumpHeaders($identifier, $multi_table = false) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
}
function dumpFooter() {
$args = func_get_args();
return $this->applyPlugin(__FUNCTION__, $args);
} }
function importServerPath() { function importServerPath() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function homepage() { function homepage() {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function navigation($missing) { function navigation($missing) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function databasesPrint($missing) { function databasesPrint($missing) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
function tablesPrint($tables) { function tablesPrint($tables) {
$args = func_get_args(); $args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args); return $this->applyPlugin(__FUNCTION__, $args);
} }
} }

View File

@@ -10,7 +10,7 @@ class AdminerPrettyJsonColumn {
$this->adminer = $adminer; $this->adminer = $adminer;
} }
private function _testJson($value) { private function testJson($value) {
if ((substr($value, 0, 1) == '{' || substr($value, 0, 1) == '[') && ($json = json_decode($value, true))) { if ((substr($value, 0, 1) == '{' || substr($value, 0, 1) == '[') && ($json = json_decode($value, true))) {
return $json; return $json;
} }
@@ -18,19 +18,17 @@ class AdminerPrettyJsonColumn {
} }
function editInput($table, $field, $attrs, $value) { function editInput($table, $field, $attrs, $value) {
$json = $this->_testJson($value); $json = $this->testJson($value);
if ($json !== $value) { if ($json !== $value) {
$jsonText = json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); $jsonText = json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
return <<<HTML return "<textarea$attrs cols='50' rows='20'>" . h($jsonText) . "</textarea>";
<textarea $attrs cols="50" rows="20">$jsonText</textarea>
HTML;
} }
return ''; return '';
} }
function processInput($field, $value, $function = '') { function processInput($field, $value, $function = '') {
if ($function === '') { if ($function === '') {
$json = $this->_testJson($value); $json = $this->testJson($value);
if ($json !== $value) { if ($json !== $value) {
$value = json_encode($json); $value = json_encode($json);
} }

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerSlugify { class AdminerSlugify {
/** @access protected */ protected $from, $to;
var $from, $to;
/** /**
* @param string find these characters ... * @param string find these characters ...

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerSqlLog { class AdminerSqlLog {
/** @access protected */ protected $filename;
var $filename;
/** /**
* @param string defaults to "$database.sql" * @param string defaults to "$database.sql"
@@ -18,14 +17,14 @@ class AdminerSqlLog {
} }
function messageQuery($query, $time, $failed = false) { function messageQuery($query, $time, $failed = false) {
$this->_log($query); $this->log($query);
} }
function sqlCommandQuery($query) { function sqlCommandQuery($query) {
$this->_log($query); $this->log($query);
} }
function _log($query) { private function log($query) {
if ($this->filename == "") { if ($this->filename == "") {
$adminer = Adminer\adminer(); $adminer = Adminer\adminer();
$this->filename = $adminer->database() . ".sql"; // no database goes to ".sql" to avoid collisions $this->filename = $adminer->database() . ".sql"; // no database goes to ".sql" to avoid collisions

View File

@@ -8,8 +8,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerTinymce { class AdminerTinymce {
/** @access protected */ protected $path;
var $path;
/** /**
* @param string * @param string

View File

@@ -18,7 +18,7 @@ CREATE TABLE translation (
*/ */
class AdminerTranslation { class AdminerTranslation {
function _translate($idf) { private function translate($idf) {
static $translations, $lang; static $translations, $lang;
if ($lang === null) { if ($lang === null) {
$lang = Adminer\get_lang(); $lang = Adminer\get_lang();
@@ -39,16 +39,16 @@ class AdminerTranslation {
} }
function tableName(&$tableStatus) { function tableName(&$tableStatus) {
$tableStatus["Comment"] = $this->_translate($tableStatus["Comment"]); $tableStatus["Comment"] = $this->translate($tableStatus["Comment"]);
} }
function fieldName(&$field, $order = 0) { function fieldName(&$field, $order = 0) {
$field["comment"] = $this->_translate($field["comment"]); $field["comment"] = $this->translate($field["comment"]);
} }
function editVal(&$val, $field) { function editVal(&$val, $field) {
if ($field["type"] == "enum") { if ($field["type"] == "enum") {
$val = $this->_translate($val); $val = $this->translate($val);
} }
} }
} }

View File

@@ -8,8 +8,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/ */
class AdminerWymeditor { class AdminerWymeditor {
/** @access protected */ protected $scripts, $options;
var $scripts, $options;
/** /**
* @param array * @param array