mirror of
https://github.com/vrana/adminer.git
synced 2026-03-27 23:00:52 +01:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a134193afa | ||
|
|
8a60243459 | ||
|
|
b94636f8a7 | ||
|
|
47ccfa2a2e | ||
|
|
949b39b191 | ||
|
|
09a946cb99 | ||
|
|
13258de188 | ||
|
|
5fe25fca67 | ||
|
|
a693e75e32 | ||
|
|
de7dd4b64f | ||
|
|
8a70474651 | ||
|
|
43a0305a23 | ||
|
|
bff6f8ca93 | ||
|
|
f38c0a1f13 | ||
|
|
835c10674b | ||
|
|
fc5a46549e | ||
|
|
898dc9e25e | ||
|
|
32160b48ae | ||
|
|
6beb07a181 | ||
|
|
ee42077e54 | ||
|
|
c3e2e6c58f | ||
|
|
49effeff09 | ||
|
|
857cbf03f2 | ||
|
|
e8c9164a77 | ||
|
|
01fe709b7a | ||
|
|
90addc5e78 | ||
|
|
b71a456514 | ||
|
|
4d7642a624 | ||
|
|
9f8dadbb40 | ||
|
|
9968851f1e | ||
|
|
a5780e58af | ||
|
|
e8b40e3b9d | ||
|
|
35afd4f88c | ||
|
|
38e4b51256 | ||
|
|
55a7d3864f | ||
|
|
e69583a800 | ||
|
|
338c81e2a3 | ||
|
|
9eb4d00564 | ||
|
|
1c5947de50 | ||
|
|
5cfd48bb68 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@
|
|||||||
/editor*.php
|
/editor*.php
|
||||||
/vendor/
|
/vendor/
|
||||||
/composer.lock
|
/composer.lock
|
||||||
|
/temp
|
||||||
|
|||||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,9 +1,3 @@
|
|||||||
[submodule "jush"]
|
|
||||||
path = externals/jush
|
|
||||||
url = https://github.com/vrana/jush
|
|
||||||
[submodule "JsShrink"]
|
|
||||||
path = externals/JsShrink
|
|
||||||
url = https://github.com/vrana/JsShrink
|
|
||||||
[submodule "designs/hydra"]
|
[submodule "designs/hydra"]
|
||||||
path = designs/hydra
|
path = designs/hydra
|
||||||
url = https://github.com/Niyko/Hydra-Dark-Theme-for-Adminer
|
url = https://github.com/Niyko/Hydra-Dark-Theme-for-Adminer
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ if ($adminer->homepage()) {
|
|||||||
echo " <input type='submit' name='search' value='" . lang('Search') . "'>\n";
|
echo " <input type='submit' name='search' value='" . lang('Search') . "'>\n";
|
||||||
echo "</div></fieldset>\n";
|
echo "</div></fieldset>\n";
|
||||||
if ($_POST["search"] && $_POST["query"] != "") {
|
if ($_POST["search"] && $_POST["query"] != "") {
|
||||||
$_GET["where"][0]["op"] = "LIKE %%";
|
$_GET["where"][0]["op"] = $driver->convertOperator("LIKE %%");
|
||||||
search_tables();
|
search_tables();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -463,6 +463,8 @@ if (isset($_GET["mongo"])) {
|
|||||||
"insert" => 1,
|
"insert" => 1,
|
||||||
"select" => 1,
|
"select" => 1,
|
||||||
"update" => 1,
|
"update" => 1,
|
||||||
|
"where" => 1,
|
||||||
|
"order" => 1,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ WHERE o.schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND o.type IN ('S', 'U',
|
|||||||
"null" => $row["is_nullable"],
|
"null" => $row["is_nullable"],
|
||||||
"auto_increment" => $row["is_identity"],
|
"auto_increment" => $row["is_identity"],
|
||||||
"collation" => $row["collation_name"],
|
"collation" => $row["collation_name"],
|
||||||
"privileges" => array("insert" => 1, "select" => 1, "update" => 1),
|
"privileges" => array("insert" => 1, "select" => 1, "update" => 1, "where" => 1, "order" => 1),
|
||||||
"primary" => $row["is_identity"], //! or indexes.is_primary_key
|
"primary" => $row["is_identity"], //! or indexes.is_primary_key
|
||||||
"comment" => $comments[$row["name"]],
|
"comment" => $comments[$row["name"]],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -551,7 +551,7 @@ if (!defined("DRIVER")) {
|
|||||||
"auto_increment" => ($row["Extra"] == "auto_increment"),
|
"auto_increment" => ($row["Extra"] == "auto_increment"),
|
||||||
"on_update" => (preg_match('~^on update (.+)~i', $row["Extra"], $match) ? $match[1] : ""), //! available since MySQL 5.1.23
|
"on_update" => (preg_match('~^on update (.+)~i', $row["Extra"], $match) ? $match[1] : ""), //! available since MySQL 5.1.23
|
||||||
"collation" => $row["Collation"],
|
"collation" => $row["Collation"],
|
||||||
"privileges" => array_flip(preg_split('~, *~', $row["Privileges"])),
|
"privileges" => array_flip(preg_split('~, *~', $row["Privileges"])) + ["where" => 1, "order" => 1],
|
||||||
"comment" => $row["Comment"],
|
"comment" => $row["Comment"],
|
||||||
"primary" => ($row["Key"] == "PRI"),
|
"primary" => ($row["Key"] == "PRI"),
|
||||||
// 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
|
||||||
|
|||||||
@@ -167,7 +167,14 @@ if (isset($_GET["oracle"])) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $hostPath
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function is_server_host_valid($hostPath) {
|
||||||
|
// EasyConnect host+path format: host[/[service_name][:server_type][/instance_name]]
|
||||||
|
return (bool)preg_match('~^[^/]+(/([^/:]+)?(:[^/:]+)?(/[^/:]+)?)?$~', $hostPath);
|
||||||
|
}
|
||||||
|
|
||||||
function idf_escape($idf) {
|
function idf_escape($idf) {
|
||||||
return '"' . str_replace('"', '""', $idf) . '"';
|
return '"' . str_replace('"', '""', $idf) . '"';
|
||||||
@@ -297,7 +304,7 @@ ORDER BY 1"
|
|||||||
"null" => ($row["NULLABLE"] == "Y"),
|
"null" => ($row["NULLABLE"] == "Y"),
|
||||||
//! "auto_increment" => false,
|
//! "auto_increment" => false,
|
||||||
//! "collation" => $row["CHARACTER_SET_NAME"],
|
//! "collation" => $row["CHARACTER_SET_NAME"],
|
||||||
"privileges" => array("insert" => 1, "select" => 1, "update" => 1),
|
"privileges" => array("insert" => 1, "select" => 1, "update" => 1, "where" => 1, "order" => 1),
|
||||||
//! "comment" => $row["Comment"],
|
//! "comment" => $row["Comment"],
|
||||||
//! "primary" => ($row["Key"] == "PRI"),
|
//! "primary" => ($row["Key"] == "PRI"),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
|||||||
"full_type" => $type,
|
"full_type" => $type,
|
||||||
"default" => (preg_match("~'(.*)'~", $default, $match) ? str_replace("''", "'", $match[1]) : ($default == "NULL" ? null : $default)),
|
"default" => (preg_match("~'(.*)'~", $default, $match) ? str_replace("''", "'", $match[1]) : ($default == "NULL" ? null : $default)),
|
||||||
"null" => !$row["notnull"],
|
"null" => !$row["notnull"],
|
||||||
"privileges" => array("select" => 1, "insert" => 1, "update" => 1),
|
"privileges" => array("select" => 1, "insert" => 1, "update" => 1, "where" => 1, "order" => 1),
|
||||||
"primary" => $row["pk"],
|
"primary" => $row["pk"],
|
||||||
);
|
);
|
||||||
if ($row["pk"]) {
|
if ($row["pk"]) {
|
||||||
|
|||||||
@@ -147,16 +147,14 @@ if ($jush == "sql") { //! use insertUpdate() in all drivers
|
|||||||
}
|
}
|
||||||
parse_str($_COOKIE["adminer_export"], $row);
|
parse_str($_COOKIE["adminer_export"], $row);
|
||||||
if (!$row) {
|
if (!$row) {
|
||||||
$row = array("output" => "text", "format" => "sql", "db_style" => (DB != "" ? "" : "CREATE"), "table_style" => "DROP+CREATE", "data_style" => "INSERT");
|
$row = array("output" => "file", "format" => "sql", "db_style" => (DB != "" ? "" : "CREATE"), "table_style" => "DROP+CREATE", "data_style" => "INSERT");
|
||||||
}
|
}
|
||||||
if (!isset($row["events"])) { // backwards compatibility
|
if (!isset($row["events"])) { // backwards compatibility
|
||||||
$row["routines"] = $row["events"] = ($_GET["dump"] == "");
|
$row["routines"] = $row["events"] = ($_GET["dump"] == "");
|
||||||
$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('Format') . "<td>" . html_select("format", $adminer->dumpFormat(), $row["format"], false) . "\n"; // false = radio
|
||||||
|
|
||||||
echo "<tr><th>" . lang('Format') . "<td>" . html_select("format", $adminer->dumpFormat(), $row["format"], 0) . "\n"; // 0 - radio
|
|
||||||
|
|
||||||
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("routine") ? checkbox("routines", 1, $row["routines"], lang('Routines')) : "")
|
. (support("routine") ? checkbox("routines", 1, $row["routines"], lang('Routines')) : "")
|
||||||
@@ -169,6 +167,9 @@ echo "<tr><th>" . lang('Tables') . "<td>" . html_select('table_style', $table_st
|
|||||||
;
|
;
|
||||||
|
|
||||||
echo "<tr><th>" . lang('Data') . "<td>" . html_select('data_style', $data_style, $row["data_style"]);
|
echo "<tr><th>" . lang('Data') . "<td>" . html_select('data_style', $data_style, $row["data_style"]);
|
||||||
|
|
||||||
|
echo "<tr><th>" . lang('Output') . "<td>" . html_select("output", $adminer->dumpOutput(), $row["output"], false) . "\n"; // false = radio
|
||||||
|
|
||||||
?>
|
?>
|
||||||
</table>
|
</table>
|
||||||
<p><input type="submit" value="<?php echo lang('Export'); ?>">
|
<p><input type="submit" value="<?php echo lang('Export'); ?>">
|
||||||
|
|||||||
13
adminer/elastic.php
Normal file
13
adminer/elastic.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
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/elastic5.php";
|
||||||
|
return new AdminerPlugin([
|
||||||
|
// 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";
|
||||||
@@ -6,13 +6,13 @@ if ($_GET["file"] == "favicon.ico") {
|
|||||||
echo lzw_decompress(compile_file('../adminer/static/favicon.ico', 'lzw_compress'));
|
echo lzw_decompress(compile_file('../adminer/static/favicon.ico', 'lzw_compress'));
|
||||||
} elseif ($_GET["file"] == "default.css") {
|
} elseif ($_GET["file"] == "default.css") {
|
||||||
header("Content-Type: text/css; charset=utf-8");
|
header("Content-Type: text/css; charset=utf-8");
|
||||||
echo lzw_decompress(compile_file('../adminer/static/default.css;../externals/jush/jush.css', 'minify_css'));
|
echo lzw_decompress(compile_file('../adminer/static/default.css;../vendor/vrana/jush/jush.css', 'minify_css'));
|
||||||
} elseif ($_GET["file"] == "functions.js") {
|
} elseif ($_GET["file"] == "functions.js") {
|
||||||
header("Content-Type: text/javascript; charset=utf-8");
|
header("Content-Type: text/javascript; charset=utf-8");
|
||||||
echo lzw_decompress(compile_file('../adminer/static/functions.js;static/editing.js', 'minify_js'));
|
echo lzw_decompress(compile_file('../adminer/static/functions.js;static/editing.js', 'minify_js'));
|
||||||
} elseif ($_GET["file"] == "jush.js") {
|
} elseif ($_GET["file"] == "jush.js") {
|
||||||
header("Content-Type: text/javascript; charset=utf-8");
|
header("Content-Type: text/javascript; charset=utf-8");
|
||||||
echo lzw_decompress(compile_file('../externals/jush/modules/jush.js;../externals/jush/modules/jush-textarea.js;../externals/jush/modules/jush-txt.js;../externals/jush/modules/jush-js.js;../externals/jush/modules/jush-sql.js;../externals/jush/modules/jush-pgsql.js;../externals/jush/modules/jush-sqlite.js;../externals/jush/modules/jush-mssql.js;../externals/jush/modules/jush-oracle.js;../externals/jush/modules/jush-simpledb.js', 'minify_js'));
|
echo lzw_decompress(compile_file('../vendor/vrana/jush/modules/jush.js;../vendor/vrana/jush/modules/jush-textarea.js;../vendor/vrana/jush/modules/jush-txt.js;../vendor/vrana/jush/modules/jush-js.js;../vendor/vrana/jush/modules/jush-sql.js;../vendor/vrana/jush/modules/jush-pgsql.js;../vendor/vrana/jush/modules/jush-sqlite.js;../vendor/vrana/jush/modules/jush-mssql.js;../vendor/vrana/jush/modules/jush-oracle.js;../vendor/vrana/jush/modules/jush-simpledb.js', 'minify_js'));
|
||||||
} else {
|
} else {
|
||||||
header("Content-Type: image/gif");
|
header("Content-Type: image/gif");
|
||||||
switch ($_GET["file"]) {
|
switch ($_GET["file"]) {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ class Adminer {
|
|||||||
*/
|
*/
|
||||||
function head() {
|
function head() {
|
||||||
?>
|
?>
|
||||||
<link rel="stylesheet" type="text/css" href="../externals/jush/jush.css">
|
<link rel="stylesheet" type="text/css" href="../vendor/vrana/jush/jush.css">
|
||||||
<?php
|
<?php
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -231,17 +231,25 @@ class Adminer {
|
|||||||
*/
|
*/
|
||||||
function selectQuery($query, $start, $failed = false) {
|
function selectQuery($query, $start, $failed = false) {
|
||||||
global $jush, $driver;
|
global $jush, $driver;
|
||||||
$return = "</p>\n"; // required for IE9 inline edit
|
|
||||||
|
$supportSql = support("sql");
|
||||||
|
|
||||||
|
$result = "<p>"
|
||||||
|
. "<code class='jush-$jush'>" . h(str_replace("\n", " ", $query)) . "</code> "
|
||||||
|
. "<span class='time'>(" . format_time($start) . ")</span>"
|
||||||
|
. ($supportSql ? " <a href='" . h(ME) . "sql=" . urlencode($query) . "'>" . lang('Edit') . "</a>" : "");
|
||||||
|
|
||||||
if (!$failed && ($warnings = $driver->warnings())) {
|
if (!$failed && ($warnings = $driver->warnings())) {
|
||||||
$id = "warnings";
|
$id = "warnings";
|
||||||
$return = ", <a href='#$id'>" . lang('Warnings') . "</a>" . script("qsl('a').onclick = partial(toggle, '$id');", "")
|
$result = ($supportSql ? "," : "")
|
||||||
. "$return<div id='$id' class='hidden'>\n$warnings</div>\n"
|
. " <a href='#$id'>" . lang('Warnings') . "</a>" . script("qsl('a').onclick = partial(toggle, '$id');", "")
|
||||||
;
|
. "</p>\n"
|
||||||
|
. "<div id='$id' class='hidden'>\n$warnings</div>\n";
|
||||||
|
} else {
|
||||||
|
$result .= "</p>\n";
|
||||||
}
|
}
|
||||||
return "<p><code class='jush-$jush'>" . h(str_replace("\n", " ", $query)) . "</code> <span class='time'>(" . format_time($start) . ")</span>"
|
|
||||||
. (support("sql") ? " <a href='" . h(ME) . "sql=" . urlencode($query) . "'>" . lang('Edit') . "</a>" : "")
|
return $result;
|
||||||
. $return
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Query printed in SQL command before execution
|
/** Query printed in SQL command before execution
|
||||||
@@ -293,7 +301,7 @@ class Adminer {
|
|||||||
if (preg_match('~json~', $field["type"])) {
|
if (preg_match('~json~', $field["type"])) {
|
||||||
$return = "<code class='jush-js'>$return</code>";
|
$return = "<code class='jush-js'>$return</code>";
|
||||||
}
|
}
|
||||||
return ($link ? "<a href='" . h($link) . "'" . (is_url($link) ? target_blank() : "") . ">$return</a>" : $return);
|
return ($link ? "<a href='" . h($link) . "'" . (is_web_url($link) ? target_blank() : "") . ">$return</a>" : $return);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Value conversion used in select and edit
|
/** Value conversion used in select and edit
|
||||||
@@ -561,7 +569,8 @@ class Adminer {
|
|||||||
// find anywhere
|
// find anywhere
|
||||||
$cols = array();
|
$cols = array();
|
||||||
foreach ($fields as $name => $field) {
|
foreach ($fields as $name => $field) {
|
||||||
if ((preg_match('~^[-\d.' . (preg_match('~IN$~', $val["op"]) ? ',' : '') . ']+$~', $val["val"]) || !preg_match('~' . number_type() . '|bit~', $field["type"]))
|
if (isset($field["privileges"]["where"])
|
||||||
|
&& (preg_match('~^[-\d.' . (preg_match('~IN$~', $val["op"]) ? ',' : '') . ']+$~', $val["val"]) || !preg_match('~' . number_type() . '|bit~', $field["type"]))
|
||||||
&& (!preg_match("~[\x80-\xFF]~", $val["val"]) || preg_match('~char|text|enum|set~', $field["type"]))
|
&& (!preg_match("~[\x80-\xFF]~", $val["val"]) || preg_match('~char|text|enum|set~', $field["type"]))
|
||||||
&& (!preg_match('~date|timestamp~', $field["type"]) || preg_match('~^\d+-\d+-\d+~', $val["val"]))
|
&& (!preg_match('~date|timestamp~', $field["type"]) || preg_match('~^\d+-\d+-\d+~', $val["val"]))
|
||||||
) {
|
) {
|
||||||
@@ -754,10 +763,11 @@ class Adminer {
|
|||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
function dumpOutput() {
|
function dumpOutput() {
|
||||||
$return = array('text' => lang('open'), 'file' => lang('save'));
|
$return = array('file' => lang('save'), 'text' => lang('open'));
|
||||||
if (function_exists('gzencode')) {
|
if (function_exists('gzencode')) {
|
||||||
$return['gz'] = 'gzip';
|
$return['gz'] = 'gzip';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -831,6 +841,7 @@ class Adminer {
|
|||||||
$insert = "";
|
$insert = "";
|
||||||
$buffer = "";
|
$buffer = "";
|
||||||
$keys = array();
|
$keys = array();
|
||||||
|
$generatedKeys = array();
|
||||||
$suffix = "";
|
$suffix = "";
|
||||||
$fetch_function = ($table != '' ? 'fetch_assoc' : 'fetch_row');
|
$fetch_function = ($table != '' ? 'fetch_assoc' : 'fetch_row');
|
||||||
while ($row = $result->$fetch_function()) {
|
while ($row = $result->$fetch_function()) {
|
||||||
@@ -838,6 +849,10 @@ class Adminer {
|
|||||||
$values = array();
|
$values = array();
|
||||||
foreach ($row as $val) {
|
foreach ($row as $val) {
|
||||||
$field = $result->fetch_field();
|
$field = $result->fetch_field();
|
||||||
|
if (!empty($fields[$field->name]['generated'])) {
|
||||||
|
$generatedKeys[$field->name] = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$keys[] = $field->name;
|
$keys[] = $field->name;
|
||||||
$key = idf_escape($field->name);
|
$key = idf_escape($field->name);
|
||||||
$values[] = "$key = VALUES($key)";
|
$values[] = "$key = VALUES($key)";
|
||||||
@@ -855,6 +870,10 @@ class Adminer {
|
|||||||
$insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('idf_escape', $keys)) . ") VALUES";
|
$insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('idf_escape', $keys)) . ") VALUES";
|
||||||
}
|
}
|
||||||
foreach ($row as $key => $val) {
|
foreach ($row as $key => $val) {
|
||||||
|
if (isset($generatedKeys[$key])) {
|
||||||
|
unset($row[$key]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$field = $fields[$key];
|
$field = $fields[$key];
|
||||||
$row[$key] = ($val !== null
|
$row[$key] = ($val !== null
|
||||||
? unconvert_field($field, preg_match(number_type(), $field["type"]) && !preg_match('~\[~', $field["full_type"]) && is_numeric($val) ? $val : q(($val === false ? 0 : $val)))
|
? unconvert_field($field, preg_match(number_type(), $field["type"]) && !preg_match('~\[~', $field["full_type"]) && is_numeric($val) ? $val : q(($val === false ? 0 : $val)))
|
||||||
@@ -934,8 +953,11 @@ class Adminer {
|
|||||||
global $VERSION, $jush, $drivers, $connection;
|
global $VERSION, $jush, $drivers, $connection;
|
||||||
?>
|
?>
|
||||||
<h1>
|
<h1>
|
||||||
<?php echo $this->name(); ?> <span class="version"><?php echo $VERSION; ?></span>
|
<?php echo $this->name(); ?>
|
||||||
<a href="https://www.adminer.org/#download"<?php echo target_blank(); ?> id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?></a>
|
<?php if ($missing != "auth"): ?>
|
||||||
|
<span class="version"><?php echo $VERSION; ?></span>
|
||||||
|
<a href="https://www.adminer.org/#download"<?php echo target_blank(); ?> id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?></a>
|
||||||
|
<?php endif; ?>
|
||||||
</h1>
|
</h1>
|
||||||
<?php
|
<?php
|
||||||
if ($missing == "auth") {
|
if ($missing == "auth") {
|
||||||
@@ -961,12 +983,12 @@ class Adminer {
|
|||||||
$connection->select_db(DB);
|
$connection->select_db(DB);
|
||||||
$tables = table_status('', true);
|
$tables = table_status('', true);
|
||||||
}
|
}
|
||||||
echo script_src("../externals/jush/modules/jush.js");
|
echo script_src("../vendor/vrana/jush/modules/jush.js");
|
||||||
echo script_src("../externals/jush/modules/jush-textarea.js");
|
echo script_src("../vendor/vrana/jush/modules/jush-textarea.js");
|
||||||
echo script_src("../externals/jush/modules/jush-txt.js");
|
echo script_src("../vendor/vrana/jush/modules/jush-txt.js");
|
||||||
echo script_src("../externals/jush/modules/jush-js.js");
|
echo script_src("../vendor/vrana/jush/modules/jush-js.js");
|
||||||
if (support("sql")) {
|
if (support("sql")) {
|
||||||
echo script_src("../externals/jush/modules/jush-$jush.js");
|
echo script_src("../vendor/vrana/jush/modules/jush-$jush.js");
|
||||||
?>
|
?>
|
||||||
<script<?php echo nonce(); ?>>
|
<script<?php echo nonce(); ?>>
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
@@ -15,6 +15,71 @@ if ($_COOKIE["adminer_permanent"]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validate_server_input() {
|
||||||
|
if (SERVER == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = parse_url(SERVER);
|
||||||
|
if (!$parts) {
|
||||||
|
auth_error(lang('Invalid server or credentials.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check proper URL parts.
|
||||||
|
if (isset($parts['user']) || isset($parts['pass']) || isset($parts['query']) || isset($parts['fragment'])) {
|
||||||
|
auth_error(lang('Invalid server or credentials.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow only HTTP/S scheme.
|
||||||
|
if (isset($parts['scheme']) && !preg_match('~^(https?)$~i', $parts['scheme'])) {
|
||||||
|
auth_error(lang('Invalid server or credentials.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that "localhost" and IP address without a scheme is parsed as a path.
|
||||||
|
$hostPath = (isset($parts['host']) ? $parts['host'] : '') . (isset($parts['path']) ? $parts['path'] : '');
|
||||||
|
|
||||||
|
// Validate host.
|
||||||
|
if (!is_server_host_valid($hostPath)) {
|
||||||
|
auth_error(lang('Invalid server or credentials.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check privileged ports.
|
||||||
|
if (isset($parts['port']) && ($parts['port'] < 1024 || $parts['port'] > 65535)) {
|
||||||
|
auth_error(lang('Connecting to privileged ports is not allowed.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('is_server_host_valid')) {
|
||||||
|
/**
|
||||||
|
* @param string $hostPath
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function is_server_host_valid($hostPath)
|
||||||
|
{
|
||||||
|
return strpos($hostPath, '/') === false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $server
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @param string $defaultServer
|
||||||
|
* @param int|null $defaultPort
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function build_http_url($server, $username, $password, $defaultServer, $defaultPort = null) {
|
||||||
|
if (!preg_match('~^(https?://)?([^:]*)(:\d+)?$~', rtrim($server, '/'), $matches)) {
|
||||||
|
$this->error = lang('Invalid server or credentials.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($matches[1] ?: "http://") .
|
||||||
|
($username !== "" || $password !== "" ? "$username:$password@" : "") .
|
||||||
|
($matches[2] !== "" ? $matches[2] : $defaultServer) .
|
||||||
|
(isset($matches[3]) ? $matches[3] : ($defaultPort ? ":$defaultPort" : ""));
|
||||||
|
}
|
||||||
|
|
||||||
function add_invalid_login() {
|
function add_invalid_login() {
|
||||||
global $adminer;
|
global $adminer;
|
||||||
$fp = file_open_lock(get_temp_dir() . "/adminer.invalid");
|
$fp = file_open_lock(get_temp_dir() . "/adminer.invalid");
|
||||||
@@ -52,7 +117,7 @@ $auth = $_POST["auth"];
|
|||||||
if ($auth) {
|
if ($auth) {
|
||||||
session_regenerate_id(); // defense against session fixation
|
session_regenerate_id(); // defense against session fixation
|
||||||
$vendor = $auth["driver"];
|
$vendor = $auth["driver"];
|
||||||
$server = $auth["server"];
|
$server = trim($auth["server"]);
|
||||||
$username = $auth["username"];
|
$username = $auth["username"];
|
||||||
$password = (string) $auth["password"];
|
$password = (string) $auth["password"];
|
||||||
$db = $auth["db"];
|
$db = $auth["db"];
|
||||||
@@ -155,18 +220,16 @@ if (isset($_GET["username"]) && !class_exists("Min_DB")) {
|
|||||||
stop_session(true);
|
stop_session(true);
|
||||||
|
|
||||||
if (isset($_GET["username"]) && is_string(get_password())) {
|
if (isset($_GET["username"]) && is_string(get_password())) {
|
||||||
list($host, $port) = explode(":", SERVER, 2);
|
validate_server_input();
|
||||||
if (preg_match('~^\s*([-+]?\d+)~', $port, $match) && ($match[1] < 1024 || $match[1] > 65535)) { // is_numeric('80#') would still connect to port 80
|
|
||||||
auth_error(lang('Connecting to privileged ports is not allowed.'));
|
|
||||||
}
|
|
||||||
check_invalid_login();
|
check_invalid_login();
|
||||||
|
|
||||||
$connection = connect();
|
$connection = connect();
|
||||||
$driver = new Min_Driver($connection);
|
$driver = new Min_Driver($connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
$login = null;
|
$login = null;
|
||||||
if (!is_object($connection) || ($login = $adminer->login($_GET["username"], get_password())) !== true) {
|
if (!is_object($connection) || ($login = $adminer->login($_GET["username"], get_password())) !== true) {
|
||||||
$error = (is_string($connection) ? h($connection) : (is_string($login) ? $login : lang('Invalid credentials.')));
|
$error = (is_string($connection) ? h($connection) : (is_string($login) ? $login : lang('Invalid server or credentials.')));
|
||||||
auth_error($error . (preg_match('~^ | $~', get_password()) ? '<br>' . lang('There is a space in the input password which might be the cause.') : ''));
|
auth_error($error . (preg_match('~^ | $~', get_password()) ? '<br>' . lang('There is a space in the input password which might be the cause.') : ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ include "../adminer/drivers/pgsql.inc.php";
|
|||||||
include "../adminer/drivers/oracle.inc.php";
|
include "../adminer/drivers/oracle.inc.php";
|
||||||
include "../adminer/drivers/mssql.inc.php";
|
include "../adminer/drivers/mssql.inc.php";
|
||||||
include "../adminer/drivers/mongo.inc.php";
|
include "../adminer/drivers/mongo.inc.php";
|
||||||
include "../adminer/drivers/elastic.inc.php";
|
|
||||||
include "./include/adminer.inc.php";
|
include "./include/adminer.inc.php";
|
||||||
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
|
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
|
||||||
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver
|
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver
|
||||||
|
|||||||
@@ -142,6 +142,14 @@ function add_driver($id, $name) {
|
|||||||
return $idf;
|
return $idf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Convert operator so it can be used in search
|
||||||
|
* @param string $operator
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function convertOperator($operator) {
|
||||||
|
return $operator;
|
||||||
|
}
|
||||||
|
|
||||||
/** Convert value returned by database to actual value
|
/** Convert value returned by database to actual value
|
||||||
* @param string
|
* @param string
|
||||||
* @param array
|
* @param array
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ function select($result, $connection2 = null, $orgtables = array(), $limit = 0)
|
|||||||
$link .= "&where" . urlencode("[" . bracket_escape($col) . "]") . "=" . urlencode($row[$j]);
|
$link .= "&where" . urlencode("[" . bracket_escape($col) . "]") . "=" . urlencode($row[$j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elseif (is_url($val)) {
|
} elseif (is_web_url($val)) {
|
||||||
$link = $val;
|
$link = $val;
|
||||||
}
|
}
|
||||||
if ($val === null) {
|
if ($val === null) {
|
||||||
@@ -86,7 +86,7 @@ function select($result, $connection2 = null, $orgtables = array(), $limit = 0)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($link) {
|
if ($link) {
|
||||||
$val = "<a href='" . h($link) . "'" . (is_url($link) ? target_blank() : '') . ">$val</a>";
|
$val = "<a href='" . h($link) . "'" . (is_web_url($link) ? target_blank() : '') . ">$val</a>";
|
||||||
}
|
}
|
||||||
echo "<td>$val";
|
echo "<td>$val";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ function optionlist($options, $selected = null, $use_keys = false) {
|
|||||||
* @param string
|
* @param string
|
||||||
* @param array
|
* @param array
|
||||||
* @param string
|
* @param string
|
||||||
* @param string true for no onchange, false for radio
|
* @param string|bool true for no onchange, false for radio
|
||||||
* @param string
|
* @param string
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@@ -1077,7 +1077,7 @@ function fields_from_edit() {
|
|||||||
$name = bracket_escape($key, 1); // 1 - back
|
$name = bracket_escape($key, 1); // 1 - back
|
||||||
$return[$name] = array(
|
$return[$name] = array(
|
||||||
"field" => $name,
|
"field" => $name,
|
||||||
"privileges" => array("insert" => 1, "update" => 1),
|
"privileges" => array("insert" => 1, "update" => 1, "where" => 1, "order" => 1),
|
||||||
"null" => 1,
|
"null" => 1,
|
||||||
"auto_increment" => ($key == $driver->primary),
|
"auto_increment" => ($key == $driver->primary),
|
||||||
);
|
);
|
||||||
@@ -1250,7 +1250,7 @@ function select_value($val, $link, $field, $text_length) {
|
|||||||
if (is_mail($val)) {
|
if (is_mail($val)) {
|
||||||
$link = "mailto:$val";
|
$link = "mailto:$val";
|
||||||
}
|
}
|
||||||
if (is_url($val)) {
|
if (is_web_url($val)) {
|
||||||
$link = $val; // IE 11 and all modern browsers hide referrer
|
$link = $val; // IE 11 and all modern browsers hide referrer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1271,20 +1271,32 @@ function select_value($val, $link, $field, $text_length) {
|
|||||||
* @param string
|
* @param string
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function is_mail($email) {
|
function is_mail($value) {
|
||||||
$atom = '[-a-z0-9!#$%&\'*+/=?^_`{|}~]'; // characters of local-name
|
return is_string($value) && filter_var($value, FILTER_VALIDATE_EMAIL);
|
||||||
$domain = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])'; // one domain component
|
|
||||||
$pattern = "$atom+(\\.$atom+)*@($domain?\\.)+$domain";
|
|
||||||
return is_string($email) && preg_match("(^$pattern(,\\s*$pattern)*\$)i", $email);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check whether the string is URL address
|
/** Check whether the string is web URL address
|
||||||
* @param string
|
* @param string
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function is_url($string) {
|
function is_web_url($value) {
|
||||||
$domain = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])'; // one domain component //! IDN
|
if (!is_string($value) || !preg_match('~^https?://~i', $value)) {
|
||||||
return preg_match("~^(https?)://($domain?\\.)+$domain(:\\d+)?(/.*)?(\\?.*)?(#.*)?\$~i", $string); //! restrict path, query and fragment characters
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$components = parse_url($value);
|
||||||
|
if (!$components) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode URL path. If path was encoded already, it will be encoded twice, but we are OK with that.
|
||||||
|
$encodedParts = array_map('urlencode', explode('/', $components['path']));
|
||||||
|
$url = str_replace($components['path'], implode('/', $encodedParts), $value);
|
||||||
|
|
||||||
|
parse_str($components['query'], $params);
|
||||||
|
$url = str_replace($components['query'], http_build_query($params), $url);
|
||||||
|
|
||||||
|
return (bool)filter_var($url, FILTER_VALIDATE_URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check if field should be shortened
|
/** Check if field should be shortened
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
<?php
|
<?php
|
||||||
$VERSION = "4.8.2";
|
$VERSION = "4.9";
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'تسجيل الدخول',
|
'Login' => 'تسجيل الدخول',
|
||||||
'Logout successful.' => 'تم تسجيل الخروج بنجاح.',
|
'Logout successful.' => 'تم تسجيل الخروج بنجاح.',
|
||||||
'Invalid credentials.' => 'بيانات الدخول غير صالحة.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'الخادم',
|
'Server' => 'الخادم',
|
||||||
'Username' => 'اسم المستخدم',
|
'Username' => 'اسم المستخدم',
|
||||||
'Password' => 'كلمة المرور',
|
'Password' => 'كلمة المرور',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $translations = array(
|
|||||||
'Logout' => 'Изход',
|
'Logout' => 'Изход',
|
||||||
'Logged as: %s' => 'Текущ потребител: %s',
|
'Logged as: %s' => 'Текущ потребител: %s',
|
||||||
'Logout successful.' => 'Излизането е успешно.',
|
'Logout successful.' => 'Излизането е успешно.',
|
||||||
'Invalid credentials.' => 'Невалидни потребителски данни.',
|
'Invalid server or credentials.' => null,
|
||||||
'Too many unsuccessful logins, try again in %d minute(s).' => array('Прекалено много неуспешни опити за вход, опитайте пак след %d минута.', 'Прекалено много неуспешни опити за вход, опитайте пак след %d минути.'),
|
'Too many unsuccessful logins, try again in %d minute(s).' => array('Прекалено много неуспешни опити за вход, опитайте пак след %d минута.', 'Прекалено много неуспешни опити за вход, опитайте пак след %d минути.'),
|
||||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Главната парола вече е невалидна. <a href="https://www.adminer.org/en/extension/"%s>Изберете</a> %s метод, за да я направите постоянна.',
|
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Главната парола вече е невалидна. <a href="https://www.adminer.org/en/extension/"%s>Изберете</a> %s метод, за да я направите постоянна.',
|
||||||
'Language' => 'Език',
|
'Language' => 'Език',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'লগইন',
|
'Login' => 'লগইন',
|
||||||
'Logout successful.' => 'সফলভাবে লগআউট হয়েছে।',
|
'Logout successful.' => 'সফলভাবে লগআউট হয়েছে।',
|
||||||
'Invalid credentials.' => 'ভুল পাসওয়ার্ড।',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'সার্ভার',
|
'Server' => 'সার্ভার',
|
||||||
'Username' => 'ইউজারের নাম',
|
'Username' => 'ইউজারের নাম',
|
||||||
'Password' => 'পাসওয়ার্ড',
|
'Password' => 'পাসওয়ার্ড',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $translations = array(
|
|||||||
'Logout' => 'Odjava',
|
'Logout' => 'Odjava',
|
||||||
'Logged as: %s' => 'Prijavi se kao: %s',
|
'Logged as: %s' => 'Prijavi se kao: %s',
|
||||||
'Logout successful.' => 'Uspešna odjava.',
|
'Logout successful.' => 'Uspešna odjava.',
|
||||||
'Invalid credentials.' => 'Nevažeće dozvole.',
|
'Invalid server or credentials.' => null,
|
||||||
'Language' => 'Jezik',
|
'Language' => 'Jezik',
|
||||||
'Invalid CSRF token. Send the form again.' => 'Nevažeći CSRF kod. Proslijedite ponovo formu.',
|
'Invalid CSRF token. Send the form again.' => 'Nevažeći CSRF kod. Proslijedite ponovo formu.',
|
||||||
'No extension' => 'Bez dodataka',
|
'No extension' => 'Bez dodataka',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Inicia la sessió',
|
'Login' => 'Inicia la sessió',
|
||||||
'Logout successful.' => 'Desconnexió correcta.',
|
'Logout successful.' => 'Desconnexió correcta.',
|
||||||
'Invalid credentials.' => 'Credencials invàlides.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'Servidor',
|
'Server' => 'Servidor',
|
||||||
'Username' => 'Nom d\'usuari',
|
'Username' => 'Nom d\'usuari',
|
||||||
'Password' => 'Contrasenya',
|
'Password' => 'Contrasenya',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ $translations = array(
|
|||||||
'Logged as: %s' => 'Přihlášen jako: %s',
|
'Logged as: %s' => 'Přihlášen jako: %s',
|
||||||
'Logout successful.' => 'Odhlášení proběhlo v pořádku.',
|
'Logout successful.' => 'Odhlášení proběhlo v pořádku.',
|
||||||
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Díky za použití Admineru, <a href="https://www.adminer.org/cs/donation/">přispějte</a> na vývoj.',
|
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Díky za použití Admineru, <a href="https://www.adminer.org/cs/donation/">přispějte</a> na vývoj.',
|
||||||
'Invalid credentials.' => 'Neplatné přihlašovací údaje.',
|
'Invalid server or credentials.' => 'Neplatný server nebo přihlašovací údaje.',
|
||||||
'There is a space in the input password which might be the cause.' => 'Problém může být, že je v zadaném hesle mezera.',
|
'There is a space in the input password which might be the cause.' => 'Problém může být, že je v zadaném hesle mezera.',
|
||||||
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer nepodporuje přístup k databázi bez hesla, <a href="https://www.adminer.org/cs/password/"%s>více informací</a>.',
|
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer nepodporuje přístup k databázi bez hesla, <a href="https://www.adminer.org/cs/password/"%s>více informací</a>.',
|
||||||
'Database does not support password.' => 'Databáze nepodporuje heslo.',
|
'Database does not support password.' => 'Databáze nepodporuje heslo.',
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ $translations = array(
|
|||||||
'Logout' => 'Log ud',
|
'Logout' => 'Log ud',
|
||||||
'Logged as: %s' => 'Logget ind som: %s',
|
'Logged as: %s' => 'Logget ind som: %s',
|
||||||
'Logout successful.' => 'Log af vellykket.',
|
'Logout successful.' => 'Log af vellykket.',
|
||||||
'Invalid credentials.' => 'Ugyldige log ind oplysninger.',
|
'Invalid server or credentials.' => null,
|
||||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-kodeordet er udløbet. <a href="https://www.adminer.org/en/extension/"%s>Implementer</a> en metode for %s for at gøre det permanent.',
|
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-kodeordet er udløbet. <a href="https://www.adminer.org/en/extension/"%s>Implementer</a> en metode for %s for at gøre det permanent.',
|
||||||
'Language' => 'Sprog',
|
'Language' => 'Sprog',
|
||||||
'Invalid CSRF token. Send the form again.' => 'Ugyldigt CSRF-token - Genindsend formen.',
|
'Invalid CSRF token. Send the form again.' => 'Ugyldigt CSRF-token - Genindsend formen.',
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ $translations = array(
|
|||||||
'Login' => 'Login',
|
'Login' => 'Login',
|
||||||
'Logout successful.' => 'Abmeldung erfolgreich.',
|
'Logout successful.' => 'Abmeldung erfolgreich.',
|
||||||
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Danke, dass Sie Adminer genutzt haben. <a href="https://www.adminer.org/de/donation/">Spenden willkommen!</a>',
|
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Danke, dass Sie Adminer genutzt haben. <a href="https://www.adminer.org/de/donation/">Spenden willkommen!</a>',
|
||||||
'Invalid credentials.' => 'Ungültige Anmelde-Informationen.',
|
'Invalid server or credentials.' => 'Ungültige Server oder Anmelde-Informationen.',
|
||||||
'Server' => 'Server',
|
'Server' => 'Server',
|
||||||
'Username' => 'Benutzer',
|
'Username' => 'Benutzer',
|
||||||
'Password' => 'Passwort',
|
'Password' => 'Passwort',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $translations = array(
|
|||||||
'Logout' => 'Αποσύνδεση',
|
'Logout' => 'Αποσύνδεση',
|
||||||
'Logged as: %s' => 'Συνδεθήκατε ως %s',
|
'Logged as: %s' => 'Συνδεθήκατε ως %s',
|
||||||
'Logout successful.' => 'Αποσυνδεθήκατε με επιτυχία.',
|
'Logout successful.' => 'Αποσυνδεθήκατε με επιτυχία.',
|
||||||
'Invalid credentials.' => 'Εσφαλμένα Διαπιστευτήρια.',
|
'Invalid server or credentials.' => null,
|
||||||
'Too many unsuccessful logins, try again in %d minute(s).' => array('Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτό.', 'Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτά.'),
|
'Too many unsuccessful logins, try again in %d minute(s).' => array('Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτό.', 'Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτά.'),
|
||||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Έληξε ο Κύριος Κωδικός. <a href="https://www.adminer.org/en/extension/"%s>Ενεργοποιήστε</a> τη μέθοδο %s για να τον κάνετε μόνιμο.',
|
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Έληξε ο Κύριος Κωδικός. <a href="https://www.adminer.org/en/extension/"%s>Ενεργοποιήστε</a> τη μέθοδο %s για να τον κάνετε μόνιμο.',
|
||||||
'Language' => 'Γλώσσα',
|
'Language' => 'Γλώσσα',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Login',
|
'Login' => 'Login',
|
||||||
'Logout successful.' => 'Sesión finalizada con éxito.',
|
'Logout successful.' => 'Sesión finalizada con éxito.',
|
||||||
'Invalid credentials.' => 'Usuario y/o clave de acceso incorrecta.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'Servidor',
|
'Server' => 'Servidor',
|
||||||
'Username' => 'Usuario',
|
'Username' => 'Usuario',
|
||||||
'Password' => 'Contraseña',
|
'Password' => 'Contraseña',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Logi sisse',
|
'Login' => 'Logi sisse',
|
||||||
'Logout successful.' => 'Väljalogimine õnnestus.',
|
'Logout successful.' => 'Väljalogimine õnnestus.',
|
||||||
'Invalid credentials.' => 'Ebakorrektsed andmed.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'Server',
|
'Server' => 'Server',
|
||||||
'Username' => 'Kasutajanimi',
|
'Username' => 'Kasutajanimi',
|
||||||
'Password' => 'Parool',
|
'Password' => 'Parool',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $translations = array(
|
|||||||
'Logout' => 'خروج',
|
'Logout' => 'خروج',
|
||||||
'Logged as: %s' => 'ورود به عنوان: %s',
|
'Logged as: %s' => 'ورود به عنوان: %s',
|
||||||
'Logout successful.' => 'با موفقیت خارج شدید.',
|
'Logout successful.' => 'با موفقیت خارج شدید.',
|
||||||
'Invalid credentials.' => 'اعتبار سنجی نامعتبر.',
|
'Invalid server or credentials.' => null,
|
||||||
'Too many unsuccessful logins, try again in %d minute(s).' => array('ورودهای ناموفق بیش از حد، %d دقیقه دیگر تلاش نمایید.', 'ورودهای ناموفق بیش از حد، %d دقیقه دیگر تلاش نمایید.'),
|
'Too many unsuccessful logins, try again in %d minute(s).' => array('ورودهای ناموفق بیش از حد، %d دقیقه دیگر تلاش نمایید.', 'ورودهای ناموفق بیش از حد، %d دقیقه دیگر تلاش نمایید.'),
|
||||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'رمز اصلی باطل شده است. روش %s را <a href="https://www.adminer.org/en/extension/"%s>پیاده سازی</a> کرده تا آن را دائمی سازید.',
|
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'رمز اصلی باطل شده است. روش %s را <a href="https://www.adminer.org/en/extension/"%s>پیاده سازی</a> کرده تا آن را دائمی سازید.',
|
||||||
'Language' => 'زبان',
|
'Language' => 'زبان',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $translations = array(
|
|||||||
'Logout' => 'Kirjaudu ulos',
|
'Logout' => 'Kirjaudu ulos',
|
||||||
'Logged as: %s' => 'Olet kirjautunut käyttäjänä: %s',
|
'Logged as: %s' => 'Olet kirjautunut käyttäjänä: %s',
|
||||||
'Logout successful.' => 'Uloskirjautuminen onnistui.',
|
'Logout successful.' => 'Uloskirjautuminen onnistui.',
|
||||||
'Invalid credentials.' => 'Virheelliset kirjautumistiedot.',
|
'Invalid server or credentials.' => null,
|
||||||
'Too many unsuccessful logins, try again in %d minute(s).' => array('Liian monta epäonnistunutta sisäänkirjautumisyritystä, kokeile uudestaan %d minuutin kuluttua.', 'Liian monta epäonnistunutta sisäänkirjautumisyritystä, kokeile uudestaan %d minuutin kuluttua.'),
|
'Too many unsuccessful logins, try again in %d minute(s).' => array('Liian monta epäonnistunutta sisäänkirjautumisyritystä, kokeile uudestaan %d minuutin kuluttua.', 'Liian monta epäonnistunutta sisäänkirjautumisyritystä, kokeile uudestaan %d minuutin kuluttua.'),
|
||||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-salasana ei ole enää voimassa. <a href="https://www.adminer.org/en/extension/"%s>Toteuta</a> %s-metodi sen tekemiseksi pysyväksi.',
|
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-salasana ei ole enää voimassa. <a href="https://www.adminer.org/en/extension/"%s>Toteuta</a> %s-metodi sen tekemiseksi pysyväksi.',
|
||||||
'Language' => 'Kieli',
|
'Language' => 'Kieli',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Authentification',
|
'Login' => 'Authentification',
|
||||||
'Logout successful.' => 'Au revoir !',
|
'Logout successful.' => 'Au revoir !',
|
||||||
'Invalid credentials.' => 'Authentification échouée.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'Serveur',
|
'Server' => 'Serveur',
|
||||||
'Username' => 'Utilisateur',
|
'Username' => 'Utilisateur',
|
||||||
'Password' => 'Mot de passe',
|
'Password' => 'Mot de passe',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Conectar',
|
'Login' => 'Conectar',
|
||||||
'Logout successful.' => 'Pechouse a sesión con éxito.',
|
'Logout successful.' => 'Pechouse a sesión con éxito.',
|
||||||
'Invalid credentials.' => 'Credenciais (usuario e/ou contrasinal) inválidos.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'Servidor',
|
'Server' => 'Servidor',
|
||||||
'Username' => 'Usuario',
|
'Username' => 'Usuario',
|
||||||
'Password' => 'Contrasinal',
|
'Password' => 'Contrasinal',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'התחברות',
|
'Login' => 'התחברות',
|
||||||
'Logout successful.' => 'ההתחברות הצליחה',
|
'Logout successful.' => 'ההתחברות הצליחה',
|
||||||
'Invalid credentials.' => 'פרטי התחברות שגויים',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'שרת',
|
'Server' => 'שרת',
|
||||||
'Username' => 'שם משתמש',
|
'Username' => 'שם משתמש',
|
||||||
'Password' => 'סיסמה',
|
'Password' => 'סיסמה',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Belépés',
|
'Login' => 'Belépés',
|
||||||
'Logout successful.' => 'Sikeres kilépés.',
|
'Logout successful.' => 'Sikeres kilépés.',
|
||||||
'Invalid credentials.' => 'Érvénytelen adatok.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'Szerver',
|
'Server' => 'Szerver',
|
||||||
'Username' => 'Felhasználó',
|
'Username' => 'Felhasználó',
|
||||||
'Password' => 'Jelszó',
|
'Password' => 'Jelszó',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $translations = array(
|
|||||||
'Logout' => 'Keluar',
|
'Logout' => 'Keluar',
|
||||||
'Logged as: %s' => 'Masuk sebagai: %s',
|
'Logged as: %s' => 'Masuk sebagai: %s',
|
||||||
'Logout successful.' => 'Berhasil keluar.',
|
'Logout successful.' => 'Berhasil keluar.',
|
||||||
'Invalid credentials.' => 'Akses tidak sah.',
|
'Invalid server or credentials.' => null,
|
||||||
'Language' => 'Bahasa',
|
'Language' => 'Bahasa',
|
||||||
'Invalid CSRF token. Send the form again.' => 'Token CSRF tidak sah. Kirim ulang formulir.',
|
'Invalid CSRF token. Send the form again.' => 'Token CSRF tidak sah. Kirim ulang formulir.',
|
||||||
'No extension' => 'Ekstensi tidak ada',
|
'No extension' => 'Ekstensi tidak ada',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Autenticazione',
|
'Login' => 'Autenticazione',
|
||||||
'Logout successful.' => 'Uscita effettuata con successo.',
|
'Logout successful.' => 'Uscita effettuata con successo.',
|
||||||
'Invalid credentials.' => 'Credenziali non valide.',
|
'Invalid server or credentials.' => 'Server o credenziali non valide.',
|
||||||
'Server' => 'Server',
|
'Server' => 'Server',
|
||||||
'Username' => 'Utente',
|
'Username' => 'Utente',
|
||||||
'Password' => 'Password',
|
'Password' => 'Password',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'ログイン',
|
'Login' => 'ログイン',
|
||||||
'Logout successful.' => 'ログアウト',
|
'Logout successful.' => 'ログアウト',
|
||||||
'Invalid credentials.' => '不正なログイン',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'サーバ',
|
'Server' => 'サーバ',
|
||||||
'Username' => 'ユーザ名',
|
'Username' => 'ユーザ名',
|
||||||
'Password' => 'パスワード',
|
'Password' => 'パスワード',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'შესვლა',
|
'Login' => 'შესვლა',
|
||||||
'Logout successful.' => 'გამოხვედით სისტემიდან.',
|
'Logout successful.' => 'გამოხვედით სისტემიდან.',
|
||||||
'Invalid credentials.' => 'არასწორი მომხმარებელი ან პაროლი.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'სერვერი',
|
'Server' => 'სერვერი',
|
||||||
'Username' => 'მომხმარებელი',
|
'Username' => 'მომხმარებელი',
|
||||||
'Password' => 'პაროლი',
|
'Password' => 'პაროლი',
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ $translations = array(
|
|||||||
'Indexes have been altered.' => '색인을 변경했습니다.',
|
'Indexes have been altered.' => '색인을 변경했습니다.',
|
||||||
'Indexes' => '색인',
|
'Indexes' => '색인',
|
||||||
'Insert' => '삽입',
|
'Insert' => '삽입',
|
||||||
'Invalid credentials.' => '잘못된 로그인',
|
'Invalid server or credentials.' => null,
|
||||||
'Invalid CSRF token. Send the form again.' => '잘못된 CSRF 토큰입니다. 다시 보내주십시오.',
|
'Invalid CSRF token. Send the form again.' => '잘못된 CSRF 토큰입니다. 다시 보내주십시오.',
|
||||||
'Invalid database.' => '잘못된 데이터베이스입니다.',
|
'Invalid database.' => '잘못된 데이터베이스입니다.',
|
||||||
'Invalid schema.' => '잘못된 스키마입니다.',
|
'Invalid schema.' => '잘못된 스키마입니다.',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $translations = array(
|
|||||||
'Logout' => 'Atsijungti',
|
'Logout' => 'Atsijungti',
|
||||||
'Logged as: %s' => 'Prisijungęs kaip: %s',
|
'Logged as: %s' => 'Prisijungęs kaip: %s',
|
||||||
'Logout successful.' => 'Jūs atsijungėte nuo sistemos.',
|
'Logout successful.' => 'Jūs atsijungėte nuo sistemos.',
|
||||||
'Invalid credentials.' => 'Neteisingi prisijungimo duomenys.',
|
'Invalid server or credentials.' => null,
|
||||||
'Language' => 'Kalba',
|
'Language' => 'Kalba',
|
||||||
'Invalid CSRF token. Send the form again.' => 'Neteisingas CSRF tokenas. Bandykite siųsti formos duomenis dar kartą.',
|
'Invalid CSRF token. Send the form again.' => 'Neteisingas CSRF tokenas. Bandykite siųsti formos duomenis dar kartą.',
|
||||||
'No extension' => 'Nėra plėtiio',
|
'No extension' => 'Nėra plėtiio',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Ieiet',
|
'Login' => 'Ieiet',
|
||||||
'Logout successful.' => 'Jūs veiksmīgi izgājāt no sistēmas.',
|
'Logout successful.' => 'Jūs veiksmīgi izgājāt no sistēmas.',
|
||||||
'Invalid credentials.' => 'Nepareizs lietotāja vārds vai parole.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'Serveris',
|
'Server' => 'Serveris',
|
||||||
'Username' => 'Lietotājs',
|
'Username' => 'Lietotājs',
|
||||||
'Password' => 'Parole',
|
'Password' => 'Parole',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ $translations = array(
|
|||||||
'Logged as: %s' => 'Log masuk sebagai: %s',
|
'Logged as: %s' => 'Log masuk sebagai: %s',
|
||||||
'Logout successful.' => 'Log keluar berjaya.',
|
'Logout successful.' => 'Log keluar berjaya.',
|
||||||
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Terima kasih kerana menggunakan Adminer, pertimbangkan untuk <a href="https://www.adminer.org/en/donation/">menderma</a>.',
|
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Terima kasih kerana menggunakan Adminer, pertimbangkan untuk <a href="https://www.adminer.org/en/donation/">menderma</a>.',
|
||||||
'Invalid credentials.' => 'Akses tidak sah.',
|
'Invalid server or credentials.' => null,
|
||||||
'Too many unsuccessful logins, try again in %d minute(s).' => 'Terlalu banyak percubaan log masuk yang gagal, sila cuba lagi dalam masa %d minit.',
|
'Too many unsuccessful logins, try again in %d minute(s).' => 'Terlalu banyak percubaan log masuk yang gagal, sila cuba lagi dalam masa %d minit.',
|
||||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Kata laluan utama telah luput. <a href="https://www.adminer.org/en/extension/"%s>Gunakan</a> cara %s untuk mengekalkannya.',
|
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Kata laluan utama telah luput. <a href="https://www.adminer.org/en/extension/"%s>Gunakan</a> cara %s untuk mengekalkannya.',
|
||||||
'Language' => 'Bahasa',
|
'Language' => 'Bahasa',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Aanmelden',
|
'Login' => 'Aanmelden',
|
||||||
'Logout successful.' => 'Successvol afgemeld.',
|
'Logout successful.' => 'Successvol afgemeld.',
|
||||||
'Invalid credentials.' => 'Ongeldige gebruikersgegevens.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'Server',
|
'Server' => 'Server',
|
||||||
'Username' => 'Gebruikersnaam',
|
'Username' => 'Gebruikersnaam',
|
||||||
'Password' => 'Wachtwoord',
|
'Password' => 'Wachtwoord',
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ $translations = array(
|
|||||||
'Logout' => 'Logg ut',
|
'Logout' => 'Logg ut',
|
||||||
'Logged as: %s' => 'Logget inn som: %s',
|
'Logged as: %s' => 'Logget inn som: %s',
|
||||||
'Logout successful.' => 'Utlogging vellykket.',
|
'Logout successful.' => 'Utlogging vellykket.',
|
||||||
'Invalid credentials.' => 'Ugylding innloggingsinformasjon.',
|
'Invalid server or credentials.' => null,
|
||||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-passord er utløpt. <a href="https://www.adminer.org/en/extension/"%s>Implementer</a> en metode for %s for å gjøre det permanent.',
|
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-passord er utløpt. <a href="https://www.adminer.org/en/extension/"%s>Implementer</a> en metode for %s for å gjøre det permanent.',
|
||||||
'Language' => 'Språk',
|
'Language' => 'Språk',
|
||||||
'Invalid CSRF token. Send the form again.' => 'Ugylding CSRF-token - Send inn skjemaet igjen.',
|
'Invalid CSRF token. Send the form again.' => 'Ugylding CSRF-token - Send inn skjemaet igjen.',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ $translations = array(
|
|||||||
'Logged as: %s' => 'Zalogowany jako: %s',
|
'Logged as: %s' => 'Zalogowany jako: %s',
|
||||||
'Logout successful.' => 'Wylogowano pomyślnie.',
|
'Logout successful.' => 'Wylogowano pomyślnie.',
|
||||||
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Dziękujemy za używanie Adminera, rozważ proszę <a href="https://www.adminer.org/pl/donation/">dotację</a>.',
|
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Dziękujemy za używanie Adminera, rozważ proszę <a href="https://www.adminer.org/pl/donation/">dotację</a>.',
|
||||||
'Invalid credentials.' => 'Nieprawidłowe dane logowania.',
|
'Invalid server or credentials.' => 'Nieprawidłowy serwer lub dane logowania.',
|
||||||
'Too many unsuccessful logins, try again in %d minute(s).' => array('Za dużo nieudanych prób logowania, spróbuj ponownie za %d minutę.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minuty.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minut.'),
|
'Too many unsuccessful logins, try again in %d minute(s).' => array('Za dużo nieudanych prób logowania, spróbuj ponownie za %d minutę.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minuty.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minut.'),
|
||||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Ważność hasła głównego wygasła. <a href="https://www.adminer.org/pl/extension/"%s>Zaimplementuj</a> własną metodę %s, aby ustawić je na stałe.',
|
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Ważność hasła głównego wygasła. <a href="https://www.adminer.org/pl/extension/"%s>Zaimplementuj</a> własną metodę %s, aby ustawić je na stałe.',
|
||||||
'Language' => 'Język',
|
'Language' => 'Język',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Entrar',
|
'Login' => 'Entrar',
|
||||||
'Logout successful.' => 'Saída bem sucedida.',
|
'Logout successful.' => 'Saída bem sucedida.',
|
||||||
'Invalid credentials.' => 'Identificação inválida.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'Servidor',
|
'Server' => 'Servidor',
|
||||||
'Username' => 'Usuário',
|
'Username' => 'Usuário',
|
||||||
'Password' => 'Senha',
|
'Password' => 'Senha',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Entrar',
|
'Login' => 'Entrar',
|
||||||
'Logout successful.' => 'Sessão terminada com sucesso.',
|
'Logout successful.' => 'Sessão terminada com sucesso.',
|
||||||
'Invalid credentials.' => 'Identificação inválida.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'Servidor',
|
'Server' => 'Servidor',
|
||||||
'Username' => 'Nome de utilizador',
|
'Username' => 'Nome de utilizador',
|
||||||
'Password' => 'Senha',
|
'Password' => 'Senha',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Intră',
|
'Login' => 'Intră',
|
||||||
'Logout successful.' => 'Ați ieșit cu succes.',
|
'Logout successful.' => 'Ați ieșit cu succes.',
|
||||||
'Invalid credentials.' => 'Numele de utilizator sau parola este greșită.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'Server',
|
'Server' => 'Server',
|
||||||
'Username' => 'Nume de utilizator',
|
'Username' => 'Nume de utilizator',
|
||||||
'Password' => 'Parola',
|
'Password' => 'Parola',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Войти',
|
'Login' => 'Войти',
|
||||||
'Logout successful.' => 'Вы успешно покинули систему.',
|
'Logout successful.' => 'Вы успешно покинули систему.',
|
||||||
'Invalid credentials.' => 'Неправильное имя пользователя или пароль.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'Сервер',
|
'Server' => 'Сервер',
|
||||||
'Username' => 'Имя пользователя',
|
'Username' => 'Имя пользователя',
|
||||||
'Password' => 'Пароль',
|
'Password' => 'Пароль',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'Prihlásiť sa',
|
'Login' => 'Prihlásiť sa',
|
||||||
'Logout successful.' => 'Odhlásenie prebehlo v poriadku.',
|
'Logout successful.' => 'Odhlásenie prebehlo v poriadku.',
|
||||||
'Invalid credentials.' => 'Neplatné prihlasovacie údaje.',
|
'Invalid server or credentials.' => 'Neplatný server alebo prihlasovacie údaje.',
|
||||||
'Server' => 'Server',
|
'Server' => 'Server',
|
||||||
'Username' => 'Používateľ',
|
'Username' => 'Používateľ',
|
||||||
'Password' => 'Heslo',
|
'Password' => 'Heslo',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $translations = array(
|
|||||||
'Logout' => 'Odjavi se',
|
'Logout' => 'Odjavi se',
|
||||||
'Logged as: %s' => 'Prijavljen kot: %s',
|
'Logged as: %s' => 'Prijavljen kot: %s',
|
||||||
'Logout successful.' => 'Prijava uspešna.',
|
'Logout successful.' => 'Prijava uspešna.',
|
||||||
'Invalid credentials.' => 'Neveljavne pravice.',
|
'Invalid server or credentials.' => 'Neveljaven strežnik ali pravice.',
|
||||||
'Language' => 'Jezik',
|
'Language' => 'Jezik',
|
||||||
'Invalid CSRF token. Send the form again.' => 'Neveljaven token CSRF. Pošljite formular še enkrat.',
|
'Invalid CSRF token. Send the form again.' => 'Neveljaven token CSRF. Pošljite formular še enkrat.',
|
||||||
'No extension' => 'Brez dodatkov',
|
'No extension' => 'Brez dodatkov',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $translations = array(
|
|||||||
'Logout' => 'Одјава',
|
'Logout' => 'Одјава',
|
||||||
'Logged as: %s' => 'Пријави се као: %s',
|
'Logged as: %s' => 'Пријави се као: %s',
|
||||||
'Logout successful.' => 'Успешна одјава.',
|
'Logout successful.' => 'Успешна одјава.',
|
||||||
'Invalid credentials.' => 'Неважеће дозволе.',
|
'Invalid server or credentials.' => null,
|
||||||
'Language' => 'Језик',
|
'Language' => 'Језик',
|
||||||
'Invalid CSRF token. Send the form again.' => 'Неважећи CSRF код. Проследите поново форму.',
|
'Invalid CSRF token. Send the form again.' => 'Неважећи CSRF код. Проследите поново форму.',
|
||||||
'No extension' => 'Без додатака',
|
'No extension' => 'Без додатака',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ $translations = array(
|
|||||||
'Logged as: %s' => 'Inloggad som: %s',
|
'Logged as: %s' => 'Inloggad som: %s',
|
||||||
'Logout successful.' => 'Du är nu utloggad.',
|
'Logout successful.' => 'Du är nu utloggad.',
|
||||||
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Tack för att du använder Adminer, vänligen fundera över att <a href="https://www.adminer.org/en/donation/">donera</a>.',
|
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Tack för att du använder Adminer, vänligen fundera över att <a href="https://www.adminer.org/en/donation/">donera</a>.',
|
||||||
'Invalid credentials.' => 'Ogiltiga inloggningsuppgifter.',
|
'Invalid server or credentials.' => null,
|
||||||
'There is a space in the input password which might be the cause.' => 'Det finns ett mellanslag i lösenordet, vilket kan vara anledningen.',
|
'There is a space in the input password which might be the cause.' => 'Det finns ett mellanslag i lösenordet, vilket kan vara anledningen.',
|
||||||
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer tillåter inte att ansluta till en databas utan lösenord. <a href="https://www.adminer.org/en/password/"%s>Mer information</a>.',
|
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer tillåter inte att ansluta till en databas utan lösenord. <a href="https://www.adminer.org/en/password/"%s>Mer information</a>.',
|
||||||
'Database does not support password.' => 'Databasen stödjer inte lösenord.',
|
'Database does not support password.' => 'Databasen stödjer inte lösenord.',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'நுழை',
|
'Login' => 'நுழை',
|
||||||
'Logout successful.' => 'வெற்றிகரமாய் வெளியேறியாயிற்று.',
|
'Logout successful.' => 'வெற்றிகரமாய் வெளியேறியாயிற்று.',
|
||||||
'Invalid credentials.' => 'சரியான விபரங்கள் இல்லை.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'வழங்கி (Server)',
|
'Server' => 'வழங்கி (Server)',
|
||||||
'Username' => 'பயனாளர் (User)',
|
'Username' => 'பயனாளர் (User)',
|
||||||
'Password' => 'கடவுச்சொல்',
|
'Password' => 'கடவுச்சொல்',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
$translations = array(
|
$translations = array(
|
||||||
'Login' => 'เข้าสู่ระบบ',
|
'Login' => 'เข้าสู่ระบบ',
|
||||||
'Logout successful.' => 'ออกจากระบบเรียบร้อยแล้ว.',
|
'Logout successful.' => 'ออกจากระบบเรียบร้อยแล้ว.',
|
||||||
'Invalid credentials.' => 'ข้อมูลไม่ถูกต้อง.',
|
'Invalid server or credentials.' => null,
|
||||||
'Server' => 'เซอเวอร์',
|
'Server' => 'เซอเวอร์',
|
||||||
'Username' => 'ชื่อผู้ใช้งาน',
|
'Username' => 'ชื่อผู้ใช้งาน',
|
||||||
'Password' => 'รหัสผ่าน',
|
'Password' => 'รหัสผ่าน',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ $translations = array(
|
|||||||
'Logged as: %s' => '%s olarak giriş yapıldı.',
|
'Logged as: %s' => '%s olarak giriş yapıldı.',
|
||||||
'Logout successful.' => 'Oturum başarıyla sonlandı.',
|
'Logout successful.' => 'Oturum başarıyla sonlandı.',
|
||||||
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Adminer kullandığınız için teşekkür ederiz <a href="https://www.adminer.org/en/donation/">bağış yapmayı düşünün</a>.',
|
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Adminer kullandığınız için teşekkür ederiz <a href="https://www.adminer.org/en/donation/">bağış yapmayı düşünün</a>.',
|
||||||
'Invalid credentials.' => 'Geçersiz kimlik bilgileri.',
|
'Invalid server or credentials.' => null,
|
||||||
'Too many unsuccessful logins, try again in %d minute(s).' => array('Çok fazla oturum açma denemesi yapıldı.', '%d Dakika sonra tekrar deneyiniz.'),
|
'Too many unsuccessful logins, try again in %d minute(s).' => array('Çok fazla oturum açma denemesi yapıldı.', '%d Dakika sonra tekrar deneyiniz.'),
|
||||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Ana şifrenin süresi doldu. Kalıcı olması için <a href="https://www.adminer.org/en/extension/"%s>%s medodunu</a> kullanın.',
|
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Ana şifrenin süresi doldu. Kalıcı olması için <a href="https://www.adminer.org/en/extension/"%s>%s medodunu</a> kullanın.',
|
||||||
'Language' => 'Dil',
|
'Language' => 'Dil',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $translations = array(
|
|||||||
'Logout' => 'Вийти',
|
'Logout' => 'Вийти',
|
||||||
'Logged as: %s' => 'Ви увійшли як: %s',
|
'Logged as: %s' => 'Ви увійшли як: %s',
|
||||||
'Logout successful.' => 'Ви вдало вийшли з системи.',
|
'Logout successful.' => 'Ви вдало вийшли з системи.',
|
||||||
'Invalid credentials.' => 'Неправильні дані входу.',
|
'Invalid server or credentials.' => null,
|
||||||
'Language' => 'Мова',
|
'Language' => 'Мова',
|
||||||
'Invalid CSRF token. Send the form again.' => 'Недійсний CSRF токен. Надішліть форму ще раз.',
|
'Invalid CSRF token. Send the form again.' => 'Недійсний CSRF токен. Надішліть форму ще раз.',
|
||||||
'No extension' => 'Нема розширень',
|
'No extension' => 'Нема розширень',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $translations = array(
|
|||||||
'Logout' => 'Thoát',
|
'Logout' => 'Thoát',
|
||||||
'Logged as: %s' => 'Vào dưới tên: %s',
|
'Logged as: %s' => 'Vào dưới tên: %s',
|
||||||
'Logout successful.' => 'Đã thoát xong.',
|
'Logout successful.' => 'Đã thoát xong.',
|
||||||
'Invalid credentials.' => 'Tài khoản sai.',
|
'Invalid server or credentials.' => null,
|
||||||
'Too many unsuccessful logins, try again in %d minute(s).' => 'Bạn gõ sai tài khoản quá nhiều lần, hãy thử lại sau %d phút nữa.',
|
'Too many unsuccessful logins, try again in %d minute(s).' => 'Bạn gõ sai tài khoản quá nhiều lần, hãy thử lại sau %d phút nữa.',
|
||||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Mật khẩu đã hết hạn. <a href="https://www.adminer.org/en/extension/"%s>Thử cách làm</a> để giữ cố định.',
|
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Mật khẩu đã hết hạn. <a href="https://www.adminer.org/en/extension/"%s>Thử cách làm</a> để giữ cố định.',
|
||||||
'Language' => 'Ngôn ngữ',
|
'Language' => 'Ngôn ngữ',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ $translations = array(
|
|||||||
'Logged as: %s' => 'Xx: %s',
|
'Logged as: %s' => 'Xx: %s',
|
||||||
'Logout successful.' => 'Xx.',
|
'Logout successful.' => 'Xx.',
|
||||||
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Xx <a href="https://www.adminer.org/en/donation/">xx</a>.',
|
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Xx <a href="https://www.adminer.org/en/donation/">xx</a>.',
|
||||||
'Invalid credentials.' => 'Xx.',
|
'Invalid server or credentials.' => 'Xx.',
|
||||||
'There is a space in the input password which might be the cause.' => 'Xx.',
|
'There is a space in the input password which might be the cause.' => 'Xx.',
|
||||||
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Xx, <a href="https://www.adminer.org/en/password/"%s>xx</a>.',
|
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Xx, <a href="https://www.adminer.org/en/password/"%s>xx</a>.',
|
||||||
'Database does not support password.' => 'Xx.',
|
'Database does not support password.' => 'Xx.',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ $translations = array(
|
|||||||
'Logged as: %s' => '登錄為: %s',
|
'Logged as: %s' => '登錄為: %s',
|
||||||
'Logout successful.' => '成功登出。',
|
'Logout successful.' => '成功登出。',
|
||||||
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => '感謝使用Adminer,請考慮為我們<a href="https://www.adminer.org/en/donation/">捐款(英文網頁)</a>.',
|
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => '感謝使用Adminer,請考慮為我們<a href="https://www.adminer.org/en/donation/">捐款(英文網頁)</a>.',
|
||||||
'Invalid credentials.' => '無效的憑證。',
|
'Invalid server or credentials.' => null,
|
||||||
'There is a space in the input password which might be the cause.' => '您輸入的密碼中有一個空格,這可能是導致問題的原因。',
|
'There is a space in the input password which might be the cause.' => '您輸入的密碼中有一個空格,這可能是導致問題的原因。',
|
||||||
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer預設不支援訪問沒有密碼的資料庫,<a href="https://www.adminer.org/en/password/"%s>詳情見這裡</a>.',
|
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer預設不支援訪問沒有密碼的資料庫,<a href="https://www.adminer.org/en/password/"%s>詳情見這裡</a>.',
|
||||||
'Database does not support password.' => '資料庫不支援密碼。',
|
'Database does not support password.' => '資料庫不支援密碼。',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ $translations = array(
|
|||||||
'Logged as: %s' => '登录用户:%s',
|
'Logged as: %s' => '登录用户:%s',
|
||||||
'Logout successful.' => '成功登出。',
|
'Logout successful.' => '成功登出。',
|
||||||
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => '感谢使用Adminer,请考虑为我们<a href="https://www.adminer.org/en/donation/">捐款(英文页面)</a>.',
|
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => '感谢使用Adminer,请考虑为我们<a href="https://www.adminer.org/en/donation/">捐款(英文页面)</a>.',
|
||||||
'Invalid credentials.' => '无效凭据。',
|
'Invalid server or credentials.' => null,
|
||||||
'There is a space in the input password which might be the cause.' => '您输入的密码中有一个空格,这可能是导致问题的原因。',
|
'There is a space in the input password which might be the cause.' => '您输入的密码中有一个空格,这可能是导致问题的原因。',
|
||||||
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer默认不支持访问没有密码的数据库,<a href="https://www.adminer.org/en/password/"%s>详情见这里</a>.',
|
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer默认不支持访问没有密码的数据库,<a href="https://www.adminer.org/en/password/"%s>详情见这里</a>.',
|
||||||
'Database does not support password.' => '数据库不支持密码。',
|
'Database does not support password.' => '数据库不支持密码。',
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ if ($_GET["script"] == "db") {
|
|||||||
foreach ($sums + array("Auto_increment" => 0, "Rows" => 0) as $key => $val) {
|
foreach ($sums + array("Auto_increment" => 0, "Rows" => 0) as $key => $val) {
|
||||||
if ($table_status[$key] != "") {
|
if ($table_status[$key] != "") {
|
||||||
$val = format_number($table_status[$key]);
|
$val = format_number($table_status[$key]);
|
||||||
json_row("$key-$name", ($key == "Rows" && $val && $table_status["Engine"] == ($sql == "pgsql" ? "table" : "InnoDB")
|
json_row("$key-$name", ($key == "Rows" && $val && $table_status["Engine"] == ($jush == "pgsql" ? "table" : "InnoDB")
|
||||||
? "~ $val"
|
? "~ $val"
|
||||||
: $val
|
: $val
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ parse_str($_COOKIE["adminer_import"], $adminer_import);
|
|||||||
|
|
||||||
$rights = array(); // privilege => 0
|
$rights = array(); // privilege => 0
|
||||||
$columns = array(); // selectable columns
|
$columns = array(); // selectable columns
|
||||||
|
$search_columns = array(); // searchable columns
|
||||||
|
$order_columns = array(); // searchable columns
|
||||||
$text_length = null;
|
$text_length = null;
|
||||||
foreach ($fields as $key => $field) {
|
foreach ($fields as $key => $field) {
|
||||||
$name = $adminer->fieldName($field);
|
$name = $adminer->fieldName($field);
|
||||||
@@ -18,6 +20,12 @@ foreach ($fields as $key => $field) {
|
|||||||
$text_length = $adminer->selectLengthProcess();
|
$text_length = $adminer->selectLengthProcess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isset($field["privileges"]["where"]) && $name != "") {
|
||||||
|
$search_columns[$key] = html_entity_decode(strip_tags($name), ENT_QUOTES);
|
||||||
|
}
|
||||||
|
if (isset($field["privileges"]["order"]) && $name != "") {
|
||||||
|
$order_columns[$key] = html_entity_decode(strip_tags($name), ENT_QUOTES);
|
||||||
|
}
|
||||||
$rights += $field["privileges"];
|
$rights += $field["privileges"];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,8 +253,8 @@ if (!$columns && support("table")) {
|
|||||||
echo '<input type="hidden" name="select" value="' . h($TABLE) . '">';
|
echo '<input type="hidden" name="select" value="' . h($TABLE) . '">';
|
||||||
echo "</div>\n";
|
echo "</div>\n";
|
||||||
$adminer->selectColumnsPrint($select, $columns);
|
$adminer->selectColumnsPrint($select, $columns);
|
||||||
$adminer->selectSearchPrint($where, $columns, $indexes);
|
$adminer->selectSearchPrint($where, $search_columns, $indexes);
|
||||||
$adminer->selectOrderPrint($order, $columns, $indexes);
|
$adminer->selectOrderPrint($order, $order_columns, $indexes);
|
||||||
$adminer->selectLimitPrint($limit);
|
$adminer->selectLimitPrint($limit);
|
||||||
$adminer->selectLengthPrint($text_length);
|
$adminer->selectLengthPrint($text_length);
|
||||||
$adminer->selectActionPrint($indexes);
|
$adminer->selectActionPrint($indexes);
|
||||||
@@ -331,12 +339,20 @@ if (!$columns && support("table")) {
|
|||||||
$column = idf_escape($key);
|
$column = idf_escape($key);
|
||||||
$href = remove_from_uri('(order|desc)[^=]*|page') . '&order%5B0%5D=' . urlencode($key);
|
$href = remove_from_uri('(order|desc)[^=]*|page') . '&order%5B0%5D=' . urlencode($key);
|
||||||
$desc = "&desc%5B0%5D=1";
|
$desc = "&desc%5B0%5D=1";
|
||||||
|
$sortable = isset($field["privileges"]["order"]);
|
||||||
echo "<th id='th[" . h(bracket_escape($key)) . "]'>" . script("mixin(qsl('th'), {onmouseover: partial(columnMouse), onmouseout: partial(columnMouse, ' hidden')});", "");
|
echo "<th id='th[" . h(bracket_escape($key)) . "]'>" . script("mixin(qsl('th'), {onmouseover: partial(columnMouse), onmouseout: partial(columnMouse, ' hidden')});", "");
|
||||||
echo '<a href="' . h($href . ($order[0] == $column || $order[0] == $key || (!$order && $is_group && $group[0] == $column) ? $desc : '')) . '">'; // $order[0] == $key - COUNT(*)
|
if ($sortable) {
|
||||||
echo apply_sql_function($val["fun"], $name) . "</a>"; //! columns looking like functions
|
echo '<a href="' . h($href . ($order[0] == $column || $order[0] == $key || (!$order && $is_group && $group[0] == $column) ? $desc : '')) . '">'; // $order[0] == $key - COUNT(*)
|
||||||
|
}
|
||||||
|
echo apply_sql_function($val["fun"], $name); //! columns looking like functions
|
||||||
|
if ($sortable) {
|
||||||
|
echo "</a>";
|
||||||
|
}
|
||||||
echo "<span class='column hidden'>";
|
echo "<span class='column hidden'>";
|
||||||
echo "<a href='" . h($href . $desc) . "' title='" . lang('descending') . "' class='text'> ↓</a>";
|
if ($sortable) {
|
||||||
if (!$val["fun"]) {
|
echo "<a href='" . h($href . $desc) . "' title='" . lang('descending') . "' class='text'> ↓</a>";
|
||||||
|
}
|
||||||
|
if (!$val["fun"] && isset($field["privileges"]["where"])) {
|
||||||
echo '<a href="#fieldset-search" title="' . lang('Search') . '" class="text jsonly"> =</a>';
|
echo '<a href="#fieldset-search" title="' . lang('Search') . '" class="text jsonly"> =</a>';
|
||||||
echo script("qsl('a').onclick = partial(selectSearch, '" . js_escape($key) . "');");
|
echo script("qsl('a').onclick = partial(selectSearch, '" . js_escape($key) . "');");
|
||||||
}
|
}
|
||||||
@@ -552,9 +568,9 @@ if (!$columns && support("table")) {
|
|||||||
}
|
}
|
||||||
if ($format) {
|
if ($format) {
|
||||||
print_fieldset("export", lang('Export') . " <span id='selected2'></span>");
|
print_fieldset("export", lang('Export') . " <span id='selected2'></span>");
|
||||||
$output = $adminer->dumpOutput();
|
|
||||||
echo ($output ? html_select("output", $output, $adminer_import["output"]) . " " : "");
|
|
||||||
echo html_select("format", $format, $adminer_import["format"]);
|
echo html_select("format", $format, $adminer_import["format"]);
|
||||||
|
$output = $adminer->dumpOutput();
|
||||||
|
echo ($output ? " " . html_select("output", $output, $adminer_import["output"]) : "");
|
||||||
echo " <input type='submit' name='export' value='" . lang('Export') . "'>\n";
|
echo " <input type='submit' name='export' value='" . lang('Export') . "'>\n";
|
||||||
echo "</div></fieldset>\n";
|
echo "</div></fieldset>\n";
|
||||||
}
|
}
|
||||||
@@ -570,7 +586,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' class='hidden'>: ";
|
echo "<span id='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>";
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ if (!$error && $_POST) {
|
|||||||
$query .= fread($fp, 1e5);
|
$query .= fread($fp, 1e5);
|
||||||
} else {
|
} else {
|
||||||
$offset = $match[0][1] + strlen($s);
|
$offset = $match[0][1] + strlen($s);
|
||||||
if ($s[0] != "\\") {
|
if (!isset($s[0]) || $s[0] != "\\") {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
bin/export.sh
Normal file
24
bin/export.sh
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Root directory.
|
||||||
|
BASEDIR=$( cd `dirname $0`/.. ; pwd )
|
||||||
|
cd "$BASEDIR"
|
||||||
|
|
||||||
|
php compile.php
|
||||||
|
php compile.php en
|
||||||
|
php compile.php de
|
||||||
|
php compile.php cs
|
||||||
|
php compile.php sk
|
||||||
|
|
||||||
|
php compile.php mysql
|
||||||
|
php compile.php mysql en
|
||||||
|
php compile.php mysql de
|
||||||
|
php compile.php mysql cs
|
||||||
|
php compile.php mysql sk
|
||||||
|
|
||||||
|
php compile.php editor
|
||||||
|
php compile.php editor en
|
||||||
|
php compile.php editor mysql
|
||||||
|
php compile.php editor mysql en
|
||||||
15
changes.txt
15
changes.txt
@@ -1,3 +1,18 @@
|
|||||||
|
Adminer 4.9 (released 2024-08-19):
|
||||||
|
- Validate server input in login form.
|
||||||
|
- Validate connection to server in HTTP based drivers.
|
||||||
|
- Move dependencies from submodules to Composer.
|
||||||
|
- Update hydra and pepa-lintha-dark themes.
|
||||||
|
- Elasticsearch 5: Make unusable driver usable again, move it to plugins.
|
||||||
|
- Add new Elasticsearch 7 driver.
|
||||||
|
- Set saving to file as a default export option.
|
||||||
|
- Improve URL and email detection.
|
||||||
|
- Fix AdminerVersionNoverify plugin blocking other plugins to modify HTML head.
|
||||||
|
- Fix several bugs and security issues in AdminerFileUpload plugin.
|
||||||
|
- Skip dump of generated columns.
|
||||||
|
- Update composer.json.
|
||||||
|
- Add script for exporting compiled adminer variants.
|
||||||
|
|
||||||
Adminer 4.8.2 (released 2024-03-16):
|
Adminer 4.8.2 (released 2024-03-16):
|
||||||
Support multi-line table comments
|
Support multi-line table comments
|
||||||
MySQL: Use ST_SRID() instead of SRID() for MySQL 8 (PR #418)
|
MySQL: Use ST_SRID() instead of SRID() for MySQL 8 (PR #418)
|
||||||
|
|||||||
11
compile.php
11
compile.php
@@ -7,7 +7,7 @@ function adminer_errors($errno, $errstr) {
|
|||||||
error_reporting(6135); // errors and warnings
|
error_reporting(6135); // errors and warnings
|
||||||
set_error_handler('adminer_errors', E_WARNING);
|
set_error_handler('adminer_errors', E_WARNING);
|
||||||
include dirname(__FILE__) . "/adminer/include/version.inc.php";
|
include dirname(__FILE__) . "/adminer/include/version.inc.php";
|
||||||
include dirname(__FILE__) . "/externals/JsShrink/jsShrink.php";
|
include dirname(__FILE__) . "/vendor/vrana/jsshrink/jsShrink.php";
|
||||||
|
|
||||||
function add_apo_slashes($s) {
|
function add_apo_slashes($s) {
|
||||||
return addcslashes($s, "\\'");
|
return addcslashes($s, "\\'");
|
||||||
@@ -418,7 +418,7 @@ if ($driver) {
|
|||||||
if (count($drivers) == 1) {
|
if (count($drivers) == 1) {
|
||||||
$file = str_replace('<?php echo html_select("auth[driver]", $drivers, DRIVER) . "\n"; ?>', "<input type='hidden' name='auth[driver]' value='" . ($driver == "mysql" ? "server" : $driver) . "'>" . reset($drivers), $file);
|
$file = str_replace('<?php echo html_select("auth[driver]", $drivers, DRIVER) . "\n"; ?>', "<input type='hidden' name='auth[driver]' value='" . ($driver == "mysql" ? "server" : $driver) . "'>" . reset($drivers), $file);
|
||||||
}
|
}
|
||||||
$file = preg_replace('(;../externals/jush/modules/jush-(?!textarea\.|txt\.|js\.|' . preg_quote($driver == "mysql" ? "sql" : $driver) . '\.)[^.]+.js)', '', $file);
|
$file = preg_replace('(;../vendor/vrana/jush/modules/jush-(?!textarea\.|txt\.|js\.|' . preg_quote($driver == "mysql" ? "sql" : $driver) . '\.)[^.]+.js)', '', $file);
|
||||||
$file = preg_replace_callback('~doc_link\(array\((.*)\)\)~sU', function ($match) use ($driver) {
|
$file = preg_replace_callback('~doc_link\(array\((.*)\)\)~sU', function ($match) use ($driver) {
|
||||||
list(, $links) = $match;
|
list(, $links) = $match;
|
||||||
$links = preg_replace("~'(?!(" . ($driver == "mysql" ? "sql|mariadb" : $driver) . ")')[^']*' => [^,]*,?~", '', $links);
|
$links = preg_replace("~'(?!(" . ($driver == "mysql" ? "sql|mariadb" : $driver) . ")')[^']*' => [^,]*,?~", '', $links);
|
||||||
@@ -441,9 +441,9 @@ if ($_SESSION["lang"]) {
|
|||||||
}
|
}
|
||||||
$file = str_replace('<?php echo script_src("static/editing.js"); ?>' . "\n", "", $file);
|
$file = str_replace('<?php echo script_src("static/editing.js"); ?>' . "\n", "", $file);
|
||||||
$file = preg_replace('~\s+echo script_src\("\.\./externals/jush/modules/jush-(textarea|txt|js|\$jush)\.js"\);~', '', $file);
|
$file = preg_replace('~\s+echo script_src\("\.\./externals/jush/modules/jush-(textarea|txt|js|\$jush)\.js"\);~', '', $file);
|
||||||
$file = str_replace('<link rel="stylesheet" type="text/css" href="../externals/jush/jush.css">' . "\n", "", $file);
|
$file = str_replace('<link rel="stylesheet" type="text/css" href="../vendor/vrana/jush/jush.css">' . "\n", "", $file);
|
||||||
$file = preg_replace_callback("~compile_file\\('([^']+)'(?:, '([^']*)')?\\)~", 'compile_file', $file); // integrate static files
|
$file = preg_replace_callback("~compile_file\\('([^']+)'(?:, '([^']*)')?\\)~", 'compile_file', $file); // integrate static files
|
||||||
$replace = 'preg_replace("~\\\\\\\\?.*~", "", ME) . "?file=\1&version=' . $VERSION . '"';
|
$replace = 'preg_replace("~\\\\\\\\?.*~", "", ME) . "?file=\1&version=' . substr(md5(microtime()), 0, 8) . '"';
|
||||||
$file = preg_replace('~\.\./adminer/static/(default\.css|favicon\.ico)~', '<?php echo h(' . $replace . '); ?>', $file);
|
$file = preg_replace('~\.\./adminer/static/(default\.css|favicon\.ico)~', '<?php echo h(' . $replace . '); ?>', $file);
|
||||||
$file = preg_replace('~"\.\./adminer/static/(functions\.js)"~', $replace, $file);
|
$file = preg_replace('~"\.\./adminer/static/(functions\.js)"~', $replace, $file);
|
||||||
$file = preg_replace('~\.\./adminer/static/([^\'"]*)~', '" . h(' . $replace . ') . "', $file);
|
$file = preg_replace('~\.\./adminer/static/([^\'"]*)~', '" . h(' . $replace . ') . "', $file);
|
||||||
@@ -451,6 +451,7 @@ $file = preg_replace('~"\.\./externals/jush/modules/(jush\.js)"~', $replace, $fi
|
|||||||
$file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file);
|
$file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file);
|
||||||
$file = php_shrink($file);
|
$file = php_shrink($file);
|
||||||
|
|
||||||
$filename = $project . (preg_match('~-dev$~', $VERSION) ? "" : "-$VERSION") . ($driver ? "-$driver" : "") . ($_SESSION["lang"] ? "-$_SESSION[lang]" : "") . ".php";
|
@mkdir("temp/export", 0777, true);
|
||||||
|
$filename = "temp/export/$project" . (preg_match('~-dev$~', $VERSION) ? "" : "-$VERSION") . ($driver ? "-$driver" : "") . ($_SESSION["lang"] ? "-$_SESSION[lang]" : "") . ".php";
|
||||||
file_put_contents($filename, $file);
|
file_put_contents($filename, $file);
|
||||||
echo "$filename created (" . strlen($file) . " B).\n";
|
echo "$filename created (" . strlen($file) . " B).\n";
|
||||||
|
|||||||
@@ -26,11 +26,42 @@
|
|||||||
"GPL-2.0-only"
|
"GPL-2.0-only"
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.6",
|
"php": "5.6 - 8.1",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
"ext-json": "*"
|
"ext-json": "*",
|
||||||
|
"vrana/jush": "@dev",
|
||||||
|
"vrana/jsshrink": "@dev"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-zlib": "*",
|
||||||
|
"ext-suhosin": "*",
|
||||||
|
"ext-mysqli": "*",
|
||||||
|
"ext-mysql": "*",
|
||||||
|
"ext-pgsql": "*",
|
||||||
|
"ext-mongo": "*",
|
||||||
|
"ext-sqlsrv": "*",
|
||||||
|
"ext-mssql": "*",
|
||||||
|
"ext-oci8": "*",
|
||||||
|
"ext-interbase": "*",
|
||||||
|
"ext-pdo_pgsql": "*",
|
||||||
|
"ext-pdo_dblib": "*",
|
||||||
|
"ext-pdo_sqlite": "*",
|
||||||
|
"ext-pdo_oci": "*"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-xdebug": "*"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"compile": "php compile.php"
|
"compile": "php compile.php"
|
||||||
}
|
},
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "https://github.com/vrana/jush.git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "https://github.com/vrana/jsshrink.git"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Submodule designs/hydra updated: afcef61f66...f8aa49777e
Submodule designs/pepa-linha-dark updated: 81eb3c4870...0f4f3789af
@@ -202,7 +202,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
|
|||||||
$return = (preg_match('~^(1|t|true|y|yes|on)$~i', $val) ? lang('yes') : lang('no'));
|
$return = (preg_match('~^(1|t|true|y|yes|on)$~i', $val) ? lang('yes') : lang('no'));
|
||||||
}
|
}
|
||||||
if ($link) {
|
if ($link) {
|
||||||
$return = "<a href='$link'" . (is_url($link) ? target_blank() : "") . ">$return</a>";
|
$return = "<a href='$link'" . (is_web_url($link) ? target_blank() : "") . ">$return</a>";
|
||||||
}
|
}
|
||||||
if (!$link && !like_bool($field) && preg_match(number_type(), $field["type"])) {
|
if (!$link && !like_bool($field) && preg_match(number_type(), $field["type"])) {
|
||||||
$return = "<div class='number'>$return</div>"; // Firefox doesn't support <colgroup>
|
$return = "<div class='number'>$return</div>"; // Firefox doesn't support <colgroup>
|
||||||
@@ -580,8 +580,11 @@ qsl('div').onclick = whisperClick;", "")
|
|||||||
global $VERSION;
|
global $VERSION;
|
||||||
?>
|
?>
|
||||||
<h1>
|
<h1>
|
||||||
<?php echo $this->name(); ?> <span class="version"><?php echo $VERSION; ?></span>
|
<?php echo $this->name(); ?>
|
||||||
<a href="https://www.adminer.org/editor/#download"<?php echo target_blank(); ?> id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?></a>
|
<?php if ($missing != "auth"): ?>
|
||||||
|
<span class="version"><?php echo $VERSION; ?></span>
|
||||||
|
<a href="https://www.adminer.org/editor/#download"<?php echo target_blank(); ?> id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?></a>
|
||||||
|
<?php endif; ?>
|
||||||
</h1>
|
</h1>
|
||||||
<?php
|
<?php
|
||||||
if ($missing == "auth") {
|
if ($missing == "auth") {
|
||||||
|
|||||||
1
externals/JsShrink
vendored
1
externals/JsShrink
vendored
Submodule externals/JsShrink deleted from 17cbfacae6
1
externals/jush
vendored
1
externals/jush
vendored
Submodule externals/jush deleted from ae33623c66
@@ -8,56 +8,78 @@ if (isset($_GET["clickhouse"])) {
|
|||||||
var $extension = "JSON", $server_info, $errno, $_result, $error, $_url;
|
var $extension = "JSON", $server_info, $errno, $_result, $error, $_url;
|
||||||
var $_db = 'default';
|
var $_db = 'default';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $db
|
||||||
|
* @param string $query
|
||||||
|
* @return Min_Result|bool
|
||||||
|
*/
|
||||||
function rootQuery($db, $query) {
|
function rootQuery($db, $query) {
|
||||||
@ini_set('track_errors', 1); // @ - may be disabled
|
@ini_set('track_errors', 1); // @ - may be disabled
|
||||||
$file = @file_get_contents("$this->_url/?database=$db", false, stream_context_create(array('http' => array(
|
$file = @file_get_contents("$this->_url/?database=$db", false, stream_context_create(array('http' => array(
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'content' => $this->isQuerySelectLike($query) ? "$query FORMAT JSONCompact" : $query,
|
'content' => $this->isQuerySelectLike($query) ? "$query FORMAT JSONCompact" : $query,
|
||||||
'header' => 'Content-type: application/x-www-form-urlencoded',
|
'header' => 'Content-type: application/x-www-form-urlencoded',
|
||||||
'ignore_errors' => 1, // available since PHP 5.2.10
|
'ignore_errors' => 1,
|
||||||
|
'follow_location' => 0,
|
||||||
|
'max_redirects' => 0,
|
||||||
))));
|
))));
|
||||||
|
|
||||||
if ($file === false) {
|
if ($file === false) {
|
||||||
$this->error = $php_errormsg;
|
$this->error = lang('Invalid server or credentials.');
|
||||||
return $file;
|
|
||||||
}
|
|
||||||
if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) {
|
|
||||||
$this->error = lang('Invalid credentials.') . " $http_response_header[0]";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$return = json_decode($file, true);
|
|
||||||
if ($return === null) {
|
|
||||||
if (!$this->isQuerySelectLike($query) && $file === '') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->errno = json_last_error();
|
if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) {
|
||||||
if (function_exists('json_last_error_msg')) {
|
foreach ($http_response_header as $header) {
|
||||||
$this->error = json_last_error_msg();
|
if (preg_match('~^X-ClickHouse-Exception-Code:~i', $header)) {
|
||||||
} else {
|
$this->error = preg_replace('~\(version [^(]+\(.+$~', '', $file);
|
||||||
$constants = get_defined_constants(true);
|
return false;
|
||||||
foreach ($constants['json'] as $name => $value) {
|
|
||||||
if ($value == $this->errno && preg_match('~^JSON_ERROR_~', $name)) {
|
|
||||||
$this->error = $name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->error = lang('Invalid server or credentials.');
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return new Min_Result($return);
|
|
||||||
|
if (!$this->isQuerySelectLike($query) && $file === '') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = json_decode($file, true);
|
||||||
|
if ($return === null) {
|
||||||
|
$this->error = lang('Invalid server or credentials.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($return['rows']) || !isset($return['data']) || !isset($return['meta'])) {
|
||||||
|
$this->error = lang('Invalid server or credentials.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Min_Result($return['rows'], $return['data'], $return['meta']);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isQuerySelectLike($query) {
|
function isQuerySelectLike($query) {
|
||||||
return (bool) preg_match('~^(select|show)~i', $query);
|
return (bool) preg_match('~^(select|show)~i', $query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
* @return bool|Min_Result
|
||||||
|
*/
|
||||||
function query($query) {
|
function query($query) {
|
||||||
return $this->rootQuery($this->_db, $query);
|
return $this->rootQuery($this->_db, $query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $server
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
function connect($server, $username, $password) {
|
function connect($server, $username, $password) {
|
||||||
preg_match('~^(https?://)?(.*)~', $server, $match);
|
$this->_url = build_http_url($server, $username, $password, "localhost", 8123);
|
||||||
$this->_url = ($match[1] ? $match[1] : "http://") . "$username:$password@$match[2]";
|
|
||||||
$return = $this->query('SELECT 1');
|
$return = $this->query('SELECT 1');
|
||||||
return (bool) $return;
|
return (bool) $return;
|
||||||
}
|
}
|
||||||
@@ -92,11 +114,17 @@ if (isset($_GET["clickhouse"])) {
|
|||||||
class Min_Result {
|
class Min_Result {
|
||||||
var $num_rows, $_rows, $columns, $meta, $_offset = 0;
|
var $num_rows, $_rows, $columns, $meta, $_offset = 0;
|
||||||
|
|
||||||
function __construct($result) {
|
/**
|
||||||
$this->num_rows = $result['rows'];
|
* @param int $rows
|
||||||
$this->_rows = $result['data'];
|
* @param array[] $data
|
||||||
$this->meta = $result['meta'];
|
* @param array[] $meta
|
||||||
$this->columns = array_column($this->meta, 'name');
|
*/
|
||||||
|
function __construct($rows, array $data, array $meta) {
|
||||||
|
$this->num_rows = $rows;
|
||||||
|
$this->_rows = $data;
|
||||||
|
$this->meta = $meta;
|
||||||
|
$this->columns = array_column($meta, 'name');
|
||||||
|
|
||||||
reset($this->_rows);
|
reset($this->_rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +240,15 @@ if (isset($_GET["clickhouse"])) {
|
|||||||
return apply_queries("DROP TABLE", $tables);
|
return apply_queries("DROP TABLE", $tables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $hostPath
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function is_server_host_valid($hostPath)
|
||||||
|
{
|
||||||
|
return strpos(rtrim($hostPath, '/'), '/') === false;
|
||||||
|
}
|
||||||
|
|
||||||
function connect() {
|
function connect() {
|
||||||
global $adminer;
|
global $adminer;
|
||||||
$connection = new Min_DB;
|
$connection = new Min_DB;
|
||||||
@@ -316,7 +353,7 @@ if (isset($_GET["clickhouse"])) {
|
|||||||
"default" => trim($row['default_expression']),
|
"default" => trim($row['default_expression']),
|
||||||
"null" => $nullable,
|
"null" => $nullable,
|
||||||
"auto_increment" => '0',
|
"auto_increment" => '0',
|
||||||
"privileges" => array("insert" => 1, "select" => 1, "update" => 0),
|
"privileges" => array("insert" => 1, "select" => 1, "update" => 0, "where" => 1, "order" => 1),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
591
plugins/drivers/elastic.php
Normal file
591
plugins/drivers/elastic.php
Normal file
@@ -0,0 +1,591 @@
|
|||||||
|
<?php
|
||||||
|
add_driver("elastic", "Elasticsearch 7 (beta)");
|
||||||
|
|
||||||
|
if (isset($_GET["elastic"])) {
|
||||||
|
define("DRIVER", "elastic");
|
||||||
|
|
||||||
|
if (ini_bool('allow_url_fopen')) {
|
||||||
|
define("ELASTIC_DB_NAME", "elastic");
|
||||||
|
|
||||||
|
class Min_DB {
|
||||||
|
var $extension = "JSON", $server_info, $errno, $error, $_url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path
|
||||||
|
* @param array|null $content
|
||||||
|
* @param string $method
|
||||||
|
* @return array|false
|
||||||
|
*/
|
||||||
|
function rootQuery($path, array $content = null, $method = 'GET') {
|
||||||
|
@ini_set('track_errors', 1); // @ - may be disabled
|
||||||
|
|
||||||
|
$file = @file_get_contents("$this->_url/" . ltrim($path, '/'), false, stream_context_create(array('http' => array(
|
||||||
|
'method' => $method,
|
||||||
|
'content' => $content !== null ? json_encode($content) : null,
|
||||||
|
'header' => $content !== null ? 'Content-Type: application/json' : [],
|
||||||
|
'ignore_errors' => 1,
|
||||||
|
'follow_location' => 0,
|
||||||
|
'max_redirects' => 0,
|
||||||
|
))));
|
||||||
|
|
||||||
|
if ($file === false) {
|
||||||
|
$this->error = lang('Invalid server or credentials.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = json_decode($file, true);
|
||||||
|
if ($return === null) {
|
||||||
|
$this->error = lang('Invalid server or credentials.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) {
|
||||||
|
if (isset($return['error']['root_cause'][0]['type'])) {
|
||||||
|
$this->error = $return['error']['root_cause'][0]['type'] . ": " . $return['error']['root_cause'][0]['reason'];
|
||||||
|
} elseif (isset($return['status']) && isset($return['error']) && is_string($return['error'])) {
|
||||||
|
$this->error = $return['error'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Performs query relative to actual selected DB
|
||||||
|
* @param string $path
|
||||||
|
* @param array|null $content
|
||||||
|
* @param string $method
|
||||||
|
* @return array|false
|
||||||
|
*/
|
||||||
|
function query($path, array $content = null, $method = 'GET') {
|
||||||
|
// Support for global search through all tables
|
||||||
|
if ($path != "" && $path[0] == "S" && preg_match('/SELECT 1 FROM ([^ ]+) WHERE (.+) LIMIT ([0-9]+)/', $path, $matches)) {
|
||||||
|
global $driver;
|
||||||
|
|
||||||
|
$where = explode(" AND ", $matches[2]);
|
||||||
|
|
||||||
|
return $driver->select($matches[1], array("*"), $where, null, array(), $matches[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->rootQuery($path, $content, $method);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $server
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function connect($server, $username, $password) {
|
||||||
|
$this->_url = build_http_url($server, $username, $password, "localhost", 9200);
|
||||||
|
|
||||||
|
$return = $this->query('');
|
||||||
|
if (!$return) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($return['version']['number'])) {
|
||||||
|
$this->error = lang('Invalid server or credentials.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->server_info = $return['version']['number'];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function select_db($database) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function quote($string) {
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Min_Result {
|
||||||
|
var $num_rows, $_rows;
|
||||||
|
|
||||||
|
function __construct($rows) {
|
||||||
|
$this->num_rows = count($rows);
|
||||||
|
$this->_rows = $rows;
|
||||||
|
|
||||||
|
reset($this->_rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetch_assoc() {
|
||||||
|
$return = current($this->_rows);
|
||||||
|
next($this->_rows);
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetch_row() {
|
||||||
|
$row = $this->fetch_assoc();
|
||||||
|
|
||||||
|
return $row ? array_values($row) : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Min_Driver extends Min_SQL {
|
||||||
|
|
||||||
|
function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
|
||||||
|
$data = array();
|
||||||
|
if ($select != array("*")) {
|
||||||
|
$data["fields"] = $select;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($order) {
|
||||||
|
$sort = array();
|
||||||
|
foreach ($order as $col) {
|
||||||
|
$col = preg_replace('~ DESC$~', '', $col, 1, $count);
|
||||||
|
$sort[] = ($count ? array($col => "desc") : $col);
|
||||||
|
}
|
||||||
|
$data["sort"] = $sort;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($limit) {
|
||||||
|
$data["size"] = +$limit;
|
||||||
|
if ($page) {
|
||||||
|
$data["from"] = ($page * $limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($where as $val) {
|
||||||
|
if (preg_match('~^\((.+ OR .+)\)$~', $val, $matches)) {
|
||||||
|
$parts = explode(" OR ", $matches[1]);
|
||||||
|
$terms = array();
|
||||||
|
foreach ($parts as $part) {
|
||||||
|
list($col, $op, $val) = explode(" ", $part, 3);
|
||||||
|
$term = array($col => $val);
|
||||||
|
if ($op == "=") {
|
||||||
|
$terms[] = array("term" => $term);
|
||||||
|
} elseif (in_array($op, array("must", "should", "must_not"))) {
|
||||||
|
$data["query"]["bool"][$op][]["match"] = $term;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($terms)) {
|
||||||
|
$data["query"]["bool"]["filter"][]["bool"]["should"] = $terms;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
list($col, $op, $val) = explode(" ", $val, 3);
|
||||||
|
$term = array($col => $val);
|
||||||
|
if ($op == "=") {
|
||||||
|
$data["query"]["bool"]["filter"][] = array("term" => $term);
|
||||||
|
} elseif (in_array($op, array("must", "should", "must_not"))) {
|
||||||
|
$data["query"]["bool"][$op][]["match"] = $term;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "$table/_search";
|
||||||
|
$start = microtime(true);
|
||||||
|
$search = $this->_conn->rootQuery($query, $data);
|
||||||
|
|
||||||
|
if ($print) {
|
||||||
|
echo adminer()->selectQuery("$query: " . json_encode($data), $start, !$search);
|
||||||
|
}
|
||||||
|
if (empty($search)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = array();
|
||||||
|
foreach ($search["hits"]["hits"] as $hit) {
|
||||||
|
$row = array();
|
||||||
|
if ($select == array("*")) {
|
||||||
|
$row["_id"] = $hit["_id"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($select != array("*")) {
|
||||||
|
$fields = array();
|
||||||
|
foreach ($select as $key) {
|
||||||
|
$fields[$key] = $key == "_id" ? $hit["_id"] : $hit["_source"][$key];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$fields = $hit["_source"];
|
||||||
|
}
|
||||||
|
foreach ($fields as $key => $val) {
|
||||||
|
$row[$key] = (is_array($val) ? json_encode($val) : $val);
|
||||||
|
}
|
||||||
|
|
||||||
|
$return[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Min_Result($return);
|
||||||
|
}
|
||||||
|
|
||||||
|
function update($type, $record, $queryWhere, $limit = 0, $separator = "\n") {
|
||||||
|
//! use $limit
|
||||||
|
$parts = preg_split('~ *= *~', $queryWhere);
|
||||||
|
if (count($parts) == 2) {
|
||||||
|
$id = trim($parts[1]);
|
||||||
|
$query = "$type/$id";
|
||||||
|
|
||||||
|
return $this->_conn->query($query, $record, 'POST');
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function insert($type, $record) {
|
||||||
|
$id = ""; //! user should be able to inform _id
|
||||||
|
$query = "$type/$id";
|
||||||
|
$response = $this->_conn->query($query, $record, 'POST');
|
||||||
|
$this->_conn->last_id = $response['_id'];
|
||||||
|
|
||||||
|
return $response['created'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($table, $queryWhere, $limit = 0) {
|
||||||
|
//! use $limit
|
||||||
|
$ids = array();
|
||||||
|
if (isset($_GET["where"]["_id"]) && $_GET["where"]["_id"]) {
|
||||||
|
$ids[] = $_GET["where"]["_id"];
|
||||||
|
}
|
||||||
|
if (isset($_POST['check'])) {
|
||||||
|
foreach ($_POST['check'] as $check) {
|
||||||
|
$parts = preg_split('~ *= *~', $check);
|
||||||
|
if (count($parts) == 2) {
|
||||||
|
$ids[] = trim($parts[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_conn->affected_rows = 0;
|
||||||
|
|
||||||
|
foreach ($ids as $id) {
|
||||||
|
$query = "$table/_doc/$id";
|
||||||
|
$response = $this->_conn->query($query, null, 'DELETE');
|
||||||
|
if (isset($response['result']) && $response['result'] == 'deleted') {
|
||||||
|
$this->_conn->affected_rows++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_conn->affected_rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertOperator($operator) {
|
||||||
|
return $operator == "LIKE %%" ? "should" : $operator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function connect() {
|
||||||
|
$connection = new Min_DB;
|
||||||
|
|
||||||
|
list($server, $username, $password) = adminer()->credentials();
|
||||||
|
if ($password != "" && $connection->connect($server, $username, "")) {
|
||||||
|
return lang('Database does not support password.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($connection->connect($server, $username, $password)) {
|
||||||
|
return $connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $connection->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
function support($feature) {
|
||||||
|
return preg_match("~table|columns~", $feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
function logged_user() {
|
||||||
|
$credentials = adminer()->credentials();
|
||||||
|
|
||||||
|
return $credentials[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_databases() {
|
||||||
|
return array(ELASTIC_DB_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
function limit($query, $where, $limit, $offset = 0, $separator = " ") {
|
||||||
|
return " $query$where" . ($limit !== null ? $separator . "LIMIT $limit" . ($offset ? " OFFSET $offset" : "") : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function collations() {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
function db_collation($db, $collations) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
function engines() {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
function count_tables($databases) {
|
||||||
|
$return = connection()->rootQuery('_aliases');
|
||||||
|
if (empty($return)) {
|
||||||
|
return array(
|
||||||
|
ELASTIC_DB_NAME => 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
ELASTIC_DB_NAME => count($return)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function tables_list() {
|
||||||
|
$aliases = connection()->rootQuery('_aliases');
|
||||||
|
if (empty($aliases)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
ksort($aliases);
|
||||||
|
|
||||||
|
$tables = array();
|
||||||
|
foreach ($aliases as $name => $index) {
|
||||||
|
$tables[$name] = "table";
|
||||||
|
|
||||||
|
ksort($index["aliases"]);
|
||||||
|
$tables += array_fill_keys(array_keys($index["aliases"]), "view");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tables;
|
||||||
|
}
|
||||||
|
|
||||||
|
function table_status($name = "", $fast = false) {
|
||||||
|
$stats = connection()->rootQuery('_stats');
|
||||||
|
$aliases = connection()->rootQuery('_aliases');
|
||||||
|
|
||||||
|
if (empty($stats) || empty($aliases)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array();
|
||||||
|
|
||||||
|
if ($name != "") {
|
||||||
|
if (isset($stats["indices"][$name])) {
|
||||||
|
return format_index_status($name, $stats["indices"][$name]);
|
||||||
|
} else foreach ($aliases as $index_name => $index) {
|
||||||
|
foreach ($index["aliases"] as $alias_name => $alias) {
|
||||||
|
if ($alias_name == $name) {
|
||||||
|
return format_alias_status($alias_name, $stats["indices"][$index_name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ksort($stats["indices"]);
|
||||||
|
foreach ($stats["indices"] as $name => $index) {
|
||||||
|
if ($name[0] == ".") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result[$name] = format_index_status($name, $index);
|
||||||
|
|
||||||
|
if (!empty($aliases[$name]["aliases"])) {
|
||||||
|
ksort($aliases[$name]["aliases"]);
|
||||||
|
foreach ($aliases[$name]["aliases"] as $alias_name => $alias) {
|
||||||
|
$result[$alias_name] = format_alias_status($alias_name, $stats["indices"][$name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function format_index_status($name, $index) {
|
||||||
|
return array(
|
||||||
|
"Name" => $name,
|
||||||
|
"Engine" => "Lucene",
|
||||||
|
"Oid" => $index["uuid"],
|
||||||
|
"Rows" => $index["total"]["docs"]["count"],
|
||||||
|
"Auto_increment" => 0,
|
||||||
|
"Data_length" => $index["total"]["store"]["size_in_bytes"],
|
||||||
|
"Index_length" => 0,
|
||||||
|
"Data_free" => $index["total"]["store"]["reserved_in_bytes"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function format_alias_status($name, $index) {
|
||||||
|
return array(
|
||||||
|
"Name" => $name,
|
||||||
|
"Engine" => "view",
|
||||||
|
"Rows" => $index["total"]["docs"]["count"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_view($table_status) {
|
||||||
|
return $table_status["Engine"] == "view";
|
||||||
|
}
|
||||||
|
|
||||||
|
function error() {
|
||||||
|
return h(connection()->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
function information_schema() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
function indexes($table, $connection2 = null) {
|
||||||
|
return array(
|
||||||
|
array("type" => "PRIMARY", "columns" => array("_id")),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fields($table) {
|
||||||
|
$mappings = array();
|
||||||
|
$mapping = connection()->rootQuery("_mapping");
|
||||||
|
|
||||||
|
if (!isset($mapping[$table])) {
|
||||||
|
$aliases = connection()->rootQuery('_aliases');
|
||||||
|
|
||||||
|
foreach ($aliases as $index_name => $index) {
|
||||||
|
foreach ($index["aliases"] as $alias_name => $alias) {
|
||||||
|
if ($alias_name == $table) {
|
||||||
|
$table = $index_name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($mapping)) {
|
||||||
|
$mappings = $mapping[$table]["mappings"]["properties"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array(
|
||||||
|
"_id" => array(
|
||||||
|
"field" => "_id",
|
||||||
|
"full_type" => "text",
|
||||||
|
"type" => "text",
|
||||||
|
"privileges" => array("insert" => 1, "select" => 1, "where" => 1, "order" => 1),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($mappings as $name => $field) {
|
||||||
|
$has_index = !isset($field["index"]) || $field["index"];
|
||||||
|
|
||||||
|
// TODO: privileges: where => $has_index
|
||||||
|
// TODO: privileges: sort => $field["type"] != "text"
|
||||||
|
|
||||||
|
$result[$name] = array(
|
||||||
|
"field" => $name,
|
||||||
|
"full_type" => $field["type"],
|
||||||
|
"type" => $field["type"],
|
||||||
|
"privileges" => array(
|
||||||
|
"insert" => 1,
|
||||||
|
"select" => 1,
|
||||||
|
"update" => 1,
|
||||||
|
"where" => !isset($field["index"]) || $field["index"] ?: null,
|
||||||
|
"order" => $field["type"] != "text" ?: null
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function foreign_keys($table) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
function table($idf) {
|
||||||
|
return $idf;
|
||||||
|
}
|
||||||
|
|
||||||
|
function idf_escape($idf) {
|
||||||
|
return $idf;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convert_field($field) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
function unconvert_field($field, $return) {
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fk_support($table_status) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
function found_rows($table_status, $where) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create index
|
||||||
|
* @param string
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function create_database($db) {
|
||||||
|
return connection()->rootQuery(urlencode($db), null, 'PUT');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove index
|
||||||
|
* @param array
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function drop_databases($databases) {
|
||||||
|
return connection()->rootQuery(urlencode(implode(',', $databases)), null, 'DELETE');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Alter type
|
||||||
|
* @param array
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
|
||||||
|
$properties = array();
|
||||||
|
foreach ($fields as $f) {
|
||||||
|
$field_name = trim($f[1][0]);
|
||||||
|
$field_type = trim($f[1][1] ? $f[1][1] : "text");
|
||||||
|
$properties[$field_name] = array(
|
||||||
|
'type' => $field_type
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($properties)) {
|
||||||
|
$properties = array('properties' => $properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection()->query("_mapping/{$name}", $properties, 'PUT');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Drop types
|
||||||
|
* @param array
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function drop_tables($tables) {
|
||||||
|
$return = true;
|
||||||
|
foreach ($tables as $table) { //! convert to bulk api
|
||||||
|
$return = $return && connection()->query(urlencode($table), null, 'DELETE');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function last_id() {
|
||||||
|
return connection()->last_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function driver_config() {
|
||||||
|
$types = array();
|
||||||
|
$structured_types = array();
|
||||||
|
|
||||||
|
foreach (array(
|
||||||
|
lang('Numbers') => array("long" => 3, "integer" => 5, "short" => 8, "byte" => 10, "double" => 20, "float" => 66, "half_float" => 12, "scaled_float" => 21),
|
||||||
|
lang('Date and time') => array("date" => 10),
|
||||||
|
lang('Strings') => array("string" => 65535, "text" => 65535),
|
||||||
|
lang('Binary') => array("binary" => 255),
|
||||||
|
) as $key => $val) {
|
||||||
|
$types += $val;
|
||||||
|
$structured_types[$key] = array_keys($val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'possible_drivers' => array("json + allow_url_fopen"),
|
||||||
|
'jush' => "elastic",
|
||||||
|
'operators' => array("=", "must", "should", "must_not"),
|
||||||
|
'functions' => array(),
|
||||||
|
'grouping' => array(),
|
||||||
|
'edit_functions' => array(array("json")),
|
||||||
|
'types' => $types,
|
||||||
|
'structured_types' => $structured_types,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,82 +1,105 @@
|
|||||||
<?php
|
<?php
|
||||||
$drivers["elastic"] = "Elasticsearch (beta)";
|
add_driver("elastic5", "Elasticsearch 5 (beta)");
|
||||||
|
|
||||||
if (isset($_GET["elastic"])) {
|
if (isset($_GET["elastic5"])) {
|
||||||
define("DRIVER", "elastic");
|
define("DRIVER", "elastic5");
|
||||||
|
|
||||||
if (function_exists('json_decode') && ini_bool('allow_url_fopen')) {
|
if (ini_bool('allow_url_fopen')) {
|
||||||
class Min_DB {
|
class Min_DB {
|
||||||
var $extension = "JSON", $server_info, $errno, $error, $_url, $_db;
|
var $extension = "JSON", $server_info, $errno, $error, $_url, $_db;
|
||||||
|
|
||||||
/** Performs query
|
/**
|
||||||
* @param string
|
* @param string $path
|
||||||
* @param array
|
* @param array|null $content
|
||||||
* @param string
|
* @param string $method
|
||||||
* @return mixed
|
* @return array|false
|
||||||
*/
|
*/
|
||||||
function rootQuery($path, $content = array(), $method = 'GET') {
|
function rootQuery($path, array $content = null, $method = 'GET') {
|
||||||
@ini_set('track_errors', 1); // @ - may be disabled
|
@ini_set('track_errors', 1); // @ - may be disabled
|
||||||
|
|
||||||
$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 ? $content : json_encode($content),
|
'content' => $content !== null ? json_encode($content) : null,
|
||||||
'header' => 'Content-Type: application/json',
|
'header' => $content !== null ? 'Content-Type: application/json' : [],
|
||||||
'ignore_errors' => 1, // available since PHP 5.2.10
|
'ignore_errors' => 1,
|
||||||
|
'follow_location' => 0,
|
||||||
|
'max_redirects' => 0,
|
||||||
))));
|
))));
|
||||||
if (!$file) {
|
|
||||||
$this->error = $php_errormsg;
|
if ($file === false) {
|
||||||
return $file;
|
$this->error = lang('Invalid server or credentials.');
|
||||||
}
|
|
||||||
if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) {
|
|
||||||
$this->error = lang('Invalid credentials.') . " $http_response_header[0]";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$return = json_decode($file, true);
|
$return = json_decode($file, true);
|
||||||
if ($return === null) {
|
if ($return === null) {
|
||||||
$this->errno = json_last_error();
|
$this->error = lang('Invalid server or credentials.');
|
||||||
if (function_exists('json_last_error_msg')) {
|
return false;
|
||||||
$this->error = json_last_error_msg();
|
|
||||||
} else {
|
|
||||||
$constants = get_defined_constants(true);
|
|
||||||
foreach ($constants['json'] as $name => $value) {
|
|
||||||
if ($value == $this->errno && preg_match('~^JSON_ERROR_~', $name)) {
|
|
||||||
$this->error = $name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) {
|
||||||
|
if (isset($return['error']['root_cause'][0]['type'])) {
|
||||||
|
$this->error = $return['error']['root_cause'][0]['type'] . ": " . $return['error']['root_cause'][0]['reason'];
|
||||||
|
} else {
|
||||||
|
$this->error = lang('Invalid server or credentials.');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Performs query relative to actual selected DB
|
/** Performs query relative to actual selected DB
|
||||||
* @param string
|
* @param string $path
|
||||||
* @param array
|
* @param array|null $content
|
||||||
* @param string
|
* @param string $method
|
||||||
* @return mixed
|
* @return array|false
|
||||||
*/
|
*/
|
||||||
function query($path, $content = array(), $method = 'GET') {
|
function query($path, array $content = null, $method = 'GET') {
|
||||||
|
// Support for global search through all tables
|
||||||
|
if ($path != "" && $path[0] == "S" && preg_match('/SELECT 1 FROM ([^ ]+) WHERE (.+) LIMIT ([0-9]+)/', $path, $matches)) {
|
||||||
|
global $driver;
|
||||||
|
|
||||||
|
$where = explode(" AND ", $matches[2]);
|
||||||
|
|
||||||
|
return $driver->select($matches[1], array("*"), $where, null, array(), $matches[3]);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->rootQuery(($this->_db != "" ? "$this->_db/" : "/") . ltrim($path, '/'), $content, $method);
|
return $this->rootQuery(($this->_db != "" ? "$this->_db/" : "/") . ltrim($path, '/'), $content, $method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $server
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
function connect($server, $username, $password) {
|
function connect($server, $username, $password) {
|
||||||
preg_match('~^(https?://)?(.*)~', $server, $match);
|
$this->_url = build_http_url($server, $username, $password, "localhost", 9200);
|
||||||
$this->_url = ($match[1] ? $match[1] : "http://") . "$username:$password@$match[2]";
|
|
||||||
$return = $this->query('');
|
$return = $this->query('');
|
||||||
if ($return) {
|
if (!$return) {
|
||||||
$this->server_info = $return['version']['number'];
|
return false;
|
||||||
}
|
}
|
||||||
return (bool) $return;
|
|
||||||
|
if (!isset($return['version']['number'])) {
|
||||||
|
$this->error = lang('Invalid server or credentials.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->server_info = $return['version']['number'];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function select_db($database) {
|
function select_db($database) {
|
||||||
$this->_db = $database;
|
$this->_db = $database;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function quote($string) {
|
function quote($string) {
|
||||||
return $string;
|
return $string;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Min_Result {
|
class Min_Result {
|
||||||
@@ -85,34 +108,33 @@ if (isset($_GET["elastic"])) {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetch_row() {
|
function fetch_row() {
|
||||||
return array_values($this->fetch_assoc());
|
$row = $this->fetch_assoc();
|
||||||
|
|
||||||
|
return $row ? array_values($row) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Min_Driver extends Min_SQL {
|
class Min_Driver extends Min_SQL {
|
||||||
|
|
||||||
function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
|
function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
|
||||||
global $adminer;
|
|
||||||
$data = array();
|
$data = array();
|
||||||
$query = "$table/_search";
|
|
||||||
if ($select != array("*")) {
|
if ($select != array("*")) {
|
||||||
$data["fields"] = $select;
|
$data["fields"] = $select;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($order) {
|
if ($order) {
|
||||||
$sort = array();
|
$sort = array();
|
||||||
foreach ($order as $col) {
|
foreach ($order as $col) {
|
||||||
@@ -121,58 +143,78 @@ if (isset($_GET["elastic"])) {
|
|||||||
}
|
}
|
||||||
$data["sort"] = $sort;
|
$data["sort"] = $sort;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($limit) {
|
if ($limit) {
|
||||||
$data["size"] = +$limit;
|
$data["size"] = +$limit;
|
||||||
if ($page) {
|
if ($page) {
|
||||||
$data["from"] = ($page * $limit);
|
$data["from"] = ($page * $limit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($where as $val) {
|
foreach ($where as $val) {
|
||||||
list($col, $op, $val) = explode(" ", $val, 3);
|
if (preg_match('~^\((.+ OR .+)\)$~', $val, $matches)) {
|
||||||
if ($col == "_id") {
|
$parts = explode(" OR ", $matches[1]);
|
||||||
$data["query"]["ids"]["values"][] = $val;
|
$terms = array();
|
||||||
}
|
foreach ($parts as $part) {
|
||||||
elseif ($col . $val != "") {
|
list($col, $op, $val) = explode(" ", $part, 3);
|
||||||
$term = array("term" => array(($col != "" ? $col : "_all") => $val));
|
$term = array($col => $val);
|
||||||
|
if ($op == "=") {
|
||||||
|
$terms[] = array("term" => $term);
|
||||||
|
} elseif (in_array($op, array("must", "should", "must_not"))) {
|
||||||
|
$data["query"]["bool"][$op][]["match"] = $term;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($terms)) {
|
||||||
|
$data["query"]["bool"]["filter"][]["bool"]["should"] = $terms;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
list($col, $op, $val) = explode(" ", $val, 3);
|
||||||
|
$term = array($col => $val);
|
||||||
if ($op == "=") {
|
if ($op == "=") {
|
||||||
$data["query"]["filtered"]["filter"]["and"][] = $term;
|
$data["query"]["bool"]["filter"][] = array("term" => $term);
|
||||||
} else {
|
} elseif (in_array($op, array("must", "should", "must_not"))) {
|
||||||
$data["query"]["filtered"]["query"]["bool"]["must"][] = $term;
|
$data["query"]["bool"][$op][]["match"] = $term;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($data["query"] && !$data["query"]["filtered"]["query"] && !$data["query"]["ids"]) {
|
|
||||||
$data["query"]["filtered"]["query"] = array("match_all" => array());
|
$query = (min_version(7) ? "" : "$table/") . "_search";
|
||||||
}
|
|
||||||
$start = microtime(true);
|
$start = microtime(true);
|
||||||
$search = $this->_conn->query($query, $data);
|
$search = $this->_conn->query($query, $data);
|
||||||
|
|
||||||
if ($print) {
|
if ($print) {
|
||||||
echo $adminer->selectQuery("$query: " . json_encode($data), $start, !$search);
|
echo adminer()->selectQuery("$query: " . json_encode($data), $start, !$search);
|
||||||
}
|
}
|
||||||
if (!$search) {
|
if (!$search) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$return = array();
|
$return = array();
|
||||||
foreach ($search['hits']['hits'] as $hit) {
|
foreach ($search['hits']['hits'] as $hit) {
|
||||||
$row = array();
|
$row = array();
|
||||||
if ($select == array("*")) {
|
if ($select == array("*")) {
|
||||||
$row["_id"] = $hit["_id"];
|
$row["_id"] = $hit["_id"];
|
||||||
}
|
}
|
||||||
|
|
||||||
$fields = $hit['_source'];
|
$fields = $hit['_source'];
|
||||||
if ($select != array("*")) {
|
if ($select != array("*")) {
|
||||||
$fields = array();
|
$fields = array();
|
||||||
foreach ($select as $key) {
|
foreach ($select as $key) {
|
||||||
$fields[$key] = $hit['fields'][$key];
|
$fields[$key] = $key == "_id" ? [$hit["_id"]] : $hit['fields'][$key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($fields as $key => $val) {
|
foreach ($fields as $key => $val) {
|
||||||
if ($data["fields"]) {
|
if ($data["fields"]) {
|
||||||
$val = $val[0];
|
$val = $val[0];
|
||||||
}
|
}
|
||||||
$row[$key] = (is_array($val) ? json_encode($val) : $val); //! display JSON and others differently
|
$row[$key] = (is_array($val) ? json_encode($val) : $val); //! display JSON and others differently
|
||||||
}
|
}
|
||||||
|
|
||||||
$return[] = $row;
|
$return[] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Min_Result($return);
|
return new Min_Result($return);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,8 +224,10 @@ if (isset($_GET["elastic"])) {
|
|||||||
if (count($parts) == 2) {
|
if (count($parts) == 2) {
|
||||||
$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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,16 +236,17 @@ if (isset($_GET["elastic"])) {
|
|||||||
$query = "$type/$id";
|
$query = "$type/$id";
|
||||||
$response = $this->_conn->query($query, $record, 'POST');
|
$response = $this->_conn->query($query, $record, 'POST');
|
||||||
$this->_conn->last_id = $response['_id'];
|
$this->_conn->last_id = $response['_id'];
|
||||||
|
|
||||||
return $response['created'];
|
return $response['created'];
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete($type, $queryWhere, $limit = 0) {
|
function delete($type, $queryWhere, $limit = 0) {
|
||||||
//! use $limit
|
//! use $limit
|
||||||
$ids = array();
|
$ids = array();
|
||||||
if (is_array($_GET["where"]) && $_GET["where"]["_id"]) {
|
if (isset($_GET["where"]["_id"]) && $_GET["where"]["_id"]) {
|
||||||
$ids[] = $_GET["where"]["_id"];
|
$ids[] = $_GET["where"]["_id"];
|
||||||
}
|
}
|
||||||
if (is_array($_POST['check'])) {
|
if (isset($_POST['check'])) {
|
||||||
foreach ($_POST['check'] as $check) {
|
foreach ($_POST['check'] as $check) {
|
||||||
$parts = preg_split('~ *= *~', $check);
|
$parts = preg_split('~ *= *~', $check);
|
||||||
if (count($parts) == 2) {
|
if (count($parts) == 2) {
|
||||||
@@ -209,30 +254,46 @@ if (isset($_GET["elastic"])) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_conn->affected_rows = 0;
|
$this->_conn->affected_rows = 0;
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
$query = "{$type}/{$id}";
|
$query = "{$type}/{$id}";
|
||||||
$response = $this->_conn->query($query, '{}', 'DELETE');
|
$response = $this->_conn->query($query, null, 'DELETE');
|
||||||
if (is_array($response) && $response['found'] == true) {
|
if ((isset($response['found']) && $response['found']) || (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) {
|
||||||
|
return $operator == "LIKE %%" ? "should" : $operator;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $hostPath
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function is_server_host_valid($hostPath)
|
||||||
|
{
|
||||||
|
return strpos(rtrim($hostPath, '/'), '/') === false;
|
||||||
|
}
|
||||||
|
|
||||||
function connect() {
|
function connect() {
|
||||||
global $adminer;
|
|
||||||
$connection = new Min_DB;
|
$connection = new Min_DB;
|
||||||
list($server, $username, $password) = $adminer->credentials();
|
|
||||||
|
list($server, $username, $password) = adminer()->credentials();
|
||||||
if ($password != "" && $connection->connect($server, $username, "")) {
|
if ($password != "" && $connection->connect($server, $username, "")) {
|
||||||
return lang('Database does not support password.');
|
return lang('Database does not support password.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($connection->connect($server, $username, $password)) {
|
if ($connection->connect($server, $username, $password)) {
|
||||||
return $connection;
|
return $connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $connection->error;
|
return $connection->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,26 +302,31 @@ if (isset($_GET["elastic"])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function logged_user() {
|
function logged_user() {
|
||||||
global $adminer;
|
$credentials = adminer()->credentials();
|
||||||
$credentials = $adminer->credentials();
|
|
||||||
return $credentials[1];
|
return $credentials[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_databases() {
|
function get_databases() {
|
||||||
global $connection;
|
$return = connection()->rootQuery('_aliases');
|
||||||
$return = $connection->rootQuery('_aliases');
|
|
||||||
if ($return) {
|
if ($return) {
|
||||||
$return = array_keys($return);
|
$return = array_keys($return);
|
||||||
sort($return, SORT_STRING);
|
sort($return, SORT_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function limit($query, $where, $limit, $offset = 0, $separator = " ") {
|
||||||
|
return " $query$where" . ($limit !== null ? $separator . "LIMIT $limit" . ($offset ? " OFFSET $offset" : "") : "");
|
||||||
|
}
|
||||||
|
|
||||||
function collations() {
|
function collations() {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
function db_collation($db, $collations) {
|
function db_collation($db, $collations) {
|
||||||
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
function engines() {
|
function engines() {
|
||||||
@@ -268,9 +334,9 @@ if (isset($_GET["elastic"])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function count_tables($databases) {
|
function count_tables($databases) {
|
||||||
global $connection;
|
|
||||||
$return = array();
|
$return = array();
|
||||||
$result = $connection->query('_stats');
|
|
||||||
|
$result = connection()->query('_stats');
|
||||||
if ($result && $result['indices']) {
|
if ($result && $result['indices']) {
|
||||||
$indices = $result['indices'];
|
$indices = $result['indices'];
|
||||||
foreach ($indices as $indice => $stats) {
|
foreach ($indices as $indice => $stats) {
|
||||||
@@ -278,26 +344,25 @@ if (isset($_GET["elastic"])) {
|
|||||||
$return[$indice] = $indexing['index_total'];
|
$return[$indice] = $indexing['index_total'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function tables_list() {
|
function tables_list() {
|
||||||
global $connection;
|
if (min_version(7)) {
|
||||||
|
|
||||||
if (min_version(6)) {
|
|
||||||
return array('_doc' => 'table');
|
return array('_doc' => 'table');
|
||||||
}
|
}
|
||||||
|
|
||||||
$return = $connection->query('_mapping');
|
$return = connection()->query('_mapping');
|
||||||
if ($return) {
|
if ($return) {
|
||||||
$return = array_fill_keys(array_keys($return[$connection->_db]["mappings"]), 'table');
|
$return = array_fill_keys(array_keys($return[connection()->_db]["mappings"]), 'table');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function table_status($name = "", $fast = false) {
|
function table_status($name = "", $fast = false) {
|
||||||
global $connection;
|
$search = connection()->query("_search", array(
|
||||||
$search = $connection->query("_search", array(
|
|
||||||
"size" => 0,
|
"size" => 0,
|
||||||
"aggregations" => array(
|
"aggregations" => array(
|
||||||
"count_by_type" => array(
|
"count_by_type" => array(
|
||||||
@@ -307,26 +372,30 @@ if (isset($_GET["elastic"])) {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
), "POST");
|
), "POST");
|
||||||
|
|
||||||
$return = array();
|
$return = array();
|
||||||
|
|
||||||
if ($search) {
|
if ($search) {
|
||||||
$tables = $search["aggregations"]["count_by_type"]["buckets"];
|
$tables = $search["aggregations"]["count_by_type"]["buckets"];
|
||||||
|
|
||||||
foreach ($tables as $table) {
|
foreach ($tables as $table) {
|
||||||
$return[$table["key"]] = array(
|
$return[$table["key"]] = array(
|
||||||
"Name" => $table["key"],
|
"Name" => $table["key"],
|
||||||
"Engine" => "table",
|
"Engine" => "table",
|
||||||
"Rows" => $table["doc_count"],
|
"Rows" => $table["doc_count"],
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($name != "" && $name == $table["key"]) {
|
if ($name != "" && $name == $table["key"]) {
|
||||||
return $return[$name];
|
return $return[$name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function error() {
|
function error() {
|
||||||
global $connection;
|
return h(connection()->error);
|
||||||
return h($connection->error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function information_schema() {
|
function information_schema() {
|
||||||
@@ -342,39 +411,54 @@ if (isset($_GET["elastic"])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fields($table) {
|
function fields($table) {
|
||||||
global $connection;
|
|
||||||
|
|
||||||
$mappings = array();
|
$mappings = array();
|
||||||
if (min_version(6)) {
|
|
||||||
$result = $connection->query("_mapping");
|
if (min_version(7)) {
|
||||||
|
$result = connection()->query("_mapping");
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$mappings = $result[$connection->_db]['mappings']['properties'];
|
$mappings = $result[connection()->_db]['mappings']['properties'];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$result = $connection->query("$table/_mapping");
|
$result = connection()->query("$table/_mapping");
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$mappings = $result[$table]['properties'];
|
$mappings = $result[$table]['properties'];
|
||||||
if (!$mappings) {
|
if (!$mappings) {
|
||||||
$mappings = $result[$connection->_db]['mappings'][$table]['properties'];
|
$mappings = $result[connection()->_db]['mappings'][$table]['properties'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$return = array();
|
$return = array(
|
||||||
if ($mappings) {
|
"_id" => array(
|
||||||
foreach ($mappings as $name => $field) {
|
"field" => "_id",
|
||||||
$return[$name] = array(
|
"full_type" => "text",
|
||||||
"field" => $name,
|
"type" => "text",
|
||||||
"full_type" => $field["type"],
|
"privileges" => array("insert" => 1, "select" => 1, "where" => 1, "order" => 1),
|
||||||
"type" => $field["type"],
|
)
|
||||||
"privileges" => array("insert" => 1, "select" => 1, "update" => 1),
|
);
|
||||||
);
|
|
||||||
if ($field["properties"]) { // only leaf fields can be edited
|
foreach ($mappings as $name => $field) {
|
||||||
unset($return[$name]["privileges"]["insert"]);
|
if (isset($field["index"]) && !$field["index"]) continue;
|
||||||
unset($return[$name]["privileges"]["update"]);
|
|
||||||
}
|
$return[$name] = array(
|
||||||
|
"field" => $name,
|
||||||
|
"full_type" => $field["type"],
|
||||||
|
"type" => $field["type"],
|
||||||
|
"privileges" => array(
|
||||||
|
"insert" => 1,
|
||||||
|
"select" => 1,
|
||||||
|
"update" => 1,
|
||||||
|
"where" => !isset($field["index"]) || $field["index"] ?: null,
|
||||||
|
"order" => $field["type"] != "text" ?: null
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($field["properties"]) { // only leaf fields can be edited
|
||||||
|
unset($return[$name]["privileges"]["insert"]);
|
||||||
|
unset($return[$name]["privileges"]["update"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,6 +475,7 @@ if (isset($_GET["elastic"])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function convert_field($field) {
|
function convert_field($field) {
|
||||||
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
function unconvert_field($field, $return) {
|
function unconvert_field($field, $return) {
|
||||||
@@ -398,6 +483,7 @@ if (isset($_GET["elastic"])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fk_support($table_status) {
|
function fk_support($table_status) {
|
||||||
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
function found_rows($table_status, $where) {
|
function found_rows($table_status, $where) {
|
||||||
@@ -405,29 +491,26 @@ if (isset($_GET["elastic"])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Create index
|
/** Create index
|
||||||
* @param string
|
* @param string
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
function create_database($db) {
|
function create_database($db) {
|
||||||
global $connection;
|
return connection()->rootQuery(urlencode($db), null, 'PUT');
|
||||||
return $connection->rootQuery(urlencode($db), null, 'PUT');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remove index
|
/** Remove index
|
||||||
* @param array
|
* @param array
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
function drop_databases($databases) {
|
function drop_databases($databases) {
|
||||||
global $connection;
|
return connection()->rootQuery(urlencode(implode(',', $databases)), null, 'DELETE');
|
||||||
return $connection->rootQuery(urlencode(implode(',', $databases)), array(), 'DELETE');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Alter type
|
/** Alter type
|
||||||
* @param array
|
* @param array
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
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;
|
|
||||||
$properties = array();
|
$properties = array();
|
||||||
foreach ($fields as $f) {
|
foreach ($fields as $f) {
|
||||||
$field_name = trim($f[1][0]);
|
$field_name = trim($f[1][0]);
|
||||||
@@ -436,33 +519,34 @@ if (isset($_GET["elastic"])) {
|
|||||||
'type' => $field_type
|
'type' => $field_type
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($properties)) {
|
if (!empty($properties)) {
|
||||||
$properties = array('properties' => $properties);
|
$properties = array('properties' => $properties);
|
||||||
}
|
}
|
||||||
return $connection->query("_mapping/{$name}", $properties, 'PUT');
|
return connection()->query("_mapping/{$name}", $properties, 'PUT');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Drop types
|
/** Drop types
|
||||||
* @param array
|
* @param array
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function drop_tables($tables) {
|
function drop_tables($tables) {
|
||||||
global $connection;
|
|
||||||
$return = true;
|
$return = true;
|
||||||
foreach ($tables as $table) { //! convert to bulk api
|
foreach ($tables as $table) { //! convert to bulk api
|
||||||
$return = $return && $connection->query(urlencode($table), array(), 'DELETE');
|
$return = $return && connection()->query(urlencode($table), null, 'DELETE');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function last_id() {
|
function last_id() {
|
||||||
global $connection;
|
return connection()->last_id;
|
||||||
return $connection->last_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function driver_config() {
|
function driver_config() {
|
||||||
$types = array();
|
$types = array();
|
||||||
$structured_types = array();
|
$structured_types = array();
|
||||||
|
|
||||||
foreach (array(
|
foreach (array(
|
||||||
lang('Numbers') => array("long" => 3, "integer" => 5, "short" => 8, "byte" => 10, "double" => 20, "float" => 66, "half_float" => 12, "scaled_float" => 21),
|
lang('Numbers') => array("long" => 3, "integer" => 5, "short" => 8, "byte" => 10, "double" => 20, "float" => 66, "half_float" => 12, "scaled_float" => 21),
|
||||||
lang('Date and time') => array("date" => 10),
|
lang('Date and time') => array("date" => 10),
|
||||||
@@ -472,10 +556,11 @@ if (isset($_GET["elastic"])) {
|
|||||||
$types += $val;
|
$types += $val;
|
||||||
$structured_types[$key] = array_keys($val);
|
$structured_types[$key] = array_keys($val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'possible_drivers' => array("json + allow_url_fopen"),
|
'possible_drivers' => array("json + allow_url_fopen"),
|
||||||
'jush' => "elastic",
|
'jush' => "elastic",
|
||||||
'operators' => array("=", "query"),
|
'operators' => array("=", "must", "should", "must_not"),
|
||||||
'functions' => array(),
|
'functions' => array(),
|
||||||
'grouping' => array(),
|
'grouping' => array(),
|
||||||
'edit_functions' => array(array("json")),
|
'edit_functions' => array(array("json")),
|
||||||
@@ -250,7 +250,7 @@ ORDER BY r.RDB$FIELD_POSITION';
|
|||||||
"null" => (trim($row["FIELD_NOT_NULL_CONSTRAINT"]) == "YES"),
|
"null" => (trim($row["FIELD_NOT_NULL_CONSTRAINT"]) == "YES"),
|
||||||
"auto_increment" => '0',
|
"auto_increment" => '0',
|
||||||
"collation" => trim($row["FIELD_COLLATION"]),
|
"collation" => trim($row["FIELD_COLLATION"]),
|
||||||
"privileges" => array("insert" => 1, "select" => 1, "update" => 1),
|
"privileges" => array("insert" => 1, "select" => 1, "update" => 1, "where" => 1, "order" => 1),
|
||||||
"comment" => trim($row["FIELD_DESCRIPTION"]),
|
"comment" => trim($row["FIELD_DESCRIPTION"]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,49 @@ if (isset($_GET["simpledb"])) {
|
|||||||
|
|
||||||
if (class_exists('SimpleXMLElement') && ini_bool('allow_url_fopen')) {
|
if (class_exists('SimpleXMLElement') && ini_bool('allow_url_fopen')) {
|
||||||
class Min_DB {
|
class Min_DB {
|
||||||
var $extension = "SimpleXML", $server_info = '2009-04-15', $error, $timeout, $next, $affected_rows, $_result;
|
var $extension = "SimpleXML", $server_info = '2009-04-15', $error, $timeout, $next, $affected_rows, $_url, $_result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $server
|
||||||
|
* @param string $password
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function connect($server, $password) {
|
||||||
|
if ($server == '' || $password == '') {
|
||||||
|
$this->error = lang('Invalid server or credentials.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = parse_url($server);
|
||||||
|
|
||||||
|
if (!$parts || !isset($parts['host']) || !preg_match('~^sdb\.([a-z0-9-]+\.)?amazonaws\.com$~i', $parts['host']) ||
|
||||||
|
isset($parts['port'])
|
||||||
|
) {
|
||||||
|
$this->error = lang('Invalid server or credentials.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_url = build_http_url($server, '', '', '');
|
||||||
|
|
||||||
|
return (bool) $this->workaroundLoginRequest('ListDomains', ['MaxNumberOfDomains' => 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: This is so wrong :-( Move sdb_request to Min_DB!
|
||||||
|
private function workaroundLoginRequest($action, $params = array()) {
|
||||||
|
global $connection;
|
||||||
|
|
||||||
|
$connection = $this;
|
||||||
|
$result = sdb_request($action, $params);
|
||||||
|
$connection = null;
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
function select_db($database) {
|
function select_db($database) {
|
||||||
return ($database == "domain");
|
return ($database == "domain");
|
||||||
}
|
}
|
||||||
|
|
||||||
function query($query, $unbuffered = false) {
|
function query($query) {
|
||||||
$params = array('SelectExpression' => $query, 'ConsistentRead' => 'true');
|
$params = array('SelectExpression' => $query, 'ConsistentRead' => 'true');
|
||||||
if ($this->next) {
|
if ($this->next) {
|
||||||
$params['NextToken'] = $this->next;
|
$params['NextToken'] = $this->next;
|
||||||
@@ -244,15 +280,26 @@ if (isset($_GET["simpledb"])) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $hostPath
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function is_server_host_valid($hostPath)
|
||||||
|
{
|
||||||
|
return strpos(rtrim($hostPath, '/'), '/') === false;
|
||||||
|
}
|
||||||
|
|
||||||
function connect() {
|
function connect() {
|
||||||
global $adminer;
|
global $adminer;
|
||||||
list(, , $password) = $adminer->credentials();
|
|
||||||
if ($password != "") {
|
$connection = new Min_DB;
|
||||||
return lang('Database does not support password.');
|
|
||||||
|
list($server, , $password) = $adminer->credentials();
|
||||||
|
if ($connection->connect($server, $password)) {
|
||||||
|
return $connection;
|
||||||
}
|
}
|
||||||
return new Min_DB;
|
|
||||||
|
return $connection->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
function support($feature) {
|
function support($feature) {
|
||||||
@@ -422,13 +469,16 @@ if (isset($_GET["simpledb"])) {
|
|||||||
$query = str_replace('%7E', '~', substr($query, 1));
|
$query = str_replace('%7E', '~', substr($query, 1));
|
||||||
$query .= "&Signature=" . urlencode(base64_encode(hmac('sha1', "POST\n" . preg_replace('~^https?://~', '', $host) . "\n/\n$query", $secret, true)));
|
$query .= "&Signature=" . urlencode(base64_encode(hmac('sha1', "POST\n" . preg_replace('~^https?://~', '', $host) . "\n/\n$query", $secret, true)));
|
||||||
@ini_set('track_errors', 1); // @ - may be disabled
|
@ini_set('track_errors', 1); // @ - may be disabled
|
||||||
$file = @file_get_contents((preg_match('~^https?://~', $host) ? $host : "http://$host"), false, stream_context_create(array('http' => array(
|
|
||||||
|
$file = @file_get_contents($connection->_url, false, stream_context_create(array('http' => array(
|
||||||
'method' => 'POST', // may not fit in URL with GET
|
'method' => 'POST', // may not fit in URL with GET
|
||||||
'content' => $query,
|
'content' => $query,
|
||||||
'ignore_errors' => 1, // available since PHP 5.2.10
|
'ignore_errors' => 1,
|
||||||
|
'follow_location' => 0,
|
||||||
|
'max_redirects' => 0,
|
||||||
))));
|
))));
|
||||||
if (!$file) {
|
if (!$file) {
|
||||||
$connection->error = $php_errormsg;
|
$connection->error = error_get_last()['message'];
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
libxml_use_internal_errors(true);
|
libxml_use_internal_errors(true);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
//! delete
|
|
||||||
|
|
||||||
/** Edit fields ending with "_path" by <input type="file"> and link to the uploaded files from select
|
/** Edit fields ending with "_path" by <input type="file"> and link to the uploaded files from select
|
||||||
* @link https://www.adminer.org/plugins/#use
|
* @link https://www.adminer.org/plugins/#use
|
||||||
@@ -12,9 +11,9 @@ class AdminerFileUpload {
|
|||||||
var $uploadPath, $displayPath, $extensions;
|
var $uploadPath, $displayPath, $extensions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string prefix for uploading data (create writable subdirectory for each table containing uploadable fields)
|
* @param string $uploadPath prefix for uploading data (create writable subdirectory for each table containing uploadable fields)
|
||||||
* @param string prefix for displaying data, null stands for $uploadPath
|
* @param string|null $displayPath prefix for displaying data, null stands for $uploadPath
|
||||||
* @param string regular expression with allowed file extensions
|
* @param string $extensions regular expression with allowed file extensions
|
||||||
*/
|
*/
|
||||||
function __construct($uploadPath = "../static/data/", $displayPath = null, $extensions = "[a-zA-Z0-9]+") {
|
function __construct($uploadPath = "../static/data/", $displayPath = null, $extensions = "[a-zA-Z0-9]+") {
|
||||||
$this->uploadPath = $uploadPath;
|
$this->uploadPath = $uploadPath;
|
||||||
@@ -30,24 +29,56 @@ class AdminerFileUpload {
|
|||||||
|
|
||||||
function processInput($field, $value, $function = "") {
|
function processInput($field, $value, $function = "") {
|
||||||
if (preg_match('~(.*)_path$~', $field["field"], $regs)) {
|
if (preg_match('~(.*)_path$~', $field["field"], $regs)) {
|
||||||
$table = ($_GET["edit"] != "" ? $_GET["edit"] : $_GET["select"]);
|
$tableName = ($_GET["edit"] != "" ? $_GET["edit"] : $_GET["select"]);
|
||||||
$name = "fields-$field[field]";
|
$fieldName = $field["field"];
|
||||||
if ($_FILES[$name]["error"] || !preg_match("~(\\.($this->extensions))?\$~", $_FILES[$name]["name"], $regs2)) {
|
$files = $_FILES["fields"];
|
||||||
|
|
||||||
|
// Check upload error and file extension.
|
||||||
|
if ($files["error"][$fieldName] || !preg_match('~\.(' . $this->extensions . ')$~', $files["name"][$fieldName], $regs2)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//! unlink old
|
|
||||||
$filename = uniqid() . $regs2[0];
|
// Generate random unique file name.
|
||||||
if (!move_uploaded_file($_FILES[$name]["tmp_name"], "$this->uploadPath$table/$regs[1]-$filename")) {
|
do {
|
||||||
|
$filename = $this->generateName() . $regs2[0];
|
||||||
|
|
||||||
|
$targetPath = $this->uploadPath . $this->fsEncode($tableName) . "/" . $this->fsEncode($regs[1]) . "-$filename";
|
||||||
|
} while (file_exists($targetPath));
|
||||||
|
|
||||||
|
// Move file to final destination.
|
||||||
|
if (!move_uploaded_file($files["tmp_name"][$fieldName], $targetPath)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return q($filename);
|
return q($filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectVal($val, &$link, $field, $original) {
|
private function fsEncode($value) {
|
||||||
if ($val != "" && preg_match('~(.*)_path$~', $field["field"], $regs)) {
|
// Encode special filesystem characters.
|
||||||
$link = "$this->displayPath$_GET[select]/$regs[1]-$val";
|
return strtr($value, [
|
||||||
}
|
'.' => '%2E',
|
||||||
|
'/' => '%2F',
|
||||||
|
'\\' => '%5C',
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function generateName()
|
||||||
|
{
|
||||||
|
$rand = function_exists("random_int") ? "random_int" : "rand";
|
||||||
|
|
||||||
|
$result = '';
|
||||||
|
for ($i = 0; $i < 16; $i++) {
|
||||||
|
$code = $rand(97, 132); // random ASCII code for a-z and shifted 0-9
|
||||||
|
$result .= chr($code > 122 ? $code - 122 + 47 : $code);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectVal($val, &$link, $field, $original) {
|
||||||
|
if ($val != "" && preg_match('~(.*)_path$~', $field["field"], $regs)) {
|
||||||
|
$link = $this->displayPath . "$_GET[select]/$regs[1]-$val";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ class AdminerVersionNoverify {
|
|||||||
|
|
||||||
function head() {
|
function head() {
|
||||||
echo script("verifyVersion = function () {};");
|
echo script("verifyVersion = function () {};");
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
1
todo.txt
1
todo.txt
@@ -20,7 +20,6 @@ Joining tables - PRIMARY KEY (table, joining)
|
|||||||
Rank, Tree structure
|
Rank, Tree structure
|
||||||
|
|
||||||
MySQL:
|
MySQL:
|
||||||
Generated columns (MySQL >= 5.7.6)
|
|
||||||
Data longer than max_allowed_packet can be sent by mysqli_stmt_send_long_data()
|
Data longer than max_allowed_packet can be sent by mysqli_stmt_send_long_data()
|
||||||
|
|
||||||
MariaDB:
|
MariaDB:
|
||||||
|
|||||||
Reference in New Issue
Block a user